diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/brown-timers-vanish.md b/.changeset/brown-timers-vanish.md new file mode 100644 index 0000000..6c18003 --- /dev/null +++ b/.changeset/brown-timers-vanish.md @@ -0,0 +1,5 @@ +--- +'better-auth-convex': patch +--- + +init diff --git a/.changeset/changelog-config.js b/.changeset/changelog-config.js new file mode 100644 index 0000000..6fda4a6 --- /dev/null +++ b/.changeset/changelog-config.js @@ -0,0 +1,99 @@ +const { config } = require('dotenv'); +const { + getInfo, + getInfoFromPullRequest, +} = require('@changesets/get-github-info'); + +config(); + +module.exports = { + getDependencyReleaseLine: async () => { + return ''; + }, + getReleaseLine: async (changeset, type, options) => { + if (!options || !options.repo) { + throw new Error( + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + ); + } + + let prFromSummary; + let commitFromSummary; + let usersFromSummary = []; + + const replacedChangelog = changeset.summary + .replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => { + let num = Number(pr); + if (!isNaN(num)) prFromSummary = num; + return ''; + }) + .replace(/^\s*commit:\s*([^\s]+)/im, (_, commit) => { + commitFromSummary = commit; + return ''; + }) + .replace(/^\s*(?:author|user):\s*@?([^\s]+)/gim, (_, user) => { + usersFromSummary.push(user); + return ''; + }) + .trim(); + + const [firstLine, ...futureLines] = replacedChangelog + .split('\n') + .map((l) => l.trimRight()); + + const links = await (async () => { + if (prFromSummary !== undefined) { + let { links } = await getInfoFromPullRequest({ + repo: options.repo, + pull: prFromSummary, + }); + if (commitFromSummary) { + links = { + ...links, + commit: `[\`${commitFromSummary}\`](https://github.com/${options.repo}/commit/${commitFromSummary})`, + }; + } + return links; + } + const commitToFetchFrom = commitFromSummary || changeset.commit; + if (commitToFetchFrom) { + let { links } = await getInfo({ + repo: options.repo, + commit: commitToFetchFrom, + }); + return links; + } + return { + commit: null, + pull: null, + user: null, + }; + })(); + + const users = usersFromSummary.length + ? usersFromSummary + .map( + (userFromSummary) => + `[@${userFromSummary}](https://github.com/${userFromSummary})` + ) + .join(', ') + : links.user; + + const pull = links.pull === null ? '' : ` ${links.pull}`; + const commit = !!pull || links.commit === null ? '' : ` ${links.commit}`; + + const prefix = [pull, commit, users === null ? '' : ` by ${users}`].join( + '' + ); + + let lines = `${firstLine}\n${futureLines.map((l) => ` ${l}`).join('\n')}`; + + if (firstLine[0] === '-') { + lines = `\n ${firstLine}\n${futureLines + .map((l) => ` ${l}`) + .join('\n')}`; + } + + return `\n\n-${prefix ? `${prefix} –` : ''} ${lines}`; + }, +}; diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..207bddc --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@1.6.0/schema.json", + "changelog": ["./changelog-config", { "repo": "udecode/better-auth-convex" }], + "commit": false, + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/ci-packages.yml b/.github/workflows/ci-packages.yml new file mode 100644 index 0000000..809a5b5 --- /dev/null +++ b/.github/workflows/ci-packages.yml @@ -0,0 +1,40 @@ +name: Build & Typecheck + +on: + push: + branches: + - main + pull_request: + types: + - opened + - synchronize + - reopened + +jobs: + cache-and-install: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 10 + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: 🏗 Build + run: pnpm build + + - name: 🔍 Typecheck + run: pnpm typecheck diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8a4666c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,54 @@ +name: ReleaseOrVersionPR + +on: + push: + branches: [main] + +jobs: + release: + # Basic security: the release job can only be executed from this repo and from the main branch (not a remote thing) + if: ${{ github.repository == 'udecode/better-auth-convex' && contains('refs/heads/main',github.ref)}} + name: Release and changelog + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + # To run comparison we need more than the latest commit. + # @link https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches + fetch-depth: 0 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 10 + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + # @link https://github.com/changesets/action + - name: 🦋 Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + # publish: yarn g:release + cwd: ${{ github.workspace }} + title: '[Release] Version packages' + publish: pnpm build && pnpm changeset publish + # Optional, might be used in conjunction with GITHUB_TOKEN to + # allow running the workflows on a Version package action. + # Be aware of security implications. + # setupGitUser: true + env: + # See https://github.com/changesets/action/issues/147 + HOME: ${{ github.workspace }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..656548e --- /dev/null +++ b/.gitignore @@ -0,0 +1,93 @@ +!.* + +.git +**/tsconfig.tsbuildinfo +CLAUDE.local.md + +# dependencies +src/generated +node_modules +/.pnp +.pnp.js +.contentlayer +.source + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +dist +/tmp +/out-tsc +**/build + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# misc +.DS_Store +*.pem + +# local env files +.env*.local +convex/.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.vscode + +# Sentry Auth Token +.sentryclirc + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# IDEs and editors +.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace +.vscode/* + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*.cache + +.turbo + +# AI Cache +.cache/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..7d3b305 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +__tests__ +__test-utils__ +__mocks__ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0f30055 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright Convex, Inc., Udecode + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index 5d243ef..1246e5d 100644 --- a/README.md +++ b/README.md @@ -1 +1,279 @@ -# better-auth-convex +# Better Auth Convex + +True local installation of Better Auth in your Convex app schema, eliminating component isolation and `ctx.runQuery`/`ctx.runMutation` overhead. + +## Why Better Auth Convex? + +The official `@convex-dev/better-auth` component stores auth tables in an isolated component schema. While the docs mention ["local install"](https://convex-better-auth.netlify.app/local-install), it's still component-isolated, not truly local to your app. + +**This package provides actual local installation:** + +1. **Auth tables live in YOUR app schema** - Not in a component boundary +2. **Direct database access** - No `ctx.runQuery`/`ctx.runMutation` overhead (>50ms latency that increases with app size) +3. **Unified context** - Auth triggers can directly access and modify your app tables transactionally +4. **Full TypeScript inference** - Single schema, single source of truth + + +**⚠️ BREAKING CHANGE from @convex-dev/better-auth** + +Auth tables are stored in your app schema instead of the component schema. If you're already in production with `@convex-dev/better-auth`, you'll need to write a migration script to move your auth data. + + +## Prerequisites + +- Follow the [official Better Auth + Convex setup guide](https://convex-better-auth.netlify.app/) first +- Choose your [framework guide](https://convex-better-auth.netlify.app/framework-guides/next) + - **IGNORE these steps from the framework guide**: + - Step 2: "Register the component" - We don't use the component approach + - Step 5: `convex/auth.ts` - We'll use a different setup + - Step 7: `convex/http.ts` - We use different route registration +- Then come back here to install locally + +## Installation + +```bash +pnpm add better-auth@1.3.13 better-auth-convex +``` + +## Local Setup + +You'll need `convex/auth.config.ts` and update your files to install Better Auth directly in your app: + +```ts +// convex/auth.ts +import { betterAuth } from 'better-auth'; +import { convex } from '@convex-dev/better-auth/plugins'; +import { admin, organization } from 'better-auth/plugins'; // Optional plugins +import { + type AuthFunctions, + createClient, + createApi, +} from 'better-auth-convex'; +import { internal } from './_generated/api'; +import type { MutationCtx, QueryCtx, GenericCtx } from './_generated/server'; +import type { DataModel } from './_generated/dataModel'; +import schema from './schema'; // YOUR app schema with auth tables + +// 1. Internal API functions for auth operations +const authFunctions: AuthFunctions = internal.auth; + +// 2. Auth client with triggers that run in YOUR app context +export const authClient = createClient({ + authFunctions, + schema, + triggers: { + user: { + onCreate: async (ctx, user) => { + // Direct access to your database + // Example: Create personal organization + const orgId = await ctx.db.insert('organization', { + name: `${user.name}'s Workspace`, + slug: `personal-${user._id}`, + // ... other fields + }); + + // Update user with personalOrganizationId + await ctx.db.patch(user._id, { + personalOrganizationId: orgId, + }); + }, + }, + session: { + onCreate: async (ctx, session) => { + // Set default active organization on session creation + if (!session.activeOrganizationId) { + const user = await ctx.db.get(session.userId); + + if (user?.personalOrganizationId) { + await ctx.db.patch(session._id, { + activeOrganizationId: user.personalOrganizationId, + }); + } + } + }, + }, + }, +}); + +// 3. Create auth configuration (with options for HTTP-only mode) +export const createAuth = ( + ctx: GenericCtx, + { optionsOnly } = { optionsOnly: false } +) => { + const baseURL = process.env.NEXT_PUBLIC_SITE_URL!; + + return betterAuth({ + baseURL, + logger: { disabled: optionsOnly }, + plugins: [ + convex(), // Required + admin(), + organization({ + // Organization plugin config + }), + ], + session: { + expiresIn: 60 * 60 * 24 * 30, // 30 days + updateAge: 60 * 60 * 24 * 15, // 15 days + }, + database: authClient.httpAdapter(ctx), + // ... other config (social providers, user fields, etc.) + }); +}; + +// 4. Static auth instance for configuration +export const auth = createAuth({} as any, { optionsOnly: true }); + +// 5. IMPORTANT: Use getAuth for queries/mutations (direct DB access) +export const getAuth = (ctx: Ctx) => { + return betterAuth({ + ...auth.options, + database: authClient.adapter(ctx, auth.options), + }); +}; + +// 6. Export trigger handlers for Convex +export const { onCreate, onDelete, onUpdate } = authClient.triggersApi(); + +// 7. Export API functions for internal use +export const { + create, + deleteMany, + deleteOne, + findMany, + findOne, + updateMany, + updateOne, +} = createApi(schema, auth.options); +``` + +```ts +// convex/http.ts +import { httpRouter } from 'convex/server'; +import { registerRoutes } from 'better-auth-convex'; +import { createAuth } from './auth'; + +const http = httpRouter(); + +registerRoutes(http, createAuth); + +export default http; +``` + +## Key Concepts + +### Direct DB Access vs HTTP Adapter + +```ts +// ✅ In queries/mutations: Use getAuth (direct DB access) +export const someQuery = query({ + handler: async (ctx) => { + const auth = getAuth(ctx); // No ctx.runQuery overhead! + const user = await auth.api.getUser({ userId }); + }, +}); + +// ⚠️ In actions: Use createAuth (needs HTTP adapter for external calls) +export const someAction = action({ + handler: async (ctx) => { + const auth = createAuth(ctx); // Actions can't directly access DB + // Use for webhooks, external API calls, etc. + }, +}); +``` + +### Unified Schema Benefits + +```ts +// Component approach (@convex-dev/better-auth): +// ❌ Auth tables in components.betterAuth schema (isolated) +// ❌ Can't join auth tables with app tables +// ❌ ctx.runQuery/runMutation overhead (>50ms) + +// Local approach (better-auth-convex): +// ✅ Auth tables in YOUR app schema +// ✅ Direct queries across auth + app tables +// ✅ Single transaction for complex operations +// ✅ No component overhead +``` + +### Helper Functions + +All helpers are exported from the main package: + +```ts +import { getAuthUserId, getSession, getHeaders } from 'better-auth-convex'; + +// Get current user ID +const userId = await getAuthUserId(ctx); + +// Get full session +const session = await getSession(ctx); + +// Get headers for auth.api calls +const headers = await getHeaders(ctx); +``` + +## Updating the Schema + +Better Auth configuration changes may require schema updates. The Better Auth docs will often note when this is the case. To regenerate the schema (it's generally safe to do), run: + +```bash +cd convex && npx @better-auth/cli generate -y --output authSchema.ts +``` + +### Import Generated Schema (Recommended) + +Import the generated schema in your `convex/schema.ts`: + +```ts +import { authSchema } from './authSchema'; +import { defineSchema } from 'convex/server'; + +export default defineSchema({ + ...authSchema, + // Your other tables here +}); +``` + +### Or Use as Reference + +Alternatively, use the generated schema as a reference to manually update your existing schema: + +```ts +// Example: Adding a missing field discovered from generated schema +import { defineSchema, defineTable } from 'convex/server'; +import { v } from 'convex/values'; + +export default defineSchema({ + user: defineTable({ + // ... existing fields + twoFactorEnabled: v.optional(v.union(v.null(), v.boolean())), // New field from Better Auth update + // ... rest of your schema + }).index('email_name', ['email', 'name']), + // ... other indexes +}); +``` + +### Adding Custom Indexes + +Better Auth may log warnings about missing indexes for certain queries. You can add custom indexes by extending the generated schema: + +```ts +// convex/schema.ts +import { authSchema } from './authSchema'; +import { defineSchema } from 'convex/server'; + +export default defineSchema({ + ...authSchema, + // Override with custom indexes + user: authSchema.user.index('username', ['username']), + // Your other tables +}); +``` + +**Note**: `authSchema` table names and field names should not be customized directly. Use Better Auth configuration options to customize the schema, then regenerate to see the expected structure. + +## Credits + +Built on top of [Better Auth](https://better-auth.com) and [@convex-dev/better-auth](https://github.com/get-convex/better-auth), optimized for [Convex](https://convex.dev). diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..da50538 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,28 @@ +import unusedImports from 'eslint-plugin-unused-imports'; + +import { configs, defineConfig } from './tooling/eslint/index.js'; + +export default defineConfig( + { + ignores: ['src/index.ts'], + }, + ...configs.base, + ...configs.typescript, + { + languageOptions: { + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + plugins: { + 'unused-imports': unusedImports, + }, + rules: { + // No unused imports + 'unused-imports/no-unused-imports': 'error', + }, + } +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..9fe6dce --- /dev/null +++ b/package.json @@ -0,0 +1,86 @@ +{ + "name": "better-auth-convex", + "version": "0.0.1", + "description": "Better Auth Convex local integration", + "keywords": [ + "convex", + "auth", + "authentication", + "better-auth" + ], + "bugs": { + "url": "https://github.com/udecode/better-auth-convex/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/udecode/better-auth-convex.git", + "directory": "packages/better-auth-convex" + }, + "license": "Apache-2.0", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "module": "./dist/index.mjs", + "require": "./dist/index.js" + } + }, + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist/**/*" + ], + "scripts": { + "brl": "sh tooling/scripts/brl.sh", + "build": "tsup", + "build:watch": "tsup:watch", + "lint": "pnpm eslint", + "lint:fix": "pnpm eslint --fix && pnpm prettier --write .", + "typecheck": "pnpm tsc --noEmit", + "typecheck:watch": "pnpm tsc --noEmit --watch" + }, + "dependencies": { + "common-tags": "^1.8.2", + "convex-helpers": "^0.1.104", + "type-fest": "^4.39.1" + }, + "devDependencies": { + "@changesets/cli": "2.27.11", + "@changesets/get-github-info": "0.6.0", + "@convex-dev/better-auth": "0.8.6", + "@eslint/compat": "1.3.2", + "@eslint/eslintrc": "3.3.1", + "@eslint/js": "9.34.0", + "@types/common-tags": "^1.8.4", + "@types/eslint": "9.6.1", + "@types/node": "^24.5.2", + "@typescript-eslint/utils": "8.42.0", + "barrelsby": "^2.8.1", + "better-auth": "1.3.13", + "convex": "1.26.2", + "eslint": "9.34.0", + "eslint-config-prettier": "10.1.8", + "eslint-import-resolver-typescript": "4.4.4", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-perfectionist": "4.15.0", + "eslint-plugin-unicorn": "60.0.0", + "eslint-plugin-unused-imports": "4.2.0", + "prettier": "3.6.2", + "prettier-plugin-jsdoc": "1.3.3", + "prettier-plugin-packagejson": "2.5.19", + "tsup": "8.5.0", + "typescript": "5.9.2", + "typescript-eslint": "8.42.0" + }, + "peerDependencies": { + "@convex-dev/better-auth": ">=0.8.6", + "better-auth": ">=1.3.13", + "convex": ">=1.26.2" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..a43b6d5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5519 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + common-tags: + specifier: ^1.8.2 + version: 1.8.2 + convex-helpers: + specifier: ^0.1.104 + version: 0.1.104(convex@1.26.2(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(zod@3.25.76) + type-fest: + specifier: ^4.39.1 + version: 4.41.0 + devDependencies: + '@changesets/cli': + specifier: 2.27.11 + version: 2.27.11 + '@changesets/get-github-info': + specifier: 0.6.0 + version: 0.6.0 + '@convex-dev/better-auth': + specifier: 0.8.6 + version: 0.8.6(better-auth@1.3.13(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(convex@1.26.2(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) + '@eslint/compat': + specifier: 1.3.2 + version: 1.3.2(eslint@9.34.0) + '@eslint/eslintrc': + specifier: 3.3.1 + version: 3.3.1 + '@eslint/js': + specifier: 9.34.0 + version: 9.34.0 + '@types/common-tags': + specifier: ^1.8.4 + version: 1.8.4 + '@types/eslint': + specifier: 9.6.1 + version: 9.6.1 + '@types/node': + specifier: ^24.5.2 + version: 24.5.2 + '@typescript-eslint/utils': + specifier: 8.42.0 + version: 8.42.0(eslint@9.34.0)(typescript@5.9.2) + barrelsby: + specifier: ^2.8.1 + version: 2.8.1 + better-auth: + specifier: 1.3.13 + version: 1.3.13(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + convex: + specifier: 1.26.2 + version: 1.26.2(react@19.1.1) + eslint: + specifier: 9.34.0 + version: 9.34.0 + eslint-config-prettier: + specifier: 10.1.8 + version: 10.1.8(eslint@9.34.0) + eslint-import-resolver-typescript: + specifier: 4.4.4 + version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.34.0) + eslint-plugin-import: + specifier: 2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.34.0) + eslint-plugin-perfectionist: + specifier: 4.15.0 + version: 4.15.0(eslint@9.34.0)(typescript@5.9.2) + eslint-plugin-unicorn: + specifier: 60.0.0 + version: 60.0.0(eslint@9.34.0) + eslint-plugin-unused-imports: + specifier: 4.2.0 + version: 4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0) + prettier: + specifier: 3.6.2 + version: 3.6.2 + prettier-plugin-jsdoc: + specifier: 1.3.3 + version: 1.3.3(prettier@3.6.2) + prettier-plugin-packagejson: + specifier: 2.5.19 + version: 2.5.19(prettier@3.6.2) + tsup: + specifier: 8.5.0 + version: 8.5.0(typescript@5.9.2) + typescript: + specifier: 5.9.2 + version: 5.9.2 + typescript-eslint: + specifier: 8.42.0 + version: 8.42.0(eslint@9.34.0)(typescript@5.9.2) + +packages: + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@better-auth/utils@0.3.0': + resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} + + '@better-fetch/fetch@1.1.18': + resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==} + + '@changesets/apply-release-plan@7.0.13': + resolution: {integrity: sha512-BIW7bofD2yAWoE8H4V40FikC+1nNFEKBisMECccS16W1rt6qqhNTBDmIw5HaqmMgtLNz9e7oiALiEUuKrQ4oHg==} + + '@changesets/assemble-release-plan@6.0.9': + resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.27.11': + resolution: {integrity: sha512-1QislpE+nvJgSZZo9+Lj3Lno5pKBgN46dAV8IVxKJy9wX8AOrs9nn5pYVZuDpoxWJJCALmbfOsHkyxujgetQSg==} + hasBin: true + + '@changesets/config@3.1.1': + resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + + '@changesets/get-github-info@0.6.0': + resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} + + '@changesets/get-release-plan@4.0.13': + resolution: {integrity: sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.1': + resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.5': + resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + + '@convex-dev/better-auth@0.8.6': + resolution: {integrity: sha512-iP2erc4YKz0HzrWSdaSRv2ck3gsdb2yBwUdSOsM0ebvNMcTsoWEBuu07cq6lUGMyJ97qxOnZDtN7CemTXKpSpA==} + peerDependencies: + better-auth: 1.3.8 + convex: ^1.26.2 + react: ^18.3.1 || ^19.0.0 + react-dom: ^18.3.1 || ^19.0.0 + + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/compat@1.3.2': + resolution: {integrity: sha512-jRNwzTbd6p2Rw4sZ1CgWRS8YMtqG15YyZf7zvb6gY2rB2u6n+2Z+ELW0GtL0fQgyl0pr4Y/BzBfng/BdsereRA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.40 || 9 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.3.1': + resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.15.2': + resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.34.0': + resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.5': + resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@hexagon/base64@1.1.28': + resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@levischuck/tiny-cbor@0.2.11': + resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@noble/ciphers@2.0.1': + resolution: {integrity: sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g==} + engines: {node: '>= 20.19.0'} + + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@peculiar/asn1-android@2.5.0': + resolution: {integrity: sha512-t8A83hgghWQkcneRsgGs2ebAlRe54ns88p7ouv8PW2tzF1nAW4yHcL4uZKrFpIU+uszIRzTkcCuie37gpkId0A==} + + '@peculiar/asn1-cms@2.5.0': + resolution: {integrity: sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A==} + + '@peculiar/asn1-csr@2.5.0': + resolution: {integrity: sha512-ioigvA6WSYN9h/YssMmmoIwgl3RvZlAYx4A/9jD2qaqXZwGcNlAxaw54eSx2QG1Yu7YyBC5Rku3nNoHrQ16YsQ==} + + '@peculiar/asn1-ecc@2.5.0': + resolution: {integrity: sha512-t4eYGNhXtLRxaP50h3sfO6aJebUCDGQACoeexcelL4roMFRRVgB20yBIu2LxsPh/tdW9I282gNgMOyg3ywg/mg==} + + '@peculiar/asn1-pfx@2.5.0': + resolution: {integrity: sha512-Vj0d0wxJZA+Ztqfb7W+/iu8Uasw6hhKtCdLKXLG/P3kEPIQpqGI4P4YXlROfl7gOCqFIbgsj1HzFIFwQ5s20ug==} + + '@peculiar/asn1-pkcs8@2.5.0': + resolution: {integrity: sha512-L7599HTI2SLlitlpEP8oAPaJgYssByI4eCwQq2C9eC90otFpm8MRn66PpbKviweAlhinWQ3ZjDD2KIVtx7PaVw==} + + '@peculiar/asn1-pkcs9@2.5.0': + resolution: {integrity: sha512-UgqSMBLNLR5TzEZ5ZzxR45Nk6VJrammxd60WMSkofyNzd3DQLSNycGWSK5Xg3UTYbXcDFyG8pA/7/y/ztVCa6A==} + + '@peculiar/asn1-rsa@2.5.0': + resolution: {integrity: sha512-qMZ/vweiTHy9syrkkqWFvbT3eLoedvamcUdnnvwyyUNv5FgFXA3KP8td+ATibnlZ0EANW5PYRm8E6MJzEB/72Q==} + + '@peculiar/asn1-schema@2.5.0': + resolution: {integrity: sha512-YM/nFfskFJSlHqv59ed6dZlLZqtZQwjRVJ4bBAiWV08Oc+1rSd5lDZcBEx0lGDHfSoH3UziI2pXt2UM33KerPQ==} + + '@peculiar/asn1-x509-attr@2.5.0': + resolution: {integrity: sha512-9f0hPOxiJDoG/bfNLAFven+Bd4gwz/VzrCIIWc1025LEI4BXO0U5fOCTNDPbbp2ll+UzqKsZ3g61mpBp74gk9A==} + + '@peculiar/asn1-x509@2.5.0': + resolution: {integrity: sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==} + + '@peculiar/x509@1.14.0': + resolution: {integrity: sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@rollup/rollup-android-arm-eabi@4.52.0': + resolution: {integrity: sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.52.0': + resolution: {integrity: sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.52.0': + resolution: {integrity: sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.52.0': + resolution: {integrity: sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.52.0': + resolution: {integrity: sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.52.0': + resolution: {integrity: sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.52.0': + resolution: {integrity: sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.52.0': + resolution: {integrity: sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.52.0': + resolution: {integrity: sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.52.0': + resolution: {integrity: sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.52.0': + resolution: {integrity: sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.52.0': + resolution: {integrity: sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.52.0': + resolution: {integrity: sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.52.0': + resolution: {integrity: sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.52.0': + resolution: {integrity: sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.52.0': + resolution: {integrity: sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.52.0': + resolution: {integrity: sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.52.0': + resolution: {integrity: sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.0': + resolution: {integrity: sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.52.0': + resolution: {integrity: sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.52.0': + resolution: {integrity: sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.0': + resolution: {integrity: sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@simplewebauthn/browser@13.2.0': + resolution: {integrity: sha512-N3fuA1AAnTo5gCStYoIoiasPccC+xPLx2YU88Dv0GeAmPQTWHETlZQq5xZ0DgUq1H9loXMWQH5qqUjcI7BHJ1A==} + + '@simplewebauthn/server@13.2.1': + resolution: {integrity: sha512-Inmfye5opZXe3HI0GaksqBnQiM7glcNySoG6DH1GgkO1Lh9dvuV4XSV9DK02DReUVX39HpcDob9nxHELjECoQw==} + engines: {node: '>=20.0.0'} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/common-tags@1.8.4': + resolution: {integrity: sha512-S+1hLDJPjWNDhcGxsxEbepzaxWqURP/o+3cP4aa2w7yBXgdcmKGQtZzP8JbyfOd0m+33nh+8+kvxYE2UJtBDkg==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@typescript-eslint/eslint-plugin@8.42.0': + resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.42.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.42.0': + resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.42.0': + resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.42.0': + resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.42.0': + resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.42.0': + resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.42.0': + resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/types@8.44.1': + resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.42.0': + resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.42.0': + resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.42.0': + resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + asn1js@3.0.6: + resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} + engines: {node: '>=12.0.0'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + barrelsby@2.8.1: + resolution: {integrity: sha512-barN2MVKqUVwmjRy3JLSMYufrBDcdWUc2pjlR0V9P8S3aMvvJ4StFz1GJMzEi5GBoQlnBIWOcCxBDzI2xfaaGw==} + engines: {node: '>=6.0.0'} + hasBin: true + + baseline-browser-mapping@2.8.6: + resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} + hasBin: true + + better-auth@1.3.13: + resolution: {integrity: sha512-vNIVExB87JTM19+1+p6SZ6xbzZFLw4ug8ir61qCArE8UbIN3SZQi0T3/PjubpWPwsLjINBsVizeHxPf5S7Ss0A==} + peerDependencies: + '@lynx-js/react': '*' + '@sveltejs/kit': ^2.0.0 + next: ^14.0.0 || ^15.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + solid-js: ^1.0.0 + svelte: ^4.0.0 || ^5.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@lynx-js/react': + optional: true + '@sveltejs/kit': + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vue: + optional: true + + better-call@1.0.19: + resolution: {integrity: sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + binary-searching@2.0.5: + resolution: {integrity: sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + builtin-modules@5.0.0: + resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} + engines: {node: '>=18.20'} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001743: + resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + ci-info@4.3.0: + resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} + engines: {node: '>=8'} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + + common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convex-helpers@0.1.104: + resolution: {integrity: sha512-7CYvx7T3K6n+McDTK4ZQaQNNGBzq5aWezpjzsKbOxPXx7oNcTP9wrpef3JxeXWFzkByJv5hRCjseh9B7eNJ7Ig==} + hasBin: true + peerDependencies: + '@standard-schema/spec': ^1.0.0 + convex: ^1.24.0 + hono: ^4.0.5 + react: ^17.0.2 || ^18.0.0 || ^19.0.0 + typescript: ^5.5 + zod: ^3.22.4 || ^4.0.15 + peerDependenciesMeta: + '@standard-schema/spec': + optional: true + hono: + optional: true + react: + optional: true + typescript: + optional: true + zod: + optional: true + + convex@1.26.2: + resolution: {integrity: sha512-QG3zvZ9GTTeeBS+N5PJj73TULHYu99eVSOI3KU2hMnB9q40fHxkMFJ+AYox+K81roTakciBvNTvGlhfz+M10fQ==} + engines: {node: '>=18.0.0', npm: '>=7.0.0'} + hasBin: true + peerDependencies: + '@auth0/auth0-react': ^2.0.1 + '@clerk/clerk-react': ^4.12.8 || ^5.0.0 + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + peerDependenciesMeta: + '@auth0/auth0-react': + optional: true + '@clerk/clerk-react': + optional: true + react: + optional: true + + core-js-compat@3.45.1: + resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + + detect-newline@4.0.1: + resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.222: + resolution: {integrity: sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@4.4.4: + resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + engines: {node: ^16.17.0 || >=18.6.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-perfectionist@4.15.0: + resolution: {integrity: sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + eslint: '>=8.45.0' + + eslint-plugin-unicorn@60.0.0: + resolution: {integrity: sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==} + engines: {node: ^20.10.0 || >=21.0.0} + peerDependencies: + eslint: '>=9.29.0' + + eslint-plugin-unused-imports@4.2.0: + resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.34.0: + resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + + git-hooks-list@4.1.1: + resolution: {integrity: sha512-cmP497iLq54AZnv4YRAEMnEyQ1eIn4tGKbmswqwmFV4GBnAqE8NLtWxxdXa++AalfgL5EBH4IxTPyquEuGY/jA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-builtin-module@5.0.0: + resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} + engines: {node: '>=18.20'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-network-error@1.3.0: + resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + engines: {node: '>=16'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jose@6.1.0: + resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kysely@0.28.7: + resolution: {integrity: sha512-u/cAuTL4DRIiO2/g4vNGRgklEKNIj5Q3CG7RoUB5DV5SfEC2hMvPxKi0GWPmnzwL2ryIeud2VTcEEmqzTzEPNw==} + engines: {node: '>=20.0.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanostores@1.0.1: + resolution: {integrity: sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==} + engines: {node: ^20.0.0 || >=22.0.0} + + napi-postinstall@0.3.3: + resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + natural-orderby@5.0.0: + resolution: {integrity: sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg==} + engines: {node: '>=18'} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-jsdoc@1.3.3: + resolution: {integrity: sha512-YIxejcbPYK4N58jHGiXjYvrCzBMyvV2AEMSoF5LvqqeMEI0nsmww57I6NGnpVc0AU9ncFCTEBoYHN/xuBf80YA==} + engines: {node: '>=14.13.1 || >=16.0.0'} + peerDependencies: + prettier: ^3.0.0 + + prettier-plugin-packagejson@2.5.19: + resolution: {integrity: sha512-Qsqp4+jsZbKMpEGZB1UP1pxeAT8sCzne2IwnKkr+QhUe665EXUo3BAvTf1kAPCqyMv9kg3ZmO0+7eOni/C6Uag==} + peerDependencies: + prettier: '>= 1.16.0' + peerDependenciesMeta: + prettier: + optional: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-dom@19.1.1: + resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} + peerDependencies: + react: ^19.1.1 + + react@19.1.1: + resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} + engines: {node: '>=0.10.0'} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + hasBin: true + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.52.0: + resolution: {integrity: sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rou3@0.5.1: + resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + sort-object-keys@1.1.3: + resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} + + sort-package-json@3.4.0: + resolution: {integrity: sha512-97oFRRMM2/Js4oEA9LJhjyMlde+2ewpZQf53pgue27UkbEXfHJnDzHlUxQ/DWUkzqmp7DFwJp8D+wi/TYeQhpA==} + engines: {node: '>=20'} + hasBin: true + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@4.1.0: + resolution: {integrity: sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.5.0: + resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.42.0: + resolution: {integrity: sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.1.11: + resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} + +snapshots: + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/runtime@7.28.4': {} + + '@better-auth/utils@0.3.0': {} + + '@better-fetch/fetch@1.1.18': {} + + '@changesets/apply-release-plan@7.0.13': + dependencies: + '@changesets/config': 3.1.1 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.2 + + '@changesets/assemble-release-plan@6.0.9': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.2 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.27.11': + dependencies: + '@changesets/apply-release-plan': 7.0.13 + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.1 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.13 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.5 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.2 + spawndamnit: 3.0.1 + term-size: 2.2.1 + + '@changesets/config@3.1.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.3': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.2 + + '@changesets/get-github-info@0.6.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.13': + dependencies: + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/config': 3.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.5 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.1': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.5': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.1 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + + '@convex-dev/better-auth@0.8.6(better-auth@1.3.13(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(convex@1.26.2(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)': + dependencies: + '@better-fetch/fetch': 1.1.18 + better-auth: 1.3.13(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + common-tags: 1.8.2 + convex: 1.26.2(react@19.1.1) + convex-helpers: 0.1.104(convex@1.26.2(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(zod@3.25.76) + is-network-error: 1.3.0 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + type-fest: 4.41.0 + zod: 3.25.76 + transitivePeerDependencies: + - '@standard-schema/spec' + - hono + - typescript + + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.4': + optional: true + + '@esbuild/android-arm64@0.25.4': + optional: true + + '@esbuild/android-arm@0.25.4': + optional: true + + '@esbuild/android-x64@0.25.4': + optional: true + + '@esbuild/darwin-arm64@0.25.4': + optional: true + + '@esbuild/darwin-x64@0.25.4': + optional: true + + '@esbuild/freebsd-arm64@0.25.4': + optional: true + + '@esbuild/freebsd-x64@0.25.4': + optional: true + + '@esbuild/linux-arm64@0.25.4': + optional: true + + '@esbuild/linux-arm@0.25.4': + optional: true + + '@esbuild/linux-ia32@0.25.4': + optional: true + + '@esbuild/linux-loong64@0.25.4': + optional: true + + '@esbuild/linux-mips64el@0.25.4': + optional: true + + '@esbuild/linux-ppc64@0.25.4': + optional: true + + '@esbuild/linux-riscv64@0.25.4': + optional: true + + '@esbuild/linux-s390x@0.25.4': + optional: true + + '@esbuild/linux-x64@0.25.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.4': + optional: true + + '@esbuild/netbsd-x64@0.25.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.4': + optional: true + + '@esbuild/openbsd-x64@0.25.4': + optional: true + + '@esbuild/sunos-x64@0.25.4': + optional: true + + '@esbuild/win32-arm64@0.25.4': + optional: true + + '@esbuild/win32-ia32@0.25.4': + optional: true + + '@esbuild/win32-x64@0.25.4': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.34.0)': + dependencies: + eslint: 9.34.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/compat@1.3.2(eslint@9.34.0)': + optionalDependencies: + eslint: 9.34.0 + + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.3.1': {} + + '@eslint/core@0.15.2': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.34.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.5': + dependencies: + '@eslint/core': 0.15.2 + levn: 0.4.1 + + '@hexagon/base64@1.1.28': {} + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@levischuck/tiny-cbor@0.2.11': {} + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.28.4 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.28.4 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@noble/ciphers@2.0.1': {} + + '@noble/hashes@2.0.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@peculiar/asn1-android@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-cms@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/asn1-x509-attr': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.5.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-pkcs8': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.5.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-pfx': 2.5.0 + '@peculiar/asn1-pkcs8': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/asn1-x509-attr': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.5.0': + dependencies: + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/x509@1.14.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-csr': 2.5.0 + '@peculiar/asn1-ecc': 2.5.0 + '@peculiar/asn1-pkcs9': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} + + '@rollup/rollup-android-arm-eabi@4.52.0': + optional: true + + '@rollup/rollup-android-arm64@4.52.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.0': + optional: true + + '@rollup/rollup-darwin-x64@4.52.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.52.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.52.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.52.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.52.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.52.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.52.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.52.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.0': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@simplewebauthn/browser@13.2.0': {} + + '@simplewebauthn/server@13.2.1': + dependencies: + '@hexagon/base64': 1.1.28 + '@levischuck/tiny-cbor': 0.2.11 + '@peculiar/asn1-android': 2.5.0 + '@peculiar/asn1-ecc': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/x509': 1.14.0 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/common-tags@1.8.4': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/node@12.20.55': {} + + '@types/node@24.5.2': + dependencies: + undici-types: 7.12.0 + + '@types/unist@3.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/type-utils': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.42.0 + eslint: 9.34.0 + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.42.0 + debug: 4.4.3 + eslint: 9.34.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) + '@typescript-eslint/types': 8.42.0 + debug: 4.4.3 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.42.0': + dependencies: + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/visitor-keys': 8.42.0 + + '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)': + dependencies: + typescript: 5.9.2 + + '@typescript-eslint/type-utils@8.42.0(eslint@9.34.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + debug: 4.4.3 + eslint: 9.34.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.42.0': {} + + '@typescript-eslint/types@8.44.1': {} + + '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/project-service': 8.42.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/visitor-keys': 8.42.0 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.42.0(eslint@9.34.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.34.0) + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + eslint: 9.34.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.42.0': + dependencies: + '@typescript-eslint/types': 8.42.0 + eslint-visitor-keys: 4.2.1 + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + any-promise@1.3.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array-union@2.1.0: {} + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + asn1js@3.0.6: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.3 + tslib: 2.8.1 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + balanced-match@1.0.2: {} + + barrelsby@2.8.1: + dependencies: + '@types/yargs': 17.0.33 + signale: 1.4.0 + yargs: 17.7.2 + + baseline-browser-mapping@2.8.6: {} + + better-auth@1.3.13(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + '@noble/ciphers': 2.0.1 + '@noble/hashes': 2.0.1 + '@simplewebauthn/browser': 13.2.0 + '@simplewebauthn/server': 13.2.1 + better-call: 1.0.19 + defu: 6.1.4 + jose: 6.1.0 + kysely: 0.28.7 + nanostores: 1.0.1 + zod: 4.1.11 + optionalDependencies: + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + better-call@1.0.19: + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + rou3: 0.5.1 + set-cookie-parser: 2.7.1 + uncrypto: 0.1.3 + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + binary-searching@2.0.5: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.26.2: + dependencies: + baseline-browser-mapping: 2.8.6 + caniuse-lite: 1.0.30001743 + electron-to-chromium: 1.5.222 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) + + builtin-modules@5.0.0: {} + + bundle-require@5.1.0(esbuild@0.25.4): + dependencies: + esbuild: 0.25.4 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001743: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + change-case@5.4.4: {} + + character-entities@2.0.2: {} + + chardet@0.7.0: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + ci-info@3.9.0: {} + + ci-info@4.3.0: {} + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + commander@4.1.1: {} + + comment-parser@1.4.1: {} + + common-tags@1.8.2: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + consola@3.4.2: {} + + convex-helpers@0.1.104(convex@1.26.2(react@19.1.1))(react@19.1.1)(typescript@5.9.2)(zod@3.25.76): + dependencies: + convex: 1.26.2(react@19.1.1) + optionalDependencies: + react: 19.1.1 + typescript: 5.9.2 + zod: 3.25.76 + + convex@1.26.2(react@19.1.1): + dependencies: + esbuild: 0.25.4 + jwt-decode: 4.0.0 + prettier: 3.6.2 + optionalDependencies: + react: 19.1.1 + + core-js-compat@3.45.1: + dependencies: + browserslist: 4.26.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + dataloader@1.4.0: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defu@6.1.4: {} + + dequal@2.0.3: {} + + detect-indent@6.1.0: {} + + detect-indent@7.0.2: {} + + detect-newline@4.0.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.222: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.34.0): + dependencies: + eslint: 9.34.0 + + eslint-import-context@0.1.9(unrs-resolver@1.11.1): + dependencies: + get-tsconfig: 4.10.1 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.11.1 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0)(eslint@9.34.0): + dependencies: + debug: 4.4.3 + eslint: 9.34.0 + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash-x: 0.2.0 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.34.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.34.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + eslint: 9.34.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.34.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.34.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.34.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.34.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-perfectionist@4.15.0(eslint@9.34.0)(typescript@5.9.2): + dependencies: + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + eslint: 9.34.0 + natural-orderby: 5.0.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-unicorn@60.0.0(eslint@9.34.0): + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.34.0) + '@eslint/plugin-kit': 0.3.5 + change-case: 5.4.4 + ci-info: 4.3.0 + clean-regexp: 1.0.0 + core-js-compat: 3.45.1 + eslint: 9.34.0 + esquery: 1.6.0 + find-up-simple: 1.0.1 + globals: 16.4.0 + indent-string: 5.0.0 + is-builtin-module: 5.0.0 + jsesc: 3.1.0 + pluralize: 8.0.0 + regexp-tree: 0.1.27 + regjsparser: 0.12.0 + semver: 7.7.2 + strip-indent: 4.1.0 + + eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0): + dependencies: + eslint: 9.34.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.34.0: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.34.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.1 + '@eslint/core': 0.15.2 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.34.0 + '@eslint/plugin-kit': 0.3.5 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + extendable-error@0.1.7: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.1: {} + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.19 + mlly: 1.8.0 + rollup: 4.52.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + git-hooks-list@4.1.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globals@14.0.0: {} + + globals@16.4.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + human-id@1.0.2: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@5.0.0: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-builtin-module@5.0.0: + dependencies: + builtin-modules: 5.0.0 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-network-error@1.3.0: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-windows@1.0.2: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jose@6.1.0: {} + + joycon@3.1.1: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jwt-decode@4.0.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kysely@0.28.7: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + load-tsconfig@0.2.5: {} + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.sortby@4.7.0: {} + + lodash.startcase@4.4.0: {} + + lru-cache@10.4.3: {} + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + mri@1.2.0: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanostores@1.0.1: {} + + napi-postinstall@0.3.3: {} + + natural-compare@1.4.0: {} + + natural-orderby@5.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-releases@2.0.21: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pirates@4.0.7: {} + + pkg-conf@2.1.0: + dependencies: + find-up: 2.1.0 + load-json-file: 4.0.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + pluralize@8.0.0: {} + + possible-typed-array-names@1.1.0: {} + + postcss-load-config@6.0.1: + dependencies: + lilconfig: 3.1.3 + + prelude-ls@1.2.1: {} + + prettier-plugin-jsdoc@1.3.3(prettier@3.6.2): + dependencies: + binary-searching: 2.0.5 + comment-parser: 1.4.1 + mdast-util-from-markdown: 2.0.2 + prettier: 3.6.2 + transitivePeerDependencies: + - supports-color + + prettier-plugin-packagejson@2.5.19(prettier@3.6.2): + dependencies: + sort-package-json: 3.4.0 + synckit: 0.11.11 + optionalDependencies: + prettier: 3.6.2 + + prettier@2.8.8: {} + + prettier@3.6.2: {} + + punycode@2.3.1: {} + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.3: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + react-dom@19.1.1(react@19.1.1): + dependencies: + react: 19.1.1 + scheduler: 0.26.0 + + react@19.1.1: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + readdirp@4.1.2: {} + + reflect-metadata@0.2.2: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp-tree@0.1.27: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + regjsparser@0.12.0: + dependencies: + jsesc: 3.0.2 + + require-directory@2.1.1: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rollup@4.52.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.0 + '@rollup/rollup-android-arm64': 4.52.0 + '@rollup/rollup-darwin-arm64': 4.52.0 + '@rollup/rollup-darwin-x64': 4.52.0 + '@rollup/rollup-freebsd-arm64': 4.52.0 + '@rollup/rollup-freebsd-x64': 4.52.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.0 + '@rollup/rollup-linux-arm-musleabihf': 4.52.0 + '@rollup/rollup-linux-arm64-gnu': 4.52.0 + '@rollup/rollup-linux-arm64-musl': 4.52.0 + '@rollup/rollup-linux-loong64-gnu': 4.52.0 + '@rollup/rollup-linux-ppc64-gnu': 4.52.0 + '@rollup/rollup-linux-riscv64-gnu': 4.52.0 + '@rollup/rollup-linux-riscv64-musl': 4.52.0 + '@rollup/rollup-linux-s390x-gnu': 4.52.0 + '@rollup/rollup-linux-x64-gnu': 4.52.0 + '@rollup/rollup-linux-x64-musl': 4.52.0 + '@rollup/rollup-openharmony-arm64': 4.52.0 + '@rollup/rollup-win32-arm64-msvc': 4.52.0 + '@rollup/rollup-win32-ia32-msvc': 4.52.0 + '@rollup/rollup-win32-x64-gnu': 4.52.0 + '@rollup/rollup-win32-x64-msvc': 4.52.0 + fsevents: 2.3.3 + + rou3@0.5.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safer-buffer@2.1.2: {} + + scheduler@0.26.0: {} + + semver@6.3.1: {} + + semver@7.7.2: {} + + set-cookie-parser@2.7.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@4.1.0: {} + + signale@1.4.0: + dependencies: + chalk: 2.4.2 + figures: 2.0.0 + pkg-conf: 2.1.0 + + slash@3.0.0: {} + + sort-object-keys@1.1.3: {} + + sort-package-json@3.4.0: + dependencies: + detect-indent: 7.0.2 + detect-newline: 4.0.1 + git-hooks-list: 4.1.1 + is-plain-obj: 4.1.0 + semver: 7.7.2 + sort-object-keys: 1.1.3 + tinyglobby: 0.2.15 + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stable-hash-x@0.2.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-indent@4.1.0: {} + + strip-json-comments@3.1.1: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + term-size@2.2.1: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-api-utils@2.1.0(typescript@5.9.2): + dependencies: + typescript: 5.9.2 + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsup@8.5.0(typescript@5.9.2): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.4) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.25.4 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1 + resolve-from: 5.0.0 + rollup: 4.52.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@4.41.0: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.42.0(eslint@9.34.0)(typescript@5.9.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0)(typescript@5.9.2) + eslint: 9.34.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + typescript@5.9.2: {} + + ufo@1.6.1: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + uncrypto@0.1.3: {} + + undici-types@7.12.0: {} + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + universalify@0.1.2: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.3 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + update-browserslist-db@1.1.3(browserslist@4.26.2): + dependencies: + browserslist: 4.26.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + webidl-conversions@3.0.1: {} + + webidl-conversions@4.0.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + zod@3.25.76: {} + + zod@4.1.11: {} diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 0000000..0063f16 --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,9 @@ +/** @type {import('prettier').Config} */ +export default { + endOfLine: 'lf', + plugins: ['prettier-plugin-packagejson', 'prettier-plugin-jsdoc'], + semi: true, + singleQuote: true, + tabWidth: 2, + trailingComma: 'es5', +}; diff --git a/src/adapter.ts b/src/adapter.ts new file mode 100644 index 0000000..7f5c546 --- /dev/null +++ b/src/adapter.ts @@ -0,0 +1,570 @@ +import type { GenericCtx } from '@convex-dev/better-auth'; +import type { BetterAuthOptions, Prettify, Where } from 'better-auth'; +import type { SetOptional } from 'type-fest'; + +import { + type AdapterDebugLogs, + type AdapterFactoryOptions, + createAdapterFactory, +} from 'better-auth/adapters'; +import { getAuthTables } from 'better-auth/db'; +import { + type FunctionHandle, + type GenericDataModel, + type PaginationOptions, + type PaginationResult, + type SchemaDefinition, + createFunctionHandle, +} from 'convex/server'; + +import type { AuthFunctions, Triggers } from './client'; + +import { + createHandler, + deleteManyHandler, + deleteOneHandler, + findManyHandler, + findOneHandler, + updateManyHandler, + updateOneHandler, +} from './api'; +import { createSchema } from './createSchema'; + +type CleanedWhere = Prettify>; + +export const handlePagination = async ( + next: ({ + paginationOpts, + }: { + paginationOpts: PaginationOptions; + }) => Promise< + SetOptional, 'page'> & { count?: number } + >, + { limit, numItems }: { limit?: number; numItems?: number } = {} +) => { + const state: { + count: number; + cursor: string | null; + docs: any[]; + isDone: boolean; + } = { + count: 0, + cursor: null, + docs: [], + isDone: false, + }; + const onResult = ( + result: SetOptional, 'page'> & { count?: number } + ) => { + state.cursor = + result.pageStatus === 'SplitRecommended' || + result.pageStatus === 'SplitRequired' + ? (result.splitCursor ?? result.continueCursor) + : result.continueCursor; + + if (result.page) { + state.docs.push(...result.page); + state.isDone = (limit && state.docs.length >= limit) || result.isDone; + + return; + } + // Update and delete only return a count + if (result.count) { + state.count += result.count; + state.isDone = (limit && state.count >= limit) || result.isDone; + + return; + } + + state.isDone = result.isDone; + }; + + do { + const result = await next({ + paginationOpts: { + cursor: state.cursor, + numItems: Math.min( + numItems ?? 200, + (limit ?? 200) - state.docs.length, + 200 + ), + }, + }); + onResult(result); + } while (!state.isDone); + + return state; +}; + +export type ConvexCleanedWhere = CleanedWhere & { + value: number[] | string[] | boolean | number | string | null; +}; + +export const parseWhere = (where?: CleanedWhere[]): ConvexCleanedWhere[] => { + return where?.map((where) => { + if (where.value instanceof Date) { + return { + ...where, + value: where.value.getTime(), + }; + } + + return where; + }) as ConvexCleanedWhere[]; +}; + +export const adapterConfig = { + adapterId: 'convex', + adapterName: 'Convex Adapter', + debugLogs: false, + disableIdGeneration: true, + mapKeysTransformOutput: { + _id: 'id', + }, + supportsNumericIds: false, + usePlural: false, + // With supportsDates: false, dates are stored as strings, + // we convert them to numbers here. This aligns with how + // Convex stores _creationTime, and avoids a breaking change. + supportsDates: false, + customTransformInput: ({ data, fieldAttributes }) => { + if (data && fieldAttributes.type === 'date') { + return new Date(data).getTime(); + } + + return data; + }, + customTransformOutput: ({ data, fieldAttributes }) => { + if (data && fieldAttributes.type === 'date') { + return new Date(data).getTime(); + } + + return data; + }, +} satisfies AdapterFactoryOptions['config']; + +export const httpAdapter = < + DataModel extends GenericDataModel, + Schema extends SchemaDefinition, +>( + ctx: GenericCtx, + { + authFunctions, + debugLogs, + triggers, + }: { + authFunctions: AuthFunctions; + debugLogs?: AdapterDebugLogs; + triggers?: Triggers; + } +) => { + return createAdapterFactory({ + config: { + ...adapterConfig, + debugLogs: debugLogs || false, + }, + adapter: ({ options }) => { + options.telemetry = { enabled: false }; + + return { + id: 'convex', + createSchema, + count: async (data) => { + // Yes, count is just findMany returning a number. + if (data.where?.some((w) => w.connector === 'OR')) { + throw new Error('OR connector not supported in findMany'); + } + + const result = await handlePagination(async ({ paginationOpts }) => { + return await ctx.runQuery(authFunctions.findMany, { + ...data, + paginationOpts, + where: parseWhere(data.where), + }); + }); + + return result.docs?.length ?? 0; + }, + create: async ({ data, model, select }): Promise => { + if (!('runMutation' in ctx)) { + throw new Error('ctx is not a mutation ctx'); + } + + const onCreateHandle = + authFunctions.onCreate && triggers?.[model]?.onCreate + ? ((await createFunctionHandle( + authFunctions.onCreate + )) as FunctionHandle<'mutation'>) + : undefined; + + return ctx.runMutation(authFunctions.create, { + input: { data, model }, + select, + onCreateHandle: onCreateHandle, + }); + }, + delete: async (data) => { + if (!('runMutation' in ctx)) { + throw new Error('ctx is not a mutation ctx'); + } + + const onDeleteHandle = + authFunctions.onDelete && triggers?.[data.model]?.onDelete + ? ((await createFunctionHandle( + authFunctions.onDelete + )) as FunctionHandle<'mutation'>) + : undefined; + await ctx.runMutation(authFunctions.deleteOne, { + input: { + model: data.model, + where: parseWhere(data.where), + }, + onDeleteHandle: onDeleteHandle, + }); + }, + deleteMany: async (data) => { + if (!('runMutation' in ctx)) { + throw new Error('ctx is not a mutation ctx'); + } + + const onDeleteHandle = + authFunctions.onDelete && triggers?.[data.model]?.onDelete + ? ((await createFunctionHandle( + authFunctions.onDelete + )) as FunctionHandle<'mutation'>) + : undefined; + const result = await handlePagination(async ({ paginationOpts }) => { + return await ctx.runMutation(authFunctions.deleteMany, { + input: { + ...data, + where: parseWhere(data.where), + }, + paginationOpts, + onDeleteHandle: onDeleteHandle, + }); + }); + + return result.count; + }, + findMany: async (data): Promise => { + if (data.offset) { + throw new Error('offset not supported'); + } + if (data.where?.some((w) => w.connector === 'OR')) { + throw new Error('OR connector not supported in findMany'); + } + + const result = await handlePagination( + async ({ paginationOpts }) => { + return await ctx.runQuery(authFunctions.findMany, { + ...data, + paginationOpts, + where: parseWhere(data.where), + }); + }, + { limit: data.limit } + ); + + return result.docs; + }, + findOne: async (data): Promise => { + if (data.where?.every((w) => w.connector === 'OR')) { + for (const w of data.where) { + const result: any = await ctx.runQuery(authFunctions.findOne, { + ...data, + where: parseWhere([w]), + }); + + if (result) { + return result; + } + } + } + + return await ctx.runQuery(authFunctions.findOne, { + ...data, + where: parseWhere(data.where), + }); + }, + update: async (data): Promise => { + if (!('runMutation' in ctx)) { + throw new Error('ctx is not a mutation ctx'); + } + if (data.where?.length === 1 && data.where[0].operator === 'eq') { + const onUpdateHandle = + authFunctions.onUpdate && triggers?.[data.model]?.onUpdate + ? ((await createFunctionHandle( + authFunctions.onUpdate + )) as FunctionHandle<'mutation'>) + : undefined; + + return ctx.runMutation(authFunctions.updateOne, { + input: { + model: data.model as any, + update: data.update as any, + where: parseWhere(data.where), + }, + onUpdateHandle: onUpdateHandle, + }); + } + + throw new Error('where clause not supported'); + }, + updateMany: async (data) => { + if (!('runMutation' in ctx)) { + throw new Error('ctx is not an action ctx'); + } + + const onUpdateHandle = + authFunctions.onUpdate && triggers?.[data.model]?.onUpdate + ? ((await createFunctionHandle( + authFunctions.onUpdate + )) as FunctionHandle<'mutation'>) + : undefined; + + const result = await handlePagination(async ({ paginationOpts }) => { + return await ctx.runMutation(authFunctions.updateMany, { + input: { + ...(data as any), + where: parseWhere(data.where), + }, + paginationOpts, + onUpdateHandle: onUpdateHandle, + }); + }); + + return result.count; + }, + }; + }, + }); +}; + +export const dbAdapter = < + DataModel extends GenericDataModel, + Schema extends SchemaDefinition, +>( + ctx: GenericCtx, + options: BetterAuthOptions, + { + authFunctions, + debugLogs, + schema, + triggers, + }: { + authFunctions: AuthFunctions; + schema: Schema; + debugLogs?: AdapterDebugLogs; + triggers?: Triggers; + } +) => { + const betterAuthSchema = getAuthTables(options); + + return createAdapterFactory({ + config: { + ...adapterConfig, + debugLogs: debugLogs || false, + }, + adapter: ({ options }) => { + options.telemetry = { enabled: false }; + + return { + id: 'convex', + createSchema, + count: async (data) => { + if (data.where?.some((w) => w.connector === 'OR')) { + throw new Error('OR connector not supported in findMany'); + } + + const result = await handlePagination(async ({ paginationOpts }) => { + return await findManyHandler( + ctx, + { + ...data, + paginationOpts, + where: parseWhere(data.where), + }, + schema, + betterAuthSchema + ); + }); + + return result.docs?.length ?? 0; + }, + create: async ({ data, model, select }): Promise => { + const onCreateHandle = + authFunctions.onCreate && triggers?.[model]?.onCreate + ? ((await createFunctionHandle( + authFunctions.onCreate + )) as FunctionHandle<'mutation'>) + : undefined; + + return createHandler( + ctx, + { + input: { data, model }, + select, + onCreateHandle: onCreateHandle, + }, + schema, + betterAuthSchema + ); + }, + delete: async (data) => { + const onDeleteHandle = + authFunctions.onDelete && triggers?.[data.model]?.onDelete + ? ((await createFunctionHandle( + authFunctions.onDelete + )) as FunctionHandle<'mutation'>) + : undefined; + + await deleteOneHandler( + ctx, + { + input: { + model: data.model, + where: parseWhere(data.where), + }, + onDeleteHandle: onDeleteHandle, + }, + schema, + betterAuthSchema + ); + }, + deleteMany: async (data) => { + const onDeleteHandle = + authFunctions.onDelete && triggers?.[data.model]?.onDelete + ? ((await createFunctionHandle( + authFunctions.onDelete + )) as FunctionHandle<'mutation'>) + : undefined; + + const result = await handlePagination(async ({ paginationOpts }) => { + return await deleteManyHandler( + ctx, + { + input: { + ...data, + where: parseWhere(data.where), + }, + paginationOpts, + onDeleteHandle: onDeleteHandle, + }, + schema, + betterAuthSchema + ); + }); + + return result.count; + }, + findMany: async (data): Promise => { + if (data.offset) { + throw new Error('offset not supported'); + } + if (data.where?.some((w) => w.connector === 'OR')) { + throw new Error('OR connector not supported in findMany'); + } + + const result = await handlePagination( + async ({ paginationOpts }) => { + return await findManyHandler( + ctx, + { + ...data, + paginationOpts, + where: parseWhere(data.where), + }, + schema, + betterAuthSchema + ); + }, + { limit: data.limit } + ); + + return result.docs; + }, + findOne: async (data): Promise => { + if (data.where?.every((w) => w.connector === 'OR')) { + for (const w of data.where) { + const result = await findOneHandler( + ctx, + { + ...data, + where: parseWhere([w]), + }, + schema, + betterAuthSchema + ); + + if (result) { + return result; + } + } + } + + return await findOneHandler( + ctx, + { + ...data, + where: parseWhere(data.where), + }, + schema, + betterAuthSchema + ); + }, + update: async (data): Promise => { + if (data.where?.length === 1 && data.where[0].operator === 'eq') { + const onUpdateHandle = + authFunctions.onUpdate && triggers?.[data.model]?.onUpdate + ? ((await createFunctionHandle( + authFunctions.onUpdate + )) as FunctionHandle<'mutation'>) + : undefined; + + return updateOneHandler( + ctx, + { + input: { + model: data.model as any, + update: data.update as any, + where: parseWhere(data.where), + }, + onUpdateHandle: onUpdateHandle, + }, + schema, + betterAuthSchema + ); + } + + throw new Error('where clause not supported'); + }, + updateMany: async (data) => { + const onUpdateHandle = + authFunctions.onUpdate && triggers?.[data.model]?.onUpdate + ? ((await createFunctionHandle( + authFunctions.onUpdate + )) as FunctionHandle<'mutation'>) + : undefined; + + const result = await handlePagination(async ({ paginationOpts }) => { + return await updateManyHandler( + ctx, + { + input: { + ...(data as any), + where: parseWhere(data.where), + }, + paginationOpts, + onUpdateHandle: onUpdateHandle, + }, + schema, + betterAuthSchema + ); + }); + + return result.count; + }, + }; + }, + }); +}; diff --git a/src/adapterUtils.ts b/src/adapterUtils.ts new file mode 100644 index 0000000..1524f24 --- /dev/null +++ b/src/adapterUtils.ts @@ -0,0 +1,718 @@ +import type { BetterAuthDbSchema } from 'better-auth/db'; +import type { + DocumentByName, + GenericDataModel, + GenericQueryCtx, + PaginationOptions, + PaginationResult, + SchemaDefinition, + TableNamesInDataModel, +} from 'convex/server'; + +import { stripIndent } from 'common-tags'; +import { asyncMap } from 'convex-helpers'; +import { stream } from 'convex-helpers/server/stream'; +import { mergedStream } from 'convex-helpers/server/stream'; +import { type GenericId, type Infer, v } from 'convex/values'; + +export const adapterWhereValidator = v.object({ + connector: v.optional(v.union(v.literal('AND'), v.literal('OR'))), + field: v.string(), + operator: v.optional( + v.union( + v.literal('lt'), + v.literal('lte'), + v.literal('gt'), + v.literal('gte'), + v.literal('eq'), + v.literal('in'), + v.literal('not_in'), + v.literal('ne'), + v.literal('contains'), + v.literal('starts_with'), + v.literal('ends_with') + ) + ), + value: v.union( + v.string(), + v.number(), + v.boolean(), + v.array(v.string()), + v.array(v.number()), + v.null() + ), +}); + +export const adapterArgsValidator = v.object({ + limit: v.optional(v.number()), + model: v.string(), + offset: v.optional(v.number()), + select: v.optional(v.array(v.string())), + sortBy: v.optional( + v.object({ + direction: v.union(v.literal('asc'), v.literal('desc')), + field: v.string(), + }) + ), + where: v.optional(v.array(adapterWhereValidator)), +}); + +const isUniqueField = ( + betterAuthSchema: BetterAuthDbSchema, + model: string, + field: string +) => { + const fields = + betterAuthSchema[model as keyof typeof betterAuthSchema].fields; + + if (!fields) { + return false; + } + + return Object.entries(fields) + .filter(([, value]) => value.unique) + .map(([key]) => key) + .includes(field); +}; + +export const hasUniqueFields = ( + betterAuthSchema: BetterAuthDbSchema, + model: string, + input: Record +) => { + for (const field of Object.keys(input)) { + if (isUniqueField(betterAuthSchema, model, field)) { + return true; + } + } + + return false; +}; + +const findIndex = ( + schema: SchemaDefinition, + args: { + model: string; + sortBy?: { + direction: 'asc' | 'desc'; + field: string; + }; + where?: { + field: string; + value: number[] | string[] | boolean | number | string | null; + connector?: 'AND' | 'OR'; + operator?: + | 'contains' + | 'ends_with' + | 'eq' + | 'gt' + | 'gte' + | 'in' + | 'lt' + | 'lte' + | 'ne' + | 'not_in' + | 'starts_with'; + }[]; + } +) => { + if ( + (args.where?.length ?? 0) > 1 && + args.where?.some((w) => w.connector === 'OR') + ) { + throw new Error( + `OR connector not supported with multiple where statements in findIndex, split up the where statements before calling findIndex: ${JSON.stringify(args.where)}` + ); + } + + const where = args.where?.filter((w) => { + return ( + (!w.operator || + ['eq', 'gt', 'gte', 'in', 'lt', 'lte', 'not_in'].includes( + w.operator + )) && + w.field !== 'id' + ); + }); + + if (!where?.length && !args.sortBy) { + return; + } + + const lowerBounds = + where?.filter((w) => w.operator === 'lt' || w.operator === 'lte') ?? []; + + if (lowerBounds.length > 1) { + throw new Error( + `cannot have more than one lower bound where clause: ${JSON.stringify(where)}` + ); + } + + const upperBounds = + where?.filter((w) => w.operator === 'gt' || w.operator === 'gte') ?? []; + + if (upperBounds.length > 1) { + throw new Error( + `cannot have more than one upper bound where clause: ${JSON.stringify(where)}` + ); + } + + const lowerBound = lowerBounds[0]; + const upperBound = upperBounds[0]; + + if (lowerBound && upperBound && lowerBound.field !== upperBound.field) { + throw new Error( + `lower bound and upper bound must have the same field: ${JSON.stringify(where)}` + ); + } + + const boundField = lowerBound?.field || upperBound?.field; + + if ( + boundField && + where?.some( + (w) => w.field === boundField && w !== lowerBound && w !== upperBound + ) + ) { + throw new Error( + `too many where clauses on the bound field: ${JSON.stringify(where)}` + ); + } + + const indexEqFields = + where + ?.filter((w) => !w.operator || w.operator === 'eq') + .sort((a, b) => { + return a.field.localeCompare(b.field); + }) + .map((w) => [w.field, w.value]) ?? []; + + if (!indexEqFields?.length && !boundField && !args.sortBy) { + return; + } + + const table = schema.tables[args.model as keyof typeof schema.tables]; + + if (!table) { + throw new Error(`Table ${args.model} not found`); + } + + // DIFF: convex-ents uses 'indexes' instead of ' indexes' + const indexes = table[' indexes'] + ? table[' indexes']() + : (table as any).export().indexes; + const sortField = args.sortBy?.field; + + // We internally use _creationTime in place of Better Auth's createdAt + const indexFields = indexEqFields + .map(([field]) => field) + .concat( + boundField && boundField !== 'createdAt' + ? `${indexEqFields.length > 0 ? '_' : ''}${boundField}` + : '' + ) + .concat( + sortField && sortField !== 'createdAt' && boundField !== sortField + ? `${indexEqFields.length > 0 || boundField ? '_' : ''}${sortField}` + : '' + ) + .filter(Boolean); + + if (indexFields.length === 0 && !boundField && !sortField) { + return; + } + + // Use the built in _creationTime index if bounding or sorting by createdAt + // with no other fields + const index = + indexFields.length === 0 + ? { + fields: [], + indexDescriptor: 'by_creation_time', + } + : indexes.find(({ fields }: { fields: string[] }) => { + const fieldsMatch = indexFields.every( + (field, idx) => field === fields[idx] + ); + // If sorting by createdAt, no intermediate fields can be on the index + // as they may override the createdAt sort order. + const boundFieldMatch = + boundField === 'createdAt' || sortField === 'createdAt' + ? indexFields.length === fields.length + : true; + + return fieldsMatch && boundFieldMatch; + }); + + if (!index) { + return { indexFields }; + } + + return { + boundField, + index: { + fields: [...index.fields, '_creationTime'], + indexDescriptor: index.indexDescriptor, + }, + sortField, + values: { + eq: indexEqFields.map(([, value]) => value), + gt: upperBound?.operator === 'gt' ? upperBound.value : undefined, + gte: upperBound?.operator === 'gte' ? upperBound.value : undefined, + lt: lowerBound?.operator === 'lt' ? lowerBound.value : undefined, + lte: lowerBound?.operator === 'lte' ? lowerBound.value : undefined, + }, + }; +}; + +export const checkUniqueFields = async < + Schema extends SchemaDefinition, +>( + ctx: GenericQueryCtx, + schema: Schema, + betterAuthSchema: BetterAuthDbSchema, + table: string, + input: Record, + doc?: Record +) => { + if (!hasUniqueFields(betterAuthSchema, table, input)) { + return; + } + + for (const field of Object.keys(input)) { + if (!isUniqueField(betterAuthSchema, table, field)) { + continue; + } + + const { index } = + findIndex(schema, { + model: table, + where: [ + { field, operator: 'eq', value: input[field as keyof typeof input] }, + ], + }) || {}; + + if (!index) { + throw new Error(`No index found for ${table}${field}`); + } + + const existingDoc = await ctx.db + .query(table as any) + .withIndex(index.indexDescriptor, (q) => + q.eq(field, input[field as keyof typeof input]) + ) + .unique(); + + if (existingDoc && existingDoc._id !== doc?._id) { + throw new Error(`${table} ${field} already exists`); + } + } +}; + +// This handles basic select (stripping out the other fields if there +// is a select arg). +export const selectFields = async < + T extends TableNamesInDataModel, + D extends DocumentByName, +>( + doc: D | null, + select?: string[] +) => { + if (!doc) { + return null; + } + if (!select?.length) { + return doc; + } + + return select.reduce((acc, field) => { + (acc as any)[field] = doc[field]; + + return acc; + }, {} as D); +}; + +// Manually filter an individual document by where clauses. This is used to +// simplify queries that can only return 0 or 1 documents, or "in" clauses that +// query multiple single documents in parallel. +const filterByWhere = < + T extends TableNamesInDataModel, + D extends DocumentByName, +>( + doc: D | null, + where?: Infer[], + // Optionally filter which where clauses to apply. + filterWhere?: (w: Infer) => any +) => { + if (!doc) { + return false; + } + + for (const w of where ?? []) { + if (filterWhere && !filterWhere(w)) { + continue; + } + + const value = doc[w.field as keyof typeof doc] as Infer< + typeof adapterWhereValidator + >['value']; + const isLessThan = (val: typeof value, wVal: typeof w.value) => { + if (!wVal) { + return false; + } + if (!val) { + return true; + } + + return val < wVal; + }; + const isGreaterThan = (val: typeof value, wVal: typeof w.value) => { + if (!val) { + return false; + } + if (!wVal) { + return true; + } + + return val > wVal; + }; + const filter = (w: Infer) => { + switch (w.operator) { + case 'contains': { + return typeof value === 'string' && value.includes(w.value as string); + } + case 'ends_with': { + return typeof value === 'string' && value.endsWith(w.value as string); + } + case 'eq': + case undefined: { + return value === w.value; + } + case 'gt': { + return isGreaterThan(value, w.value); + } + case 'gte': { + return value === w.value || isGreaterThan(value, w.value); + } + case 'in': { + return Array.isArray(w.value) && (w.value as any[]).includes(value); + } + case 'lt': { + return isLessThan(value, w.value); + } + case 'lte': { + return value === w.value || isLessThan(value, w.value); + } + case 'ne': { + return value !== w.value; + } + case 'not_in': { + return Array.isArray(w.value) && !(w.value as any[]).includes(value); + } + case 'starts_with': { + return ( + typeof value === 'string' && value.startsWith(w.value as string) + ); + } + } + }; + + if (!filter(w)) { + return false; + } + } + + return true; +}; + +const generateQuery = ( + ctx: GenericQueryCtx, + schema: SchemaDefinition, + args: Infer +) => { + const { boundField, index, indexFields, values } = + findIndex(schema, args) ?? {}; + const query = stream(ctx.db as any, schema).query(args.model as any); + const hasValues = + values?.eq?.length || + values?.lt || + values?.lte || + values?.gt || + values?.gte; + const indexedQuery = + index && index.indexDescriptor !== 'by_creation_time' + ? query.withIndex( + index.indexDescriptor, + hasValues + ? (q: any) => { + for (const [idx, value] of (values?.eq ?? []).entries()) { + q = q.eq(index.fields[idx], value); + } + + if (values?.lt) { + q = q.lt(boundField, values.lt); + } + if (values?.lte) { + q = q.lte(boundField, values.lte); + } + if (values?.gt) { + q = q.gt(boundField, values.gt); + } + if (values?.gte) { + q = q.gte(boundField, values.gte); + } + + return q; + } + : undefined + ) + : query; + const orderedQuery = args.sortBy + ? indexedQuery.order(args.sortBy.direction === 'asc' ? 'asc' : 'desc') + : indexedQuery; + const filteredQuery = orderedQuery.filterWith(async (doc) => { + if (!index && indexFields?.length) { + console.warn( + stripIndent` + Querying without an index on table "${args.model}". + This can cause performance issues, and may hit the document read limit. + To fix, add an index that begins with the following fields in order: + [${indexFields.join(', ')}] + ` + ); + + // No index, handle all where clauses statically. + return filterByWhere(doc, args.where); + } + + return filterByWhere( + doc, + args.where, + // Index used for all eq and range clauses, apply remaining clauses + // incompatible with Convex statically. + (w) => + w.operator && + ['contains', 'ends_with', 'ne', 'not_in', 'starts_with'].includes( + w.operator + ) + ); + }); + + return filteredQuery; +}; + +// This is the core function for reading from the database, it parses and +// validates where conditions, selects indexes, and allows the caller to +// optionally paginate as needed. Every response is a pagination result. +export const paginate = async < + Doc extends DocumentByName, + T extends TableNamesInDataModel, +>( + ctx: GenericQueryCtx, + schema: SchemaDefinition, + betterAuthSchema: BetterAuthDbSchema, + args: Infer & { + paginationOpts: PaginationOptions; + } +): Promise> => { + if (args.offset) { + throw new Error(`offset not supported: ${JSON.stringify(args.offset)}`); + } + if (args.where?.some((w) => w.connector === 'OR') && args.where?.length > 1) { + throw new Error( + `OR connector not supported with multiple where statements in paginate, split up the where statements before calling paginate: ${JSON.stringify(args.where)}` + ); + } + if ( + args.where?.some( + (w) => + w.field === 'id' && + w.operator && + !['eq', 'in', 'ne', 'not_in'].includes(w.operator) + ) + ) { + throw new Error( + `id can only be used with eq, in, not_in, or ne operator: ${JSON.stringify(args.where)}` + ); + } + + // If any where clause is "eq" (or missing operator) on a unique field, + // we can only return a single document, so we get it and use any other + // where clauses as static filters. + const uniqueWhere = args.where?.find( + (w) => + (!w.operator || w.operator === 'eq') && + (isUniqueField(betterAuthSchema, args.model, w.field) || w.field === 'id') + ); + + if (uniqueWhere) { + const { index } = + findIndex(schema, { + model: args.model, + where: [uniqueWhere], + }) || {}; + const doc = + uniqueWhere.field === 'id' + ? await ctx.db.get(uniqueWhere.value as GenericId) + : await ctx.db + .query(args.model as any) + .withIndex(index?.indexDescriptor as any, (q) => + q.eq(index?.fields[0], uniqueWhere.value) + ) + .unique(); + + // Apply all other clauses as static filters to our 0 or 1 result. + if (filterByWhere(doc, args.where, (w) => w !== uniqueWhere)) { + return { + continueCursor: '', + isDone: true, + page: [await selectFields(doc, args.select)].filter(Boolean) as Doc[], + }; + } + + return { + continueCursor: '', + isDone: true, + page: [], + }; + } + + const paginationOpts = { + ...args.paginationOpts, + // If maximumRowsRead is not at least 1 higher than numItems, bad cursors + // and incorrect paging will result (at least with convex-test). + maximumRowsRead: Math.max((args.paginationOpts.numItems ?? 0) + 1, 200), + }; + + // Large queries using "in" clause will crash, but these are only currently + // possible with the organization plugin listing all members with a high + // limit. For cases like this we need to create proper convex queries in + // the component as an alternative to using Better Auth api's. + const inWhere = args.where?.find((w) => w.operator === 'in'); + + if (inWhere) { + if (!Array.isArray(inWhere.value)) { + throw new TypeError('in clause value must be an array'); + } + // For ids, just use asyncMap + .get() + if (inWhere.field === 'id') { + const docs = await asyncMap(inWhere.value as any[], async (value) => { + return ctx.db.get(value as GenericId); + }); + const filteredDocs = docs + .flatMap((doc) => (doc ? [doc] : [])) + .filter((doc) => filterByWhere(doc, args.where, (w) => w !== inWhere)); + + return { + continueCursor: '', + isDone: true, + page: filteredDocs.sort((a, b) => { + if (args.sortBy?.field === 'createdAt') { + return args.sortBy.direction === 'asc' + ? (a._creationTime as number) - (b._creationTime as number) + : (b._creationTime as number) - (a._creationTime as number); + } + if (args.sortBy) { + const aValue = a[args.sortBy.field as keyof typeof a]; + const bValue = b[args.sortBy.field as keyof typeof b]; + + if (aValue === bValue) { + return 0; + } + + return args.sortBy.direction === 'asc' + ? aValue! > bValue! + ? 1 + : -1 + : aValue! > bValue! + ? -1 + : 1; + } + + return 0; + }) as Doc[], + }; + } + + const streams = inWhere.value.map((value) => { + return generateQuery(ctx, schema, { + ...args, + where: args.where?.map((w) => { + if (w === inWhere) { + return { ...w, operator: 'eq', value }; + } + + return w; + }), + }); + }); + const result = await mergedStream( + streams, + [ + args.sortBy?.field !== 'createdAt' && args.sortBy?.field, + '_creationTime', + ].flatMap((f) => (f ? [f] : [])) + ).paginate(paginationOpts); + + return { + ...result, + page: await asyncMap(result.page, (doc) => + selectFields(doc, args.select) + ), + }; + } + + // Handle not_in operator separately as it requires filtering out documents + const notInWhere = args.where?.find((w) => w.operator === 'not_in'); + + if (notInWhere) { + if (!Array.isArray(notInWhere.value)) { + throw new TypeError('not_in clause value must be an array'); + } + + // For not_in with IDs, we need to query all and filter out the excluded ones + const query = generateQuery(ctx, schema, { + ...args, + where: args.where?.filter((w) => w !== notInWhere), + }); + const result = await query.paginate(paginationOpts); + const filteredPage = result.page.filter((doc) => + filterByWhere(doc, [notInWhere]) + ); + + return { + ...result, + page: await asyncMap(filteredPage, (doc) => + selectFields(doc, args.select) + ), + }; + } + + const query = generateQuery(ctx, schema, args); + const result = await query.paginate(paginationOpts); + + return { + ...result, + page: await asyncMap(result.page, (doc) => selectFields(doc, args.select)), + }; +}; + +export const listOne = async < + Doc extends DocumentByName, + T extends TableNamesInDataModel, +>( + ctx: GenericQueryCtx, + schema: SchemaDefinition, + betterAuthSchema: BetterAuthDbSchema, + args: Infer +): Promise => { + return ( + await paginate(ctx, schema, betterAuthSchema, { + ...args, + paginationOpts: { + cursor: null, + numItems: 1, + }, + }) + ).page[0] as Doc | null; +}; diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 0000000..a7922e3 --- /dev/null +++ b/src/api.ts @@ -0,0 +1,442 @@ +import type { BetterAuthOptions } from 'better-auth'; + +import { getAuthTables } from 'better-auth/db'; +import { asyncMap } from 'convex-helpers'; +import { partial } from 'convex-helpers/validators'; +import { + type FunctionHandle, + type SchemaDefinition, + internalMutationGeneric, + internalQueryGeneric, + paginationOptsValidator, +} from 'convex/server'; +import { type GenericId, v } from 'convex/values'; + +import { + adapterWhereValidator, + checkUniqueFields, + hasUniqueFields, + listOne, + paginate, + selectFields, +} from './adapterUtils'; + +type Schema = SchemaDefinition; + +const whereValidator = (schema: Schema, tableName: keyof Schema['tables']) => + v.object({ + connector: v.optional(v.union(v.literal('AND'), v.literal('OR'))), + field: v.union( + ...Object.keys(schema.tables[tableName].validator.fields).map((field) => + v.literal(field) + ), + v.literal('id') + ), + operator: v.optional( + v.union( + v.literal('lt'), + v.literal('lte'), + v.literal('gt'), + v.literal('gte'), + v.literal('eq'), + v.literal('in'), + v.literal('not_in'), + v.literal('ne'), + v.literal('contains'), + v.literal('starts_with'), + v.literal('ends_with') + ) + ), + value: v.union( + v.string(), + v.number(), + v.boolean(), + v.array(v.string()), + v.array(v.number()), + v.null() + ), + }); + +// Extracted handler functions +export const createHandler = async ( + ctx: any, + args: { + input: { + data: any; + model: string; + }; + select?: string[]; + onCreateHandle?: string; + }, + schema: Schema, + betterAuthSchema: any +) => { + await checkUniqueFields( + ctx, + schema, + betterAuthSchema, + args.input.model, + args.input.data + ); + const id = await ctx.db.insert(args.input.model as any, args.input.data); + const doc = await ctx.db.get(id); + + if (!doc) { + throw new Error(`Failed to create ${args.input.model}`); + } + + const result = selectFields(doc, args.select); + + if (args.onCreateHandle) { + await ctx.runMutation(args.onCreateHandle as FunctionHandle<'mutation'>, { + doc, + model: args.input.model, + }); + } + + return result; +}; + +export const findOneHandler = async ( + ctx: any, + args: { + model: string; + select?: string[]; + where?: any[]; + }, + schema: Schema, + betterAuthSchema: any +) => { + return await listOne(ctx, schema, betterAuthSchema, args); +}; + +export const findManyHandler = async ( + ctx: any, + args: { + model: string; + paginationOpts: any; + limit?: number; + offset?: number; + sortBy?: { + direction: 'asc' | 'desc'; + field: string; + }; + where?: any[]; + }, + schema: Schema, + betterAuthSchema: any +) => { + return await paginate(ctx, schema, betterAuthSchema, args); +}; + +export const updateOneHandler = async ( + ctx: any, + args: { + input: { + model: string; + update: any; + where?: any[]; + }; + onUpdateHandle?: string; + }, + schema: Schema, + betterAuthSchema: any +) => { + const doc = await listOne(ctx, schema, betterAuthSchema, args.input); + + if (!doc) { + throw new Error(`Failed to update ${args.input.model}`); + } + + await checkUniqueFields( + ctx, + schema, + betterAuthSchema, + args.input.model, + args.input.update, + doc + ); + await ctx.db.patch(doc._id as GenericId, args.input.update as any); + const updatedDoc = await ctx.db.get(doc._id as GenericId); + + if (!updatedDoc) { + throw new Error(`Failed to update ${args.input.model}`); + } + if (args.onUpdateHandle) { + await ctx.runMutation(args.onUpdateHandle as FunctionHandle<'mutation'>, { + model: args.input.model, + newDoc: updatedDoc, + oldDoc: doc, + }); + } + + return updatedDoc; +}; + +export const updateManyHandler = async ( + ctx: any, + args: { + input: { + model: string; + update?: any; + where?: any[]; + }; + paginationOpts: any; + onUpdateHandle?: string; + }, + schema: Schema, + betterAuthSchema: any +) => { + const { page, ...result } = await paginate(ctx, schema, betterAuthSchema, { + ...args.input, + paginationOpts: args.paginationOpts, + }); + + if (args.input.update) { + if ( + hasUniqueFields( + betterAuthSchema, + args.input.model, + args.input.update ?? {} + ) && + page.length > 1 + ) { + throw new Error( + `Attempted to set unique fields in multiple documents in ${args.input.model} with the same value. Fields: ${Object.keys(args.input.update ?? {}).join(', ')}` + ); + } + + await asyncMap(page, async (doc: any) => { + await checkUniqueFields( + ctx, + schema, + betterAuthSchema, + args.input.model, + args.input.update ?? {}, + doc + ); + await ctx.db.patch( + doc._id as GenericId, + args.input.update as any + ); + + if (args.onUpdateHandle) { + await ctx.runMutation( + args.onUpdateHandle as FunctionHandle<'mutation'>, + { + model: args.input.model, + newDoc: await ctx.db.get(doc._id as GenericId), + oldDoc: doc, + } + ); + } + }); + } + + return { + ...result, + count: page.length, + ids: page.map((doc: any) => doc._id), + }; +}; + +export const deleteOneHandler = async ( + ctx: any, + args: { + input: { + model: string; + where?: any[]; + }; + onDeleteHandle?: string; + }, + schema: Schema, + betterAuthSchema: any +) => { + const doc = await listOne(ctx, schema, betterAuthSchema, args.input); + + if (!doc) { + return; + } + + await ctx.db.delete(doc._id as GenericId); + + if (args.onDeleteHandle) { + await ctx.runMutation(args.onDeleteHandle as FunctionHandle<'mutation'>, { + doc, + model: args.input.model, + }); + } + + return doc; +}; + +export const deleteManyHandler = async ( + ctx: any, + args: { + input: { + model: string; + where?: any[]; + }; + paginationOpts: any; + onDeleteHandle?: string; + }, + schema: Schema, + betterAuthSchema: any +) => { + const { page, ...result } = await paginate(ctx, schema, betterAuthSchema, { + ...args.input, + paginationOpts: args.paginationOpts, + }); + await asyncMap(page, async (doc: any) => { + if (args.onDeleteHandle) { + await ctx.runMutation(args.onDeleteHandle as FunctionHandle<'mutation'>, { + doc, + model: args.input.model, + }); + } + + await ctx.db.delete(doc._id as GenericId); + }); + + return { + ...result, + count: page.length, + ids: page.map((doc: any) => doc._id), + }; +}; + +export const createApi = >( + schema: Schema, + authOptions: BetterAuthOptions +) => { + const betterAuthSchema = getAuthTables(authOptions); + + return { + create: internalMutationGeneric({ + args: { + input: v.union( + ...Object.entries(schema.tables).map(([model, table]) => + v.object({ + data: v.object((table as any).validator.fields), + model: v.literal(model), + }) + ) + ), + select: v.optional(v.array(v.string())), + onCreateHandle: v.optional(v.string()), + }, + handler: async (ctx, args) => + createHandler(ctx, args, schema, betterAuthSchema), + }), + deleteMany: internalMutationGeneric({ + args: { + input: v.union( + ...Object.keys(schema.tables).map((tableName) => { + return v.object({ + model: v.literal(tableName), + where: v.optional( + v.array( + whereValidator(schema, tableName as keyof Schema['tables']) + ) + ), + }); + }) + ), + paginationOpts: paginationOptsValidator, + onDeleteHandle: v.optional(v.string()), + }, + handler: async (ctx, args) => + deleteManyHandler(ctx, args, schema, betterAuthSchema), + }), + deleteOne: internalMutationGeneric({ + args: { + input: v.union( + ...Object.keys(schema.tables).map((tableName) => { + return v.object({ + model: v.literal(tableName), + where: v.optional( + v.array( + whereValidator(schema, tableName as keyof Schema['tables']) + ) + ), + }); + }) + ), + onDeleteHandle: v.optional(v.string()), + }, + handler: async (ctx, args) => + deleteOneHandler(ctx, args, schema, betterAuthSchema), + }), + findMany: internalQueryGeneric({ + args: { + limit: v.optional(v.number()), + model: v.union( + ...Object.keys(schema.tables).map((model) => v.literal(model)) + ), + offset: v.optional(v.number()), + paginationOpts: paginationOptsValidator, + sortBy: v.optional( + v.object({ + direction: v.union(v.literal('asc'), v.literal('desc')), + field: v.string(), + }) + ), + where: v.optional(v.array(adapterWhereValidator)), + }, + handler: async (ctx, args) => + findManyHandler(ctx, args, schema, betterAuthSchema), + }), + findOne: internalQueryGeneric({ + args: { + model: v.union( + ...Object.keys(schema.tables).map((model) => v.literal(model)) + ), + select: v.optional(v.array(v.string())), + where: v.optional(v.array(adapterWhereValidator)), + }, + handler: async (ctx, args) => + findOneHandler(ctx, args, schema, betterAuthSchema), + }), + updateMany: internalMutationGeneric({ + args: { + input: v.union( + ...Object.entries(schema.tables).map( + ([tableName, table]: [string, Schema['tables'][string]]) => { + const fields = partial(table.validator.fields); + + return v.object({ + model: v.literal(tableName), + update: v.object(fields), + where: v.optional(v.array(whereValidator(schema, tableName))), + }); + } + ) + ), + paginationOpts: paginationOptsValidator, + onUpdateHandle: v.optional(v.string()), + }, + handler: async (ctx, args) => + updateManyHandler(ctx, args, schema, betterAuthSchema), + }), + updateOne: internalMutationGeneric({ + args: { + input: v.union( + ...Object.entries(schema.tables).map( + ([tableName, table]: [string, Schema['tables'][string]]) => { + const fields = partial(table.validator.fields); + + return v.object({ + model: v.literal(tableName), + update: v.object(fields), + where: v.optional(v.array(whereValidator(schema, tableName))), + }); + } + ) + ), + onUpdateHandle: v.optional(v.string()), + }, + handler: async (ctx, args) => + updateOneHandler(ctx, args, schema, betterAuthSchema), + }), + }; +}; diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..1e86372 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,106 @@ +import type { GenericCtx } from '@convex-dev/better-auth'; +import type { BetterAuthOptions } from 'better-auth'; + +import { + type FunctionReference, + type GenericDataModel, + type GenericMutationCtx, + type GenericSchema, + type IdField, + type SchemaDefinition, + type SystemFields, + internalMutationGeneric, +} from 'convex/server'; +import { type Infer, v } from 'convex/values'; + +import { dbAdapter, httpAdapter } from './adapter'; + +export type AuthFunctions = { + create: FunctionReference<'mutation', 'internal', Record>; + deleteMany: FunctionReference<'mutation', 'internal', Record>; + deleteOne: FunctionReference<'mutation', 'internal', Record>; + findMany: FunctionReference<'query', 'internal', Record>; + findOne: FunctionReference<'query', 'internal', Record>; + updateMany: FunctionReference<'mutation', 'internal', Record>; + updateOne: FunctionReference<'mutation', 'internal', Record>; + onCreate: FunctionReference<'mutation', 'internal', Record>; + onDelete: FunctionReference<'mutation', 'internal', Record>; + onUpdate: FunctionReference<'mutation', 'internal', Record>; +}; + +export type Triggers< + DataModel extends GenericDataModel, + Schema extends SchemaDefinition, +> = { + [K in keyof Schema['tables'] & string]?: { + onCreate?: ( + ctx: GenericMutationCtx, + doc: Infer & IdField & SystemFields + ) => Promise; + onDelete?: ( + ctx: GenericMutationCtx, + doc: Infer & IdField & SystemFields + ) => Promise; + onUpdate?: ( + ctx: GenericMutationCtx, + oldDoc: Infer & + IdField & + SystemFields, + newDoc: Infer & + IdField & { + _creationTime: number; + } + ) => Promise; + }; +}; + +export const createClient = < + DataModel extends GenericDataModel, + Schema extends SchemaDefinition, +>(config: { + authFunctions: AuthFunctions; + schema: Schema; + triggers?: Triggers; +}) => { + return { + authFunctions: config.authFunctions, + triggers: config.triggers, + adapter: (ctx: GenericCtx, options: BetterAuthOptions) => + dbAdapter(ctx, options, config), + httpAdapter: (ctx: GenericCtx) => httpAdapter(ctx, config), + triggersApi: () => ({ + onCreate: internalMutationGeneric({ + args: { + doc: v.any(), + model: v.string(), + }, + handler: async (ctx, args) => { + await config?.triggers?.[args.model]?.onCreate?.(ctx, args.doc); + }, + }), + onDelete: internalMutationGeneric({ + args: { + doc: v.any(), + model: v.string(), + }, + handler: async (ctx, args) => { + await config?.triggers?.[args.model]?.onDelete?.(ctx, args.doc); + }, + }), + onUpdate: internalMutationGeneric({ + args: { + model: v.string(), + newDoc: v.any(), + oldDoc: v.any(), + }, + handler: async (ctx, args) => { + await config?.triggers?.[args.model]?.onUpdate?.( + ctx, + args.oldDoc, + args.newDoc + ); + }, + }), + }), + }; +}; diff --git a/src/createSchema.ts b/src/createSchema.ts new file mode 100644 index 0000000..e814812 --- /dev/null +++ b/src/createSchema.ts @@ -0,0 +1,170 @@ +/* eslint-disable unicorn/consistent-function-scoping */ +import type { BetterAuthDbSchema, FieldAttribute } from 'better-auth/db'; + +// Manually add fields to index on for schema generation, +// all fields in the schema specialFields are automatically indexed +export const indexFields = { + account: ['accountId', ['accountId', 'providerId'], ['providerId', 'userId']], + apikey: ['key'], + invitation: [ + ['email', 'organizationId', 'status'], + ['organizationId', 'status'], + ], + member: [['organizationId', 'userId']], + oauthConsent: [['clientId', 'userId']], + passkey: ['credentialID'], + rateLimit: ['key'], + session: ['expiresAt', ['expiresAt', 'userId']], + ssoProvider: ['organizationId', 'domain'], + subscription: ['stripeSubscriptionId', 'stripeCustomerId', 'referenceId'], + user: [['email', 'name'], 'name', 'userId'], + verification: ['expiresAt', 'identifier'], +}; + +// Return map of unique, sortable, and reference fields +const specialFields = (tables: BetterAuthDbSchema) => + Object.fromEntries( + Object.entries(tables) + .map(([key, table]) => { + const fields = Object.fromEntries( + Object.entries(table.fields) + .map(([fieldKey, field]) => [ + fieldKey, + { + ...(field.sortable ? { sortable: true } : {}), + ...(field.unique ? { unique: true } : {}), + ...(field.references ? { references: field.references } : {}), + }, + ]) + .filter(([_key, value]) => + typeof value === 'object' ? Object.keys(value).length > 0 : true + ) + ); + + return [key, fields]; + }) + .filter(([_key, value]) => + typeof value === 'object' ? Object.keys(value).length > 0 : true + ) + ); + +const mergedIndexFields = (tables: BetterAuthDbSchema) => + Object.fromEntries( + Object.entries(tables).map(([key]) => { + const manualIndexes = indexFields[key as keyof typeof indexFields] || []; + const specialFieldIndexes = Object.keys( + specialFields(tables)[key as keyof ReturnType] || + {} + ).filter( + (index) => + !manualIndexes.some((m) => + Array.isArray(m) ? m[0] === index : m === index + ) + ); + + return [key, manualIndexes.concat(specialFieldIndexes)]; + }) + ); + +export const createSchema = async ({ + file, + tables, +}: { + tables: BetterAuthDbSchema; + file?: string; +}) => { + // stop convex esbuild from throwing over this import, only runs + // in the better auth cli + const pathImport = 'path'; + const path = await import(pathImport); + const baseName = path.basename(path.resolve(process.cwd(), file ?? '')); + + // if the target directory is named "convex", they're almost definitely + // generating the schema in the wrong directory, likely would replace the + // app schema + if (baseName === 'convex') { + throw new Error( + 'Better Auth schema must be generated in the Better Auth component directory.' + ); + } + + let code = `// eslint-disable +// This file is auto-generated. Do not edit this file manually. +// To regenerate the schema, run: +// \`npx @better-auth/cli generate --output ${file} -y\` + +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; + +export const tables = { +`; + + for (const tableKey in tables) { + const table = tables[tableKey]!; + const modelName = table.modelName; + + // No id fields in Convex schema + const fields = Object.fromEntries( + Object.entries(table.fields).filter(([key]) => key !== 'id') + ); + + function getType(name: string, field: FieldAttribute) { + const type = field.type as + | 'boolean' + | 'date' + | 'number' + | 'string' + | `${'number' | 'string'}[]`; + + const typeMap: Record = { + boolean: `v.boolean()`, + date: `v.number()`, + number: `v.number()`, + 'number[]': `v.array(v.number())`, + string: `v.string()`, + 'string[]': `v.array(v.string())`, + } as const; + + return typeMap[type]; + } + + const indexes = + mergedIndexFields(tables)[ + modelName as keyof typeof mergedIndexFields + ]?.map((index) => { + const indexArray = Array.isArray(index) ? index.sort() : [index]; + const indexName = indexArray.join('_'); + + return `.index("${indexName}", ${JSON.stringify(indexArray)})`; + }) || []; + + const schema = `${modelName}: defineTable({ +${Object.keys(fields) + .map((field) => { + const attr = fields[field]!; + const type = getType(field, attr as FieldAttribute); + const optional = (fieldSchema: string) => + attr.required + ? fieldSchema + : `v.optional(v.union(v.null(), ${fieldSchema}))`; + + return ` ${field}: ${optional(type)},`; + }) + .join('\n')} + })${indexes.length > 0 ? `\n ${indexes.join('\n ')}` : ''},\n`; + code += ` ${schema}`; + } + + code += `}; + +const schema = defineSchema(tables); + +export default schema; +`; + + return { + code, + overwrite: true, + path: file ?? './schema.ts', + }; +}; diff --git a/src/helpers.ts b/src/helpers.ts new file mode 100644 index 0000000..a47dbdc --- /dev/null +++ b/src/helpers.ts @@ -0,0 +1,50 @@ +import type { + DocumentByName, + GenericDataModel, + GenericQueryCtx, +} from 'convex/server'; + +export const getAuthUserId = async ( + ctx: GenericQueryCtx +) => { + const identity = await ctx.auth.getUserIdentity(); + + if (!identity) { + return null; + } + + return identity.subject as DocumentByName['_id']; +}; + +export const getSession = async ( + ctx: GenericQueryCtx +) => { + const userId = await getAuthUserId(ctx); + + if (!userId) { + return null; + } + + return (await ctx.db + .query('session' as any) + .withIndex('userId', (q) => q.eq('userId', userId as any)) + .order('desc') + .first()) as DocumentByName | null; +}; + +export const getHeaders = async ( + ctx: GenericQueryCtx +) => { + const session = await getSession(ctx); + + if (!session) { + return new Headers(); + } + + return new Headers({ + ...(session?.token ? { authorization: `Bearer ${session.token}` } : {}), + ...(session?.ipAddress + ? { 'x-forwarded-for': session.ipAddress as string } + : {}), + }); +}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..528a993 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,11 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './adapter'; +export * from './adapterUtils'; +export * from './api'; +export * from './client'; +export * from './createSchema'; +export * from './helpers'; +export * from './registerRoutes'; diff --git a/src/registerRoutes.ts b/src/registerRoutes.ts new file mode 100644 index 0000000..73010ca --- /dev/null +++ b/src/registerRoutes.ts @@ -0,0 +1,130 @@ +import type { betterAuth } from 'better-auth'; + +import { requireEnv } from '@convex-dev/better-auth/utils'; +import { corsRouter } from 'convex-helpers/server/cors'; +import { type HttpRouter, httpActionGeneric } from 'convex/server'; + +export type CreateAuth = + | ((ctx: any) => ReturnType) + | (( + ctx: any, + opts?: { optionsOnly?: boolean } + ) => ReturnType); + +export const getStaticAuth = (createAuth: CreateAuth) => { + return createAuth({}, { optionsOnly: true }); +}; + +export const registerRoutes = ( + http: HttpRouter, + createAuth: CreateAuth, + opts: { + cors?: + | { + allowedHeaders?: string[]; + // These values are appended to the default values + allowedOrigins?: string[]; + exposedHeaders?: string[]; + } + | boolean; + verbose?: boolean; + } = {} +) => { + const staticAuth = getStaticAuth(createAuth); + const path = staticAuth.options.basePath ?? '/api/auth'; + const authRequestHandler = httpActionGeneric(async (ctx, request) => { + if (opts?.verbose) { + console.log('options.baseURL', staticAuth.options.baseURL); + console.log('request headers', request.headers); + } + + const auth = createAuth(ctx as any); + const response = await auth.handler(request); + + if (opts?.verbose) { + console.log('response headers', response.headers); + } + + return response; + }); + const wellKnown = http.lookup('/.well-known/openid-configuration', 'GET'); + + // If registerRoutes is used multiple times, this may already be defined + if (!wellKnown) { + // Redirect root well-known to api well-known + http.route({ + handler: httpActionGeneric(async () => { + const url = `${requireEnv('CONVEX_SITE_URL')}${path}/convex/.well-known/openid-configuration`; + + return Response.redirect(url); + }), + method: 'GET', + path: '/.well-known/openid-configuration', + }); + } + if (!opts.cors) { + http.route({ + handler: authRequestHandler, + method: 'GET', + pathPrefix: `${path}/`, + }); + + http.route({ + handler: authRequestHandler, + method: 'POST', + pathPrefix: `${path}/`, + }); + + return; + } + + const corsOpts = + typeof opts.cors === 'boolean' + ? { allowedHeaders: [], allowedOrigins: [], exposedHeaders: [] } + : opts.cors; + let trustedOriginsOption: + | ((request: Request) => Promise | string[]) + | string[] + | undefined; + const cors = corsRouter(http, { + allowCredentials: true, + allowedHeaders: ['Content-Type', 'Better-Auth-Cookie'].concat( + corsOpts.allowedHeaders ?? [] + ), + debug: opts?.verbose, + enforceAllowOrigins: false, + exposedHeaders: ['Set-Better-Auth-Cookie'].concat( + corsOpts.exposedHeaders ?? [] + ), + allowedOrigins: async (request) => { + trustedOriginsOption = + trustedOriginsOption ?? + (await staticAuth.$context).options.trustedOrigins ?? + []; + const trustedOrigins = Array.isArray(trustedOriginsOption) + ? trustedOriginsOption + : await trustedOriginsOption(request); + + return trustedOrigins + .map((origin) => + // Strip trailing wildcards, unsupported for allowedOrigins + origin.endsWith('*') && origin.length > 1 + ? origin.slice(0, -1) + : origin + ) + .concat(corsOpts.allowedOrigins ?? []); + }, + }); + + cors.route({ + handler: authRequestHandler, + method: 'GET', + pathPrefix: `${path}/`, + }); + + cors.route({ + handler: authRequestHandler, + method: 'POST', + pathPrefix: `${path}/`, + }); +}; diff --git a/tooling/eslint/configs/eslint-base.js b/tooling/eslint/configs/eslint-base.js new file mode 100644 index 0000000..83ed231 --- /dev/null +++ b/tooling/eslint/configs/eslint-base.js @@ -0,0 +1,137 @@ +import js from '@eslint/js'; + +import { defineConfig } from '../utils.js'; +import perfectionistConfig from './eslint-perfectionist.js'; +import unicornConfig from './eslint-unicorn.js'; + +export default defineConfig( + { + ignores: [ + '.next', + '.vercel', + '.astro', + '.source', + 'dist', + '.tsup', + `**/node_modules`, + '.cache', + '**/.cache', + '**/build', + '**/dist', + '**/bundled', + '**/vault', + '**/_vault', + '**/__*', + '**/*.mdx', + 'tooling/scripts/**/*', + '**/*demo', + '.changeset', + ], + }, + + // ─── JavaScript ─────────────────────────────────────────────────────── + + js.configs.recommended, + { + files: ['**/*.{js,mjs,cjs}'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + }, + { + files: ['**/*.{js,mjs,cjs,ts,tsx}'], + }, + { + // List of rules to use + rules: { + 'linebreak-style': ['error', 'unix'], + 'no-case-declarations': 'off', + 'no-empty': ['error', { allowEmptyCatch: true }], + 'no-empty-function': 'off', + 'no-prototype-builtins': 'off', + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['*/_generated/server'], + importNames: ['mutation', 'internalMutation'], + message: 'Use functions.ts for mutation', + }, + ], + }, + ], + }, + }, + // Formatting + { + rules: { + 'arrow-body-style': 'off', + 'lines-around-directive': ['warn', 'always'], + 'padding-line-between-statements': [ + 'warn', + { blankLine: 'never', next: 'case', prev: '*' }, + { blankLine: 'always', next: 'break', prev: '*' }, + { blankLine: 'always', next: 'class', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'class' }, + { blankLine: 'always', next: 'continue', prev: '*' }, + { blankLine: 'always', next: 'do', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'do' }, + { blankLine: 'always', next: 'export', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'export' }, + { blankLine: 'always', next: 'for', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'for' }, + { blankLine: 'always', next: 'function', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'function' }, + { blankLine: 'always', next: 'if', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'if' }, + { blankLine: 'never', next: 'if', prev: 'if' }, + { blankLine: 'always', next: 'return', prev: '*' }, + { blankLine: 'always', next: 'switch', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'switch' }, + { blankLine: 'always', next: 'throw', prev: '*' }, + { blankLine: 'always', next: 'try', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'try' }, + { blankLine: 'always', next: 'while', prev: '*' }, + { blankLine: 'always', next: '*', prev: 'while' }, + ], + 'prefer-arrow-callback': 'off', + 'spaced-comment': [ + 'error', + 'always', + { + block: { + balanced: true, + exceptions: ['*'], + markers: ['!'], + }, + line: { + exceptions: ['-', '+'], + markers: ['/'], + }, + }, + ], + }, + }, + + // ─── Test ──────────────────────────────────────────────────────────── + + // ...vitestConfig, + + // ─── Perfectionist / Unicorn ───────────────────────────────────────── + + ...unicornConfig, + ...perfectionistConfig + + // ─── Tailwind (disabled, not yet compatible) ───────────────────────── + + // ...fixupConfigRules(compat.extends('plugin:tailwindcss/recommended')), + // { + // settings: { + // tailwindcss: { + // callees: ['classnames', 'clsx', 'ctl', 'cn', 'cva'], + // }, + // }, + // }, +); diff --git a/tooling/eslint/configs/eslint-perfectionist.js b/tooling/eslint/configs/eslint-perfectionist.js new file mode 100644 index 0000000..0b301c1 --- /dev/null +++ b/tooling/eslint/configs/eslint-perfectionist.js @@ -0,0 +1,295 @@ +import perfectionist from 'eslint-plugin-perfectionist'; + +import { defineConfig } from '../utils.js'; + +export default defineConfig(perfectionist.configs['recommended-natural'], { + rules: { + // '@typescript-eslint/adjacent-overload-signatures': 'off', + 'perfectionist/sort-array-includes': [ + 'warn', + { + groupKind: 'literals-first', + type: 'natural', + }, + ], + 'perfectionist/sort-classes': [ + 'warn', + { + groups: [ + 'index-signature', + 'static-property', + 'private-property', + 'protected-property', + 'property', + 'constructor', + 'static-method', + 'private-method', + 'protected-method', + 'method', + ['get-method', 'set-method'], + 'static-block', + 'unknown', + ], + type: 'natural', + }, + ], + 'perfectionist/sort-decorators': [ + 'warn', + { + type: 'natural', + }, + ], + 'perfectionist/sort-enums': [ + 'warn', + { + sortByValue: true, + type: 'natural', + }, + ], + 'perfectionist/sort-exports': [ + 'warn', + { + groupKind: 'types-first', + type: 'natural', + }, + ], + 'perfectionist/sort-heritage-clauses': [ + 'off', + { + type: 'natural', + }, + ], + 'perfectionist/sort-imports': [ + // 'off', + 'warn', + { + customGroups: { + type: { + next: '^next$', + react: '^react$', + }, + value: { + next: ['^next$'], + react: ['^react$', '^react-.*$'], + }, + }, + groups: [ + 'react', + ['type', 'internal-type'], + 'next', + ['builtin', 'external'], + 'internal', + ['parent-type', 'sibling-type', 'index-type'], + ['parent', 'sibling', 'index'], + 'side-effect', + 'style', + 'object', + 'unknown', + ], + internalPattern: ['^@/.*'], + type: 'natural', + }, + ], + 'perfectionist/sort-interfaces': [ + 'warn', + { + customGroups: { + key: ['^key$', '^keys$'], + id: ['^id$', '^_id$'], + }, + groupKind: 'required-first', + groups: [ + 'key', + 'id', + 'unknown', + // 'multiline', + 'method', + ], + partitionByComment: true, + + type: 'natural', + }, + ], + // breaking: ordering matters + 'perfectionist/sort-intersection-types': 'off', + 'perfectionist/sort-jsx-props': [ + 'warn', + { + customGroups: { + key: ['^key$', '^keys$'], + id: ['^id$', '^name$', '^testId$', '^data-testid$'], + accessibility: [ + '^title$', + '^alt$', + '^placeholder$', + '^label$', + '^description$', + '^fallback$', + ], + callback: ['^on[A-Z]', '^handle[A-Z]'], + className: ['^className$', '^class$', '^style$'], + control: ['^asChild$', '^as$'], + data: ['^data-*', '^aria-*'], + ref: ['^ref$', '^innerRef$'], + state: [ + '^value$', + '^checked$', + '^selected$', + '^open$', + '^defaultValue$', + '^defaultChecked$', + '^defaultOpen$', + '^disabled$', + '^required$', + '^readOnly$', + '^loading$', + ], + variant: ['^variant$', '^size$', '^orientation$', '^color$'], + }, + groups: [ + 'id', + 'key', + 'ref', + 'control', + 'variant', + 'className', + 'state', + 'callback', + 'accessibility', + 'data', + 'unknown', + 'shorthand', + ], + type: 'natural', + }, + ], + 'perfectionist/sort-modules': 'off', + // 'perfectionist/sort-modules': [ + // 'warn', + // { + // groups: [ + // 'declare-enum', + // 'export-enum', + // 'enum', + // ['declare-interface', 'declare-type'], + // ['export-interface', 'export-type'], + // ['interface', 'type'], + // 'declare-class', + // 'class', + // 'export-class', + + // // 'declare-function', + // // 'export-function', + // // 'function', + + // // 'unknown', + // ], + // partitionByComment: true, + // type: 'natural', + // }, + // ], + 'perfectionist/sort-named-exports': [ + 'warn', + { + groupKind: 'types-first', + type: 'natural', + }, + ], + 'perfectionist/sort-named-imports': [ + 'warn', + { + groupKind: 'types-first', + type: 'natural', + }, + ], + 'perfectionist/sort-object-types': [ + 'warn', + { + customGroups: { + key: ['^key$', '^keys$'], + id: ['^id$', '^_id$'], + callback: ['^on[A-Z]', '^handle[A-Z]'], + }, + groupKind: 'required-first', + groups: [ + 'key', + 'id', + 'unknown', + // 'multiline', + 'method', + 'callback', + ], + newlinesBetween: 'never', + type: 'natural', + }, + ], + 'perfectionist/sort-objects': [ + 'warn', + { + customGroups: { + key: ['^key$', '^keys$'], + id: ['^id$', '^_id$'], + callback: ['^on[A-Z]', '^handle[A-Z]'], + }, + groups: [ + 'key', + 'id', + 'unknown', + // 'multiline', + 'method', + 'callback', + ], + partitionByComment: true, + // newlinesBetween: 'never', + type: 'natural', + }, + ], + 'perfectionist/sort-sets': [ + 'warn', + { + type: 'natural', + }, + ], + 'perfectionist/sort-switch-case': [ + 'warn', + { + type: 'natural', + }, + ], + 'perfectionist/sort-union-types': [ + 'warn', + { + groups: [ + 'unknown', + 'conditional', + 'function', + 'import', + ['intersection', 'union'], + 'named', + 'operator', + 'object', + 'keyword', + 'literal', + 'tuple', + 'nullish', + ], + type: 'natural', + }, + ], + 'perfectionist/sort-variable-declarations': [ + 'warn', + { + type: 'natural', + }, + ], + 'react/jsx-sort-props': 'off', + 'sort-imports': 'off', + + 'sort-keys': 'off', + }, + settings: { + perfectionist: { + ignoreCase: false, + }, + }, +}); diff --git a/tooling/eslint/configs/eslint-typescript.js b/tooling/eslint/configs/eslint-typescript.js new file mode 100644 index 0000000..e35b4fd --- /dev/null +++ b/tooling/eslint/configs/eslint-typescript.js @@ -0,0 +1,105 @@ +/* eslint-disable unicorn/no-useless-spread */ +import tseslint from 'typescript-eslint'; + +import { defineConfig } from '../utils.js'; + +export default defineConfig( + { + files: ['**/*.ts', '**/*.tsx'], + }, + + // Base JS/TS configs + ...tseslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + + { + ignores: ['tooling/eslint/index.d.ts'], + rules: { + // When not using in default config + ...{ + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + '@typescript-eslint/prefer-for-of': 'off', + '@typescript-eslint/prefer-optional-chain': 'off', + }, + '@typescript-eslint/await-thenable': 'off', + + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-base-to-string': 'off', + '@typescript-eslint/no-floating-promises': 'off', + // Override recommended-type-checked + ...{ + // '@typescript-eslint/ban-ts-comment': [ + // 'error', + // { + // minimumDescriptionLength: 10, + // 'ts-check': false, + // 'ts-expect-error': 'allow-with-description', + // 'ts-ignore': true, + // 'ts-nocheck': true, + // }, + // ], + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/no-empty-object-type': [ + 'error', + { + allowInterfaces: 'always', + allowObjectTypes: 'always', + }, + ], + '@typescript-eslint/no-explicit-any': 'off', + // PERF: disable + '@typescript-eslint/no-misused-promises': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-function-type': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/only-throw-error': 'off', + '@typescript-eslint/require-await': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/unbound-method': 'off', + }, + // Override stylistic-type-checked + ...{ + '@typescript-eslint/ban-tslint-comment': ['error'], + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-definitions': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/non-nullable-type-assertion-style': 'off', + '@typescript-eslint/prefer-nullish-coalescing': 'off', + }, + // Override strict-type-checked + ...{ + '@typescript-eslint/no-non-null-assertion': 'off', + }, + // for now we can use both type and interface + '@typescript-eslint/consistent-type-exports': 'warn', + '@typescript-eslint/consistent-type-imports': [ + 'warn', + { fixStyle: 'inline-type-imports' }, + ], + '@typescript-eslint/method-signature-style': ['error', 'property'], + '@typescript-eslint/no-import-type-side-effects': 'error', + '@typescript-eslint/no-var-requires': 'off', + }, + }, + + { + files: ['*.mjs'], + rules: { + '@typescript-eslint/consistent-type-exports': 'off', + '@typescript-eslint/consistent-type-imports': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/naming-convention': 'off', + }, + } +); diff --git a/tooling/eslint/configs/eslint-unicorn.js b/tooling/eslint/configs/eslint-unicorn.js new file mode 100644 index 0000000..0734329 --- /dev/null +++ b/tooling/eslint/configs/eslint-unicorn.js @@ -0,0 +1,43 @@ +import eslintPluginUnicorn from 'eslint-plugin-unicorn'; + +import { defineConfig } from '../utils.js'; + +export default defineConfig(eslintPluginUnicorn.configs['flat/recommended'], { + // plugins: { + // unicorn: eslintPluginUnicorn, + // }, + rules: { + 'unicorn/consistent-destructuring': 'off', + 'unicorn/consistent-function-scoping': [ + 'error', + { + checkArrowFunctions: false, + }, + ], + 'unicorn/expiring-todo-comments': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/import-style': 'off', + 'unicorn/no-abusive-eslint-disable': 'off', + 'unicorn/no-array-callback-reference': 'off', + 'unicorn/no-array-for-each': 'off', + 'unicorn/no-array-push-push': 'off', + 'unicorn/no-array-reduce': 'off', + 'unicorn/no-await-expression-member': 'off', + 'unicorn/no-document-cookie': 'off', + 'unicorn/no-unreadable-array-destructuring': 'off', + 'unicorn/no-useless-undefined': 'off', + // TypeScript doesn't like the for-of loop this rule fixes to + 'unicorn/no-for-loop': 'off', + 'unicorn/no-nested-ternary': 'off', + 'unicorn/no-null': 'off', + 'unicorn/prefer-export-from': 'off', + 'unicorn/prefer-global-this': 'off', + 'unicorn/prefer-logical-operator-over-ternary': 'off', + 'unicorn/prefer-module': 'off', + // Spread syntax causes non-deterministic type errors + 'unicorn/prefer-spread': 'off', + 'unicorn/prefer-ternary': 'off', + 'unicorn/prefer-top-level-await': 'off', + 'unicorn/prevent-abbreviations': 'off', + }, +}); diff --git a/tooling/eslint/eslint.d.ts b/tooling/eslint/eslint.d.ts new file mode 100644 index 0000000..2eea808 --- /dev/null +++ b/tooling/eslint/eslint.d.ts @@ -0,0 +1,85 @@ +/** + * Since ESLint and many plugins are written in JavaScript, we need to provide + * or change some types to make them work with TypeScript. + */ + +// From: https://github.com/t3-oss/create-t3-turbo/blob/main/tooling/eslint/types.d.ts +declare module '@eslint/js' { + import type { Linter } from 'eslint'; + + export const configs: { + readonly all: { readonly rules: Readonly }; + readonly recommended: { readonly rules: Readonly }; + }; +} + +declare module '@eslint-community/eslint-plugin-eslint-comments/configs' { + import type { Linter } from 'eslint'; + + export const recommended: { + rules: Linter.RulesRecord; + }; +} + +declare module '@eslint/eslintrc' { + import type { Linter } from 'eslint'; + + export class FlatCompat { + constructor({ + baseDirectory, + resolvePluginsRelativeTo, + }: { + baseDirectory: string; + resolvePluginsRelativeTo: string; + }); + + config(config: Linter.Config): { + [Symbol.iterator]: () => IterableIterator; + } & Linter.FlatConfig; + + extends(extendsValue: string): { + [Symbol.iterator]: () => IterableIterator; + } & Linter.FlatConfig; + } +} + +declare module '@eslint/compat' { + import type { Linter } from 'eslint'; + import type { ConfigWithExtends } from 'typescript-eslint'; + + export const fixupConfigRules: ( + config: Linter.FlatConfig | string + ) => ConfigWithExtends[]; +} + +declare module 'eslint-plugin-regexp' { + import type { Linter } from 'eslint'; + import type { ConfigWithExtends } from 'typescript-eslint'; + + export const configs: { + 'flat/all': { + rules: Linter.RulesRecord; + [Symbol.iterator]: () => IterableIterator; + }; + 'flat/recommended': { + rules: Linter.RulesRecord; + [Symbol.iterator]: () => IterableIterator; + }; + }; +} + +declare module 'eslint-plugin-unicorn' { + import type { Linter } from 'eslint'; + import type { ConfigWithExtends } from 'typescript-eslint'; + + export const configs: { + 'flat/all': { + rules: Linter.RulesRecord; + [Symbol.iterator]: () => IterableIterator; + }; + 'flat/recommended': { + rules: Linter.RulesRecord; + [Symbol.iterator]: () => IterableIterator; + }; + }; +} diff --git a/tooling/eslint/index.d.ts b/tooling/eslint/index.d.ts new file mode 100644 index 0000000..7d10096 --- /dev/null +++ b/tooling/eslint/index.d.ts @@ -0,0 +1,20 @@ +/// + +import type { FlatCompat } from '@eslint/eslintrc'; +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +export declare const defineConfig: typeof import('typescript-eslint').config; + +export declare const compat: FlatCompat; + +export declare const configs: { + base: FlatConfig.ConfigArray; + next: FlatConfig.ConfigArray; + prettier: FlatConfig.ConfigArray; + react: FlatConfig.ConfigArray; + typescript: FlatConfig.ConfigArray; + getTailwind: (options: { + config: string; + cssFiles: string; + }) => FlatConfig.ConfigArray; +}; diff --git a/tooling/eslint/index.js b/tooling/eslint/index.js new file mode 100644 index 0000000..0cfd2da --- /dev/null +++ b/tooling/eslint/index.js @@ -0,0 +1,13 @@ +import base from './configs/eslint-base.js'; +import typescript from './configs/eslint-typescript.js'; + +export { defineConfig } from './utils.js'; + +/** + * Note: You MUST import files using the .js extension in this entire package + * (not only this file) otherwise ESLint will not be able to resolve the files. + */ +export const configs = { + base, + typescript, +}; diff --git a/tooling/eslint/utils.js b/tooling/eslint/utils.js new file mode 100644 index 0000000..818af8b --- /dev/null +++ b/tooling/eslint/utils.js @@ -0,0 +1,25 @@ +import { fixupPluginRules } from '@eslint/compat'; +import { FlatCompat } from '@eslint/eslintrc'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import tseslint from 'typescript-eslint'; + +export const defineConfig = tseslint.config; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export const compat = new FlatCompat({ + baseDirectory: __dirname, + resolvePluginsRelativeTo: __dirname, +}); + +export function legacyPlugin(name, alias = name) { + const plugin = compat.plugins(name)[0]?.plugins?.[alias]; + + if (!plugin) { + throw new Error(`Unable to resolve plugin ${name} and/or alias ${alias}`); + } + + return fixupPluginRules(plugin); +} diff --git a/tooling/scripts/brl.sh b/tooling/scripts/brl.sh new file mode 100644 index 0000000..e68d15c --- /dev/null +++ b/tooling/scripts/brl.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Change to the initial working directory +cd "$INIT_CWD" || { echo "Failed to change directory to $INIT_CWD"; exit 1; } + +# Function to check if index.tsx exists and run barrelsby if it doesn't +run_barrelsby() { + local dir="$1" + shift # Remove the first argument (dir) from the list + if [ ! -f "$dir/index.tsx" ]; then + barrelsby -d "$dir" "$@" + fi +} + +# Run barrelsby on the src directory if index.tsx doesn't exist +run_barrelsby "$INIT_CWD/src" -D -l all -q -e '.*__tests__.*|(.*(fixture|template|spec|internal).*)|(^.*\/react\/.*$)' + +# Check if the src/react directory exists and run barrelsby if it does and if index.tsx doesn't exist +if [ -d "$INIT_CWD/src/react" ]; then + run_barrelsby "$INIT_CWD/src/react" -D -l all -q -e '.*__tests__.*|(.*(fixture|template|spec|internal).*)' +fi diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e46c669 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,44 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": false, + "strict": true, + "jsx": "react-jsx", + + "target": "ESNext", + "lib": ["ES2021", "dom", "DOM.Iterable"], + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "module": "ESNext", + "moduleResolution": "Bundler", + + "isolatedModules": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "skipLibCheck": true + }, + "tsc-alias": { + "resolveFullPaths": true + }, + + "include": [ + "next-env.d.ts", + ".next/types/**/*.ts", + "**/*.ts", + "**/*.tsx", + "**/*.cts", + "**/*.ctsx", + "**/*.mts", + "**/*.mtsx", + "**/*.js", + "**/*.jsx", + "**/*.cjs", + "**/*.cjsx", + "**/*.mjs", + "**/*.mjsx", + ".contentlayer/generated" + ], + "exclude": ["node_modules", "dist"] +} diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..441dbb0 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/index.ts'], + external: [], + format: ['esm'], + minify: false, + outDir: 'dist', + sourcemap: true, + target: 'esnext', + treeshake: true, +});