From 39d7373472df58f0658cbecaef52209d30ae8a91 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Fri, 13 Mar 2026 10:37:40 -0700 Subject: [PATCH 01/10] feat: custom storage --- AGENTS.md | 86 ++++++ agent-docs/architecture/data-flow.md | 153 +++++++++++ agent-docs/architecture/overview.md | 95 +++++++ agent-docs/architecture/project-structure.md | 268 +++++++++++++++++++ agent-docs/auth/authentication.md | 178 ++++++++++++ agent-docs/data-layer/caching.md | 137 ++++++++++ agent-docs/data-layer/database.md | 124 +++++++++ agent-docs/data-layer/github-sync.md | 141 ++++++++++ agent-docs/features/billing.md | 127 +++++++++ agent-docs/features/ghost-ai.md | 119 ++++++++ agent-docs/features/github-integration.md | 182 +++++++++++++ agent-docs/features/pr-reviews.md | 110 ++++++++ agent-docs/frontend/components.md | 186 +++++++++++++ agent-docs/frontend/routing.md | 111 ++++++++ agent-docs/frontend/ui-patterns.md | 165 ++++++++++++ agent-docs/infrastructure/deployment.md | 111 ++++++++ agent-docs/infrastructure/development.md | 165 ++++++++++++ agent-docs/infrastructure/environment.md | 115 ++++++++ apps/web/package.json | 1 + apps/web/src/lib/storage/index.ts | 6 + apps/web/test.ts | 0 bun.lock | 17 +- 22 files changed, 2596 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md create mode 100644 agent-docs/architecture/data-flow.md create mode 100644 agent-docs/architecture/overview.md create mode 100644 agent-docs/architecture/project-structure.md create mode 100644 agent-docs/auth/authentication.md create mode 100644 agent-docs/data-layer/caching.md create mode 100644 agent-docs/data-layer/database.md create mode 100644 agent-docs/data-layer/github-sync.md create mode 100644 agent-docs/features/billing.md create mode 100644 agent-docs/features/ghost-ai.md create mode 100644 agent-docs/features/github-integration.md create mode 100644 agent-docs/features/pr-reviews.md create mode 100644 agent-docs/frontend/components.md create mode 100644 agent-docs/frontend/routing.md create mode 100644 agent-docs/frontend/ui-patterns.md create mode 100644 agent-docs/infrastructure/deployment.md create mode 100644 agent-docs/infrastructure/development.md create mode 100644 agent-docs/infrastructure/environment.md create mode 100644 apps/web/src/lib/storage/index.ts create mode 100644 apps/web/test.ts diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..b3f6ed24 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,86 @@ +# Better Hub -- Agent Documentation + +Better Hub is a reimagined GitHub UI for code collaboration, built by the Better Auth team. It is a Next.js 16 / React 19 monorepo that proxies the GitHub API, adds AI features (Ghost assistant), and provides a faster, keyboard-driven experience for repos, PRs, issues, and CI/CD. + +## How to Use These Docs + +The `agent-docs/` directory contains detailed documentation organized by topic. Start with the section most relevant to your task. If you need a broad understanding, read **architecture/overview.md** first. + +## Keeping Docs Up to Date + +When you make changes to the codebase that affect architecture, patterns, configuration, or conventions documented in `agent-docs/`, update the relevant doc files as part of the same change. Examples of when to update: + +- Adding or removing a page, API route, or component directory -- update `architecture/project-structure.md` and `frontend/components.md` +- Changing the database schema -- update `data-layer/database.md` +- Adding or modifying environment variables -- update `infrastructure/environment.md` +- Changing the auth flow, caching strategy, or data-fetching patterns -- update the relevant feature or data-layer doc +- Introducing a new major dependency or tool -- update `architecture/overview.md` +- Adding a new feature area -- consider creating a new doc file under the appropriate directory + +If a change is significant enough that it would surprise a future agent reading the current docs, the docs need updating. Keep descriptions concise and factual -- document what exists and how it works, not aspirational plans. + +## Documentation Index + +### Architecture + +- [agent-docs/architecture/overview.md](agent-docs/architecture/overview.md) -- Tech stack, monorepo layout, key dependencies, how systems connect +- [agent-docs/architecture/project-structure.md](agent-docs/architecture/project-structure.md) -- Full directory tree with annotations for every folder and key file +- [agent-docs/architecture/data-flow.md](agent-docs/architecture/data-flow.md) -- Request lifecycle, the `localFirstGitRead` caching pattern, AI data flow, mutation flow + +### Features + +- [agent-docs/features/ghost-ai.md](agent-docs/features/ghost-ai.md) -- Ghost AI assistant: model routing, ~30 tools, conversation persistence, semantic search, E2B sandboxes +- [agent-docs/features/github-integration.md](agent-docs/features/github-integration.md) -- Octokit REST client, ~30 sync job types, shared vs per-user cache security, rate limiting, OAuth scopes +- [agent-docs/features/pr-reviews.md](agent-docs/features/pr-reviews.md) -- PR review system: diff viewing, inline comments, AI summaries, merge panel, conflict resolution, CI checks +- [agent-docs/features/billing.md](agent-docs/features/billing.md) -- Stripe metered billing, credit system, spending limits, AI model pricing, usage tracking + +### Data Layer + +- [agent-docs/data-layer/database.md](agent-docs/data-layer/database.md) -- Prisma schema (20 models), connection pool config, migration commands +- [agent-docs/data-layer/caching.md](agent-docs/data-layer/caching.md) -- Multi-tier Redis caching: per-user, shared, repo data (TTL tiers), Vercel cache, DB fallback +- [agent-docs/data-layer/github-sync.md](agent-docs/data-layer/github-sync.md) -- Background sync job system: job lifecycle, deduplication, draining, ETag support + +### Authentication + +- [agent-docs/auth/authentication.md](agent-docs/auth/authentication.md) -- better-auth config, GitHub OAuth, `getServerSession()`, session/cookie handling, PAT sign-in, scopes + +### Frontend + +- [agent-docs/frontend/routing.md](agent-docs/frontend/routing.md) -- GitHub-compatible URL rewriting, middleware, git protocol redirects, route groups +- [agent-docs/frontend/components.md](agent-docs/frontend/components.md) -- Component organization by domain (~150 components), server vs client patterns +- [agent-docs/frontend/ui-patterns.md](agent-docs/frontend/ui-patterns.md) -- TailwindCSS 4, Radix UI, CVA, Shiki, TipTap, theming, keyboard shortcuts, hooks + +### Infrastructure + +- [agent-docs/infrastructure/development.md](agent-docs/infrastructure/development.md) -- Local setup, Docker Compose, dev scripts, linting, TypeScript config, testing +- [agent-docs/infrastructure/deployment.md](agent-docs/infrastructure/deployment.md) -- Vercel hosting, GitHub Actions CI, Sentry, security headers, build process +- [agent-docs/infrastructure/environment.md](agent-docs/infrastructure/environment.md) -- All environment variables categorized with descriptions + +## Quick Reference + +### Critical Files + +| File | Purpose | +| ---------------------------------------- | ---------------------------------------------- | +| `apps/web/src/lib/github.ts` | All GitHub API data fetching (~7300 lines) | +| `apps/web/src/lib/auth.ts` | Authentication config and `getServerSession()` | +| `apps/web/src/lib/db.ts` | Database client and connection pool | +| `apps/web/src/proxy.ts` | Middleware (auth + URL rewriting) | +| `apps/web/src/app/api/ai/ghost/route.ts` | Ghost AI endpoint (~3500 lines) | +| `apps/web/prisma/schema.prisma` | Database schema | +| `apps/web/next.config.ts` | Next.js configuration | +| `apps/web/.env.example` | Environment variable template | + +### Common Tasks + +**Adding a new page**: Create `page.tsx` in `apps/web/src/app/(app)/your-route/`. It will automatically get the app layout (navbar, Ghost, auth). + +**Adding a new API route**: Create `route.ts` in `apps/web/src/app/api/your-endpoint/`. Use `getServerSession()` for auth and `getOctokitFromSession()` for GitHub API access. + +**Adding a new component**: Place in the appropriate feature directory under `apps/web/src/components/`. Use `"use client"` only if the component needs interactivity. + +**Fetching GitHub data**: Add a function in `apps/web/src/lib/github.ts` using the `localFirstGitRead` pattern. Define the cache key, job type, and remote fetcher. + +**Adding a database model**: Update `apps/web/prisma/schema.prisma`, run `bunx prisma migrate dev --name your_migration`, then `bunx prisma generate`. + +**Running checks before PR**: Run `bun check` from the repo root (lint + format + typecheck). diff --git a/agent-docs/architecture/data-flow.md b/agent-docs/architecture/data-flow.md new file mode 100644 index 00000000..fffd4ba7 --- /dev/null +++ b/agent-docs/architecture/data-flow.md @@ -0,0 +1,153 @@ +# Data Flow + +This document describes how data moves through Better Hub from an incoming HTTP request to a rendered page. + +## Request Lifecycle + +### 1. Middleware (`src/proxy.ts`) + +Every request first passes through Next.js middleware which handles three concerns: + +**Git protocol redirect** -- If the URL matches a git service path (`info/refs?service=git-upload-pack`, `git-receive-pack`), the request is redirected to `github.com` with a 307. This lets `git clone` and `git push` work transparently. + +**Authentication** -- Public paths (`/`, `/api/auth`, `/api/inngest`) are allowed through. All other paths require a `better-auth` session cookie. Missing sessions redirect to `/`. + +**URL rewriting** -- GitHub-compatible URLs are rewritten to internal App Router paths: +- `/:owner/:repo` -> `/repos/:owner/:repo` +- `/:owner/:repo/pull/:number` -> `/repos/:owner/:repo/pulls/:number` +- `/:owner/:repo/commit/:sha` -> `/repos/:owner/:repo/commits/:sha` +- `/:owner/:repo/compare/base...head` -> `/repos/:owner/:repo/pulls/new?base=&head=` + +The `APP_ROUTES` set prevents rewriting known first-segment routes (`dashboard`, `repos`, `api`, `_next`, etc.). + +### 2. App Layout (`src/app/(app)/layout.tsx`) + +The `(app)` route group layout runs for every authenticated page: + +1. Calls `getServerSession()` which is wrapped in React `cache()` for request deduplication +2. If no session exists, redirects to `/` with a `?redirect=` parameter +3. Fetches notifications via `getNotifications()` +4. Checks onboarding status and star state for first-run overlay +5. Wraps children in providers: `NuqsAdapter`, `GlobalChatProvider`, `MutationEventProvider`, `ColorThemeProvider`, `GitHubLinkInterceptor`, `TooltipProvider` +6. Renders: navbar, navigation progress bar, nav-aware content area, Ghost chat panel, onboarding overlay + +### 3. Repo Layout (`src/app/(app)/repos/[owner]/[repo]/layout.tsx`) + +For repository pages, a nested layout provides: + +1. Fetches repo page data via `getRepoPageData()` (repo metadata, nav counts, star status, org membership, latest commit) +2. Loads cached data in parallel: file tree, contributor avatars, languages, branches, tags +3. Prefetches PR data in the background via `waitUntil(prefetchPRData())` +4. Renders: sidebar (description, stats, contributors, languages), repo nav tabs, code content wrapper with file tree and branch selector + +### 4. Page Components + +Individual pages fetch their specific data using functions from `src/lib/github.ts`. These all use the `localFirstGitRead` pattern described below. + +## GitHub Data Fetching: `localFirstGitRead` Pattern + +The core data-fetching pattern prioritizes local cache for speed while keeping data fresh via background sync: + +``` +1. Check Redis cache (gh:{userId}:{cacheKey}) + ├── HIT with fresh data → return immediately + └── MISS or stale + │ +2. Check shared cache (for public data types) + ├── HIT → return + enqueue background sync job + └── MISS + │ +3. Fetch from GitHub API (Octokit) + ├── SUCCESS → update cache, return data + └── FAILURE (rate limit, network) + │ +4. Fall back to DB cache (github_cache_entries table) + ├── HIT → return stale data + └── MISS → return fallback value +``` + +**Security model**: Only certain data types are shareable across users (branches, tags, releases, issues, PRs, contributors, etc. -- defined in `SHAREABLE_CACHE_TYPES`). Private repo data and user-specific data is always scoped to the requesting user's cache key. + +### Background Sync Jobs + +When data is served from cache and may be stale, a sync job is enqueued: + +1. Jobs are deduplicated by `(userId, dedupeKey)` -- only one pending job per user per data type +2. The `drainGithubSyncJobs()` function claims and processes jobs for a user +3. Jobs are processed with the user's GitHub token, updating both Redis and DB caches +4. Failed jobs are retried up to 8 times with backoff +5. Running jobs have a 10-minute timeout to prevent stuck jobs + +## AI Data Flow + +### Ghost Chat (`/api/ai/ghost`) + +``` +Client message + │ + ├── Check usage limits (credits, spending cap) + ├── Resolve model (user preference or "auto" → default model) + ├── Load/create conversation from DB + │ + ▼ +streamText() with tools + │ + ├── GitHub tools (via user's Octokit) + │ ├── get_repo_info, list_issues, list_prs + │ ├── get_issue, get_pull_request, get_file_content + │ ├── create_issue, create_pr, add_comment + │ ├── merge_pr, create_branch, update_file + │ └── ... (~30 tools) + │ + ├── Search tools + │ ├── search_repos, search_code, search_issues + │ └── semantic_search (Mixedbread embeddings + reranking) + │ + ├── Code execution (E2B sandbox) + │ + └── Navigation tools (generate Better Hub URLs) + │ + ▼ +Stream response to client + │ + ├── Save messages to DB (chat_messages) + ├── Log token usage (ai_call_logs + usage_logs) + └── Report to Stripe (metered billing) +``` + +### Embedding Pipeline (Background) + +``` +User views PR/Issue + │ + ▼ +Inngest event: app/content.viewed + │ + ▼ +embedContent function + ├── Embed title + body (Mixedbread mxbai-embed-large-v1) + ├── Embed comments in batches of 20 + ├── Embed reviews + └── Store in search_embeddings table (with content hash for dedup) +``` + +## Caching Tiers + +| Tier | TTL | Use Case | Key Pattern | +|---|---|---|---| +| Per-user Redis | Varies | User-specific GitHub data | `gh:{userId}:{cacheKey}` | +| Shared Redis | Varies | Public repo data (branches, tags, etc.) | `shared:{cacheKey}` | +| Repo data cache | 24h / 1h / 5min | Languages, branches, file tree, events | `repo_*:{owner}/{repo}` | +| Vercel cache | `unstable_cache` | Server component data revalidation | Function-based | +| DB cache | Permanent | Fallback when GitHub API is unavailable | `github_cache_entries` table | +| README cache | Medium TTL | Rendered README content | `readme:{owner}/{repo}` | + +## Mutation Flow + +When users perform write actions (create issue, merge PR, add comment), the flow is: + +1. Client calls a mutation function (often via `use-mutation.ts` hook) +2. The function calls the GitHub API directly via Octokit +3. On success, relevant caches are invalidated (`invalidateIssueCache`, `invalidatePullRequestCache`, etc.) +4. A mutation event is dispatched via `MutationEventProvider` to update other components on the page +5. `use-mutation-subscription.ts` hooks in other components react to the event and refetch data diff --git a/agent-docs/architecture/overview.md b/agent-docs/architecture/overview.md new file mode 100644 index 00000000..e8c31c39 --- /dev/null +++ b/agent-docs/architecture/overview.md @@ -0,0 +1,95 @@ +# Architecture Overview + +Better Hub is a reimagined GitHub UI for code collaboration, built by the Better Auth team. It provides a faster, more pleasant experience for browsing repos, reviewing PRs, triaging issues, and interacting with an AI assistant (Ghost). + +Production URL: `https://www.better-hub.com` + +## Tech Stack + +| Layer | Technology | Version | +|---|---|---| +| Framework | Next.js (App Router) | 16 | +| UI | React | 19 | +| Styling | TailwindCSS | 4 | +| Component primitives | Radix UI | - | +| ORM | Prisma | 7 | +| Database | PostgreSQL | 16 | +| Cache | Redis via Upstash REST | 7 | +| Package manager | Bun | 1.3.5 | +| Linter | oxlint | - | +| Formatter | oxfmt | - | +| Language | TypeScript (strict) | 5.7+ | +| Error tracking | Sentry | 10 | +| Hosting | Vercel | - | + +## Monorepo Layout + +The repo uses Bun workspaces with three packages: + +- **`apps/web`** -- The main Next.js application. Contains all pages, API routes, components, and server-side logic. +- **`packages/chrome-extension`** -- Chrome Manifest V3 extension that adds "Open in Better Hub" buttons on GitHub pages and optionally redirects GitHub URLs. +- **`packages/firefox-extension`** -- Firefox equivalent of the Chrome extension. + +## Key Dependencies + +### GitHub Integration +- `@octokit/rest` -- REST client for all GitHub API calls +- `better-auth` -- Authentication library (built by the same team) with GitHub OAuth + +### AI / ML +- `@openrouter/ai-sdk-provider` + `ai` (Vercel AI SDK) -- Model routing and streaming for Ghost AI +- `@ai-sdk/anthropic` -- Anthropic provider for specific AI tasks +- `@mixedbread-ai/sdk` -- Embedding generation and reranking for semantic search +- `supermemory` -- Long-term AI conversation memory +- `e2b` -- Sandboxed code execution environments + +### Billing +- `stripe` -- Metered billing and subscriptions +- `@better-auth/stripe` -- Stripe plugin for better-auth + +### Background Jobs +- `inngest` -- Durable background functions (embedding content, retrying Stripe usage reports) + +### UI +- `radix-ui` -- Accessible UI primitives (dialog, dropdown, tooltip, popover, etc.) +- `cmdk` -- Command palette (`Cmd+K`) +- `shiki` -- Syntax highlighting for code blocks and diffs +- `@tiptap/*` -- Rich text editor for comments and markdown +- `motion` -- Animations +- `lucide-react` -- Icons +- `react-markdown` + remark/rehype plugins -- Markdown rendering +- `nuqs` -- URL query state management +- `next-themes` -- Theme switching + +### Data +- `@prisma/client` + `@prisma/adapter-pg` -- ORM with native PostgreSQL adapter +- `@upstash/redis` -- Redis REST client for caching +- `pg` -- PostgreSQL connection pool +- `zod` -- Schema validation + +## How They Connect + +``` +Browser ──► Next.js Middleware (proxy.ts) + │ + ├── URL rewriting (GitHub-compatible routes) + ├── Authentication check (better-auth session cookie) + │ + ▼ + App Router (React Server Components) + │ + ├── getServerSession() ──► better-auth ──► PostgreSQL + ├── GitHub data fetching ──► localFirstGitRead pattern + │ │ + │ ├── Redis cache (Upstash) + │ ├── DB cache (github_cache_entries) + │ └── GitHub API (Octokit) + background sync jobs + │ + ├── AI endpoints ──► OpenRouter / Anthropic + │ │ + │ ├── Tool calls (GitHub API via Octokit) + │ ├── E2B sandbox (code execution) + │ └── Semantic search (Mixedbread embeddings) + │ + └── Billing ──► Stripe (metered usage) +``` diff --git a/agent-docs/architecture/project-structure.md b/agent-docs/architecture/project-structure.md new file mode 100644 index 00000000..738c7841 --- /dev/null +++ b/agent-docs/architecture/project-structure.md @@ -0,0 +1,268 @@ +# Project Structure + +## Root + +``` +better-hub/ +├── AGENTS.md # Agent documentation entry point +├── CONTRIBUTING.md # Contributor guide +├── README.md # Project readme +├── SECURITY.md # Security policy +├── LICENSE # MIT license +├── package.json # Root workspace config (scripts, devDependencies) +├── tsconfig.json # Base TypeScript config (strict mode) +├── oxlint.json # Linter config (plugins: typescript, import, promise, unicorn) +├── bunfig.toml # Bun configuration +├── docker-compose.yml # Local dev services (Postgres, Redis, Redis REST proxy) +├── bun.lock / pnpm-lock.yaml # Lock files +├── apps/ # Application packages +├── packages/ # Shared/extension packages +└── agent-docs/ # Agent documentation (this directory) +``` + +## `apps/web/` -- Main Next.js Application + +``` +apps/web/ +├── package.json # App dependencies and scripts +├── next.config.ts # Next.js config (rewrites, images, headers, Sentry) +├── prisma/ +│ ├── schema.prisma # Database schema (20 models) +│ └── migrations/ # Prisma migrations +├── public/ +│ ├── extension/ # Extension download assets +│ └── fonts/ # Custom fonts +├── scripts/ +│ └── generate-openrouter-models.mts # Fetches model pricing from OpenRouter API +└── src/ + ├── proxy.ts # Next.js middleware (auth, URL rewrites, git redirects) + ├── app/ # App Router pages and API routes + ├── components/ # React components organized by feature + ├── generated/ # Auto-generated code (Prisma client) + ├── hooks/ # Custom React hooks + └── lib/ # Core business logic, utilities, stores +``` + +## `src/app/` -- App Router + +### Page Routes (`src/app/(app)/`) + +The `(app)` route group wraps all authenticated pages with a shared layout that provides the navbar, session, notifications, Ghost AI chat panel, and theming. + +``` +(app)/ +├── layout.tsx # Auth gate, navbar, Ghost chat, theme provider +├── dashboard/page.tsx # User dashboard (activity feed, repos) +├── repos/page.tsx # Repository listing +├── repos/[owner]/[repo]/ # Repository detail (has its own layout) +│ ├── layout.tsx # Repo sidebar, nav tabs, file tree, branch selector +│ ├── page.tsx # Repo overview (README, file list) +│ ├── blob/[...path]/ # File viewer +│ ├── tree/[...path]/ # Directory viewer +│ ├── pulls/ # Pull requests list and detail +│ │ ├── page.tsx # PR list +│ │ ├── new/ # Create PR +│ │ └── [number]/ # PR detail (conversation, diff, files, checks) +│ ├── issues/ # Issues list and detail +│ │ ├── page.tsx +│ │ └── [number]/ +│ ├── actions/ # CI/CD workflow runs +│ │ ├── page.tsx +│ │ ├── compare/ # Compare workflow runs +│ │ ├── [runId]/ # Run detail +│ │ └── workflows/[...path]/ +│ ├── commits/ # Commit history and detail +│ ├── discussions/ # Repository discussions +│ ├── releases/ # Releases and tags +│ ├── tags/ # Tag listing +│ ├── security/ # Security advisories +│ ├── people/ # Contributors and org members +│ ├── insights/ # Repository insights +│ ├── settings/ # Repo settings +│ ├── activity/ # Activity feed +│ ├── code/ # Code search within repo +│ └── prompts/ # Prompt requests +├── issues/page.tsx # Cross-repo issues view +├── pulls/page.tsx # Cross-repo PRs view +├── stars/ # Starred repos +├── trending/page.tsx # Trending repositories +├── search/page.tsx # Global search +├── notifications/page.tsx # Notification center +├── orgs/ # Organizations listing and detail +├── users/[username]/ # User profile +├── extension/page.tsx # Browser extension download page +└── [owner]/page.tsx # Owner profile (redirected via rewrites) +``` + +### API Routes (`src/app/api/`) + +``` +api/ +├── auth/[...all]/ # better-auth catch-all handler +├── ai/ +│ ├── ghost/ # Ghost AI chat (main endpoint + stream resume) +│ ├── ghost-tabs/ # Ghost tab management +│ ├── chat-history/ # Chat history retrieval +│ ├── commit-message/ # AI commit message generation +│ ├── pr-overview/ # AI PR analysis/summary +│ ├── command/ # AI command execution +│ └── rewrite-prompt/ # AI prompt rewriting +├── billing/ +│ ├── balance/ # Credit balance check +│ ├── spending-limit/ # Spending limit management +│ └── welcome/ # Welcome credit grant +├── search-*/ # Search endpoints (repos, issues, PRs, code, users) +├── repo-files/ # Repository file listing +├── file-content/ # File content retrieval +├── highlight-code/ # Server-side syntax highlighting +├── highlight-diff/ # Diff syntax highlighting +├── workflow-runs/ # CI/CD workflow data +├── check-status/ # PR check status +├── compare-runs/ # Compare workflow runs +├── merge-conflicts/ # PR merge conflict detection +├── job-logs/ # CI job log streaming +├── user-*/ # User data endpoints (profile, repos, scopes, settings) +├── org-repos/ # Organization repos +├── rate-limit/ # GitHub rate limit status +├── upload/ # File upload (images) +├── github-image/ # GitHub image proxy +├── extension-download/ # Extension download handler +├── og/ # OpenGraph image generation +└── inngest/ # Inngest webhook handler +``` + +## `src/components/` -- UI Components + +Components are organized by feature domain: + +``` +components/ +├── layout/ # App shell (navbar, nav-aware-content, notification sheet) +├── repo/ # Repository views (sidebar, nav, code viewer, file tree, etc.) ~38 files +├── pr/ # Pull request UI (diff viewer, conversation, merge, reviews) ~30 files +├── issue/ # Issue detail views +├── issues/ # Issue listing +├── prs/ # PR listing +├── dashboard/ # Dashboard widgets +├── search/ # Search UI +├── settings/ # User settings +│ └── tabs/ # Settings tab panels +├── shared/ # Cross-cutting components ~32 files +│ ├── ai-chat.tsx # AI chat interface +│ ├── global-chat-panel.tsx # Ghost panel (slide-out) +│ ├── markdown-renderer.tsx # Server-side markdown +│ ├── highlighted-code-block.tsx +│ ├── comment.tsx / comment-thread.tsx +│ └── github-link-interceptor.tsx # Rewrites github.com links to Better Hub +├── ui/ # Base UI primitives (button, dialog, badge, etc.) ~14 files +├── actions/ # CI/CD action views +├── discussion/ # Discussion views +├── notifications/ # Notification UI +├── onboarding/ # First-run onboarding overlay +├── orgs/ # Organization views +├── people/ # People/contributors views +├── security/ # Security advisory views +├── trending/ # Trending repos +├── users/ # User profile views +│ └── activity-timeline/ # Activity timeline components +├── providers/ # React context providers +├── extension/ # Extension promo +├── prompt-request/ # Prompt request UI +├── repos/ # Repos listing +├── pwa/ # PWA support +└── theme/ # Theme provider and selector +``` + +## `src/lib/` -- Core Logic + +``` +lib/ +├── auth.ts # better-auth server config, getServerSession() +├── auth-client.ts # better-auth React client +├── ai-auth.ts # Helper to get Octokit from session for AI routes +├── db.ts # Prisma client with PG pool configuration +├── redis.ts # Upstash Redis client +├── github.ts # GitHub API layer (~7300 lines, all data fetching) +├── github-types.ts # TypeScript interfaces for GitHub entities +├── github-utils.ts # Utility functions (language colors, URL helpers) +├── github-scopes.ts # OAuth scope groups and definitions +├── github-sync-store.ts # DB/Redis sync job persistence layer +├── github-user-attachments.ts # User attachment handling +├── inngest.ts # Background job definitions (embed content, retry billing) +├── mixedbread.ts # Embedding and reranking client (Mixedbread AI) +├── embedding-store.ts # Semantic search embedding CRUD +├── chat-store.ts # Ghost AI conversation persistence +├── repo-data-cache.ts # Redis cache helpers for repo data +├── repo-data-cache-vc.ts # Vercel cache layer for repo data +├── readme-cache.ts # README content cache +├── user-settings-store.ts # User preferences persistence +├── prompt-request-store.ts # Prompt request CRUD +├── pinned-repos.ts # Pinned repos management +├── pinned-items-store.ts # Pinned items (issues, PRs) management +├── recent-views.ts # Recently viewed items tracking +├── pr-overview-store.ts # PR AI analysis cache +├── contributor-score.ts # Contributor scoring algorithm +├── user-profile-score.ts # User profile scoring +├── file-tree.ts # File tree builder from git tree +├── shiki.ts / shiki-client.ts # Syntax highlighter (server and client) +├── diff-preferences.ts # Diff view preferences +├── extract-snippet.ts # Code snippet extraction +├── three-way-merge.ts # Three-way merge for conflict resolution +├── commit-utils.ts # Commit-related utilities +├── image-upload.ts # Image upload helpers +├── image-upload-r2.ts # R2 storage upload +├── resumable-stream.ts # Resumable AI stream support +├── live-tick.ts # Live duration ticker +├── mutation-events.ts # Client-side mutation event system +├── tiptap-mention.ts # TipTap mention plugin config +├── theme-script.ts # Theme initialization script +├── utils.ts # General utilities (cn, etc.) +├── storage/ +│ └── index.ts # Git storage client (@pierre/storage) +├── billing/ +│ ├── config.ts # Billing constants (welcome credit, cost units, etc.) +│ ├── ai-models.ts # AI model registry and pricing calculations +│ ├── ai-models.server.ts # Server-side model helpers +│ ├── openrouter-models.generated.ts # Auto-generated model catalog +│ ├── credit.ts # Credit ledger operations +│ ├── spending-limit.ts # Spending limit management +│ ├── stripe.ts # Stripe client and metered usage reporting +│ ├── token-usage.ts # Token usage logging +│ └── usage-limit.ts # Usage limit checks +├── themes/ +│ ├── index.ts # Theme exports +│ ├── themes.tsx # Theme definitions +│ ├── types.ts # Theme type definitions +│ └── border-radius.ts # Border radius presets +├── auth-plugins/ +│ └── pat-signin.ts # PAT (Personal Access Token) sign-in plugin +├── schemas/ # (empty — Zod schemas inline) +└── og/ # OpenGraph image generation helpers +``` + +## `src/hooks/` -- Custom React Hooks + +``` +hooks/ +├── use-readme.ts # README content fetching +├── use-is-mobile.ts # Mobile viewport detection +├── use-server-initial-data.ts # Hydrate server data into client state +├── use-mutation.ts # Optimistic mutation helper +├── use-mutation-subscription.ts # Subscribe to mutation events +├── use-infinite-scroll.ts # Infinite scroll pagination +└── use-click-outside.ts # Click-outside detection +``` + +## `packages/` -- Browser Extensions + +Both extensions share the same architecture: + +``` +packages/chrome-extension/ # Manifest V3 +packages/firefox-extension/ # Manifest V3 (Firefox-compatible) +├── manifest.json # Extension manifest +├── background.js # Service worker (URL redirect rules) +├── popup.html / popup.js # Extension popup UI +├── rules.json # Declarative redirect rules +└── icons/ # Extension icons +``` diff --git a/agent-docs/auth/authentication.md b/agent-docs/auth/authentication.md new file mode 100644 index 00000000..cbe0869b --- /dev/null +++ b/agent-docs/auth/authentication.md @@ -0,0 +1,178 @@ +# Authentication + +Better Hub uses the `better-auth` library (built by the same team) for authentication, with GitHub as the sole OAuth provider. + +## Key Files + +- `apps/web/src/lib/auth.ts` -- Server-side auth configuration and `getServerSession()` +- `apps/web/src/lib/auth-client.ts` -- Client-side auth hooks (`useSession`, `signIn`, `signOut`) +- `apps/web/src/lib/ai-auth.ts` -- Helper to extract Octokit/token for AI routes +- `apps/web/src/lib/auth-plugins/pat-signin.ts` -- Personal Access Token sign-in plugin +- `apps/web/src/lib/github-scopes.ts` -- OAuth scope groups and descriptions +- `apps/web/src/app/api/auth/[...all]/route.ts` -- better-auth catch-all API handler +- `apps/web/src/proxy.ts` -- Middleware with auth checks + +## Server Configuration (`auth.ts`) + +The `betterAuth()` instance is configured with: + +### Database Adapter +```typescript +database: prismaAdapter(prisma, { provider: "postgresql" }) +``` + +### Plugins +- `dash()` -- Dashboard/admin panel with activity tracking +- `sentinel()` -- Rate limiting and abuse protection +- `admin()` -- Admin user management +- `patSignIn()` -- Custom plugin for Personal Access Token authentication +- `stripe()` -- Stripe billing integration (conditional on `STRIPE_SECRET_KEY` being set) +- `oAuthProxy()` -- OAuth proxy for Vercel preview deployments (production URL: `https://www.better-hub.com`) + +### GitHub OAuth +```typescript +socialProviders: { + github: { + clientId: process.env.GITHUB_CLIENT_ID!, + clientSecret: process.env.GITHUB_CLIENT_SECRET!, + scope: ["read:user", "user:email", "public_repo"], + mapProfileToUser(profile) { + return { githubLogin: profile.login }; + }, + }, +}, +``` + +Default scopes are minimal. Users can opt into additional scopes (private repos, notifications, etc.) through the sign-in UI. + +### Session Configuration +```typescript +session: { + cookieCache: { + enabled: true, + maxAge: 60 * 60 * 24 * 7, // 7 days + strategy: "jwe", // JSON Web Encryption + }, +}, +``` + +Sessions are cached in the cookie itself using JWE encryption. This means most auth checks don't require a DB lookup. + +### Account Settings +```typescript +account: { + encryptOAuthTokens: true, // OAuth tokens encrypted at rest + storeAccountCookie: true, // Account data cached in cookie + updateAccountOnSignIn: true, // Sync scopes on each sign-in +}, +``` + +### User Fields +Custom fields added to the User model: +- `githubPat` (string, optional) -- Personal Access Token for enhanced API access +- `onboardingDone` (boolean, optional) -- Whether the user completed onboarding + +### Trusted Origins +```typescript +trustedOrigins: [ + "https://www.better-hub.com", + "https://better-hub-*-better-auth.vercel.app", + "https://beta.better-hub.com", +], +``` + +## `getServerSession()` + +This is the primary function for getting the authenticated user in server components and API routes. It is wrapped in React `cache()` for request deduplication. + +```typescript +export const getServerSession = cache(async () => { + // 1. Get session from better-auth + // 2. Get GitHub access token + // 3. Fetch GitHub user data (cached in Redis for 1 hour) + // 4. Return { user, session, githubUser: { ...githubData, accessToken } } +}); +``` + +Returns `null` if: +- No valid session cookie exists +- The session has expired +- The GitHub access token is invalid + +The `$Session` type is exported for use throughout the app: +```typescript +export type $Session = NonNullable>>; +``` + +## Client-Side Auth (`auth-client.ts`) + +```typescript +export const authClient = createAuthClient({ + plugins: [ + inferAdditionalFields(), + dashClient(), + sentinelClient(), + stripeClient({ subscription: true }), + ], +}); + +export const { signIn, signOut, useSession } = authClient; +``` + +- `useSession()` -- React hook for accessing session state +- `signIn()` -- Initiate GitHub OAuth flow +- `signOut()` -- End the session + +## AI Route Auth (`ai-auth.ts`) + +Helper functions for AI API routes: + +```typescript +// Get an authenticated Octokit client from the session +getOctokitFromSession(): Promise + +// Get just the GitHub token +getGitHubToken(): Promise +``` + +## Middleware Auth (`proxy.ts`) + +The middleware checks authentication before any protected route: + +1. Public paths bypass auth: `/`, `/api/auth`, `/api/inngest` +2. All other paths require a valid session cookie (`getSessionCookie(request.headers)`) +3. Missing sessions redirect to `/` (the landing page with sign-in) + +## OAuth Scopes + +Scopes are defined in `github-scopes.ts` as groups: + +| Group | Scopes | Required? | +|---|---|---| +| `profile` | `user`, `user:email`, `user:follow` | Yes | +| `public_repos` | `public_repo`, `repo:status`, `repo_deployment`, `read:org` | Yes | +| `private_repos` | `repo` | No | +| `notifications` | `notifications` | No | +| `gist` | `gist` | No | +| `admin` | `admin:repo_hook`, `admin:org` | No | +| `workflow` | `workflow` | No | +| `delete_repo` | `delete_repo` | No | + +Each group has a label, description, and reason shown to the user during scope selection. + +## GitHub User Data Caching + +When a session is established, the GitHub user profile is fetched and cached: + +1. Hash the access token with SHA-256 +2. Check Redis for `github_user:{tokenHash}` +3. If miss, call `octokit.users.getAuthenticated()` +4. Cache result in Redis with 1-hour TTL +5. Caching is fire-and-forget via `waitUntil()` to not block the response + +## PAT Sign-In + +The `patSignIn()` plugin allows users to authenticate with a GitHub Personal Access Token instead of OAuth. This is useful for: +- CI/CD integrations +- Automated testing +- Users who prefer token-based auth diff --git a/agent-docs/data-layer/caching.md b/agent-docs/data-layer/caching.md new file mode 100644 index 00000000..13ca17ea --- /dev/null +++ b/agent-docs/data-layer/caching.md @@ -0,0 +1,137 @@ +# Caching + +Better Hub uses a multi-tier caching strategy to minimize GitHub API calls and maximize page load speed. + +## Key Files + +- `apps/web/src/lib/redis.ts` -- Upstash Redis client +- `apps/web/src/lib/repo-data-cache.ts` -- Redis cache helpers for repository data (write path) +- `apps/web/src/lib/repo-data-cache-vc.ts` -- Vercel `unstable_cache` wrappers (read path) +- `apps/web/src/lib/github-sync-store.ts` -- Per-user GitHub cache entries (Redis + DB) +- `apps/web/src/lib/readme-cache.ts` -- README content cache +- `apps/web/src/lib/github.ts` -- Contains the `localFirstGitRead` function that orchestrates all cache layers + +## Redis Client + +```typescript +import { Redis } from "@upstash/redis"; + +export const redis = new Redis({ + url: process.env.UPSTASH_REDIS_REST_URL!, + token: process.env.UPSTASH_REDIS_REST_TOKEN!, +}); +``` + +In local development, Docker Compose provides Redis + a serverless-redis-http proxy on port 8079 that emulates the Upstash REST API. + +## Cache Tiers + +### Tier 1: Per-User GitHub Cache (Redis) + +**Key pattern**: `gh:{userId}:{cacheKey}` + +Used for user-specific GitHub data (repos, notifications, etc.). Each user gets their own cache namespace to prevent private data leakage. + +Operations in `github-sync-store.ts`: +- `getGithubCacheEntry(userId, cacheKey)` -- Read from Redis +- `upsertGithubCacheEntry(userId, cacheKey, type, data, etag)` -- Write to Redis +- `touchGithubCacheEntrySyncedAt(userId, cacheKey)` -- Update timestamp +- `deleteGithubCacheByPrefix(userId, prefix)` -- Invalidate by prefix + +### Tier 2: Shared Cache (Redis) + +**Key pattern**: `shared:{cacheKey}` + +Used for public data types that are safe to share across users (see `SHAREABLE_CACHE_TYPES` in `github.ts`). This dramatically reduces API calls for popular repos. + +Operations: +- `getSharedCacheEntry(cacheKey)` -- Read +- `upsertSharedCacheEntry(cacheKey, type, data, etag)` -- Write +- `touchSharedCacheEntrySyncedAt(cacheKey)` -- Update timestamp +- `deleteSharedCacheByPrefix(prefix)` -- Invalidate + +### Tier 3: Repo Data Cache (Redis with TTL) + +**Key pattern**: `{suffix}:{owner}/{repo}` (e.g., `repo_languages:vercel/next.js`) + +Purpose-built cache for specific repo data with TTL tiers: + +| TTL Tier | Duration | Data Types | +|---|---|---| +| `slow` | 24 hours | Languages, contributor avatars | +| `medium` | 1 hour | Branches, tags, file tree, page data | +| `fast` | 5 minutes | PRs, issues, events, CI status | + +Cache functions in `repo-data-cache.ts`: +- `setCachedRepoLanguages(owner, repo, data)` +- `setCachedContributorAvatars(owner, repo, data)` +- `setCachedBranches(owner, repo, data)` +- `setCachedTags(owner, repo, data)` +- `setCachedRepoTree(owner, repo, data)` +- `setCachedAuthorDossier(owner, repo, login, data)` +- And corresponding `getCached*` functions + +Some cache entries also support per-user scoping: `{suffix}:{userId}:{owner}/{repo}`. + +### Tier 4: Vercel Cache (Server Component Caching) + +Read wrappers in `repo-data-cache-vc.ts` use Next.js `unstable_cache` with revalidation tags: + +```typescript +getCachedRepoTree(owner, repo) // tag: "repo-tree:{owner}/{repo}" +getCachedContributorAvatars(owner, repo) +getCachedRepoLanguages(owner, repo) +getCachedBranches(owner, repo) +getCachedTags(owner, repo) +``` + +These read from the Redis cache but add a Vercel-level cache layer for server components, reducing Redis calls during page renders. + +### Tier 5: DB Cache (PostgreSQL -- Fallback) + +The `github_cache_entries` table serves as the last-resort fallback. If Redis is down or the entry has been evicted, the system falls back to the DB. + +This tier has no TTL -- data persists until explicitly overwritten. It ensures the app can still render (with stale data) even when GitHub's API is completely unavailable. + +## Cache Invalidation + +### Automatic (TTL-based) +Redis entries expire automatically based on their TTL tier. + +### Manual (After Mutations) +When users perform write operations, specific caches are invalidated: + +```typescript +// After creating/updating an issue +invalidateIssueCache(owner, repo, issueNumber); +invalidateRepoIssuesCache(owner, repo); + +// After merging/updating a PR +invalidatePullRequestCache(owner, repo, pullNumber); +invalidateRepoPullRequestsCache(owner, repo); +``` + +These functions delete the relevant cache entries from both per-user and shared caches. + +### Force Refresh +The `forceRefresh` flag on `GitHubAuthContext` bypasses all caches and fetches directly from the GitHub API. This is triggered by explicit user refresh actions. + +## Cache Warming + +The repo layout pre-warms caches for data that will be needed: + +1. `getCachedRepoTree` -- File tree for the sidebar +2. `getCachedContributorAvatars` -- Contributor faces +3. `getCachedRepoLanguages` -- Language breakdown +4. `getCachedBranches` / `getCachedTags` -- Branch/tag selectors +5. `prefetchPRData()` -- Background warmup of PR and issue caches via `waitUntil()` + +## GitHub User Data Cache + +GitHub user profile data is cached in Redis per access token: + +```typescript +redis.set(`github_user:${tokenHash}`, JSON.stringify(userData), { ex: 3600 }); +``` + +This avoids repeated `/user` API calls during a session. The token is hashed before being used as a cache key. diff --git a/agent-docs/data-layer/database.md b/agent-docs/data-layer/database.md new file mode 100644 index 00000000..d4438bf0 --- /dev/null +++ b/agent-docs/data-layer/database.md @@ -0,0 +1,124 @@ +# Database + +Better Hub uses PostgreSQL as its primary database, accessed through Prisma ORM with a native `pg` adapter for connection pooling. + +## Key Files + +- `apps/web/prisma/schema.prisma` -- Database schema (20 models) +- `apps/web/prisma/migrations/` -- Prisma migrations +- `apps/web/src/lib/db.ts` -- Prisma client initialization and connection pool config +- `apps/web/src/generated/prisma/` -- Auto-generated Prisma client + +## Connection Pool + +The pool is configured in `db.ts` with environment-aware settings: + +| Setting | Development | Production | +|---|---|---| +| `max` connections | 20 | 5 | +| `idleTimeoutMillis` | 10,000 | 30,000 | +| `connectionTimeoutMillis` | 0 (unlimited) | 5,000 | + +Development uses a larger pool because Next.js spawns 10-15 child processes, each needing its own connections. Docker Compose sets `max_connections=300` on PostgreSQL. Production sits behind a managed pooler (PgBouncer/Neon). + +The pool is attached to `process` as a singleton (`_proc.__dbPool`) to survive HMR in development. + +## Schema Overview + +### Authentication (managed by better-auth) + +| Model | Purpose | +|---|---| +| `User` | User accounts. Extended with `githubPat`, `onboardingDone`, `aiMessageCount`, `stripeCustomerId`, ban fields | +| `Session` | Active sessions with token, expiry, IP, user agent. Supports impersonation (`impersonatedBy`) | +| `Account` | OAuth accounts (GitHub). Stores encrypted access/refresh tokens, scopes | +| `Verification` | Email/token verification records | + +### GitHub Data Sync + +| Model | Purpose | +|---|---| +| `GithubCacheEntry` | DB-level cache for GitHub API responses. Keyed by `(userId, cacheKey)`. Stores JSON data + etag + syncedAt | +| `GithubSyncJob` | Background sync job queue. Deduplicated by `(userId, dedupeKey)`. Tracks status, attempts, errors | + +### AI / Chat + +| Model | Purpose | +|---|---| +| `ChatConversation` | Ghost AI conversations. Keyed by `(userId, contextKey)`. Tracks active stream ID for resumability | +| `ChatMessage` | Individual messages in a conversation. Stores role, content, and `partsJson` for multi-part AI SDK messages | +| `GhostTab` | Ghost panel tab state (tab ID, label, position) | +| `GhostTabState` | Per-user active tab and counter | + +### Search + +| Model | Purpose | +|---|---| +| `SearchEmbedding` | Semantic search embeddings for viewed PRs/issues. Stores embedding vectors as JSON, content hashes for dedup | + +### User Preferences + +| Model | Purpose | +|---|---| +| `UserSettings` | User preferences: theme, color theme, Ghost model, code theme, font, API keys, onboarding status | +| `CustomCodeTheme` | User-created custom code syntax themes | +| `PinnedItem` | Pinned issues/PRs per repo per user | + +### Billing + +| Model | Purpose | +|---|---| +| `Subscription` | Stripe subscription state (plan, status, period, cancellation) | +| `UsageLog` | Per-AI-call billing records. Links to `AiCallLog`. Tracks Stripe reporting status | +| `AiCallLog` | Detailed AI call logs: provider, model, token counts, cost breakdown | +| `CreditLedger` | Credit transactions (grants and expirations) | +| `SpendingLimit` | Per-user monthly spending cap | + +### Prompt Requests + +| Model | Purpose | +|---|---| +| `PromptRequest` | Community prompt requests tied to repos. Has title, body, status (open/accepted/closed) | +| `PromptRequestComment` | Comments on prompt requests | +| `PromptRequestReaction` | Reactions (emoji) on prompt requests | + +### PR Analysis + +| Model | Purpose | +|---|---| +| `PrOverviewAnalysis` | Cached AI-generated PR analysis. Keyed by `(owner, repo, pullNumber)`, invalidated when `headSha` changes | + +## Prisma Commands + +```bash +cd apps/web + +# Generate Prisma client (run after schema changes) +bunx prisma generate + +# Create a migration +bunx prisma migrate dev --name your_migration_name + +# Apply migrations +bunx prisma migrate dev + +# Reset database (destructive) +bunx prisma migrate reset + +# Open Prisma Studio +bunx prisma studio +``` + +The `postinstall` script in `apps/web/package.json` runs `prisma generate` automatically on `bun install`. The `build` script also runs `prisma generate` before `next build`. + +## Accessing the Database + +Always import the Prisma client from `@/lib/db`: + +```typescript +import { prisma } from "@/lib/db"; + +const user = await prisma.user.findUnique({ where: { id: userId } }); +``` + +Never create a new `PrismaClient` instance directly -- the singleton in `db.ts` manages the connection pool. diff --git a/agent-docs/data-layer/github-sync.md b/agent-docs/data-layer/github-sync.md new file mode 100644 index 00000000..8fc95110 --- /dev/null +++ b/agent-docs/data-layer/github-sync.md @@ -0,0 +1,141 @@ +# GitHub Data Synchronization + +The sync system keeps locally cached GitHub data fresh by running background jobs that fetch updated data from the API. + +## Key Files + +- `apps/web/src/lib/github-sync-store.ts` -- CRUD for sync jobs and cache entries +- `apps/web/src/lib/github.ts` -- Contains `localFirstGitRead()`, `drainGithubSyncJobs()`, and job enqueue logic + +## How It Works + +### Job Lifecycle + +``` +Data requested (page load) + │ + ├── Cache HIT (fresh) → return cached data, done + │ + └── Cache MISS or stale + │ + ├── Fetch from GitHub API directly + ├── Update cache with result + └── Enqueue sync job for next refresh + │ + ▼ + GithubSyncJob created + (status: "pending", dedupeKey prevents duplicates) + │ + ▼ + drainGithubSyncJobs(userId) picks up job + │ + ├── Claims job (status: "running") + ├── Fetches data from GitHub API + ├── Updates cache (Redis + optionally DB) + ├── Marks job succeeded (deletes it) + │ + └── On failure: + ├── Increments attempts counter + ├── Records error message + └── Schedules next attempt (backoff) +``` + +### Job Deduplication + +Jobs are deduplicated by `(userId, dedupeKey)` via a unique constraint on the `github_sync_jobs` table. If a job already exists for the same user and data type, a new one is not created. This prevents flooding the job queue when a user rapidly navigates pages. + +### Job Draining + +The `drainGithubSyncJobs()` function: + +1. Claims a batch of pending jobs for the user (`claimDueGithubSyncJobs`) +2. Processes each job by calling the appropriate GitHub API +3. On success, marks the job completed and updates the cache +4. On failure, marks the job failed with error details +5. Uses a per-user lock (`githubSyncDrainingUsers` Set) to prevent concurrent drains for the same user + +Draining is triggered by `waitUntil()` during page loads -- it runs in the background after the response is sent. + +## Sync Store Operations + +### Cache Entry Operations + +```typescript +// Read +getGithubCacheEntry(userId, cacheKey): GithubCacheEntry | null +getSharedCacheEntry(cacheKey): GithubCacheEntry | null + +// Write +upsertGithubCacheEntry(userId, cacheKey, cacheType, data, etag?) +upsertSharedCacheEntry(cacheKey, cacheType, data, etag?) + +// Touch (update syncedAt without changing data) +touchGithubCacheEntrySyncedAt(userId, cacheKey) +touchSharedCacheEntrySyncedAt(cacheKey) + +// Delete +deleteGithubCacheByPrefix(userId, prefix) +deleteSharedCacheByPrefix(prefix) +``` + +Cache entries are stored in Redis with the structure: + +```typescript +interface GithubCacheEntry { + data: T; + syncedAt: string; // ISO timestamp + etag: string | null; +} +``` + +### Sync Job Operations + +```typescript +// Enqueue +enqueueGithubSyncJob(userId, dedupeKey, jobType, payload) + +// Claim (for processing) +claimDueGithubSyncJobs(userId, limit): GithubSyncJob[] + +// Complete +markGithubSyncJobSucceeded(jobId) +markGithubSyncJobFailed(jobId, error) +``` + +## Configuration + +| Constant | Value | Purpose | +|---|---|---| +| `MAX_ATTEMPTS` | 8 | Maximum retry attempts before giving up | +| `RUNNING_JOB_TIMEOUT_MS` | 10 minutes | Stuck job detection threshold | + +## Job Payload + +All sync jobs carry a typed payload: + +```typescript +interface GitDataSyncJobPayload { + owner?: string; + repo?: string; + sort?: RepoSort; + perPage?: number; + path?: string; + ref?: string; + treeSha?: string; + recursive?: boolean; + username?: string; + orgName?: string; + state?: "open" | "closed" | "all"; + query?: string; + issueNumber?: number; + pullNumber?: number; + language?: string; + since?: "daily" | "weekly" | "monthly"; +} +``` + +The payload contains all the parameters needed to re-fetch the data from the GitHub API when the job runs. + +## ETag Support + +Cache entries store GitHub's ETag header value. When refreshing data, the sync job can send the ETag in an `If-None-Match` header. If GitHub returns 304 (Not Modified), the job simply touches the `syncedAt` timestamp without updating the data. This saves bandwidth and API quota. diff --git a/agent-docs/features/billing.md b/agent-docs/features/billing.md new file mode 100644 index 00000000..f97dc062 --- /dev/null +++ b/agent-docs/features/billing.md @@ -0,0 +1,127 @@ +# Billing System + +Better Hub uses Stripe for metered billing of AI usage. Users receive welcome credits and can set spending limits. The system tracks every AI call with token-level granularity. + +## Key Files + +- `apps/web/src/lib/billing/config.ts` -- Constants: error codes, welcome credit amount, cost-to-units ratio, Stripe config +- `apps/web/src/lib/billing/ai-models.ts` -- AI model registry with pricing per million tokens +- `apps/web/src/lib/billing/ai-models.server.ts` -- Server-side model helpers +- `apps/web/src/lib/billing/openrouter-models.generated.ts` -- Auto-generated model catalog (from `scripts/generate-openrouter-models.mts`) +- `apps/web/src/lib/billing/credit.ts` -- Credit ledger operations (grant, check balance) +- `apps/web/src/lib/billing/spending-limit.ts` -- Per-user spending limit management +- `apps/web/src/lib/billing/stripe.ts` -- Stripe client, metered usage reporting +- `apps/web/src/lib/billing/token-usage.ts` -- Token usage logging and cost calculation +- `apps/web/src/lib/billing/usage-limit.ts` -- Pre-request usage limit checks +- `apps/web/src/lib/inngest.ts` -- Background job: `retryUnreportedUsage` (cron every 10 min) +- `apps/web/src/app/api/billing/balance/route.ts` -- Credit balance endpoint +- `apps/web/src/app/api/billing/spending-limit/route.ts` -- Spending limit CRUD +- `apps/web/src/app/api/billing/welcome/route.ts` -- Welcome credit grant + +## Billing Flow + +``` +AI Request + │ + ├── checkUsageLimit(userId) + │ ├── Check credit balance (credit_ledger, minus usage_logs) + │ ├── Check spending limit (spending_limit table) + │ └── Return: { allowed, creditExhausted?, spendingLimitReached? } + │ + ├── If not allowed → return BILLING_ERROR code + │ ├── MESSAGE_LIMIT_REACHED + │ ├── CREDIT_EXHAUSTED + │ └── SPENDING_LIMIT_REACHED + │ + ▼ (request proceeds) + │ + ├── AI model processes request + │ + ▼ (response complete) + │ + ├── logTokenUsage(userId, model, usage) + │ ├── Calculate cost via calculateCostUsd() + │ ├── Insert ai_call_logs record + │ ├── Insert usage_logs record + │ └── Deduct from credits if applicable + │ + └── reportUsageToStripe(usageLogId, userId, costUsd) + ├── Convert cost to units (1 USD = 10,000 units) + └── Report to Stripe Meter API +``` + +## Credit System + +### Welcome Credits +- New users receive **$10.00 USD** in credits upon signup +- Credits expire after **30 days** +- Granted via `grantSignupCredits()` called from the Stripe `onCustomerCreate` hook + +### Credit Ledger +The `credit_ledger` table tracks all credit transactions: +- `amount` -- Credit amount (positive = grant, negative = usage) +- `type` -- Transaction type (e.g., `welcome_credit`) +- `expiresAt` -- Optional expiration date + +### Balance Calculation +Available balance = sum of non-expired credits minus sum of usage costs. + +## AI Model Pricing + +Models are registered in `ai-models.ts` with pricing per million tokens: + +```typescript +interface ModelPricing { + inputPerM: number; // Cost per 1M input tokens + outputPerM: number; // Cost per 1M output tokens + cacheReadMultiplier?: number; // Discount for cache reads (e.g., 0.1 = 90% off) + cacheWriteMultiplier?: number; // Premium for cache writes +} +``` + +Cost calculation handles: +- Standard input/output token costs +- Cache read discounts (subtract cache reads from input, apply multiplier) +- Cache write premiums + +The model catalog is auto-generated from the OpenRouter API via `scripts/generate-openrouter-models.mts`. Run `bun generate:models` to refresh. + +## Stripe Integration + +### Metered Billing +- 1 USD = 10,000 Stripe meter units (`COST_TO_UNITS`) +- The Stripe meter price must be set to $0.0001 per unit +- Usage is reported per AI call via `reportUsageToStripe()` + +### Subscription +- Plan: `base` with a metered line item +- Active statuses: `active`, `trialing` +- Configured via `STRIPE_BASE_PRICE_ID` and `STRIPE_METERED_PRICE_ID` env vars + +### Stripe is Optional +Stripe features are disabled when `STRIPE_SECRET_KEY` is not set. A console warning is logged. This allows local development without Stripe. + +## Spending Limits + +Users can set a monthly spending cap via the settings UI: +- Stored in the `spending_limit` table (`monthlyCapUsd`, default $10.00) +- Minimum cap: $0.01 +- Checked before each AI request in `checkUsageLimit()` + +## Failure Recovery + +The `retryUnreportedUsage` Inngest function runs every 10 minutes: + +1. **Expire old entries**: Usage logs older than 35 days (Stripe meter API limit) that were never reported are marked as reported and logged as permanent loss +2. **Retry pending entries**: Unreported usage logs (at least 1 minute old) are retried in batches of 25 +3. This ensures no revenue leakage from transient Stripe API failures + +## Database Tables + +| Table | Purpose | +|---|---| +| `ai_call_logs` | Per-call token usage, model, provider, cost | +| `usage_logs` | Billing usage records, links to ai_call_logs, Stripe report status | +| `credit_ledger` | Credit grants and expirations | +| `spending_limit` | Per-user monthly spending cap | +| `subscription` | Stripe subscription state | diff --git a/agent-docs/features/ghost-ai.md b/agent-docs/features/ghost-ai.md new file mode 100644 index 00000000..5fad90b7 --- /dev/null +++ b/agent-docs/features/ghost-ai.md @@ -0,0 +1,119 @@ +# Ghost AI Assistant + +Ghost is Better Hub's built-in AI assistant. Users toggle it with `Cmd+I`. It can review PRs, navigate code, triage issues, write commit messages, and execute code in sandboxes. + +## Key Files + +- `apps/web/src/app/api/ai/ghost/route.ts` -- Main Ghost chat endpoint (~3500 lines) +- `apps/web/src/app/api/ai/ghost/[id]/stream/route.ts` -- Stream resume endpoint +- `apps/web/src/app/api/ai/ghost-tabs/route.ts` -- Ghost tab CRUD +- `apps/web/src/app/api/ai/commit-message/route.ts` -- AI commit message generation +- `apps/web/src/app/api/ai/pr-overview/route.ts` -- AI PR analysis/summary +- `apps/web/src/app/api/ai/command/route.ts` -- AI command execution +- `apps/web/src/app/api/ai/rewrite-prompt/route.ts` -- Prompt rewriting +- `apps/web/src/app/api/ai/chat-history/route.ts` -- Chat history retrieval +- `apps/web/src/lib/chat-store.ts` -- Conversation and message persistence (PostgreSQL) +- `apps/web/src/lib/resumable-stream.ts` -- Resumable stream support for AI responses +- `apps/web/src/lib/ai-auth.ts` -- Helper to get Octokit/token from the user's session +- `apps/web/src/components/shared/ai-chat.tsx` -- Chat UI component +- `apps/web/src/components/shared/global-chat-panel.tsx` -- Slide-out Ghost panel +- `apps/web/src/components/shared/global-chat-provider.tsx` -- Chat context provider +- `apps/web/src/components/shared/floating-ghost-button.tsx` -- Floating toggle button +- `apps/web/src/components/shared/chat-page-activator.tsx` -- Sets chat context per page + +## Model Configuration + +Ghost uses a two-tier model approach: + +```typescript +const GHOST_MODELS = { + default: process.env.GHOST_MODEL || "moonshotai/kimi-k2.5", + mergeConflict: process.env.GHOST_MERGE_MODEL || "google/gemini-2.5-pro-preview", +}; +``` + +- **"auto" mode** (default): The system picks the model based on the task type. Users see "auto" in settings. +- **User-selected model**: Users can pick a specific model from settings or the command palette. The choice is stored in `UserSettings.ghostModel`. +- **BYOK (Bring Your Own Key)**: Users can provide their own OpenRouter API key via settings (`UserSettings.openrouterApiKey`). When `useOwnApiKey` is true, their key is used instead of the platform key. + +All model routing goes through OpenRouter via `@openrouter/ai-sdk-provider`. + +## Tool System + +Ghost has ~30 tools organized into categories. All tool `execute` functions are wrapped with `withSafeTools()` which catches errors so a single tool failure doesn't crash the stream. + +### GitHub Tools (require user's Octokit) +- `get_repo_info` -- Fetch repository metadata +- `list_issues` / `get_issue` -- Browse and read issues +- `list_pull_requests` / `get_pull_request` -- Browse and read PRs +- `get_pull_request_diff` -- Fetch PR diff +- `get_file_content` -- Read file contents from a repo +- `list_repo_files` -- List files in a directory +- `create_issue` -- Create a new issue +- `create_pull_request` -- Create a new PR +- `add_comment` -- Comment on issues/PRs +- `merge_pull_request` -- Merge a PR +- `create_branch` -- Create a new branch +- `update_file` -- Commit file changes +- `create_review` -- Submit a PR review +- `manage_labels` -- Add/remove labels + +### Search Tools +- `search_repos` -- Search GitHub repositories +- `search_code` -- Search code across repos +- `search_issues` -- Search issues and PRs +- `semantic_search` -- Search user's viewed content using Mixedbread embeddings and reranking + +### Code Execution +- `execute_code` -- Run code in an E2B sandbox. Creates a `Sandbox` instance, writes files, runs commands, and returns output. Billed as a fixed cost. + +### Navigation +- `navigate` -- Generate Better Hub URLs for the user to click + +## Conversation Persistence + +Conversations are stored in PostgreSQL via `chat-store.ts`: + +- `ChatConversation` -- Identified by `(userId, contextKey)`. The `contextKey` ties a conversation to a specific context (e.g., `owner/repo` for repo chats, a specific PR URL for PR chats). +- `ChatMessage` -- Messages within a conversation, stored with `role`, `content`, and `partsJson` (for multi-part AI SDK messages). +- `GhostTab` / `GhostTabState` -- Tab management for the Ghost panel (multiple conversations). + +The `activeStreamId` on conversations supports resumable streams -- if a response is interrupted, the client can resume from where it left off. + +## Semantic Search + +Ghost can search the user's previously viewed content: + +1. When a user views a PR or issue, an Inngest event (`app/content.viewed`) is fired +2. The `embedContent` function embeds the title, body, comments, and reviews using Mixedbread's `mxbai-embed-large-v1` model +3. Embeddings are stored in the `search_embeddings` table with content hashes for deduplication +4. When Ghost's `semantic_search` tool is called, it: + - Embeds the query with Mixedbread + - Searches embeddings using cosine similarity + - Reranks results with Mixedbread's `mxbai-rerank-large-v1` + - Returns the top results with snippets + +Additionally, SuperMemory (`supermemory` package) provides long-term conversation memory across sessions. + +## Usage Tracking + +Every Ghost interaction is tracked for billing: + +1. `logTokenUsage()` records input/output tokens, model, and calculated cost in `ai_call_logs` +2. Cost is calculated using the model pricing registry in `src/lib/billing/ai-models.ts` +3. A corresponding `usage_logs` entry is created +4. Usage is reported to Stripe as metered billing events +5. Before each request, `checkUsageLimit()` verifies the user has credits and hasn't hit their spending cap + +## Cache Invalidation + +When Ghost performs write operations (create issue, merge PR, etc.), it invalidates relevant caches: + +```typescript +invalidateIssueCache(owner, repo, issueNumber); +invalidateRepoIssuesCache(owner, repo); +invalidatePullRequestCache(owner, repo, prNumber); +invalidateRepoPullRequestsCache(owner, repo); +``` + +This ensures the UI reflects changes immediately after Ghost acts. diff --git a/agent-docs/features/github-integration.md b/agent-docs/features/github-integration.md new file mode 100644 index 00000000..479ad33e --- /dev/null +++ b/agent-docs/features/github-integration.md @@ -0,0 +1,182 @@ +# GitHub Integration + +Better Hub is a client for the GitHub API. All repository data, issues, PRs, notifications, and user information comes from GitHub's REST API via Octokit. + +## Key Files + +- `apps/web/src/lib/github.ts` -- Primary GitHub API layer (~7300 lines). Contains all data fetching functions. +- `apps/web/src/lib/github-types.ts` -- TypeScript interfaces for GitHub entities (IssueItem, RepoItem, NotificationItem, ActivityEvent, etc.) +- `apps/web/src/lib/github-utils.ts` -- Utility functions: language colors, URL converters (GitHub <-> Better Hub), formatting helpers +- `apps/web/src/lib/github-scopes.ts` -- OAuth scope groups and their descriptions +- `apps/web/src/lib/github-sync-store.ts` -- Persistence layer for cache entries and sync jobs +- `apps/web/src/lib/github-user-attachments.ts` -- User attachment handling +- `apps/web/src/lib/ai-auth.ts` -- Helper to get authenticated Octokit from session + +## Authentication Context + +Every GitHub API call requires a `GitHubAuthContext`: + +```typescript +interface GitHubAuthContext { + userId: string; + token: string; + octokit: Octokit; + forceRefresh: boolean; + githubUser: $Session["githubUser"]; +} +``` + +This is constructed from the user's session. The `token` is the OAuth access token stored (encrypted) in the `account` table by better-auth. + +## Data Sync Job Types + +The system defines ~30 job types for background data synchronization: + +| Job Type | Description | +|---|---| +| `user_repos` | User's repositories | +| `repo` | Repository metadata | +| `repo_contents` | Repository file listing | +| `repo_tree` | Git tree (recursive) | +| `repo_branches` | Branch listing | +| `repo_tags` | Tag listing | +| `repo_releases` | Release listing | +| `file_content` | Single file content | +| `repo_readme` | Repository README | +| `repo_issues` | Issue listing | +| `repo_pull_requests` | PR listing | +| `issue` | Single issue detail | +| `issue_comments` | Issue comments | +| `pull_request` | Single PR detail | +| `pull_request_files` | PR changed files | +| `pull_request_comments` | PR review comments | +| `pull_request_reviews` | PR reviews | +| `pull_request_commits` | PR commit history | +| `pr_bundle` | Bundled PR data fetch | +| `repo_contributors` | Contributor listing | +| `repo_workflows` | CI/CD workflow definitions | +| `repo_workflow_runs` | Workflow run history | +| `repo_nav_counts` | Counts for nav tabs (open issues, PRs, active runs) | +| `repo_discussions` | Discussion listing | +| `authenticated_user` | Current user profile | +| `user_orgs` | User's organizations | +| `org` | Organization detail | +| `org_repos` | Organization repositories | +| `org_members` | Organization members | +| `notifications` | User notifications | +| `search_issues` | Issue/PR search | +| `user_events` | User activity events | +| `starred_repos` | Starred repositories | +| `contributions` | Contribution data | +| `trending_repos` | Trending repositories | +| `user_profile` | Public user profile | +| `user_public_repos` | User's public repos | +| `user_public_orgs` | User's public orgs | +| `person_repo_activity` | Person's activity in a repo | + +## Shared vs Per-User Caching + +The caching system has a critical security distinction: + +**Per-user cache**: Data that may contain private information is cached per-user. The cache key includes the user ID: `gh:{userId}:{cacheKey}`. This prevents data from one user's private repos leaking to another user. + +**Shared cache**: Public data types defined in `SHAREABLE_CACHE_TYPES` can be shared across users. These include: +- `repo_branches`, `repo_tags`, `repo_releases` +- `repo_issues`, `repo_pull_requests` +- `issue`, `issue_comments` +- `pull_request`, `pull_request_files`, `pull_request_comments`, `pull_request_reviews`, `pull_request_commits` +- `repo_contributors`, `repo_workflows`, `repo_workflow_runs`, `repo_nav_counts` +- `user_profile`, `user_public_repos`, `user_public_orgs`, `user_events` +- `org`, `org_repos`, `org_members` +- `trending_repos` + +This distinction is enforced by `isShareableCacheType()`. Any data from repos (code, contents, trees) is **excluded** from the shared cache because private-repo data fetched by one authorized user would leak to others. + +## The `localFirstGitRead` Pattern + +This is the core data-fetching pattern used by all GitHub data functions: + +```typescript +interface LocalFirstGitReadOptions { + authCtx: GitHubAuthContext | null; + cacheKey: string; + cacheType: string; + fallback: T; + jobType: GitDataSyncJobType; + jobPayload: GitDataSyncJobPayload; + fetchRemote: (octokit: Octokit) => Promise; +} +``` + +The function: +1. Checks Redis for cached data (per-user, then shared if applicable) +2. If cache miss, fetches from GitHub API directly +3. Updates the cache on successful fetch +4. Enqueues a background sync job for future freshness +5. If the API call fails (rate limit, etc.), falls back to the DB cache +6. If all else fails, returns the provided `fallback` value + +## Rate Limit Handling + +The `GitHubRateLimitError` class captures rate limit details: + +```typescript +class GitHubRateLimitError extends Error { + readonly resetAt: number; // unix timestamp (seconds) + readonly limit: number; + readonly used: number; +} +``` + +When a 403 rate limit response is received, the error is thrown and caught at the page level. The `/api/rate-limit` endpoint exposes the current rate limit status to the client. + +## GitHub OAuth Scopes + +Scopes are organized into groups in `github-scopes.ts`: + +- **profile** (required): `user`, `user:email`, `user:follow` +- **public_repos** (required): `public_repo`, `repo:status`, `repo_deployment`, `read:org` +- **private_repos** (optional): `repo` (full access to private repositories) +- **notifications** (optional): `notifications` +- **gist** (optional): `gist` +- **admin** (optional): `admin:repo_hook`, `admin:org` +- **workflow** (optional): `workflow` +- **delete_repo** (optional): `delete_repo` + +Users can opt into additional scopes during sign-in or later in settings. The sign-in UI shows each group with its description and reason. + +## Repository Permissions + +The `extractRepoPermissions()` function normalizes GitHub's permission object: + +```typescript +type RepoPermissions = { + admin: boolean; + push: boolean; + pull: boolean; + maintain: boolean; + triage: boolean; +}; +``` + +These permissions drive UI decisions like showing merge buttons, edit controls, and settings access. + +## Key Data Fetching Functions + +The most important functions exported from `github.ts` (non-exhaustive): + +- `getRepoPageData(owner, repo)` -- Fetches everything needed for the repo layout +- `getRepoTree(owner, repo, ref, recursive)` -- Git tree for file explorer +- `getFileContent(owner, repo, path, ref)` -- Single file content +- `getRepoPullRequests(owner, repo, state, page)` -- PR listing +- `getPullRequest(owner, repo, number)` -- PR detail with full data +- `getPullRequestFiles(owner, repo, number)` -- Changed files in a PR +- `getRepoIssues(owner, repo, state, page)` -- Issue listing +- `getIssue(owner, repo, number)` -- Issue detail +- `getNotifications(perPage)` -- User notifications +- `getUserRepos(sort, perPage)` -- User's repositories +- `getStarredRepos(username, page)` -- Starred repos +- `getTrendingRepos(language, since)` -- Trending repos +- `prefetchPRData(owner, repo, opts)` -- Background prefetch for PR data +- `checkIsStarred(owner, repo)` -- Check if user starred a repo +- `getForkSyncStatus(owner, repo, branch)` -- Fork behind/ahead status diff --git a/agent-docs/features/pr-reviews.md b/agent-docs/features/pr-reviews.md new file mode 100644 index 00000000..292407e1 --- /dev/null +++ b/agent-docs/features/pr-reviews.md @@ -0,0 +1,110 @@ +# Pull Request Reviews + +The PR review experience is one of Better Hub's core differentiators. It includes inline diffs, AI-powered summaries, threaded review comments, merge conflict resolution, and CI status integration. + +## Key Files + +### Pages +- `apps/web/src/app/(app)/repos/[owner]/[repo]/pulls/page.tsx` -- PR listing +- `apps/web/src/app/(app)/repos/[owner]/[repo]/pulls/[number]/page.tsx` -- PR detail +- `apps/web/src/app/(app)/repos/[owner]/[repo]/pulls/[number]/[...sub]/page.tsx` -- PR sub-pages (files, commits, checks) +- `apps/web/src/app/(app)/repos/[owner]/[repo]/pulls/new/page.tsx` -- Create PR + +### Components (`src/components/pr/`) + +**Layout and Navigation** +- `pr-detail-layout.tsx` -- Main PR detail page layout +- `pr-header.tsx` -- PR title, status, metadata header +- `editable-pr-title.tsx` -- Inline-editable PR title +- `editable-base-branch.tsx` -- Change base branch +- `pr-status-indicator.tsx` -- Open/merged/closed status badge + +**Diff Viewing** +- `pr-diff-viewer.tsx` -- Main diff rendering component +- `pr-diff-list.tsx` -- List of changed files with diffs +- `pr-files-list.tsx` -- File listing for "Files changed" tab +- `diff-file-tree.tsx` -- Tree view of changed files +- `diff-snippet-table.tsx` -- Individual diff snippet rendering + +**Conversation and Comments** +- `pr-conversation.tsx` -- Full PR conversation timeline +- `pr-comment-form.tsx` -- Comment input (uses TipTap rich text editor) +- `pr-optimistic-comments-provider.tsx` -- Optimistic UI for new comments +- `deleted-comments-context.tsx` -- Tracks deleted comments +- `chat-message-wrapper.tsx` -- Wraps individual messages +- `message-actions-menu.tsx` -- Actions menu on comments (edit, delete, quote) +- `collapsible-description.tsx` -- Collapsible PR description +- `collapsible-review-card.tsx` -- Collapsible review summary card + +**Reviews** +- `pr-reviews-panel.tsx` -- Review submissions panel +- `pr-review-form.tsx` -- Submit review form (approve, request changes, comment) + +**Merge and CI** +- `pr-merge-panel.tsx` -- Merge controls (merge, squash, rebase) +- `pr-conflict-resolver.tsx` -- Merge conflict resolution UI +- `pr-checks-panel.tsx` -- CI check status listing +- `check-status-badge.tsx` -- Individual check status badge + +**AI Integration** +- `pr-overview-panel.tsx` -- AI-generated PR summary/analysis +- `pr-author-dossier.tsx` -- AI-generated author context +- `pr-author-dossier-lazy.tsx` -- Lazy-loaded variant + +**Activity Groups** +- `commit-activity-group.tsx` -- Grouped commit activity in timeline +- `bot-activity-group.tsx` -- Grouped bot activity in timeline + +## PR Data Flow + +### Loading a PR Detail Page + +1. The page component calls `getPullRequest(owner, repo, number)` which fetches: + - PR metadata (title, body, state, author, labels, assignees) + - PR files (changed files with patches) + - PR reviews and review comments + - PR commits + - PR check status +2. Data is fetched using the `localFirstGitRead` pattern (cache-first) +3. The `prefetchPRData()` function is called in the repo layout to warm caches + +### PR Overview (AI Analysis) + +The AI PR overview is generated via `/api/ai/pr-overview`: + +1. Client requests an overview for a specific PR +2. Server checks the `pr_overview_analyses` table for a cached analysis matching the current `headSha` +3. If no cache or SHA mismatch, generates a new analysis using the AI model +4. The analysis is streamed to the client and cached in the DB +5. The `pr-overview-panel.tsx` component displays: summary, key changes, risk assessment, and suggested reviewers + +### Creating a PR + +The create PR flow (`pulls/new/page.tsx`) supports: +- GitHub Desktop / `gh pr create` compatible URLs via middleware rewriting of `/compare/base...head` +- Pre-filling title and body from URL query parameters +- Branch comparison view with diff preview + +### Merge Panel + +The `pr-merge-panel.tsx` supports three merge strategies: +- **Merge commit** -- Standard merge +- **Squash and merge** -- Squash all commits +- **Rebase and merge** -- Rebase onto base branch + +It also shows merge requirements (required reviews, CI checks) and handles merge conflicts. + +### Conflict Resolution + +The `pr-conflict-resolver.tsx` provides an in-browser conflict resolution experience: +- Uses `three-way-merge.ts` for merge conflict detection +- Can invoke Ghost AI (using the `mergeConflict` model, defaulting to Gemini 2.5 Pro) to suggest resolutions +- Presents a side-by-side view of conflicting changes + +## Related API Routes + +- `/api/merge-conflicts` -- Fetches merge conflict data for a PR +- `/api/check-status` -- Fetches CI check status for a PR +- `/api/highlight-diff` -- Server-side syntax highlighting for diff content +- `/api/ai/pr-overview` -- AI-generated PR analysis +- `/api/ai/commit-message` -- AI commit message suggestions diff --git a/agent-docs/frontend/components.md b/agent-docs/frontend/components.md new file mode 100644 index 00000000..a2fb6a2d --- /dev/null +++ b/agent-docs/frontend/components.md @@ -0,0 +1,186 @@ +# Component Organization + +Components live in `apps/web/src/components/` and are organized by feature domain. The app uses React Server Components by default (Next.js App Router), with client components marked explicitly with `"use client"`. + +## Directory Structure + +### `layout/` -- App Shell (3 files) +- `navbar.tsx` -- Top navigation bar with user menu, notifications, command palette trigger +- `nav-aware-content.tsx` -- Content wrapper that adjusts for navbar visibility +- `notification-sheet.tsx` -- Slide-out notification panel + +### `repo/` -- Repository Views (38 files) + +The largest component group, covering all repository UI: + +**Layout** +- `repo-layout-wrapper.tsx` -- Outer wrapper managing sidebar + content split +- `repo-sidebar.tsx` -- Left sidebar: description, stats, topics, license, links, contributors, languages +- `repo-nav.tsx` -- Tab navigation (Code, Issues, PRs, Actions, Discussions, etc.) +- `code-content-wrapper.tsx` -- Wraps code views with file tree and branch selector + +**Code Browsing** +- `code-viewer.tsx` / `code-viewer-client.tsx` -- File content display with syntax highlighting +- `file-list.tsx` -- Directory listing (table of files) +- `file-explorer-tree.tsx` -- Sidebar file tree +- `markdown-blob-view.tsx` -- Rendered markdown file view +- `notebook-viewer.tsx` / `notebook-viewer-client.tsx` -- Jupyter notebook rendering +- `document-outline.tsx` -- Markdown heading outline + +**Repository Info** +- `repo-overview.tsx` -- Main repo page (README + file list) +- `repo-badge.tsx` -- Repo visibility badge (public/private) +- `repo-breadcrumb.tsx` / `breadcrumb-nav.tsx` -- Path breadcrumbs +- `repo-settings.tsx` -- Repo settings view +- `repo-activity-view.tsx` -- Activity feed +- `insights-view.tsx` -- Repository insights + +**Branch/Tag Management** +- `branch-selector.tsx` -- Branch/tag dropdown +- `sidebar-branch-switcher.tsx` -- Sidebar branch switcher +- `tags-list.tsx` -- Tags listing page + +**Releases and Commits** +- `releases-list.tsx` -- Releases listing +- `release-detail.tsx` -- Individual release view +- `commits-list.tsx` -- Commit history +- `commit-detail.tsx` -- Individual commit view +- `latest-commit-section.tsx` -- Latest commit display in code view + +**Sidebar Sections** +- `sidebar-contributors.tsx` -- Top contributors with avatars +- `sidebar-languages.tsx` -- Language breakdown bar +- `sidebar-used-by.tsx` -- "Used by" section + +**Actions** +- `star-button.tsx` -- Star/unstar repo +- `fork-button.tsx` -- Fork repo +- `fork-sync-button.tsx` -- Sync fork with upstream +- `pin-button.tsx` -- Pin repo +- `create-repo-dialog.tsx` -- Create new repo dialog +- `code-toolbar.tsx` -- Code view toolbar +- `readme-toolbar.tsx` -- README view toolbar + +**Utilities** +- `repo-revalidator.tsx` -- Triggers background data revalidation + +### `pr/` -- Pull Request UI (30 files) + +See [features/pr-reviews.md](../features/pr-reviews.md) for detailed documentation. + +### `issue/` -- Issue Detail +Components for viewing and interacting with individual issues. + +### `issues/` -- Issue Listing +Components for the issues list view with filtering and sorting. + +### `prs/` -- PR Listing +Components for the pull requests list view. + +### `shared/` -- Cross-Cutting Components (32 files) + +Reusable components used across multiple features: + +**AI** +- `ai-chat.tsx` -- Chat interface component +- `global-chat-panel.tsx` -- Ghost AI slide-out panel +- `global-chat-provider.tsx` -- Chat state context provider +- `floating-ghost-button.tsx` -- Floating Ghost toggle +- `chat-page-activator.tsx` -- Sets chat context based on current page + +**Markdown** +- `markdown-renderer.tsx` -- Server-side markdown rendering +- `client-markdown.tsx` -- Client-side markdown rendering +- `markdown-editor.tsx` -- TipTap-based markdown editor +- `markdown-mention-tooltips.tsx` -- @mention tooltips in markdown +- `markdown-copy-handler.tsx` -- Copy-to-clipboard for code blocks in markdown +- `github-emoji.tsx` -- GitHub emoji rendering + +**Code** +- `highlighted-code-block.tsx` -- Syntax-highlighted code block +- `reactive-code-blocks.tsx` -- Interactive code blocks with copy buttons + +**Comments** +- `comment.tsx` -- Individual comment component +- `comment-thread.tsx` -- Threaded comment display + +**GitHub UI** +- `github-avatar.tsx` -- GitHub user avatar with fallback +- `github-link-interceptor.tsx` -- Rewrites github.com links to Better Hub +- `user-tooltip.tsx` -- User info tooltip on hover +- `label-badge.tsx` -- Issue/PR label badge +- `permission-badge.tsx` -- Repo permission badge +- `reaction-display.tsx` -- Emoji reaction display and picker + +**Navigation** +- `navigation-progress.tsx` -- Top loading bar +- `nav-visibility-provider.tsx` -- Navbar visibility context + +**Actions** +- `refresh-button.tsx` -- Force refresh button +- `copy-link-button.tsx` -- Copy URL to clipboard +- `pin-button.tsx` -- Pin item button +- `track-view.tsx` -- View tracking component + +**Utilities** +- `list-controls.tsx` -- List filtering/sorting controls +- `mention-suggestion.tsx` -- @mention autocomplete +- `mutation-event-provider.tsx` -- Mutation event bus context +- `commit-dialog.tsx` -- Commit creation dialog +- `file-icon.tsx` -- File type icon + +### `ui/` -- Base Primitives (14 files) + +Low-level UI components, mostly wrapping Radix UI: + +- `button.tsx` -- Button with variants (CVA) +- `badge.tsx` -- Badge component +- `dialog.tsx` -- Modal dialog (Radix) +- `sheet.tsx` -- Slide-out sheet (Radix) +- `dropdown-menu.tsx` -- Dropdown menu (Radix) +- `tooltip.tsx` -- Tooltip (Radix) +- `command.tsx` -- Command palette (cmdk) +- `resize-handle.tsx` -- Draggable resize handle +- `time-ago.tsx` -- Relative time display +- `live-duration.tsx` -- Live updating duration +- `logo.tsx` -- Better Hub logo +- `agent-icon.tsx` -- AI agent icon +- `github-background.tsx` -- GitHub-style background pattern +- `halftone-background.tsx` -- Halftone dot background + +### Other Feature Directories + +| Directory | Purpose | +|---|---| +| `dashboard/` | Dashboard page widgets | +| `search/` | Search UI and results | +| `settings/` | User settings panels | +| `settings/tabs/` | Individual settings tab content | +| `actions/` | CI/CD workflow views | +| `discussion/` | Discussion UI | +| `notifications/` | Notification list and items | +| `onboarding/` | First-run onboarding overlay | +| `orgs/` | Organization views | +| `people/` | People/contributors views | +| `security/` | Security advisory views | +| `trending/` | Trending repos view | +| `users/` | User profile views | +| `users/activity-timeline/` | Activity timeline components | +| `repos/` | Repository listing views | +| `prompt-request/` | Prompt request UI | +| `extension/` | Browser extension promo | +| `providers/` | React context providers | +| `pwa/` | PWA support | +| `theme/` | Theme provider and selector | + +## Component Patterns + +### Server vs Client Components +- **Server components** (default): Used for data fetching, database access, rendering with session context. No `"use client"` directive. +- **Client components**: Used for interactivity (event handlers, state, effects). Marked with `"use client"` at the top. + +### Data Passing +Server components fetch data and pass it as props to client components. The `use-server-initial-data.ts` hook pattern hydrates server-fetched data into client state without refetching. + +### Optimistic Updates +The `use-mutation.ts` hook provides optimistic update support. `MutationEventProvider` and `use-mutation-subscription.ts` enable cross-component communication after mutations. diff --git a/agent-docs/frontend/routing.md b/agent-docs/frontend/routing.md new file mode 100644 index 00000000..cc25bfb0 --- /dev/null +++ b/agent-docs/frontend/routing.md @@ -0,0 +1,111 @@ +# Routing + +Better Hub implements GitHub-compatible URLs so users can swap `github.com` with `better-hub.com` in any URL. This is achieved through middleware URL rewriting. + +## Key Files + +- `apps/web/src/proxy.ts` -- Next.js middleware (auth + URL rewriting) +- `apps/web/next.config.ts` -- `rewrites()` config as a fallback layer + +## URL Rewriting Strategy + +There are two layers of URL rewriting, both achieving the same goal: + +### Layer 1: Middleware (`proxy.ts`) + +The middleware handles specific GitHub URL patterns that require transformation beyond simple path prefixing: + +| GitHub URL | Better Hub Internal Route | +|---|---| +| `/:owner/:repo` | `/repos/:owner/:repo` | +| `/:owner/:repo/pull/:number` | `/repos/:owner/:repo/pulls/:number` | +| `/:owner/:repo/commit/:sha` | `/repos/:owner/:repo/commits/:sha` | +| `/:owner/:repo/actions/runs/:runId` | `/repos/:owner/:repo/actions/:runId` | +| `/:owner/:repo/compare/base...head` | `/repos/:owner/:repo/pulls/new?base=&head=` | + +The middleware uses `NextResponse.rewrite()` for transparent rewrites (URL stays the same in the browser) and `NextResponse.redirect()` for the compare URL (which changes the URL). + +### Layer 2: Next.js Config Rewrites (`next.config.ts`) + +The `beforeFiles` rewrites in `next.config.ts` handle the generic case: + +```typescript +rewrites: { + beforeFiles: [ + // /:owner/:repo/:path* → /repos/:owner/:repo/:path* + // /:owner/:repo → /repos/:owner/:repo + // Only when first segment is NOT a known route + ], +} +``` + +### Known Routes Exclusion + +Both layers maintain a list of first-segment routes that should NOT be rewritten: + +**Middleware (`APP_ROUTES`)**: +`dashboard`, `repos`, `issues`, `prs`, `stars`, `settings`, `search`, `trending`, `notifications`, `orgs`, `users`, `api`, `debug`, `_next` + +**Next.js Config (`KNOWN_ROUTES`)**: +`api`, `dashboard`, `debug`, `extension`, `issues`, `notifications`, `orgs`, `prompt`, `repos`, `search`, `stars`, `trending`, `users`, `_next` + +If the first URL segment matches a known route, the URL is passed through unmodified. Otherwise, it's assumed to be an `/:owner/:repo` pattern and gets rewritten. + +## Git Protocol Handling + +The middleware detects git client requests and redirects them to GitHub: + +```typescript +// Detects: /:owner/:repo/info/refs?service=git-upload-pack +// Detects: /:owner/:repo/git-upload-pack +// Detects: /:owner/:repo/git-receive-pack +// → Redirects to https://github.com/... (307) +``` + +This ensures `git clone`, `git fetch`, and `git push` work correctly when pointed at Better Hub URLs. + +## GitHub Link Interception + +The `GitHubLinkInterceptor` component (`src/components/shared/github-link-interceptor.tsx`) intercepts clicks on `github.com` links within the app and rewrites them to Better Hub URLs. Links with `data-no-github-intercept` attribute bypass this behavior. + +The `toAppUrl()` function in `github-utils.ts` converts GitHub URLs to Better Hub internal URLs. + +## Route Groups + +The App Router uses route groups for layout organization: + +- `(app)/` -- All authenticated pages. Wrapped in the app layout with navbar, Ghost panel, providers. +- `debug/` -- Debug pages (outside the app group). + +## Dynamic Segments + +Key dynamic route segments: + +| Segment | Purpose | +|---|---| +| `[owner]` | GitHub user or organization login | +| `[repo]` | Repository name | +| `[number]` | Issue or PR number | +| `[sha]` | Commit SHA | +| `[...path]` | File or directory path (catch-all) | +| `[runId]` | CI/CD workflow run ID | +| `[jobId]` | CI/CD job ID | +| `[tag]` | Release tag | +| `[ghsaId]` | GitHub Security Advisory ID | +| `[username]` | GitHub username | +| `[org]` | Organization name | +| `[id]` | Generic ID (prompt requests) | +| `[...sub]` | Sub-pages (catch-all for PR tabs, new PR sub-views) | + +## Middleware Matcher + +```typescript +export const config = { + matcher: ["/((?!api|_next/static|_next/image|favicon\\.ico|[^/]+\\.[^/]+$).*)"], +}; +``` + +The middleware runs on all paths except: +- `/api/*` (API routes handle their own auth) +- `/_next/static/*` and `/_next/image/*` (static assets) +- `/favicon.ico` and other root-level files with extensions diff --git a/agent-docs/frontend/ui-patterns.md b/agent-docs/frontend/ui-patterns.md new file mode 100644 index 00000000..8327b7fa --- /dev/null +++ b/agent-docs/frontend/ui-patterns.md @@ -0,0 +1,165 @@ +# UI Patterns and Libraries + +## Styling + +### TailwindCSS 4 +The app uses TailwindCSS 4 with PostCSS integration (`@tailwindcss/postcss`). Utility classes are the primary styling method. The `tw-animate-css` package provides animation utilities. + +### Class Merging +The `cn()` utility function (from `src/lib/utils.ts`) combines `clsx` and `tailwind-merge`: + +```typescript +import { cn } from "@/lib/utils"; + +
+``` + +Always use `cn()` when merging class names to avoid Tailwind class conflicts. + +### Class Variance Authority (CVA) +Component variants are defined using `class-variance-authority`: + +```typescript +import { cva } from "class-variance-authority"; + +const buttonVariants = cva("base-classes", { + variants: { + variant: { default: "...", destructive: "...", outline: "..." }, + size: { default: "...", sm: "...", lg: "..." }, + }, + defaultVariants: { variant: "default", size: "default" }, +}); +``` + +## Component Libraries + +### Radix UI +Unstyled, accessible primitives used for: +- `Dialog` -- Modal dialogs +- `DropdownMenu` -- Context menus and dropdown menus +- `Popover` -- Popovers +- `Tooltip` -- Tooltips +- `Avatar` -- User avatars with fallback +- `Slot` -- Component composition via slot pattern +- `VisuallyHidden` -- Screen reader only content + +All Radix components are re-exported with Better Hub styling from `src/components/ui/`. + +### cmdk +Command palette component (`src/components/ui/command.tsx`), triggered with `Cmd+K`. Provides fuzzy search across repos, navigation, theme switching, and actions. + +### Motion (Framer Motion) +Used for animations throughout the app. Common patterns: +- Page transitions +- Panel slide-in/out (Ghost chat, notification sheet) +- List item animations +- Loading states + +## Syntax Highlighting + +### Shiki +Two Shiki configurations exist: + +- `src/lib/shiki.ts` -- Server-side highlighter for rendering code blocks during SSR +- `src/lib/shiki-client.ts` -- Client-side highlighter for dynamic code highlighting + +Code themes are configurable per user: +- `codeThemeLight` -- Light mode theme (default: `vitesse-light`) +- `codeThemeDark` -- Dark mode theme (default: `vitesse-black`) +- Custom themes can be created and stored in `custom_code_themes` table + +### Diff Highlighting +The `/api/highlight-diff` endpoint provides server-side syntax highlighting for PR diffs. The `pr-diff-viewer.tsx` component renders highlighted diffs inline. + +## Rich Text Editing + +### TipTap +Used for comment and markdown editing: + +- `@tiptap/react` -- React integration +- `@tiptap/starter-kit` -- Basic editing features +- `@tiptap/extension-link` -- Link support +- `@tiptap/extension-mention` -- @mention support +- `@tiptap/extension-placeholder` -- Placeholder text +- `@tiptap/suggestion` -- Autocomplete suggestions +- `tiptap-markdown` -- Markdown input/output + +The mention suggestion system (`src/lib/tiptap-mention.ts`, `src/components/shared/mention-suggestion.tsx`) provides @username autocomplete with GitHub user search. + +## Markdown Rendering + +Multiple rendering approaches: + +- **Server-side**: `react-markdown` with `remark-gfm`, `remark-rehype`, `rehype-raw`, `rehype-sanitize`, `rehype-stringify` in `markdown-renderer.tsx` +- **Client-side**: `client-markdown.tsx` for dynamic markdown updates +- Both support GitHub-Flavored Markdown (tables, task lists, strikethrough, autolinks) + +## Theming + +### Color Themes (`src/lib/themes/`) + +The app supports multiple color themes beyond standard light/dark: + +- `themes.tsx` -- Theme definitions (colors, backgrounds) +- `types.ts` -- Theme type interfaces +- `border-radius.ts` -- Border radius presets +- `index.ts` -- Theme exports + +Themes are applied via CSS custom properties. The `ColorThemeProvider` component sets the theme based on user preferences. + +### System Theme +`next-themes` handles system-level light/dark mode detection. The user can choose: system, light, or dark mode (`UserSettings.colorMode`). + +### Code Font +Users can select from preset code fonts and font sizes (`UserSettings.codeFont`, `UserSettings.codeFontSize`). + +## Keyboard Shortcuts + +`@tanstack/react-hotkeys` provides keyboard shortcut handling. Key shortcuts: +- `Cmd+K` -- Command palette +- `Cmd+I` -- Toggle Ghost AI +- Various navigation shortcuts within views + +## URL State Management + +`nuqs` manages URL query parameters as React state: + +```typescript +import { useQueryState } from "nuqs"; +const [tab, setTab] = useQueryState("tab"); +``` + +The `NuqsAdapter` is mounted in the app layout to enable query state throughout the app. + +## Icons + +`lucide-react` provides the icon set. Icons are tree-shaken at build time. + +## Custom Hooks (`src/hooks/`) + +| Hook | Purpose | +|---|---| +| `use-readme.ts` | Fetches and caches README content | +| `use-is-mobile.ts` | Detects mobile viewport | +| `use-server-initial-data.ts` | Hydrates server-fetched data into client state | +| `use-mutation.ts` | Optimistic mutation with rollback | +| `use-mutation-subscription.ts` | Subscribe to mutation events across components | +| `use-infinite-scroll.ts` | Infinite scroll pagination | +| `use-click-outside.ts` | Detect clicks outside an element | + +## Data Fetching Patterns + +### Server Components +Data is fetched directly in server components using functions from `src/lib/github.ts`. No client-side fetching needed for initial renders. + +### React Query +`@tanstack/react-query` is used for client-side data fetching where real-time updates or polling are needed. + +### Mutation Events +The `MutationEventProvider` / `use-mutation-subscription.ts` pattern enables cross-component communication: + +1. Component A performs a mutation (e.g., merges a PR) +2. Component A dispatches a mutation event +3. Components B and C subscribe to that event type and refetch their data + +This avoids prop drilling and keeps components loosely coupled. diff --git a/agent-docs/infrastructure/deployment.md b/agent-docs/infrastructure/deployment.md new file mode 100644 index 00000000..699cb374 --- /dev/null +++ b/agent-docs/infrastructure/deployment.md @@ -0,0 +1,111 @@ +# Deployment + +## Hosting + +Better Hub is deployed on **Vercel**. The production URL is `https://www.better-hub.com`. + +## CI/CD + +### GitHub Actions (`.github/workflows/ci.yml`) + +The CI pipeline runs on pushes to `main` and on pull requests: + +``` +lint ──┐ +format ├──► build +typecheck┘ +``` + +| Job | Command | Purpose | +|---|---|---| +| `Lint` | `bun lint` | oxlint checks | +| `Format` | `bun fmt:check` | oxfmt formatting verification | +| `Typecheck` | `bun typecheck` | TypeScript type checking | +| `Build` | `bun run build` | Full production build (depends on all above passing) | + +All jobs use: +- `actions/checkout@v4` +- `oven-sh/setup-bun@v2` +- `bun install --frozen-lockfile` + +The build job sets `SKIP_ENV_VALIDATION=true` to allow building without real environment variables. + +## Error Tracking + +### Sentry (`@sentry/nextjs` v10) + +Configured in `next.config.ts` via `withSentryConfig()`: + +- **Org**: `better-hub` +- **Project**: `javascript-nextjs` +- **Tunnel route**: `/monitoring` -- Routes browser Sentry requests through Next.js to circumvent ad-blockers +- **Source maps**: Uploaded with `widenClientFileUpload: true` for better stack traces +- **Silent mode**: Only prints source map upload logs in CI (`!process.env.CI`) +- **Tree-shaking**: Debug logging is removed from production bundles + +### Vercel Cron Monitors +`automaticVercelMonitors: true` enables automatic instrumentation of Vercel Cron jobs. + +## Security Headers + +All responses include security headers (configured in `next.config.ts`): + +| Header | Value | +|---|---| +| `X-Content-Type-Options` | `nosniff` | +| `X-Frame-Options` | `DENY` | +| `Referrer-Policy` | `strict-origin-when-cross-origin` | +| `Permissions-Policy` | `camera=(), microphone=(), geolocation=()` | +| `Strict-Transport-Security` | `max-age=63072000; includeSubDomains; preload` | + +## Image Optimization + +Remote image patterns are allowlisted in `next.config.ts`: + +- `avatars.githubusercontent.com` +- `*.githubusercontent.com` +- `github.com` +- `opengraph.githubassets.com` +- `raw.githubusercontent.com` +- `user-images.githubusercontent.com` +- `repository-images.githubusercontent.com` +- `better-hub.com` +- `images.better-auth.com` + +Image optimization timeout: 3 seconds (`imgOptTimeoutInSeconds`). + +## Caching Configuration + +Next.js experimental stale times: +- `dynamic`: 300 seconds (5 minutes) +- `static`: 180 seconds (3 minutes) + +These control how long dynamically and statically rendered pages can be served from the Vercel edge cache before revalidation. + +## OAuth Proxy + +For Vercel preview deployments, the `oAuthProxy` plugin redirects OAuth callbacks through the production URL: + +```typescript +oAuthProxy({ productionURL: "https://www.better-hub.com" }) +``` + +This is only enabled when `process.env.VERCEL` is set. + +## Build Process + +The web app build command: + +```bash +prisma generate && next build +``` + +1. Generate the Prisma client from the schema +2. Run the Next.js production build (compiles pages, API routes, generates static assets) + +## Background Jobs + +Inngest handles background job processing. The webhook endpoint is at `/api/inngest`. In production, Inngest calls this endpoint to trigger functions. The two functions defined: + +1. `embed-content` -- Embed PR/issue content when viewed (event-driven) +2. `retry-unreported-usage` -- Retry failed Stripe usage reports (cron: every 10 minutes) diff --git a/agent-docs/infrastructure/development.md b/agent-docs/infrastructure/development.md new file mode 100644 index 00000000..42ca5817 --- /dev/null +++ b/agent-docs/infrastructure/development.md @@ -0,0 +1,165 @@ +# Development Setup + +## Prerequisites + +- **Node.js** 22+ +- **Bun** (package manager, v1.3.5+) +- **Docker** (for PostgreSQL and Redis) +- A **GitHub OAuth App** ([create one here](https://github.com/settings/developers)) + +## Local Setup + +```bash +# 1. Clone the repo +git clone https://github.com/better-auth/better-hub.git +cd better-hub + +# 2. Use the repo Node version +nvm use + +# 3. Start PostgreSQL and Redis +docker compose up -d + +# 4. Configure environment +cp apps/web/.env.example apps/web/.env +# Fill in required values (see environment.md) + +# 5. Install dependencies +bun install + +# 6. Run database migrations +cd apps/web && bunx prisma migrate dev && bunx prisma generate && cd ../.. + +# 7. Start dev server +bun dev +``` + +The app will be available at `http://localhost:3000`. + +## Docker Compose Services + +Defined in `docker-compose.yml`: + +| Service | Image | Port | Purpose | +|---|---|---|---| +| `postgres` | `postgres:16-alpine` | `127.0.0.1:54320` | PostgreSQL database (`max_connections=300`) | +| `redis` | `redis:7-alpine` | (internal) | Redis cache | +| `redis-rest` | `hiett/serverless-redis-http` | `127.0.0.1:8079` | Upstash-compatible REST API proxy for Redis | + +The Redis REST proxy emulates the Upstash REST API locally, so the same `@upstash/redis` client works in both development and production. + +Default connection strings: +- PostgreSQL: `postgresql://postgres:postgres@localhost:54320/better_hub` +- Redis REST: `http://localhost:8079` with token `local_token` + +## Development Scripts + +Run from the repo root: + +| Command | Description | +|---|---| +| `bun dev` | Start all apps in dev mode (Next.js dev server) | +| `bun lint` | Run oxlint across `apps/` and `packages/` | +| `bun lint:fix` | Run oxlint with auto-fix | +| `bun fmt` | Format with oxfmt | +| `bun fmt:check` | Check formatting (CI mode) | +| `bun typecheck` | TypeScript type checking (`tsc --noEmit`) | +| `bun check` | Run lint + fmt:check + typecheck (full CI check) | +| `bun fix` | Run lint:fix + fmt (fix everything) | +| `bun build` | Build all workspaces | + +### Web App Scripts (`apps/web/`) + +| Command | Description | +|---|---| +| `bun dev` | Next.js dev server | +| `bun build` | `prisma generate && next build` | +| `bun start` | Next.js production server | +| `bun test` | Run tests with Vitest | +| `bun generate:models` | Refresh AI model catalog from OpenRouter API | +| `bun generate:models:check` | Verify model catalog is up to date | + +## Pre-Commit Hooks + +Configured via `simple-git-hooks` + `lint-staged`: + +```json +{ + "pre-commit": "bun lint-staged" +} +``` + +Lint-staged runs on staged files: +- `*.{ts,tsx,js,jsx}` -> `oxfmt --write` + `oxlint --fix` +- `*.json` -> `oxfmt --write` + +After cloning, run `bun prepare` (or `bun install`, which triggers `postinstall`) to set up the git hooks. + +## Linting and Formatting + +### oxlint (`oxlint.json`) +- Plugins: `typescript`, `import`, `promise`, `unicorn` +- Key rules: `eqeqeq: error`, `no-var: error`, `prefer-const: error`, `no-unused-vars: warn` +- Ignores: `node_modules`, `dist`, `.git`, `.next` + +### oxfmt +- Configured via `.oxfmtignore` for file exclusions +- Handles TypeScript, JavaScript, JSON, and YAML files + +## TypeScript Configuration + +Root `tsconfig.json` sets strict defaults: + +```json +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "exactOptionalPropertyTypes": true, + "verbatimModuleSyntax": true, + "noEmit": true + } +} +``` + +Notable strict settings: +- `noUncheckedIndexedAccess` -- Array/object index access returns `T | undefined` +- `exactOptionalPropertyTypes` -- Distinguishes between `undefined` and missing +- `verbatimModuleSyntax` -- Requires explicit `type` imports + +## Database Management + +```bash +cd apps/web + +# Create a new migration +bunx prisma migrate dev --name migration_name + +# Apply pending migrations +bunx prisma migrate dev + +# Generate Prisma client (after schema changes) +bunx prisma generate + +# Open Prisma Studio (database GUI) +bunx prisma studio + +# Reset database (drops all data) +bunx prisma migrate reset +``` + +## Testing + +Tests use Vitest (`vitest` v4): + +```bash +cd apps/web +bun test +``` + +Test files follow the `*.test.ts` convention (e.g., `extract-snippet.test.ts`). diff --git a/agent-docs/infrastructure/environment.md b/agent-docs/infrastructure/environment.md new file mode 100644 index 00000000..0d7b9441 --- /dev/null +++ b/agent-docs/infrastructure/environment.md @@ -0,0 +1,115 @@ +# Environment Variables + +All environment variables are defined in `apps/web/.env`. See `apps/web/.env.example` for a template. + +## Required Variables + +### Authentication + +| Variable | Description | +|---|---| +| `GITHUB_CLIENT_ID` | GitHub OAuth App client ID | +| `GITHUB_CLIENT_SECRET` | GitHub OAuth App client secret | +| `BETTER_AUTH_SECRET` | 32-char random string for session encryption. Generate with `openssl rand -hex 16` | +| `BETTER_AUTH_URL` | Base URL of the app (e.g., `http://localhost:3000`) | +| `NEXT_PUBLIC_APP_URL` | Public-facing app URL (same as above for local dev) | + +### Database + +| Variable | Description | +|---|---| +| `DATABASE_URL` | PostgreSQL connection string. Docker Compose default: `postgresql://postgres:postgres@localhost:54320/better_hub` | + +### Redis + +| Variable | Description | +|---|---| +| `UPSTASH_REDIS_REST_URL` | Upstash Redis REST API URL. Docker Compose default: `http://localhost:8079` | +| `UPSTASH_REDIS_REST_TOKEN` | Upstash Redis REST API token. Docker Compose default: `local_token` | + +## AI (Required for AI Features) + +| Variable | Description | Default | +|---|---|---| +| `OPEN_ROUTER_API_KEY` | OpenRouter API key for Ghost AI | (none) | +| `GHOST_MODEL` | Default Ghost model ID | `moonshotai/kimi-k2.5` | +| `GHOST_MERGE_MODEL` | Model for merge conflict resolution | `google/gemini-2.5-pro-preview` | +| `ANTHROPIC_API_KEY` | Anthropic API key for specific tasks | (none) | +| `OPENAPI_KEY` | OpenAI API key (optional, for specific tasks) | (none) | + +## Billing (Optional) + +| Variable | Description | +|---|---| +| `STRIPE_SECRET_KEY` | Stripe API key. If unset, all billing features are disabled. | +| `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret | +| `STRIPE_BASE_PRICE_ID` | Stripe Price ID for the base subscription plan | +| `STRIPE_METERED_PRICE_ID` | Stripe Price ID for metered usage | + +## Code Execution (Optional) + +| Variable | Description | +|---|---| +| `E2B_API_KEY` | E2B API key for sandboxed code execution | +| `E2B_TEMPLATE` | Custom E2B template ID (falls back to default base image) | + +## Background Jobs (Optional) + +| Variable | Description | +|---|---| +| `INNGEST_EVENT_KEY` | Inngest event key for background job processing | +| `INNGEST_SIGNING_KEY` | Inngest webhook signing key | + +## Search and Memory (Optional) + +| Variable | Description | +|---|---| +| `MIXEDBREAD_API_KEY` | Mixedbread API key for embeddings and reranking | +| `SUPER_MEMORY_API_KEY` | SuperMemory API key for AI conversation memory | + +## Git Storage (Optional) + +| Variable | Description | +|---|---| +| `GIT_STORAGE_PRIVATE_KEY` | Private key for `@pierre/storage` Git storage client | + +## Integrations (Optional) + +| Variable | Description | +|---|---| +| `SLACK_CLIENT_ID` | Slack app client ID for notifications | +| `SLACK_CLIENT_SECRET` | Slack app client secret | +| `VERCEL_OIDC_TOKEN` | Vercel OIDC token for deployment auth | + +## Error Tracking (Optional) + +| Variable | Description | +|---|---| +| `SENTRY_DSN` | Sentry Data Source Name | +| `SENTRY_AUTH_TOKEN` | Sentry auth token for source map uploads | + +## Docker Compose Variables + +The Docker Compose file uses these with defaults: + +| Variable | Default | Purpose | +|---|---|---| +| `POSTGRES_PASSWORD` | `postgres` | PostgreSQL password | +| `SRH_TOKEN` | `local_token` | Redis REST proxy token | + +## Minimal Local Setup + +For basic local development, you need at minimum: + +```env +GITHUB_CLIENT_ID=your_github_oauth_app_client_id +GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret +BETTER_AUTH_SECRET=any_32_character_random_string_here +BETTER_AUTH_URL=http://localhost:3000 +NEXT_PUBLIC_APP_URL=http://localhost:3000 +DATABASE_URL=postgresql://postgres:postgres@localhost:54320/better_hub +UPSTASH_REDIS_REST_URL=http://localhost:8079 +UPSTASH_REDIS_REST_TOKEN=local_token +``` + +AI features require `OPEN_ROUTER_API_KEY` at minimum. All other variables are optional and enable additional features when provided. diff --git a/apps/web/package.json b/apps/web/package.json index e6bd1f71..7ea5ed6a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -23,6 +23,7 @@ "@mixedbread-ai/sdk": "^2.2.11", "@octokit/rest": "^22.0.1", "@openrouter/ai-sdk-provider": "^2.2.3", + "@pierre/storage": "^1.3.2", "@prisma/adapter-pg": "^7.4.1", "@prisma/client": "^7.4.1", "@radix-ui/react-avatar": "^1.1.11", diff --git a/apps/web/src/lib/storage/index.ts b/apps/web/src/lib/storage/index.ts new file mode 100644 index 00000000..d0048bfc --- /dev/null +++ b/apps/web/src/lib/storage/index.ts @@ -0,0 +1,6 @@ +import { GitStorage } from "@pierre/storage"; + +export const storage = new GitStorage({ + name: "better-hub", + key: process.env.GIT_STORAGE_PRIVATE_KEY!, +}); diff --git a/apps/web/test.ts b/apps/web/test.ts new file mode 100644 index 00000000..e69de29b diff --git a/bun.lock b/bun.lock index 05a261f1..ead148c8 100644 --- a/bun.lock +++ b/bun.lock @@ -27,6 +27,7 @@ "@mixedbread-ai/sdk": "^2.2.11", "@octokit/rest": "^22.0.1", "@openrouter/ai-sdk-provider": "^2.2.3", + "@pierre/storage": "^1.3.2", "@prisma/adapter-pg": "^7.4.1", "@prisma/client": "^7.4.1", "@radix-ui/react-avatar": "^1.1.11", @@ -821,6 +822,8 @@ "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.51.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Q14+fOGb9T28nWF/0EUsYqERiRA7cl1oy4TJrGmLaqhm+aO2cV+JttboHI3CbdeMCAyDI1+NoSlrM7Melhp/cw=="], + "@pierre/storage": ["@pierre/storage@1.3.2", "", { "dependencies": { "jose": "^5.10.0", "snakecase-keys": "^9.0.2", "zod": "^3.23.8" } }, "sha512-j6u+/RJiETmS+WJwCB98vRU3n60lemFXmShhTp8qutPCO6OAAmpUJiW2CWin+tc/N8EyFpT7YrbkGo3/e1gzcQ=="], + "@prisma/adapter-pg": ["@prisma/adapter-pg@7.4.2", "", { "dependencies": { "@prisma/driver-adapter-utils": "7.4.2", "pg": "^8.16.3", "postgres-array": "3.0.4" } }, "sha512-oUo2Zhe9Tf6YwVL8kLPuOLTK1Z2pwi/Ua77t2PuGyBan2w7shRKqHvYK+3XXmRH9RWhPJ4SMtHZKpNo6Ax/4bQ=="], "@prisma/client": ["@prisma/client@7.4.2", "", { "dependencies": { "@prisma/client-runtime-utils": "7.4.2" }, "peerDependencies": { "prisma": "*", "typescript": ">=5.4.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-ts2mu+cQHriAhSxngO3StcYubBGTWDtu/4juZhXCUKOwgh26l+s4KD3vT2kMUzFyrYnll9u/3qWrtzRv9CGWzA=="], @@ -1655,6 +1658,8 @@ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="], + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], @@ -2141,6 +2146,8 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "map-obj": ["map-obj@5.0.2", "", {}, "sha512-K6K2NgKnTXimT3779/4KxSvobxOtMmx1LBZ3NwRxT/MDIR3Br/fQ4Q+WCX5QxjyUR8zg5+RV9Tbf2c5pAWTD2A=="], + "markdown-it": ["markdown-it@14.1.1", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA=="], "markdown-it-task-lists": ["markdown-it-task-lists@2.1.1", "", {}, "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="], @@ -2641,6 +2648,8 @@ "smol-toml": ["smol-toml@1.6.0", "", {}, "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw=="], + "snakecase-keys": ["snakecase-keys@9.0.2", "", { "dependencies": { "change-case": "^5.4.4", "map-obj": "^5.0.2", "type-fest": "^4.15.0" } }, "sha512-Tr4gONsDj1Pa6HJH9D3b411r6tuRyCGgb1l7YpzDFp/thjVSWs7rcbNjyTyRqJi5SUV23sFpzf9epIJRbLR6Yw=="], + "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], @@ -2761,7 +2770,7 @@ "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], - "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], @@ -3033,6 +3042,10 @@ "@opentelemetry/instrumentation-undici/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="], + "@pierre/storage/jose": ["jose@5.10.0", "", {}, "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg=="], + + "@pierre/storage/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@prisma/config/c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="], "@prisma/engines/@prisma/get-platform": ["@prisma/get-platform@7.4.2", "", { "dependencies": { "@prisma/debug": "7.4.2" } }, "sha512-UTnChXRwiauzl/8wT4hhe7Xmixja9WE28oCnGpBtRejaHhvekx5kudr3R4Y9mLSA0kqGnAMeyTiKwDVMjaEVsw=="], @@ -3381,6 +3394,8 @@ "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + "stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + "string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], From fc380e2547fa4c166e785a6088f61dda8dcd39d2 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Sun, 15 Mar 2026 19:11:35 -0700 Subject: [PATCH 02/10] add: CLI & some endpoints --- AGENTS.md | 22 +- agent-docs/data-layer/database.md | 84 +- apps/web/package.json | 2 +- apps/web/prisma.config.ts | 2 +- .../{schema.prisma => schema/app.prisma} | 136 +- apps/web/prisma/schema/auth.prisma | 191 + apps/web/prisma/schema/base.prisma | 8 + apps/web/src/app/api/auth/[...all]/route.ts | 2 +- apps/web/src/app/device/page.tsx | 357 + apps/web/src/lib/auth-client.ts | 6 +- .../lib/auth-hooks/backfill-github-login.ts | 51 + .../backfill-uncreated-user-orgs.ts | 30 + .../lib/auth-hooks/create-default-user-org.ts | 24 + apps/web/src/lib/auth.ts | 126 +- bun.lock | 260 +- package.json | 5 +- packages/cli/package.json | 34 + packages/cli/src/commands/auth.ts | 135 + packages/cli/src/commands/cd.ts | 96 + packages/cli/src/commands/commit.ts | 351 + packages/cli/src/commands/create-repo.ts | 305 + packages/cli/src/commands/delete.ts | 147 + packages/cli/src/commands/list-repo.ts | 66 + packages/cli/src/commands/repo.ts | 246 + packages/cli/src/index.ts | 22 + packages/cli/src/lib/auth-client.ts | 15 + packages/cli/src/lib/client.ts | 19 + packages/cli/src/lib/config.ts | 62 + packages/cli/src/lib/device-auth.ts | 135 + packages/cli/src/lib/intro.ts | 6 + packages/cli/src/lib/open-url.ts | 5 + packages/cli/src/lib/repo-registry.ts | 106 + packages/cli/src/lib/spinner.ts | 33 + packages/cli/src/lib/utils.ts | 3 + packages/cli/tsconfig.json | 12 + packages/storage/package.json | 40 + packages/storage/src/adapter.ts | 113 + packages/storage/src/client.ts | 12 + packages/storage/src/db-schema.ts | 96 + .../storage => packages/storage/src}/index.ts | 2 +- packages/storage/src/lib/middleware.ts | 8 + packages/storage/src/lib/parse-slug.ts | 52 + packages/storage/src/plugin.ts | 22 + packages/storage/src/routes/create-repo.ts | 66 + packages/storage/src/routes/delete-repo.ts | 46 + packages/storage/src/routes/list-repo.ts | 16 + packages/storage/src/zod-schema.ts | 8 + packages/storage/tsconfig.json | 10 + packages/storage/tsdown.config.ts | 15 + pnpm-lock.yaml | 15289 ---------------- 50 files changed, 3325 insertions(+), 15574 deletions(-) rename apps/web/prisma/{schema.prisma => schema/app.prisma} (67%) create mode 100644 apps/web/prisma/schema/auth.prisma create mode 100644 apps/web/prisma/schema/base.prisma create mode 100644 apps/web/src/app/device/page.tsx create mode 100644 apps/web/src/lib/auth-hooks/backfill-github-login.ts create mode 100644 apps/web/src/lib/auth-hooks/backfill-uncreated-user-orgs.ts create mode 100644 apps/web/src/lib/auth-hooks/create-default-user-org.ts create mode 100644 packages/cli/package.json create mode 100644 packages/cli/src/commands/auth.ts create mode 100644 packages/cli/src/commands/cd.ts create mode 100644 packages/cli/src/commands/commit.ts create mode 100644 packages/cli/src/commands/create-repo.ts create mode 100644 packages/cli/src/commands/delete.ts create mode 100644 packages/cli/src/commands/list-repo.ts create mode 100644 packages/cli/src/commands/repo.ts create mode 100644 packages/cli/src/index.ts create mode 100644 packages/cli/src/lib/auth-client.ts create mode 100644 packages/cli/src/lib/client.ts create mode 100644 packages/cli/src/lib/config.ts create mode 100644 packages/cli/src/lib/device-auth.ts create mode 100644 packages/cli/src/lib/intro.ts create mode 100644 packages/cli/src/lib/open-url.ts create mode 100644 packages/cli/src/lib/repo-registry.ts create mode 100644 packages/cli/src/lib/spinner.ts create mode 100644 packages/cli/src/lib/utils.ts create mode 100644 packages/cli/tsconfig.json create mode 100644 packages/storage/package.json create mode 100644 packages/storage/src/adapter.ts create mode 100644 packages/storage/src/client.ts create mode 100644 packages/storage/src/db-schema.ts rename {apps/web/src/lib/storage => packages/storage/src}/index.ts (70%) create mode 100644 packages/storage/src/lib/middleware.ts create mode 100644 packages/storage/src/lib/parse-slug.ts create mode 100644 packages/storage/src/plugin.ts create mode 100644 packages/storage/src/routes/create-repo.ts create mode 100644 packages/storage/src/routes/delete-repo.ts create mode 100644 packages/storage/src/routes/list-repo.ts create mode 100644 packages/storage/src/zod-schema.ts create mode 100644 packages/storage/tsconfig.json create mode 100644 packages/storage/tsdown.config.ts delete mode 100644 pnpm-lock.yaml diff --git a/AGENTS.md b/AGENTS.md index b3f6ed24..f0b9977b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,16 +60,16 @@ If a change is significant enough that it would surprise a future agent reading ### Critical Files -| File | Purpose | -| ---------------------------------------- | ---------------------------------------------- | -| `apps/web/src/lib/github.ts` | All GitHub API data fetching (~7300 lines) | -| `apps/web/src/lib/auth.ts` | Authentication config and `getServerSession()` | -| `apps/web/src/lib/db.ts` | Database client and connection pool | -| `apps/web/src/proxy.ts` | Middleware (auth + URL rewriting) | -| `apps/web/src/app/api/ai/ghost/route.ts` | Ghost AI endpoint (~3500 lines) | -| `apps/web/prisma/schema.prisma` | Database schema | -| `apps/web/next.config.ts` | Next.js configuration | -| `apps/web/.env.example` | Environment variable template | +| File | Purpose | +| ---------------------------------------- | ----------------------------------------------------- | +| `apps/web/src/lib/github.ts` | All GitHub API data fetching (~7300 lines) | +| `apps/web/src/lib/auth.ts` | Authentication config and `getServerSession()` | +| `apps/web/src/lib/db.ts` | Database client and connection pool | +| `apps/web/src/proxy.ts` | Middleware (auth + URL rewriting) | +| `apps/web/src/app/api/ai/ghost/route.ts` | Ghost AI endpoint (~3500 lines) | +| `apps/web/prisma/schema/` | Database schema (multi-file: auth.prisma, app.prisma) | +| `apps/web/next.config.ts` | Next.js configuration | +| `apps/web/.env.example` | Environment variable template | ### Common Tasks @@ -81,6 +81,6 @@ If a change is significant enough that it would surprise a future agent reading **Fetching GitHub data**: Add a function in `apps/web/src/lib/github.ts` using the `localFirstGitRead` pattern. Define the cache key, job type, and remote fetcher. -**Adding a database model**: Update `apps/web/prisma/schema.prisma`, run `bunx prisma migrate dev --name your_migration`, then `bunx prisma generate`. +**Adding a database model**: Add to the appropriate file in `apps/web/prisma/schema/` (`auth.prisma` for better-auth tables, `app.prisma` for everything else), run `bunx prisma migrate dev --name your_migration`, then `bunx prisma generate`. **Running checks before PR**: Run `bun check` from the repo root (lint + format + typecheck). diff --git a/agent-docs/data-layer/database.md b/agent-docs/data-layer/database.md index d4438bf0..4700b532 100644 --- a/agent-docs/data-layer/database.md +++ b/agent-docs/data-layer/database.md @@ -4,7 +4,7 @@ Better Hub uses PostgreSQL as its primary database, accessed through Prisma ORM ## Key Files -- `apps/web/prisma/schema.prisma` -- Database schema (20 models) +- `apps/web/prisma/schema/` -- Database schema (multi-file: `base.prisma` for config, `auth.prisma` for better-auth tables, `app.prisma` for app tables) - `apps/web/prisma/migrations/` -- Prisma migrations - `apps/web/src/lib/db.ts` -- Prisma client initialization and connection pool config - `apps/web/src/generated/prisma/` -- Auto-generated Prisma client @@ -13,11 +13,11 @@ Better Hub uses PostgreSQL as its primary database, accessed through Prisma ORM The pool is configured in `db.ts` with environment-aware settings: -| Setting | Development | Production | -|---|---|---| -| `max` connections | 20 | 5 | -| `idleTimeoutMillis` | 10,000 | 30,000 | -| `connectionTimeoutMillis` | 0 (unlimited) | 5,000 | +| Setting | Development | Production | +| ------------------------- | ------------- | ---------- | +| `max` connections | 20 | 5 | +| `idleTimeoutMillis` | 10,000 | 30,000 | +| `connectionTimeoutMillis` | 0 (unlimited) | 5,000 | Development uses a larger pool because Next.js spawns 10-15 child processes, each needing its own connections. Docker Compose sets `max_connections=300` on PostgreSQL. Production sits behind a managed pooler (PgBouncer/Neon). @@ -27,65 +27,65 @@ The pool is attached to `process` as a singleton (`_proc.__dbPool`) to survive H ### Authentication (managed by better-auth) -| Model | Purpose | -|---|---| -| `User` | User accounts. Extended with `githubPat`, `onboardingDone`, `aiMessageCount`, `stripeCustomerId`, ban fields | -| `Session` | Active sessions with token, expiry, IP, user agent. Supports impersonation (`impersonatedBy`) | -| `Account` | OAuth accounts (GitHub). Stores encrypted access/refresh tokens, scopes | -| `Verification` | Email/token verification records | +| Model | Purpose | +| -------------- | ------------------------------------------------------------------------------------------------------------ | +| `User` | User accounts. Extended with `githubPat`, `onboardingDone`, `aiMessageCount`, `stripeCustomerId`, ban fields | +| `Session` | Active sessions with token, expiry, IP, user agent. Supports impersonation (`impersonatedBy`) | +| `Account` | OAuth accounts (GitHub). Stores encrypted access/refresh tokens, scopes | +| `Verification` | Email/token verification records | ### GitHub Data Sync -| Model | Purpose | -|---|---| +| Model | Purpose | +| ------------------ | ---------------------------------------------------------------------------------------------------------- | | `GithubCacheEntry` | DB-level cache for GitHub API responses. Keyed by `(userId, cacheKey)`. Stores JSON data + etag + syncedAt | -| `GithubSyncJob` | Background sync job queue. Deduplicated by `(userId, dedupeKey)`. Tracks status, attempts, errors | +| `GithubSyncJob` | Background sync job queue. Deduplicated by `(userId, dedupeKey)`. Tracks status, attempts, errors | ### AI / Chat -| Model | Purpose | -|---|---| -| `ChatConversation` | Ghost AI conversations. Keyed by `(userId, contextKey)`. Tracks active stream ID for resumability | -| `ChatMessage` | Individual messages in a conversation. Stores role, content, and `partsJson` for multi-part AI SDK messages | -| `GhostTab` | Ghost panel tab state (tab ID, label, position) | -| `GhostTabState` | Per-user active tab and counter | +| Model | Purpose | +| ------------------ | ----------------------------------------------------------------------------------------------------------- | +| `ChatConversation` | Ghost AI conversations. Keyed by `(userId, contextKey)`. Tracks active stream ID for resumability | +| `ChatMessage` | Individual messages in a conversation. Stores role, content, and `partsJson` for multi-part AI SDK messages | +| `GhostTab` | Ghost panel tab state (tab ID, label, position) | +| `GhostTabState` | Per-user active tab and counter | ### Search -| Model | Purpose | -|---|---| +| Model | Purpose | +| ----------------- | ------------------------------------------------------------------------------------------------------------ | | `SearchEmbedding` | Semantic search embeddings for viewed PRs/issues. Stores embedding vectors as JSON, content hashes for dedup | ### User Preferences -| Model | Purpose | -|---|---| -| `UserSettings` | User preferences: theme, color theme, Ghost model, code theme, font, API keys, onboarding status | -| `CustomCodeTheme` | User-created custom code syntax themes | -| `PinnedItem` | Pinned issues/PRs per repo per user | +| Model | Purpose | +| ----------------- | ------------------------------------------------------------------------------------------------ | +| `UserSettings` | User preferences: theme, color theme, Ghost model, code theme, font, API keys, onboarding status | +| `CustomCodeTheme` | User-created custom code syntax themes | +| `PinnedItem` | Pinned issues/PRs per repo per user | ### Billing -| Model | Purpose | -|---|---| -| `Subscription` | Stripe subscription state (plan, status, period, cancellation) | -| `UsageLog` | Per-AI-call billing records. Links to `AiCallLog`. Tracks Stripe reporting status | -| `AiCallLog` | Detailed AI call logs: provider, model, token counts, cost breakdown | -| `CreditLedger` | Credit transactions (grants and expirations) | -| `SpendingLimit` | Per-user monthly spending cap | +| Model | Purpose | +| --------------- | --------------------------------------------------------------------------------- | +| `Subscription` | Stripe subscription state (plan, status, period, cancellation) | +| `UsageLog` | Per-AI-call billing records. Links to `AiCallLog`. Tracks Stripe reporting status | +| `AiCallLog` | Detailed AI call logs: provider, model, token counts, cost breakdown | +| `CreditLedger` | Credit transactions (grants and expirations) | +| `SpendingLimit` | Per-user monthly spending cap | ### Prompt Requests -| Model | Purpose | -|---|---| -| `PromptRequest` | Community prompt requests tied to repos. Has title, body, status (open/accepted/closed) | -| `PromptRequestComment` | Comments on prompt requests | -| `PromptRequestReaction` | Reactions (emoji) on prompt requests | +| Model | Purpose | +| ----------------------- | --------------------------------------------------------------------------------------- | +| `PromptRequest` | Community prompt requests tied to repos. Has title, body, status (open/accepted/closed) | +| `PromptRequestComment` | Comments on prompt requests | +| `PromptRequestReaction` | Reactions (emoji) on prompt requests | ### PR Analysis -| Model | Purpose | -|---|---| +| Model | Purpose | +| -------------------- | --------------------------------------------------------------------------------------------------------- | | `PrOverviewAnalysis` | Cached AI-generated PR analysis. Keyed by `(owner, repo, pullNumber)`, invalidated when `headSha` changes | ## Prisma Commands diff --git a/apps/web/package.json b/apps/web/package.json index 7ea5ed6a..1d475e14 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -48,7 +48,7 @@ "ai": "^6.0.97", "auth": "1.5.0-beta.18", "better-all": "^0.0.7", - "better-auth": "1.5.1", + "better-auth": "catalog:", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", diff --git a/apps/web/prisma.config.ts b/apps/web/prisma.config.ts index 76f03ef1..fd02e59e 100644 --- a/apps/web/prisma.config.ts +++ b/apps/web/prisma.config.ts @@ -2,7 +2,7 @@ import "dotenv/config"; import { defineConfig } from "prisma/config"; export default defineConfig({ - schema: "prisma/schema.prisma", + schema: "prisma/schema", migrations: { path: "prisma/migrations", }, diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema/app.prisma similarity index 67% rename from apps/web/prisma/schema.prisma rename to apps/web/prisma/schema/app.prisma index 2490f348..4f9271f8 100644 --- a/apps/web/prisma/schema.prisma +++ b/apps/web/prisma/schema/app.prisma @@ -1,116 +1,3 @@ - -generator client { - provider = "prisma-client" - output = "../src/generated/prisma" -} - -datasource db { - provider = "postgresql" -} - -model User { - id String @id - name String - email String - githubPat String? - onboardingDone Boolean @default(false) - emailVerified Boolean - image String? - createdAt DateTime - updatedAt DateTime - - sessions Session[] - accounts Account[] - usageLogs UsageLog[] - aiCallLogs AiCallLog[] - creditLedger CreditLedger[] - - aiMessageCount Int @default(0) - lastActiveAt DateTime? - role String? - banned Boolean? @default(false) - banReason String? - banExpires DateTime? - - stripeCustomerId String? - - @@map("user") - @@index([githubPat, email]) -} - -model Session { - id String @id - expiresAt DateTime - token String @unique - createdAt DateTime - updatedAt DateTime - ipAddress String? - userAgent String? - userId String - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - impersonatedBy String? - - @@map("session") - @@index([userId, expiresAt]) -} - -model Account { - id String @id - accountId String - providerId String - userId String - accessToken String? - refreshToken String? - idToken String? - accessTokenExpiresAt DateTime? - refreshTokenExpiresAt DateTime? - scope String? - password String? - createdAt DateTime - updatedAt DateTime - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@map("account") - @@index([userId, providerId]) -} - -model Verification { - id String @id - identifier String - value String - expiresAt DateTime - createdAt DateTime? - updatedAt DateTime? - - @@map("verification") - @@index([identifier, expiresAt]) -} - -model Subscription { - id String @id - plan String - referenceId String - stripeCustomerId String? - stripeSubscriptionId String? - status String? @default("incomplete") - periodStart DateTime? - periodEnd DateTime? - trialStart DateTime? - trialEnd DateTime? - cancelAtPeriodEnd Boolean? @default(false) - cancelAt DateTime? - canceledAt DateTime? - endedAt DateTime? - seats Int? - billingInterval String? - stripeScheduleId String? - - @@map("subscription") -} - model GithubCacheEntry { userId String cacheKey String @@ -263,14 +150,14 @@ model PinnedItem { } model UsageLog { - id String @id @default(cuid()) - userId String - taskType String - costUsd Decimal @default(0) @db.Decimal(10, 6) - creditUsed Decimal @default(0) @db.Decimal(10, 6) - aiCallLogId Int? @unique - stripeReported Boolean @default(false) - createdAt DateTime @default(now()) + id String @id @default(cuid()) + userId String + taskType String + costUsd Decimal @default(0) @db.Decimal(10, 6) + creditUsed Decimal @default(0) @db.Decimal(10, 6) + aiCallLogId Int? @unique + stripeReported Boolean @default(false) + createdAt DateTime @default(now()) aiCallLog AiCallLog? @relation(fields: [aiCallLogId], references: [id]) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@ -319,14 +206,13 @@ model CreditLedger { model SpendingLimit { userId String @id - monthlyCapUsd Decimal @db.Decimal(10, 2) @default(10.00) + monthlyCapUsd Decimal @default(10.00) @db.Decimal(10, 2) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("spending_limit") } - model PromptRequest { id String @id userId String @@ -349,7 +235,7 @@ model PromptRequest { } model PromptRequestComment { - id String @id + id String @id promptRequestId String userId String userLogin String? @@ -365,7 +251,7 @@ model PromptRequestComment { } model PromptRequestReaction { - id String @id + id String @id promptRequestId String userId String userLogin String? diff --git a/apps/web/prisma/schema/auth.prisma b/apps/web/prisma/schema/auth.prisma new file mode 100644 index 00000000..def5382a --- /dev/null +++ b/apps/web/prisma/schema/auth.prisma @@ -0,0 +1,191 @@ +model User { + id String @id + name String + email String + emailVerified Boolean @default(false) + image String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + lastActiveAt DateTime? + username String? + displayUsername String? + role String? + banned Boolean? @default(false) + banReason String? + banExpires DateTime? + stripeCustomerId String? + githubPat String? + githubLogin String? + onboardingDone Boolean? + aiMessageCount Int? + sessions Session[] + accounts Account[] + members Member[] + invitations Invitation[] + repositorymembers RepositoryMember[] + usageLogs UsageLog[] + aiCallLogs AiCallLog[] + creditLedgers CreditLedger[] + + @@unique([email]) + @@unique([username]) + @@map("user") +} + +model Session { + id String @id + expiresAt DateTime + token String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + ipAddress String? + userAgent String? + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + impersonatedBy String? + activeOrganizationId String? + + @@unique([token]) + @@index([userId]) + @@map("session") +} + +model Account { + id String @id + accountId String + providerId String + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + accessToken String? + refreshToken String? + idToken String? + accessTokenExpiresAt DateTime? + refreshTokenExpiresAt DateTime? + scope String? + password String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([userId]) + @@map("account") +} + +model Verification { + id String @id + identifier String + value String + expiresAt DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([identifier]) + @@map("verification") +} + +model Organization { + id String @id + name String + slug String + logo String? + createdAt DateTime + metadata String? + members Member[] + invitations Invitation[] + + @@unique([slug]) + @@map("organization") +} + +model Member { + id String @id + organizationId String + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + role String @default("member") + createdAt DateTime + + @@index([organizationId]) + @@index([userId]) + @@map("member") +} + +model Invitation { + id String @id + organizationId String + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) + email String + role String? + status String @default("pending") + expiresAt DateTime + createdAt DateTime @default(now()) + inviterId String + user User @relation(fields: [inviterId], references: [id], onDelete: Cascade) + + @@index([organizationId]) + @@index([email]) + @@map("invitation") +} + +model Repository { + id String @id + name String + slug String + createdAt DateTime + updatedAt DateTime? + description String? + visibility String + repositorymembers RepositoryMember[] + + @@unique([slug]) + @@map("repository") +} + +model RepositoryMember { + id String @id + repositoryId String + repository Repository @relation(fields: [repositoryId], references: [id], onDelete: Cascade) + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + createdAt DateTime + updatedAt DateTime? + + @@map("repositoryMember") +} + +model DeviceCode { + id String @id + deviceCode String + userCode String + userId String? + expiresAt DateTime + status String + lastPolledAt DateTime? + pollingInterval Int? + clientId String? + scope String? + + @@map("deviceCode") +} + +model Subscription { + id String @id + plan String + referenceId String + stripeCustomerId String? + stripeSubscriptionId String? + status String? @default("incomplete") + periodStart DateTime? + periodEnd DateTime? + trialStart DateTime? + trialEnd DateTime? + cancelAtPeriodEnd Boolean? @default(false) + cancelAt DateTime? + canceledAt DateTime? + endedAt DateTime? + seats Int? + billingInterval String? + stripeScheduleId String? + + @@map("subscription") +} diff --git a/apps/web/prisma/schema/base.prisma b/apps/web/prisma/schema/base.prisma new file mode 100644 index 00000000..bc49346e --- /dev/null +++ b/apps/web/prisma/schema/base.prisma @@ -0,0 +1,8 @@ +generator client { + provider = "prisma-client" + output = "../../src/generated/prisma" +} + +datasource db { + provider = "postgresql" +} diff --git a/apps/web/src/app/api/auth/[...all]/route.ts b/apps/web/src/app/api/auth/[...all]/route.ts index 7cbe91bb..7a660c03 100644 --- a/apps/web/src/app/api/auth/[...all]/route.ts +++ b/apps/web/src/app/api/auth/[...all]/route.ts @@ -1,4 +1,4 @@ import { auth } from "@/lib/auth"; import { toNextJsHandler } from "better-auth/next-js"; -export const { POST, GET } = toNextJsHandler(auth); +export const { POST, GET, DELETE, PATCH, PUT } = toNextJsHandler(auth); diff --git a/apps/web/src/app/device/page.tsx b/apps/web/src/app/device/page.tsx new file mode 100644 index 00000000..86419c4b --- /dev/null +++ b/apps/web/src/app/device/page.tsx @@ -0,0 +1,357 @@ +"use client"; + +import { useState, useEffect, useCallback, useRef } from "react"; +import { useSearchParams } from "next/navigation"; +import { authClient, useSession } from "@/lib/auth-client"; +import { LoadingSpinner } from "@/components/shared/icons/loading-spinner"; +import { cn } from "@/lib/utils"; +import { CheckCircle2, Monitor, ShieldAlert, XCircle } from "lucide-react"; + +type Phase = "enter-code" | "approve" | "success" | "denied" | "error"; + +const LOGO_SVG_PATH = + "M25.3906 16.25C25.3908 14.8872 24.9992 13.5531 24.2627 12.4066C23.5261 11.26 22.4755 10.3494 21.236 9.78298C19.9965 9.21661 18.6203 9.01841 17.2714 9.21199C15.9224 9.40557 14.6576 9.98277 13.6274 10.8749C12.5972 11.7669 11.8451 12.9363 11.4606 14.2437C11.0762 15.5512 11.0756 16.9415 11.459 18.2492C11.8424 19.557 12.5935 20.727 13.623 21.6199C14.6524 22.5128 15.9169 23.091 17.2656 23.2857V41.7142C15.4867 41.971 13.871 42.8921 12.7438 44.2921C11.6165 45.6921 11.0614 47.467 11.1901 49.2598C11.3189 51.0526 12.1218 52.7301 13.4375 53.9547C14.7532 55.1793 16.4839 55.8601 18.2813 55.8601C20.0787 55.8601 21.8093 55.1793 23.125 53.9547C24.4407 52.7301 25.2437 51.0526 25.3724 49.2598C25.5011 47.467 24.946 45.6921 23.8188 44.2921C22.6915 42.8921 21.0758 41.971 19.2969 41.7142V23.2857C20.9888 23.0415 22.5361 22.1959 23.6552 20.9037C24.7744 19.6116 25.3905 17.9594 25.3906 16.25ZM13.2031 16.25C13.2031 15.2456 13.501 14.2638 14.059 13.4287C14.6169 12.5936 15.41 11.9428 16.3379 11.5584C17.2659 11.1741 18.2869 11.0735 19.272 11.2694C20.257 11.4654 21.1619 11.949 21.872 12.6592C22.5822 13.3694 23.0659 14.2742 23.2618 15.2593C23.4578 16.2444 23.3572 17.2654 22.9728 18.1933C22.5885 19.1212 21.9376 19.9143 21.1025 20.4723C20.2674 21.0303 19.2856 21.3281 18.2813 21.3281C16.9345 21.3281 15.6428 20.7931 14.6905 19.8408C13.7382 18.8884 13.2031 17.5968 13.2031 16.25ZM23.3594 48.75C23.3594 49.7543 23.0616 50.7362 22.5036 51.5712C21.9456 52.4063 21.1525 53.0572 20.2246 53.4416C19.2967 53.8259 18.2756 53.9265 17.2906 53.7305C16.3055 53.5346 15.4007 53.051 14.6905 52.3408C13.9803 51.6306 13.4967 50.7257 13.3007 49.7407C13.1048 48.7556 13.2053 47.7346 13.5897 46.8067C13.974 45.8788 14.6249 45.0857 15.46 44.5277C16.2951 43.9697 17.2769 43.6719 18.2813 43.6719C18.9481 43.6719 19.6085 43.8032 20.2246 44.0584C20.8407 44.3136 21.4005 44.6877 21.872 45.1592C22.3436 45.6308 22.7176 46.1906 22.9728 46.8067C23.228 47.4228 23.3594 48.0831 23.3594 48.75ZM51.7969 41.7142V28.0896C51.7985 27.4222 51.6678 26.761 51.4124 26.1444C51.157 25.5277 50.782 24.9678 50.309 24.4969L39.0152 13.2031H48.75C49.0194 13.2031 49.2777 13.0961 49.4682 12.9056C49.6586 12.7152 49.7656 12.4568 49.7656 12.1875C49.7656 11.9181 49.6586 11.6598 49.4682 11.4693C49.2777 11.2789 49.0194 11.1719 48.75 11.1719H36.5625C36.2932 11.1719 36.0348 11.2789 35.8444 11.4693C35.6539 11.6598 35.5469 11.9181 35.5469 12.1875V24.375C35.5469 24.6443 35.6539 24.9027 35.8444 25.0931C36.0348 25.2836 36.2932 25.3906 36.5625 25.3906C36.8319 25.3906 37.0902 25.2836 37.2807 25.0931C37.4711 24.9027 37.5781 24.6443 37.5781 24.375V14.6402L48.8744 25.934C49.1573 26.2171 49.3816 26.5533 49.5345 26.9231C49.6874 27.293 49.766 27.6894 49.7656 28.0896V41.7142C47.9867 41.971 46.371 42.8921 45.2438 44.2921C44.1165 45.6921 43.5614 47.467 43.6901 49.2598C43.8189 51.0526 44.6219 52.7301 45.9375 53.9547C47.2532 55.1793 48.9839 55.8601 50.7813 55.8601C52.5787 55.8601 54.3093 55.1793 55.625 53.9547C56.9407 52.7301 57.7437 51.0526 57.8724 49.2598C58.0011 47.467 57.446 45.6921 56.3187 44.2921C55.1915 42.8921 53.5758 41.971 51.7969 41.7142ZM50.7813 53.8281C49.7769 53.8281 48.7951 53.5303 47.96 52.9723C47.1249 52.4143 46.474 51.6212 46.0897 50.6933C45.7053 49.7654 45.6048 48.7444 45.8007 47.7593C45.9967 46.7742 46.4803 45.8694 47.1905 45.1592C47.9007 44.449 48.8055 43.9654 49.7906 43.7694C50.7756 43.5735 51.7967 43.6741 52.7246 44.0584C53.6525 44.4428 54.4456 45.0936 55.0036 45.9287C55.5616 46.7638 55.8594 47.7456 55.8594 48.75C55.8594 50.0968 55.3244 51.3884 54.372 52.3408C53.4197 53.2931 52.1281 53.8281 50.7813 53.8281Z"; + +export default function DeviceAuthorizationPage() { + const searchParams = useSearchParams(); + const { data: session, isPending: sessionLoading } = useSession(); + + const [phase, setPhase] = useState("enter-code"); + const [userCode, setUserCode] = useState(""); + const [verifying, setVerifying] = useState(false); + const [processing, setProcessing] = useState(false); + const [error, setError] = useState(null); + const inputRef = useRef(null); + + const urlCode = searchParams.get("user_code"); + + useEffect(() => { + if (urlCode) { + setUserCode(urlCode.trim().replace(/-/g, "").toUpperCase()); + } + }, [urlCode]); + + useEffect(() => { + if (phase === "enter-code" && !urlCode) { + inputRef.current?.focus(); + } + }, [phase, urlCode]); + + const verifyCode = useCallback(async (code: string) => { + setVerifying(true); + setError(null); + try { + const formatted = code.trim().replace(/-/g, "").toUpperCase(); + const response = await authClient.device({ + query: { user_code: formatted }, + }); + if (response.data) { + setUserCode(formatted); + setPhase("approve"); + } else { + setError("Invalid or expired code. Please check and try again."); + } + } catch { + setError("Invalid or expired code. Please check and try again."); + } finally { + setVerifying(false); + } + }, []); + + // Auto-verify if code comes from URL and user is authenticated + const autoVerified = useRef(false); + useEffect(() => { + if (urlCode && session && !autoVerified.current && phase === "enter-code") { + autoVerified.current = true; + verifyCode(urlCode); + } + }, [urlCode, session, phase, verifyCode]); + + function handleSubmitCode(e: React.FormEvent) { + e.preventDefault(); + if (!userCode.trim() || verifying) return; + verifyCode(userCode); + } + + async function handleApprove() { + setProcessing(true); + setError(null); + try { + await authClient.device.approve({ userCode }); + setPhase("success"); + } catch { + setError("Failed to approve. The code may have expired."); + setProcessing(false); + } + } + + async function handleDeny() { + setProcessing(true); + setError(null); + try { + await authClient.device.deny({ userCode }); + setPhase("denied"); + } catch { + setError("Failed to deny. The code may have expired."); + setProcessing(false); + } + } + + function formatDisplayCode(code: string): string { + const clean = code.replace(/-/g, "").toUpperCase(); + if (clean.length === 8) return `${clean.slice(0, 4)}-${clean.slice(4)}`; + return clean; + } + + if (sessionLoading) { + return ( + + + + ); + } + + if (!session) { + const returnUrl = urlCode + ? `/device?user_code=${encodeURIComponent(urlCode)}` + : "/device"; + return ( + +
+
+ +
+
+

+ Device Authorization +

+

+ Sign in to your account to authorize a + device. +

+
+ + Sign in to continue + +
+
+ ); + } + + return ( + + {phase === "enter-code" && ( +
+
+ +
+
+

+ Authorize Device +

+

+ Enter the code shown on your device to grant + access. +

+
+ { + setUserCode( + e.target.value + .toUpperCase() + .replace(/[^A-Z0-9]/g, ""), + ); + setError(null); + }} + placeholder="ABCD1234" + maxLength={8} + spellCheck={false} + autoComplete="off" + className="w-full max-w-[220px] text-center tracking-[0.3em] font-mono text-2xl font-semibold bg-transparent border border-foreground/15 rounded-lg px-4 py-3 text-foreground placeholder:text-foreground/20 focus:outline-none focus:border-foreground/40 focus:ring-1 focus:ring-foreground/20 transition-all" + /> + {error &&

{error}

} + +
+ )} + + {phase === "approve" && ( +
+
+ +
+
+

+ Confirm Authorization +

+

+ A device is requesting access to your + account. +

+
+
+
+ + Device Code + + + {formatDisplayCode(userCode)} + +
+
+ + Account + + + {session.user.name || + session.user.email} + +
+
+ {error &&

{error}

} +
+ + +
+
+ )} + + {phase === "success" && ( +
+
+ +
+
+

+ Device Authorized +

+

+ The device has been granted access. You can + close this tab and return to your terminal. +

+
+
+ )} + + {phase === "denied" && ( +
+
+ +
+
+

+ Authorization Denied +

+

+ The device was not granted access. You can + close this tab. +

+
+
+ )} + + {phase === "error" && ( +
+
+ +
+
+

+ Something went wrong +

+

+ {error ?? "An unexpected error occurred."} +

+
+ +
+ )} +
+ ); +} + +function Shell({ children }: { children: React.ReactNode }) { + return ( +
+ {/* Logo */} +
+ + + + + BETTER-HUB. + +
+ +
{children}
+
+ ); +} diff --git a/apps/web/src/lib/auth-client.ts b/apps/web/src/lib/auth-client.ts index 5ffa1125..2ad5f02d 100644 --- a/apps/web/src/lib/auth-client.ts +++ b/apps/web/src/lib/auth-client.ts @@ -1,15 +1,19 @@ import { createAuthClient } from "better-auth/react"; -import { inferAdditionalFields } from "better-auth/client/plugins"; +import { inferAdditionalFields, deviceAuthorizationClient } from "better-auth/client/plugins"; import { auth } from "./auth"; import { dashClient, sentinelClient } from "@better-auth/infra/client"; import { stripeClient } from "@better-auth/stripe/client"; +import { storageClient } from "@better-hub/storage/client"; export const authClient = createAuthClient({ plugins: [ inferAdditionalFields(), dashClient(), sentinelClient(), + //@ts-expect-error - better-auth type issues stripeClient({ subscription: true }), + deviceAuthorizationClient(), + storageClient(), ], }); diff --git a/apps/web/src/lib/auth-hooks/backfill-github-login.ts b/apps/web/src/lib/auth-hooks/backfill-github-login.ts new file mode 100644 index 00000000..bcdddb60 --- /dev/null +++ b/apps/web/src/lib/auth-hooks/backfill-github-login.ts @@ -0,0 +1,51 @@ +import type { GenericEndpointContext, Session, User } from "better-auth"; +import { auth } from "../auth"; +import { Octokit } from "@octokit/rest"; +import { prisma } from "../db"; +import { setCookieCache } from "better-auth/cookies"; + +export const backfillGithubLogin = async (ctx: GenericEndpointContext): Promise => { + // This hook is used to backfill the githubLogin field for users who signed up before the field was added. + if (ctx.path !== "/get-session") return; + const returned = ctx.context.returned as { session: Session; user: User } | undefined; + + if (!returned || !("session" in returned)) return; + if ((returned.user as any).githubLogin) return; + console.log(11111111, "Missing githubLogin", returned.user); + + const userId = returned.user.id; + const reqHeaders = ctx.headers; + + try { + const account = await auth.api.getAccessToken({ + headers: reqHeaders, + body: { providerId: "github" }, + }); + if (!account?.accessToken) return; + + const octokit = new Octokit({ + auth: account.accessToken, + }); + const { data } = await octokit.users.getAuthenticated(); + if (data.login) { + console.log(`Setting githubLogin for user ${userId} to ${data.login}`); + await prisma.user.update({ + where: { id: userId }, + data: { githubLogin: data.login }, + }); + + const value = { + session: returned.session, + user: { + ...returned.user, + githubLogin: data.login, + } as any, + }; + + await setCookieCache(ctx, value, false); + return value; + } + } catch { + // Will retry on the next session fetch + } +}; diff --git a/apps/web/src/lib/auth-hooks/backfill-uncreated-user-orgs.ts b/apps/web/src/lib/auth-hooks/backfill-uncreated-user-orgs.ts new file mode 100644 index 00000000..55b7bc09 --- /dev/null +++ b/apps/web/src/lib/auth-hooks/backfill-uncreated-user-orgs.ts @@ -0,0 +1,30 @@ +import type { GenericEndpointContext, Session, User } from "better-auth"; +import { prisma } from "../db"; +import { createDefaultOrganization } from "./create-default-user-org"; + +export const backfillUncreatedUserOrgs = async ( + overwriteUser: (User & { githubLogin: string }) | null, + ctx: GenericEndpointContext, +) => { + // This hook is used to backfill the user's organizations who signed up before the organizations were added. + if (ctx.path !== "/get-session") return; + const returned = + overwriteUser ?? + (ctx.context.returned as + | { session: Session; user: User & { githubLogin: string } } + | undefined); + if (!returned || !("session" in returned)) return; + if (!returned.user.githubLogin) return; + + const organization = await prisma.organization.findFirst({ + where: { + slug: returned.user.githubLogin, + }, + select: { + id: true, + }, + }); + if (!organization) { + await createDefaultOrganization(returned.user); + } +}; diff --git a/apps/web/src/lib/auth-hooks/create-default-user-org.ts b/apps/web/src/lib/auth-hooks/create-default-user-org.ts new file mode 100644 index 00000000..8c014e49 --- /dev/null +++ b/apps/web/src/lib/auth-hooks/create-default-user-org.ts @@ -0,0 +1,24 @@ +import type { User } from "better-auth"; +import { auth } from "../auth"; + +export async function createDefaultOrganization(_user: User) { + const user = _user as User & { + username: string; + githubLogin: string; + }; + if (!user.githubLogin) { + throw new Error("User has no github login"); + } + + await auth.api.createOrganization({ + body: { + name: user.githubLogin, + slug: user.githubLogin, + userId: user.id, + logo: user.image ?? undefined, + metadata: { + isUserOrganization: true, + }, + }, + }); +} diff --git a/apps/web/src/lib/auth.ts b/apps/web/src/lib/auth.ts index 0b4d3d6b..424fb97f 100644 --- a/apps/web/src/lib/auth.ts +++ b/apps/web/src/lib/auth.ts @@ -4,16 +4,21 @@ import { prisma } from "./db"; import { Octokit } from "@octokit/rest"; import { redis } from "./redis"; import { waitUntil } from "@vercel/functions"; +import { createAuthMiddleware } from "better-auth/api"; import { all } from "better-all"; import { headers } from "next/headers"; import { cache } from "react"; import { dash, sentinel } from "@better-auth/infra"; import { createHash } from "@better-auth/utils/hash"; -import { admin, oAuthProxy } from "better-auth/plugins"; +import { admin, bearer, deviceAuthorization, oAuthProxy, organization } from "better-auth/plugins"; import { stripe } from "@better-auth/stripe"; import { getStripeClient, isStripeEnabled } from "./billing/stripe"; import { grantSignupCredits } from "./billing/credit"; import { patSignIn } from "./auth-plugins/pat-signin"; +import { storagePlugin } from "@better-hub/storage/plugin"; +import { backfillGithubLogin } from "./auth-hooks/backfill-github-login"; +import { backfillUncreatedUserOrgs } from "./auth-hooks/backfill-uncreated-user-orgs"; +import { createDefaultOrganization } from "./auth-hooks/create-default-user-org"; async function getOctokitUser(token: string) { const cached = await redis.get>( @@ -35,59 +40,24 @@ export const auth = betterAuth({ experimental: { joins: true, }, - plugins: [ - dash({ - activityTracking: { - enabled: true, - }, - }), - sentinel(), - admin(), - patSignIn(), - ...(isStripeEnabled - ? [ - stripe({ - stripeClient: getStripeClient(), - stripeWebhookSecret: - process.env.STRIPE_WEBHOOK_SECRET!, - createCustomerOnSignUp: true, - onCustomerCreate: async ({ user }) => { - await grantSignupCredits(user.id); - }, - subscription: { - enabled: true, - plans: [ - { - name: "base", - priceId: process.env - .STRIPE_BASE_PRICE_ID!, - lineItems: [ - { - price: process - .env - .STRIPE_METERED_PRICE_ID!, - }, - ], - }, - ], - }, - }), - ] - : []), - ...(process.env.VERCEL - ? [oAuthProxy({ productionURL: "https://www.better-hub.com" })] - : []), - ], user: { additionalFields: { githubPat: { type: "string", required: false, }, + githubLogin: { + type: "string", + required: false, + }, onboardingDone: { type: "boolean", required: false, }, + aiMessageCount: { + type: "number", + required: false, + }, }, deleteUser: { enabled: true, @@ -133,6 +103,74 @@ export const auth = betterAuth({ ipAddressHeaders: ["x-vercel-forwarded-for", "x-forwarded-for"], }, }, + databaseHooks: { + user: { + create: { + after: async (user) => { + await createDefaultOrganization(user); + }, + }, + }, + }, + hooks: { + after: createAuthMiddleware(async (ctx) => { + // Could return an updated user obj from get-session + const result = await backfillGithubLogin(ctx); + await backfillUncreatedUserOrgs(result ?? null, ctx); + if (result) return result; + }), + }, + plugins: [ + dash({ + activityTracking: { + enabled: true, + }, + }), + sentinel(), + admin(), + organization(), + storagePlugin(), + patSignIn(), + bearer(), + deviceAuthorization(), + ...(isStripeEnabled + ? ([ + stripe({ + stripeClient: getStripeClient(), + stripeWebhookSecret: + process.env.STRIPE_WEBHOOK_SECRET!, + createCustomerOnSignUp: true, + onCustomerCreate: async ({ user }) => { + await grantSignupCredits(user.id); + }, + subscription: { + enabled: true, + plans: [ + { + name: "base", + priceId: process.env + .STRIPE_BASE_PRICE_ID!, + lineItems: [ + { + price: process + .env + .STRIPE_METERED_PRICE_ID!, + }, + ], + }, + ], + }, + }), + ] as unknown as []) + : []), + ...(process.env.VERCEL + ? [ + oAuthProxy({ + productionURL: "https://www.better-hub.com", + }), + ] + : []), + ], }); export const getServerSession = cache(async () => { diff --git a/bun.lock b/bun.lock index ead148c8..04653a9f 100644 --- a/bun.lock +++ b/bun.lock @@ -52,7 +52,7 @@ "ai": "^6.0.97", "auth": "1.5.0-beta.18", "better-all": "^0.0.7", - "better-auth": "1.5.1", + "better-auth": "catalog:", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -98,6 +98,40 @@ "tailwindcss": "^4", }, }, + "packages/cli": { + "name": "@better-hub/cli", + "version": "0.1.0", + "bin": { + "bh": "dist/index.js", + }, + "dependencies": { + "@clack/prompts": "^1.1.0", + "better-auth": "catalog:", + "commander": "^13.1.0", + "fzf": "^0.5.2", + "open": "^11.0.0", + "picocolors": "^1.1.1", + }, + "devDependencies": { + "@types/node": "^25.3.0", + }, + }, + "packages/storage": { + "name": "@better-hub/storage", + "version": "0.1.0", + "dependencies": { + "@pierre/storage": "^1.3.2", + "better-auth": "catalog:", + "zod": "^4.3.6", + }, + "devDependencies": { + "@types/node": "^25.3.0", + "tsdown": "latest", + }, + }, + }, + "catalog": { + "better-auth": "^1.5.5", }, "packages": { "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.51", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.16" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZQ3UE4KpKFBe6Vr1mJu6QwUxlnwwJNGrnxGpW1eFj9CA3hmDVT3XVeevCWps4R+c1YT4GZig6IjJgFmwLeWlFQ=="], @@ -206,7 +240,7 @@ "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="], - "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], + "@babel/generator": ["@babel/generator@8.0.0-rc.2", "", { "dependencies": { "@babel/parser": "^8.0.0-rc.2", "@babel/types": "^8.0.0-rc.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "@types/jsesc": "^2.5.0", "jsesc": "^3.0.2" } }, "sha512-oCQ1IKPwkzCeJzAPb7Fv8rQ9k5+1sG8mf2uoHiMInPYvkRfrDJxbTIbH51U+jstlkghus0vAi3EBvkfvEsYNLQ=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], @@ -232,13 +266,13 @@ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@8.0.0-rc.2", "", {}, "sha512-xExUBkuXWJjVuIbO7z6q7/BA9bgfJDEhVL0ggrggLMbg0IzCUWGT1hZGE8qUH7Il7/RD/a6cZ3AAFrrlp1LF/A=="], "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], - "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + "@babel/parser": ["@babel/parser@8.0.0-rc.2", "", { "dependencies": { "@babel/types": "^8.0.0-rc.2" }, "bin": "./bin/babel-parser.js" }, "sha512-29AhEtcq4x8Dp3T72qvUMZHx0OMXCj4Jy/TEReQa+KWLln524Cj1fWb3QFi0l/xSpptQBR6y9RNEXuxpFvwiUQ=="], "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], @@ -266,30 +300,34 @@ "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], - "@better-auth/core": ["@better-auth/core@1.5.0-beta.18", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-bwR8uH10PiEK6lQhmF37VzUc+bmY79KKHd0UGuM4Bi5INEivYCZjpI2pKUB+aVgnxKjovpbUYjoB+NpuwTXK0A=="], + "@better-auth/core": ["@better-auth/core@1.5.5", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-1oR/2jAp821Dcf67kQYHUoyNcdc1TcShfw4QMK0YTVntuRES5mUOyvEJql5T6eIuLfaqaN4LOF78l0FtF66HXA=="], - "@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" } }, "sha512-0KKIpDTi1IWXVHL//H8w0S8oQ9KjdlE5YgN9mMloMbU1uyxZ0shhUiT8mC9025vwkZ7OXLywI2hFeGJ+mcdRBQ=="], + "@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.5", "", { "peerDependencies": { "@better-auth/core": "1.5.5", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" }, "optionalPeers": ["drizzle-orm"] }, "sha512-HAi9xAP40oDt48QZeYBFTcmg3vt1Jik90GwoRIfangd7VGbxesIIDBJSnvwMbZ52GBIc6+V4FRw9lasNiNrPfw=="], "@better-auth/infra": ["@better-auth/infra@0.1.9-beta.1", "", { "dependencies": { "@better-fetch/fetch": "^1.1.21", "better-call": "^1.3.3", "jose": "^6.1.0", "libphonenumber-js": "^1.12.36" }, "peerDependencies": { "@better-auth/core": ">=1.4.0", "@better-auth/sso": ">=1.4.0", "better-auth": ">=1.4.0", "zod": ">=4.1.12" } }, "sha512-atEjhVjwoTVEjmVJUh88cefBrmuXHrp+6UX3rPhyFNCUYKwXszcZ4NpymgldfldhAk++O41HhEzfUYIiybYh9Q=="], - "@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "kysely": "^0.27.0 || ^0.28.0" } }, "sha512-OuhmNKjxpHlSw214kww4/tGfLHjtyC/HzN6Q/HulUeRF5QyCCHqj0y44ba6WGj3hcGsvPUkdUk4SayKXCrUCFw=="], + "@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.5.5", "", { "peerDependencies": { "@better-auth/core": "1.5.5", "@better-auth/utils": "^0.3.0", "kysely": "^0.27.0 || ^0.28.0" } }, "sha512-LmHffIVnqbfsxcxckMOoE8MwibWrbVFch+kwPKJ5OFDFv6lin75ufN7ZZ7twH0IMPLT/FcgzaRjP8jRrXRef9g=="], - "@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0" } }, "sha512-FSacaykLJXEizbnShF2FWZtWk5j0f87iq5Esjfd/7XHcF9nZeXn9Ju8jItDKeOWbEasOdfErEBqWSn30hmueRQ=="], + "@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.5.5", "", { "peerDependencies": { "@better-auth/core": "1.5.5", "@better-auth/utils": "^0.3.0" } }, "sha512-4X0j1/2L+nsgmObjmy9xEGUFWUv38Qjthp558fwS3DAp6ueWWyCaxaD6VJZ7m5qPNMrsBStO5WGP8CmJTEWm7g=="], - "@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "mongodb": "^6.0.0 || ^7.0.0" } }, "sha512-BrbVuH1cqjs86Z6ae8OFEbvNLNxibddU4hDApVNtJcz7a/BaUPUdIM1Ep7HFhDozK7DrODXWZGLFXk+yV2pt3g=="], + "@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.5.5", "", { "peerDependencies": { "@better-auth/core": "1.5.5", "@better-auth/utils": "^0.3.0", "mongodb": "^6.0.0 || ^7.0.0" } }, "sha512-P1J9ljL5X5k740I8Rx1esPWNgWYPdJR5hf2CY7BwDSrQFPUHuzeCg0YhtEEP55niNateTXhBqGAcy0fVOeamZg=="], - "@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.1", "", { "dependencies": { "@prisma/client": "^7.4.1" }, "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-24kBkBVaQbLnGe3/V/H+nX0hYaI+wNZFJhMnK16GQV7g6LyQw7UOcsd1xPDKtC61JCDmXEEEqXfnyuw5QITMVw=="], + "@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.5", "", { "peerDependencies": { "@better-auth/core": "1.5.5", "@better-auth/utils": "^0.3.0", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@prisma/client", "prisma"] }, "sha512-CliDd78CXHzzwQIXhCdwGr5Ml53i6JdCHWV7PYwTIJz9EAm6qb2RVBdpP3nqEfNjINGM22A6gfleCgCdZkTIZg=="], "@better-auth/sso": ["@better-auth/sso@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "fast-xml-parser": "^5.4.1", "jose": "^6.1.3", "samlify": "^2.10.2", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/core": "1.5.1", "better-auth": "1.5.1", "better-call": "1.3.2" } }, "sha512-c6xO8+eaKZ7kUCrazpbjSZGIUxDrjmdB+WIXFWeWi5kXCbWe2nl39j1kCwkiudFs0nmPKjtFGGNGNbJoleXiag=="], "@better-auth/stripe": ["@better-auth/stripe@1.5.1", "", { "dependencies": { "defu": "^6.1.4", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/core": "1.5.1", "better-auth": "1.5.1", "better-call": "1.3.2", "stripe": "^18 || ^19 || ^20" } }, "sha512-YOOJ5pxtJ7EB7qf0TRegAUqI1AFL9SiONJiLqAwqBOpRquKbiOnypEOenNCuRBeK8NktURdcbQoT0rIeD7nVkQ=="], - "@better-auth/telemetry": ["@better-auth/telemetry@1.5.0-beta.16", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.0-beta.16" } }, "sha512-EiNe7xSQkuypvR9i/C10M/DhoLyba+Ptdeczrj1z8Z+2/bP65utkwQ/Vq0j0zw7K8IgRp7CuMtrDa4j8Fp08Xw=="], + "@better-auth/telemetry": ["@better-auth/telemetry@1.5.5", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.5" } }, "sha512-1+lklxArn4IMHuU503RcPdXrSG2tlXt4jnGG3omolmspQ7tktg/Y9XO/yAkYDurtvMn1xJ8X1Ov01Ji/r5s9BQ=="], "@better-auth/utils": ["@better-auth/utils@0.3.1", "", {}, "sha512-+CGp4UmZSUrHHnpHhLPYu6cV+wSUSvVbZbNykxhUDocpVNTo9uFFxw/NqJlh1iC4wQ9HKKWGCKuZ5wUgS0v6Kg=="], "@better-fetch/fetch": ["@better-fetch/fetch@1.1.21", "", {}, "sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A=="], + "@better-hub/cli": ["@better-hub/cli@workspace:packages/cli"], + + "@better-hub/storage": ["@better-hub/storage@workspace:packages/storage"], + "@better-hub/web": ["@better-hub/web@workspace:apps/web"], "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], @@ -304,9 +342,9 @@ "@chevrotain/utils": ["@chevrotain/utils@10.5.0", "", {}, "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ=="], - "@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="], + "@clack/core": ["@clack/core@1.1.0", "", { "dependencies": { "sisteransi": "^1.0.5" } }, "sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA=="], - "@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], + "@clack/prompts": ["@clack/prompts@1.1.0", "", { "dependencies": { "@clack/core": "1.1.0", "sisteransi": "^1.0.5" } }, "sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g=="], "@connectrpc/connect": ["@connectrpc/connect@2.0.0-rc.3", "", { "peerDependencies": { "@bufbuild/protobuf": "^2.2.0" } }, "sha512-ARBt64yEyKbanyRETTjcjJuHr2YXorzQo0etyS5+P6oSeW8xEuzajA9g+zDnMcj1hlX2dQE93foIWQGfpru7gQ=="], @@ -704,7 +742,7 @@ "@opentelemetry/sql-common": ["@opentelemetry/sql-common@0.41.2", "", { "dependencies": { "@opentelemetry/core": "^2.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0" } }, "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ=="], - "@oxc-project/types": ["@oxc-project/types@0.110.0", "", {}, "sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow=="], + "@oxc-project/types": ["@oxc-project/types@0.115.0", "", {}, "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw=="], "@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.111.0", "", { "os": "android", "cpu": "arm" }, "sha512-NdFLicvorfHYu0g2ftjVJaH7+Dz27AQUNJOq8t/ofRUoWmczOodgUCHx8C1M1htCN4ZmhS/FzfSy6yd/UngJGg=="], @@ -872,6 +910,8 @@ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], + "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="], + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], @@ -998,33 +1038,37 @@ "@renovatebot/pep440": ["@renovatebot/pep440@4.2.1", "", {}, "sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.1", "", { "os": "android", "cpu": "arm64" }, "sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.9", "", { "os": "android", "cpu": "arm64" }, "sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm" }, "sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm" }, "sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "x64" }, "sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.9", "", { "os": "linux", "cpu": "x64" }, "sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.1", "", { "os": "none", "cpu": "arm64" }, "sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.9", "", { "os": "none", "cpu": "arm64" }, "sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.9", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.9", "", { "os": "win32", "cpu": "x64" }, "sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.1", "", {}, "sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.9", "", {}, "sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw=="], "@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA=="], @@ -1388,6 +1432,8 @@ "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + "@types/jsesc": ["@types/jsesc@2.5.1", "", {}, "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], "@types/linkify-it": ["@types/linkify-it@3.0.5", "", {}, "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="], @@ -1572,6 +1618,8 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], "arg": ["arg@4.1.0", "", {}, "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg=="], @@ -1584,6 +1632,8 @@ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "ast-kit": ["ast-kit@3.0.0-beta.1", "", { "dependencies": { "@babel/parser": "^8.0.0-beta.4", "estree-walker": "^3.0.3", "pathe": "^2.0.3" } }, "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw=="], + "ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], "async-listen": ["async-listen@3.0.0", "", {}, "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg=="], @@ -1612,9 +1662,9 @@ "better-all": ["better-all@0.0.7", "", {}, "sha512-xgdUMWb88Qhz6RtC/PY/7QtR61K/JabCcbKhNYYuXC/IoY3c/bgYdIjVxyTHXR41KP8JQeP+6dg4zH4KOpwJzw=="], - "better-auth": ["better-auth@1.5.1", "", { "dependencies": { "@better-auth/core": "1.5.1", "@better-auth/drizzle-adapter": "1.5.1", "@better-auth/kysely-adapter": "1.5.1", "@better-auth/memory-adapter": "1.5.1", "@better-auth/mongo-adapter": "1.5.1", "@better-auth/prisma-adapter": "1.5.1", "@better-auth/telemetry": "1.5.1", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-Hnr4Ar49WpC0wyHFKYA86eQL5HhN5sNhtNquHrsH0T0r/IDqxDxAfW1VdSnTaXv4zc2WCXCQ8b1+InAopR2hAw=="], + "better-auth": ["better-auth@1.5.5", "", { "dependencies": { "@better-auth/core": "1.5.5", "@better-auth/drizzle-adapter": "1.5.5", "@better-auth/kysely-adapter": "1.5.5", "@better-auth/memory-adapter": "1.5.5", "@better-auth/mongo-adapter": "1.5.5", "@better-auth/prisma-adapter": "1.5.5", "@better-auth/telemetry": "1.5.5", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-GpVPaV1eqr3mOovKfghJXXk6QvlcVeFbS3z+n+FPDid5rK/2PchnDtiaVCzWyXA9jH2KkirOfl+JhAUvnja0Eg=="], - "better-call": ["better-call@1.3.3", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-7IhuPAdH2m1z7ILNiH5DrIkLkA0vvMM8Q3cfqveiglA1p/Ad8yNDOSYMQ4h/rNounLcsJf2GoZemRKLHxE7E5A=="], + "better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], "bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], @@ -1622,6 +1672,8 @@ "bippy": ["bippy@0.5.30", "", { "dependencies": { "@types/react-reconciler": "^0.28.9" }, "peerDependencies": { "react": ">=17.0.1" } }, "sha512-8CFmJAHD3gmTLDOCDHuWhjm1nxHSFZdlGoWtak9r53Uxn36ynOjxBLyxXHh/7h/XiKLyPvfdXa0gXWcD9o9lLQ=="], + "birpc": ["birpc@4.0.0", "", {}, "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw=="], + "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], "brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], @@ -1642,6 +1694,8 @@ "c12": ["c12@3.3.3", "", { "dependencies": { "chokidar": "^5.0.0", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^17.2.3", "exsolve": "^1.0.8", "giget": "^2.0.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q=="], + "cac": ["cac@7.0.0", "", {}, "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ=="], + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], @@ -1708,7 +1762,7 @@ "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], "commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="], @@ -1776,6 +1830,8 @@ "drizzle-orm": ["drizzle-orm@0.41.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q=="], + "dts-resolver": ["dts-resolver@2.1.3", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "e2b": ["e2b@2.13.0", "", { "dependencies": { "@bufbuild/protobuf": "^2.6.2", "@connectrpc/connect": "2.0.0-rc.3", "@connectrpc/connect-web": "2.0.0-rc.3", "chalk": "^5.3.0", "compare-versions": "^6.1.0", "dockerfile-ast": "^0.7.1", "glob": "^11.1.0", "openapi-fetch": "^0.14.1", "platform": "^1.3.6", "tar": "^7.5.4" } }, "sha512-tYsRDXKx47WoV0lVHZxg1uGlSGC2+085Vy+LMxAnnw96vCQm0lBIKPaxV59xDkQZp4yI9/vgZtd2NzNNnoQPTg=="], @@ -1900,6 +1956,8 @@ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + "fzf": ["fzf@0.5.2", "", {}, "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q=="], + "gaxios": ["gaxios@7.1.4", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2" } }, "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA=="], "gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="], @@ -1974,6 +2032,8 @@ "hono": ["hono@4.11.4", "", {}, "sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA=="], + "hookable": ["hookable@6.1.0", "", {}, "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw=="], + "html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="], "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], @@ -1994,6 +2054,8 @@ "import-in-the-middle": ["import-in-the-middle@2.0.6", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw=="], + "import-without-cache": ["import-without-cache@0.2.5", "", {}, "sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A=="], + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], @@ -2022,6 +2084,8 @@ "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="], + "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], @@ -2342,7 +2406,7 @@ "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], - "open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], + "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], "openapi-fetch": ["openapi-fetch@0.14.1", "", { "dependencies": { "openapi-typescript-helpers": "^0.0.15" } }, "sha512-l7RarRHxlEZYjMLd/PR0slfMVse2/vvIAGm75/F7J6MlQ8/b9uUQmUF2kCPrQhJqMXSxmYWObVgeYXbFYzZR+A=="], @@ -2438,6 +2502,8 @@ "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], + "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], "pretty-ms": ["pretty-ms@7.0.1", "", { "dependencies": { "parse-ms": "^2.1.0" } }, "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q=="], @@ -2506,6 +2572,8 @@ "qs": ["qs@6.11.2", "", { "dependencies": { "side-channel": "^1.0.4" } }, "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA=="], + "quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "radix-ui": ["radix-ui@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="], @@ -2578,7 +2646,9 @@ "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], - "rolldown": ["rolldown@1.0.0-rc.1", "", { "dependencies": { "@oxc-project/types": "=0.110.0", "@rolldown/pluginutils": "1.0.0-rc.1" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-x64": "1.0.0-rc.1", "@rolldown/binding-freebsd-x64": "1.0.0-rc.1", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.1", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.1", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.1", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.1", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.1", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.1" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg=="], + "rolldown": ["rolldown@1.0.0-rc.9", "", { "dependencies": { "@oxc-project/types": "=0.115.0", "@rolldown/pluginutils": "1.0.0-rc.9" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.9", "@rolldown/binding-darwin-arm64": "1.0.0-rc.9", "@rolldown/binding-darwin-x64": "1.0.0-rc.9", "@rolldown/binding-freebsd-x64": "1.0.0-rc.9", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.9", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.9", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.9", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.9", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.9", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.9", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.9" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q=="], + + "rolldown-plugin-dts": ["rolldown-plugin-dts@0.22.5", "", { "dependencies": { "@babel/generator": "8.0.0-rc.2", "@babel/helper-validator-identifier": "8.0.0-rc.2", "@babel/parser": "8.0.0-rc.2", "@babel/types": "8.0.0-rc.2", "ast-kit": "^3.0.0-beta.1", "birpc": "^4.0.0", "dts-resolver": "^2.1.3", "get-tsconfig": "^4.13.6", "obug": "^2.1.1" }, "peerDependencies": { "@ts-macro/tsc": "^0.3.6", "@typescript/native-preview": ">=7.0.0-dev.20250601.1", "rolldown": "^1.0.0-rc.3", "typescript": "^5.0.0 || ^6.0.0-beta", "vue-tsc": "~3.2.0" }, "optionalPeers": ["@ts-macro/tsc", "@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-M/HXfM4cboo+jONx9Z0X+CUf3B5tCi7ni+kR5fUW50Fp9AlZk0oVLesibGWgCXDKFp5lpgQ9yhKoImUFjl3VZw=="], "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], @@ -2764,6 +2834,8 @@ "ts-toolbelt": ["ts-toolbelt@6.15.5", "", {}, "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A=="], + "tsdown": ["tsdown@0.21.2", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.4", "empathic": "^2.0.0", "hookable": "^6.0.1", "import-without-cache": "^0.2.5", "obug": "^2.1.1", "picomatch": "^4.0.3", "rolldown": "1.0.0-rc.9", "rolldown-plugin-dts": "^0.22.5", "semver": "^7.7.4", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0", "unrun": "^0.2.32" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.2", "@tsdown/exe": "0.21.2", "@vitejs/devtools": "*", "publint": "^0.3.0", "typescript": "^5.0.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "typescript", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-pP8eAcd1XAWjl5gjosuJs0BAuVoheUe3V8VDHx31QK7YOgXjcCMsBSyFWO3CMh/CSUkjRUzR96JtGH3WJFTExQ=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], @@ -2780,6 +2852,8 @@ "ulid": ["ulid@2.4.0", "", { "bin": { "ulid": "bin/cli.js" } }, "sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg=="], + "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="], + "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], "undici": ["undici@5.28.4", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g=="], @@ -2804,6 +2878,8 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + "unrun": ["unrun@0.2.32", "", { "dependencies": { "rolldown": "1.0.0-rc.9" }, "peerDependencies": { "synckit": "^0.11.11" }, "optionalPeers": ["synckit"], "bin": { "unrun": "dist/cli.mjs" } }, "sha512-opd3z6791rf281JdByf0RdRQrpcc7WyzqittqIXodM/5meNWdTwrVxeyzbaCp4/Rgls/um14oUaif1gomO8YGg=="], + "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], @@ -2862,7 +2938,7 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], + "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], "xdg-app-paths": ["xdg-app-paths@5.1.0", "", { "dependencies": { "xdg-portable": "^7.0.0" } }, "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA=="], @@ -2916,33 +2992,43 @@ "@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + "@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/core/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], + + "@babel/core/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/generator/@babel/types": ["@babel/types@8.0.0-rc.2", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.2", "@babel/helper-validator-identifier": "^8.0.0-rc.2" } }, "sha512-91gAaWRznDwSX4E2tZ1YjBuIfnQVOFDCQ2r0Toby0gu4XEbyF623kXLMA8d4ZbCu+fINcrudkmEcwSUHgDDkNw=="], + "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@babel/helper-module-transforms/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - "@better-auth/drizzle-adapter/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@babel/parser/@babel/types": ["@babel/types@8.0.0-rc.2", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.2", "@babel/helper-validator-identifier": "^8.0.0-rc.2" } }, "sha512-91gAaWRznDwSX4E2tZ1YjBuIfnQVOFDCQ2r0Toby0gu4XEbyF623kXLMA8d4ZbCu+fINcrudkmEcwSUHgDDkNw=="], - "@better-auth/kysely-adapter/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@babel/template/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], - "@better-auth/memory-adapter/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@babel/traverse/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], - "@better-auth/mongo-adapter/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@babel/traverse/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], - "@better-auth/prisma-adapter/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - "@better-auth/sso/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/infra/better-call": ["better-call@1.3.3", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-7IhuPAdH2m1z7ILNiH5DrIkLkA0vvMM8Q3cfqveiglA1p/Ad8yNDOSYMQ4h/rNounLcsJf2GoZemRKLHxE7E5A=="], - "@better-auth/stripe/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + "@better-auth/sso/@better-auth/core": ["@better-auth/core@1.5.0-beta.18", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-bwR8uH10PiEK6lQhmF37VzUc+bmY79KKHd0UGuM4Bi5INEivYCZjpI2pKUB+aVgnxKjovpbUYjoB+NpuwTXK0A=="], + + "@better-auth/sso/better-auth": ["better-auth@1.5.1", "", { "dependencies": { "@better-auth/core": "1.5.1", "@better-auth/drizzle-adapter": "1.5.1", "@better-auth/kysely-adapter": "1.5.1", "@better-auth/memory-adapter": "1.5.1", "@better-auth/mongo-adapter": "1.5.1", "@better-auth/prisma-adapter": "1.5.1", "@better-auth/telemetry": "1.5.1", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-Hnr4Ar49WpC0wyHFKYA86eQL5HhN5sNhtNquHrsH0T0r/IDqxDxAfW1VdSnTaXv4zc2WCXCQ8b1+InAopR2hAw=="], - "@better-auth/stripe/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/stripe/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], - "@better-auth/telemetry/@better-auth/core": ["@better-auth/core@1.5.0-beta.16", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-eGM4Q2Btj6WNh/9jGTUIFsvFPt4kUsRa9/3tDSPfY/M3OkCUFkscANTeq/AVyJkBMO/IG2pQ8F48Hy1CBn7eyw=="], + "@better-auth/stripe/better-auth": ["better-auth@1.5.1", "", { "dependencies": { "@better-auth/core": "1.5.1", "@better-auth/drizzle-adapter": "1.5.1", "@better-auth/kysely-adapter": "1.5.1", "@better-auth/memory-adapter": "1.5.1", "@better-auth/mongo-adapter": "1.5.1", "@better-auth/prisma-adapter": "1.5.1", "@better-auth/telemetry": "1.5.1", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-Hnr4Ar49WpC0wyHFKYA86eQL5HhN5sNhtNquHrsH0T0r/IDqxDxAfW1VdSnTaXv4zc2WCXCQ8b1+InAopR2hAw=="], "@fastify/otel/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA=="], @@ -3212,6 +3298,8 @@ "@radix-ui/react-tooltip/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], + "@react-grab/cli/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "@sentry/bundler-plugin-core/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], "@sentry/bundler-plugin-core/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], @@ -3240,6 +3328,8 @@ "@vercel/backends/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], + "@vercel/backends/rolldown": ["rolldown@1.0.0-rc.1", "", { "dependencies": { "@oxc-project/types": "=0.110.0", "@rolldown/pluginutils": "1.0.0-rc.1" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-x64": "1.0.0-rc.1", "@rolldown/binding-freebsd-x64": "1.0.0-rc.1", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.1", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.1", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.1", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.1", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.1", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.1" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg=="], + "@vercel/backends/zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="], "@vercel/blob/undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], @@ -3294,21 +3384,23 @@ "ajv-keywords/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "ast-kit/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + "async-retry/retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="], "auth/@better-auth/core": ["@better-auth/core@1.5.0-beta.16", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-eGM4Q2Btj6WNh/9jGTUIFsvFPt4kUsRa9/3tDSPfY/M3OkCUFkscANTeq/AVyJkBMO/IG2pQ8F48Hy1CBn7eyw=="], + "auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.0-beta.16", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.0-beta.16" } }, "sha512-EiNe7xSQkuypvR9i/C10M/DhoLyba+Ptdeczrj1z8Z+2/bP65utkwQ/Vq0j0zw7K8IgRp7CuMtrDa4j8Fp08Xw=="], + + "auth/@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], + "auth/@prisma/client": ["@prisma/client@5.22.0", "", { "peerDependencies": { "prisma": "*" }, "optionalPeers": ["prisma"] }, "sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA=="], "auth/better-auth": ["better-auth@1.5.0-beta.16", "", { "dependencies": { "@better-auth/core": "1.5.0-beta.16", "@better-auth/drizzle-adapter": "1.5.0-beta.16", "@better-auth/kysely-adapter": "1.5.0-beta.16", "@better-auth/memory-adapter": "1.5.0-beta.16", "@better-auth/mongo-adapter": "1.5.0-beta.16", "@better-auth/prisma-adapter": "1.5.0-beta.16", "@better-auth/telemetry": "1.5.0-beta.16", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.0", "kysely": "^0.28.10", "nanostores": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-hkpcNioqkgYs9MNRiK9fD/l8gaiFhODpf8U58v5efTZ2HrXbTfiWKfM2KxcOyFeF2SNdqal+cn762a0ym/3WGA=="], "auth/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], - "better-auth/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], - - "better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.1" } }, "sha512-bHn9sdmf1bWUiC75J8FIF3rAEnL5ICihY5IBoXKVwxemaB3jSXL/sG9OpmadapPXlC8BY2OuATxdg39qbg+JlA=="], - - "better-auth/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], @@ -3340,6 +3432,8 @@ "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + "lint-staged/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], "log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], @@ -3388,6 +3482,8 @@ "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + "rolldown-plugin-dts/@babel/types": ["@babel/types@8.0.0-rc.2", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.2", "@babel/helper-validator-identifier": "^8.0.0-rc.2" } }, "sha512-91gAaWRznDwSX4E2tZ1YjBuIfnQVOFDCQ2r0Toby0gu4XEbyF623kXLMA8d4ZbCu+fINcrudkmEcwSUHgDDkNw=="], + "samlify/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], "schema-utils/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], @@ -3420,19 +3516,37 @@ "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + "@babel/generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.2", "", {}, "sha512-noLx87RwlBEMrTzncWd/FvTxoJ9+ycHNg0n8yyYydIoDsLZuxknKgWRJUqcrVkNrJ74uGyhWQzQaS3q8xfGAhQ=="], + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "@better-auth/drizzle-adapter/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.2", "", {}, "sha512-noLx87RwlBEMrTzncWd/FvTxoJ9+ycHNg0n8yyYydIoDsLZuxknKgWRJUqcrVkNrJ74uGyhWQzQaS3q8xfGAhQ=="], + + "@better-auth/sso/better-auth/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], + + "@better-auth/sso/better-auth/@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" } }, "sha512-0KKIpDTi1IWXVHL//H8w0S8oQ9KjdlE5YgN9mMloMbU1uyxZ0shhUiT8mC9025vwkZ7OXLywI2hFeGJ+mcdRBQ=="], + + "@better-auth/sso/better-auth/@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "kysely": "^0.27.0 || ^0.28.0" } }, "sha512-OuhmNKjxpHlSw214kww4/tGfLHjtyC/HzN6Q/HulUeRF5QyCCHqj0y44ba6WGj3hcGsvPUkdUk4SayKXCrUCFw=="], + + "@better-auth/sso/better-auth/@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0" } }, "sha512-FSacaykLJXEizbnShF2FWZtWk5j0f87iq5Esjfd/7XHcF9nZeXn9Ju8jItDKeOWbEasOdfErEBqWSn30hmueRQ=="], - "@better-auth/kysely-adapter/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/sso/better-auth/@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "mongodb": "^6.0.0 || ^7.0.0" } }, "sha512-BrbVuH1cqjs86Z6ae8OFEbvNLNxibddU4hDApVNtJcz7a/BaUPUdIM1Ep7HFhDozK7DrODXWZGLFXk+yV2pt3g=="], - "@better-auth/memory-adapter/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/sso/better-auth/@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.1", "", { "dependencies": { "@prisma/client": "^7.4.1" }, "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-24kBkBVaQbLnGe3/V/H+nX0hYaI+wNZFJhMnK16GQV7g6LyQw7UOcsd1xPDKtC61JCDmXEEEqXfnyuw5QITMVw=="], - "@better-auth/mongo-adapter/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/sso/better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.1" } }, "sha512-bHn9sdmf1bWUiC75J8FIF3rAEnL5ICihY5IBoXKVwxemaB3jSXL/sG9OpmadapPXlC8BY2OuATxdg39qbg+JlA=="], - "@better-auth/prisma-adapter/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/stripe/better-auth/@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" } }, "sha512-0KKIpDTi1IWXVHL//H8w0S8oQ9KjdlE5YgN9mMloMbU1uyxZ0shhUiT8mC9025vwkZ7OXLywI2hFeGJ+mcdRBQ=="], - "@better-auth/telemetry/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "@better-auth/stripe/better-auth/@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "kysely": "^0.27.0 || ^0.28.0" } }, "sha512-OuhmNKjxpHlSw214kww4/tGfLHjtyC/HzN6Q/HulUeRF5QyCCHqj0y44ba6WGj3hcGsvPUkdUk4SayKXCrUCFw=="], + + "@better-auth/stripe/better-auth/@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0" } }, "sha512-FSacaykLJXEizbnShF2FWZtWk5j0f87iq5Esjfd/7XHcF9nZeXn9Ju8jItDKeOWbEasOdfErEBqWSn30hmueRQ=="], + + "@better-auth/stripe/better-auth/@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "mongodb": "^6.0.0 || ^7.0.0" } }, "sha512-BrbVuH1cqjs86Z6ae8OFEbvNLNxibddU4hDApVNtJcz7a/BaUPUdIM1Ep7HFhDozK7DrODXWZGLFXk+yV2pt3g=="], + + "@better-auth/stripe/better-auth/@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.1", "", { "dependencies": { "@prisma/client": "^7.4.1" }, "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-24kBkBVaQbLnGe3/V/H+nX0hYaI+wNZFJhMnK16GQV7g6LyQw7UOcsd1xPDKtC61JCDmXEEEqXfnyuw5QITMVw=="], + + "@better-auth/stripe/better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.1" } }, "sha512-bHn9sdmf1bWUiC75J8FIF3rAEnL5ICihY5IBoXKVwxemaB3jSXL/sG9OpmadapPXlC8BY2OuATxdg39qbg+JlA=="], "@fastify/otel/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="], @@ -3568,6 +3682,36 @@ "@vercel/backends/@vercel/nft/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + "@vercel/backends/rolldown/@oxc-project/types": ["@oxc-project/types@0.110.0", "", {}, "sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow=="], + + "@vercel/backends/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.1", "", { "os": "android", "cpu": "arm64" }, "sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA=="], + + "@vercel/backends/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg=="], + + "@vercel/backends/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ=="], + + "@vercel/backends/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog=="], + + "@vercel/backends/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm" }, "sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q=="], + + "@vercel/backends/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g=="], + + "@vercel/backends/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw=="], + + "@vercel/backends/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A=="], + + "@vercel/backends/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg=="], + + "@vercel/backends/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.1", "", { "os": "none", "cpu": "arm64" }, "sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg=="], + + "@vercel/backends/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw=="], + + "@vercel/backends/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g=="], + + "@vercel/backends/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A=="], + + "@vercel/backends/rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.1", "", {}, "sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA=="], + "@vercel/fun/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], "@vercel/fun/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], @@ -3580,7 +3724,7 @@ "@vercel/rust/execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - "auth/@better-auth/core/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "auth/@clack/prompts/@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="], "auth/better-auth/@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.0-beta.16", "", { "peerDependencies": { "@better-auth/core": "1.5.0-beta.16", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" } }, "sha512-ArM+7rWepLN7kFXIDmkV9CFBblBhfwOVIzPJgv7ZaWnAsjGj5oLhSkBQXvAfw0W/2UK1yziSuD4/HqiqKuEl7Q=="], @@ -3592,7 +3736,7 @@ "auth/better-auth/@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.0-beta.16", "", { "dependencies": { "@prisma/client": "^5.0.0" }, "peerDependencies": { "@better-auth/core": "1.5.0-beta.16", "@better-auth/utils": "^0.3.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-5xBsHd1LIhtIZGJ6D1m7GRKQ15pN1cX0N4yTY5BTvssmqGBUu2mKNmgcERESoENO5VAGpmd6Gky+nG/9hvH4vQ=="], - "auth/better-auth/better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], + "auth/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], @@ -3618,6 +3762,8 @@ "prosemirror-markdown/@types/markdown-it/@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + "rolldown-plugin-dts/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.2", "", {}, "sha512-noLx87RwlBEMrTzncWd/FvTxoJ9+ycHNg0n8yyYydIoDsLZuxknKgWRJUqcrVkNrJ74uGyhWQzQaS3q8xfGAhQ=="], + "string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], diff --git a/package.json b/package.json index 886407a8..0bab4338 100644 --- a/package.json +++ b/package.json @@ -57,5 +57,8 @@ "oxfmt --write" ] }, - "packageManager": "bun@1.3.5" + "packageManager": "bun@1.3.5", + "catalog": { + "better-auth": "^1.5.5" + } } diff --git a/packages/cli/package.json b/packages/cli/package.json new file mode 100644 index 00000000..8dd87d24 --- /dev/null +++ b/packages/cli/package.json @@ -0,0 +1,34 @@ +{ + "name": "@better-hub/cli", + "version": "0.1.0", + "description": "CLI for Better Hub — manage repos, auth, and more from your terminal", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/better-auth/better-hub.git", + "directory": "packages/cli" + }, + "bin": { + "bh": "dist/index.js" + }, + "files": [ + "dist" + ], + "type": "module", + "scripts": { + "dev": "bun run --watch src/index.ts --", + "build": "bun build src/index.ts --outdir dist --target node --format esm", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@clack/prompts": "^1.1.0", + "better-auth": "catalog:", + "commander": "^13.1.0", + "fzf": "^0.5.2", + "open": "^11.0.0", + "picocolors": "^1.1.1" + }, + "devDependencies": { + "@types/node": "^25.3.0" + } +} diff --git a/packages/cli/src/commands/auth.ts b/packages/cli/src/commands/auth.ts new file mode 100644 index 00000000..a8affa38 --- /dev/null +++ b/packages/cli/src/commands/auth.ts @@ -0,0 +1,135 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import { clearAuth, getBaseUrl, getToken, setAuth } from "../lib/config.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { deviceAuthFlow } from "../lib/device-auth.js"; +import { spinner } from "../lib/spinner.js"; + +export const authCommand = new Command("auth").description("Manage authentication"); + +authCommand + .command("login") + .description("Sign in to Better Hub via device authorization") + .option("-t, --token ", "Authenticate with a token directly (skips device flow)") + .action(async (opts: { token?: string }) => { + let token: string; + + if (opts.token) { + token = opts.token; + } else { + try { + token = await deviceAuthFlow(); + } catch (err) { + console.log( + ` ${pc.dim(err instanceof Error ? err.message : String(err))}`, + ); + console.log(); + process.exit(1); + } + } + + setAuth(token); + + const s = spinner("Verifying session..."); + try { + const client = getAuthClient(); + const { data } = await client.getSession(); + if (!data?.user) throw new Error("No session"); + + s.stop(` ${pc.green("✓")} Logged in as ${pc.bold(data.user.name)}`); + console.log(); + } catch { + s.stop( + ` ${pc.red("✗")} Token is invalid or session could not be verified.`, + ); + clearAuth(); + console.log(); + process.exit(1); + } + }); + +authCommand + .command("logout") + .description("Sign out and remove stored credentials") + .action(() => { + const had = !!getToken(); + clearAuth(); + + console.log(); + if (had) { + console.log(` ${pc.green("✓")} Logged out. Credentials removed.`); + } else { + console.log(` ${pc.dim("○")} Already logged out.`); + } + console.log(); + }); + +authCommand + .command("whoami") + .description("Show the current authenticated user") + .action(async () => { + const token = getToken(); + if (!token) { + console.log(); + console.log(` ${pc.yellow("○")} Not logged in`); + console.log( + ` ${pc.dim("Run")} ${pc.bold("better-hub auth login")} ${pc.dim("to sign in.")}`, + ); + console.log(); + return; + } + + const s = spinner("Fetching session..."); + try { + const client = getAuthClient(); + const { data } = await client.getSession(); + if (!data?.user) throw new Error("No session"); + + s.stop(); + console.log(); + console.log(` ${pc.bold(data.user.name)}`); + console.log(` ${pc.dim(getBaseUrl())}`); + console.log(); + } catch { + s.stop(); + console.log(); + console.log(` ${pc.red("✗")} Session expired or invalid`); + console.log( + ` ${pc.dim("Run")} ${pc.bold("better-hub auth login")} ${pc.dim("to sign in again.")}`, + ); + console.log(); + } + }); + +authCommand + .command("status") + .description("Check authentication status") + .action(async () => { + const token = getToken(); + const base = getBaseUrl(); + + console.log(); + console.log(` ${pc.bold("Auth Status")}`); + console.log(); + console.log(` Server ${pc.cyan(base)}`); + + if (!token) { + console.log(` Status ${pc.yellow("not authenticated")}`); + console.log(); + return; + } + + const s = spinner("Checking session..."); + try { + const client = getAuthClient(); + const { data } = await client.getSession(); + if (!data?.user) throw new Error("No session"); + + s.stop(` Session ${pc.green("active")}`); + console.log(` User ${pc.bold(data.user.name)}`); + console.log(); + } catch { + s.stop(` Session ${pc.red("expired")}`); + console.log(); + } + }); diff --git a/packages/cli/src/commands/cd.ts b/packages/cli/src/commands/cd.ts new file mode 100644 index 00000000..01ab2655 --- /dev/null +++ b/packages/cli/src/commands/cd.ts @@ -0,0 +1,96 @@ +import { spawn } from "node:child_process"; +import { Command } from "commander"; +import pc from "picocolors"; +import { select, isCancel, cancel, outro, log } from "@clack/prompts"; +import { fuzzyFindRepos, getRepoPath, listRegisteredRepos } from "../lib/repo-registry.js"; +import { betterHubIntro } from "../lib/intro.js"; + +export const cdCommand = new Command("cd") + .description("Change the current working directory to a repository") + .argument("[slug]", "Repository slug (org/name)") + .action(async (slug?: string) => { + betterHubIntro("Change Directory"); + if (!slug) { + const repos = listRegisteredRepos(); + if (!repos.length) { + log.step(`${pc.bold("No repositories found")} ${pc.red("✗")}`); + outro(pc.dim("You don't have any repositories to go to.")); + process.exit(0); + } + + const selected = await select({ + message: "Select a repository:", + options: repos.map((r) => { + const segments = r.slug.split("/"); + return { + label: `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))} ${pc.dim(r.path)}`, + value: r.slug, + }; + }), + }); + + if (isCancel(selected)) { + cancel("Operation cancelled."); + process.exit(0); + } + + slug = selected; + } + + let repoPath = getRepoPath(slug); + + if (!repoPath) { + const matches = fuzzyFindRepos(slug); + + if (matches.length === 0) { + console.error( + pc.red( + `No repositories matching "${slug}" found in local registry.`, + ), + ); + console.error( + pc.dim( + "Registered repos are tracked when you create them with `bh repo create`.", + ), + ); + process.exit(1); + } + + if (matches.length === 1) { + slug = matches[0]!.entry.slug; + repoPath = matches[0]!.entry.path; + } else { + const selected = await select({ + message: `Multiple repos match "${slug}":`, + options: matches.map((m) => { + const segments = m.entry.slug.split("/"); + return { + label: `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))} ${pc.dim(m.entry.path)}`, + value: m.entry.slug, + }; + }), + }); + + if (isCancel(selected)) { + cancel("Operation cancelled."); + process.exit(0); + } + + slug = selected; + repoPath = getRepoPath(slug)!; + } + } + + const segments = slug.split("/"); + + outro( + pc.green(`${pc.bold("Directory changed to")}`) + + " " + + `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))}`, + ); + + spawn(process.env["SHELL"]!, { + stdio: "inherit", + cwd: repoPath, + }); + }); diff --git a/packages/cli/src/commands/commit.ts b/packages/cli/src/commands/commit.ts new file mode 100644 index 00000000..90ae1015 --- /dev/null +++ b/packages/cli/src/commands/commit.ts @@ -0,0 +1,351 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { + cancel, + confirm, + intro, + isCancel, + log, + multiselect, + outro, + progress, + spinner, + stream, + taskLog, + text, +} from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { sleep } from "../lib/utils.js"; + +export const commitCommand = new Command("commit") + .alias("push") + .alias("c") + .alias("p") + .description("Commit changes and view CI results") + .option("-m, --message [message]", "Commit message (omit value to generate with AI)") + .option("-a, --all", "Stage all changed files") + .option("-p, --push", "Push to remote after commit") + .option("--no-push", "Skip pushing to remote") + .action(async (opts: { message?: string | boolean; all?: boolean; push?: boolean }) => { + requireAuth(); + betterHubIntro("Commit & Push"); + const fakeFiles: { + raw: string; + status: "modified" | "added" | "deleted" | "renamed"; + diff: { additions: number; deletions: number } | null; + }[] = [ + { + raw: "src/lib/auth.ts", + status: "modified", + diff: { additions: 10, deletions: 5 }, + }, + { + raw: "src/components/navbar.tsx", + status: "modified", + diff: { additions: 10, deletions: 5 }, + }, + { raw: "src/app/settings/page.tsx", status: "added", diff: null }, + { + raw: "src/utils/format.ts", + status: "modified", + diff: { additions: 10, deletions: 5 }, + }, + { raw: "tests/auth.test.ts", status: "deleted", diff: null }, + ]; + + const maxLen = Math.max(...fakeFiles.map((f) => f.raw.length)); + + const statusColor = (s: string) => { + if (s === "added") return pc.green(s); + if (s === "deleted") return pc.red(s); + return pc.yellowBright(s); + }; + + const formatPath = ( + raw: string, + status: "modified" | "added" | "deleted" | "renamed", + ) => { + const sep = raw.lastIndexOf("/"); + const dir = raw.slice(0, sep + 1); + const file = raw.slice(sep + 1); + let color: keyof typeof pc = "gray"; + switch (status) { + case "added": + color = "green"; + break; + case "deleted": + color = "red"; + break; + case "modified": + color = "yellow"; + break; + case "renamed": + color = "blue"; + break; + default: + color = "gray"; + break; + } + let fileText = pc[color](file); + if (status === "deleted") { + fileText = pc.strikethrough(fileText); + } + return `${pc.gray(dir)}${fileText}`; + }; + + log.info( + `${pc.dim("On branch")} ${pc.cyan("feat/custom-storage")} ${pc.dim("· 5 changed files")}`, + ); + + const staged = opts.all + ? (() => { + log.step("Staging all changed files:"); + const logs: string[] = []; + for (const f of fakeFiles) { + const padding = " ".repeat( + maxLen - f.raw.length + 2, + ); + + let diff = ""; + if (f.diff) { + diff = ` ${pc.dim(pc.green(`+${f.diff.additions}`) + " " + `${pc.red(`-${f.diff.deletions}`)}`)}`; + } + logs.push( + ` ${formatPath(f.raw, f.status)}${padding}${pc.dim(`${statusColor(f.status)}${diff}`)}`, + ); + } + log.message(logs.join("\n")); + return fakeFiles.map((f) => f.raw); + })() + : await multiselect({ + message: "Select files to stage:", + options: fakeFiles.map((f) => { + const padding = " ".repeat( + maxLen - f.raw.length + 2, + ); + let diff = ""; + if (f.diff) { + diff = ` ${pc.dim(pc.green(`+${f.diff.additions}`) + " " + `${pc.red(`-${f.diff.deletions}`)}`)}`; + } + return { + label: `${formatPath(f.raw, f.status)}${padding}${pc.dim(`${statusColor(f.status)}${diff}`)}`, + value: f.raw, + }; + }), + initialValues: fakeFiles.map((x) => x.raw), + }); + + if (isCancel(staged)) { + cancel("Operation cancelled."); + process.exit(0); + } + + let commitMsg = typeof opts.message === "string" ? opts.message : undefined; + const useAI = opts.message === true; + + if (!commitMsg && !useAI) { + const raw = await text({ + message: `Commit message: ${pc.dim("(leave empty to generate with AI)")}`, + defaultValue: "auto-generate", + }); + + if (isCancel(raw)) { + cancel("Operation cancelled."); + process.exit(0); + } + + commitMsg = raw; + } + + if (!commitMsg || commitMsg === "auto-generate") { + const s = spinner(); + s.start("Generating commit message with AI..."); + await sleep(1500); + s.stop("AI commit message:"); + + commitMsg = "feat: add custom storage adapter with device auth flow"; + await stream.info(asyncTypeOut(pc.cyan(commitMsg), 60, 2)); + } + + let shouldPush = opts.push; + + if (shouldPush === undefined) { + const answer = await confirm({ + message: "Push to remote after commit?", + initialValue: true, + }); + + if (isCancel(answer)) { + cancel("Operation cancelled."); + process.exit(0); + } + + shouldPush = answer; + } + + const shortHash = Math.random().toString(16).slice(2, 9); + + log.success(`Committed ${pc.bold(shortHash)} ${pc.dim("→")} ${pc.cyan(commitMsg)}`); + log.message( + `${pc.dim(`${(staged as string[]).length} file(s) changed, 47 insertions(+), 12 deletions(-)`)}`, + ); + + if (!shouldPush) { + outro(pc.green("Done!")); + return; + } + + const p = progress({ max: 100 }); + p.start(`Pushing to ${pc.cyan("origin/feat/custom-storage")}`); + await sleep(800); + p.advance(15, "Enumerating objects..."); + await sleep(600); + p.advance(30, "Counting objects..."); + await sleep(700); + p.advance(50, "Compressing objects..."); + await sleep(800); + p.advance(70, "Writing objects..."); + await sleep(900); + p.advance(90, "Resolving deltas..."); + await sleep(600); + p.stop(`${pc.green("✓")} Pushed to ${pc.cyan("origin/feat/custom-storage")}`); + log.info(`${pc.bold("Running Actions")} ${pc.dim("— watching CI run...")}`); + + await streamCIResults(); + + outro(pc.green("All checks passed! ") + pc.dim(`(${shortHash})`)); + }); + +async function* asyncTypeOut(text: string, delayMs = 30, chunkSize = 3): AsyncGenerator { + for (let i = 0; i < text.length; i += chunkSize) { + await sleep(delayMs); + yield text.slice(i, i + chunkSize); + } +} + +async function emitLines(tl: { message(msg: string): void }, lines: string[], delayMs: number) { + for (const line of lines) { + await sleep(delayMs); + tl.message(line); + } +} + +const CI_ACTIONS = ["lint", "typecheck", "test", "build", "deploy-preview"]; +const CI_MAX_NAME = Math.max(...CI_ACTIONS.map((n) => n.length)); + +function ciTitle(name: string) { + const pad = " ".repeat(CI_MAX_NAME - name.length); + return `${pc.yellow("◆")} ${pc.cyan(name)}${pad} ${pc.dim("running...")}`; +} + +function ciSuccess(name: string, result: string) { + const pad = " ".repeat(CI_MAX_NAME - name.length); + return `${pc.green("✓")} ${pc.bold(name)}${pad} — ${result}`; +} + +async function streamCIResults() { + const lint = taskLog({ title: ciTitle("lint") }); + await emitLines( + lint, + [ + "Checking code style...", + `${pc.dim("src/lib/auth.ts")} — no issues`, + `${pc.dim("src/components/navbar.tsx")} — no issues`, + `${pc.dim("src/app/settings/page.tsx")} — no issues`, + `${pc.dim("src/utils/format.ts")} — no issues`, + `${pc.dim("tests/auth.test.ts")} — no issues`, + ], + 400, + ); + await sleep(300); + lint.success(ciSuccess("lint", `${pc.green("passed")} ${pc.dim("(3.2s)")}`)); + await sleep(500); + const typecheck = taskLog({ title: ciTitle("typecheck") }); + await emitLines( + typecheck, + [ + "Running tsc --noEmit...", + `${pc.dim("Compiling 247 files...")}`, + `${pc.dim("src/lib/auth.ts")} — ok`, + `${pc.dim("src/components/navbar.tsx")} — ok`, + `${pc.dim("src/app/settings/page.tsx")} — ok`, + `${pc.dim("src/utils/format.ts")} — ok`, + `${pc.dim("tests/auth.test.ts")} — ok`, + `${pc.dim("Found 0 errors in 247 files.")}`, + ], + 350, + ); + await sleep(300); + typecheck.success(ciSuccess("typecheck", `${pc.green("passed")} ${pc.dim("(8.1s)")}`)); + await sleep(500); + const test = taskLog({ title: ciTitle("test") }); + await emitLines( + test, + [ + "Running vitest...", + `${pc.dim("DEV v3.1.0")}`, + "", + ` ${pc.green("✓")} src/lib/auth.test.ts ${pc.dim("(12 tests)")} ${pc.dim("1.2s")}`, + ` ${pc.green("✓")} src/utils/format.test.ts ${pc.dim("(8 tests)")} ${pc.dim("0.4s")}`, + ` ${pc.green("✓")} src/components/navbar.test.tsx ${pc.dim("(6 tests)")} ${pc.dim("0.9s")}`, + ` ${pc.green("✓")} src/app/settings/page.test.tsx ${pc.dim("(10 tests)")} ${pc.dim("1.8s")}`, + ` ${pc.green("✓")} tests/auth.test.ts ${pc.dim("(6 tests)")} ${pc.dim("0.7s")}`, + "", + `${pc.green("Test Files")} 5 passed (5)`, + `${pc.green(" Tests")} 42 passed (42)`, + ], + 300, + ); + await sleep(400); + test.success( + ciSuccess( + "test", + `${pc.green("42 passed")}, ${pc.gray("0 failed")} ${pc.dim("(12.4s)")}`, + ), + ); + await sleep(500); + const build = taskLog({ title: ciTitle("build") }); + await emitLines( + build, + [ + "Building with Next.js...", + `${pc.dim("Creating an optimized production build...")}`, + `${pc.dim("Compiled successfully.")}`, + `${pc.dim("Collecting page data...")}`, + `${pc.dim("Generating static pages (0/24)...")}`, + `${pc.dim("Generating static pages (12/24)...")}`, + `${pc.dim("Generating static pages (24/24)...")}`, + `${pc.dim("Finalizing page optimization...")}`, + `${pc.dim("Route (app)")} Size First Load JS`, + `${pc.dim("├ ○ /")} ${pc.dim("5.2 kB")} ${pc.dim("89 kB")}`, + `${pc.dim("├ ○ /settings")} ${pc.dim("3.1 kB")} ${pc.dim("87 kB")}`, + `${pc.dim("└ ○ /device")} ${pc.dim("1.8 kB")} ${pc.dim("85 kB")}`, + ], + 250, + ); + await sleep(400); + build.success(ciSuccess("build", `${pc.green("passed")} ${pc.dim("(24.7s)")}`)); + + await sleep(500); + + const deploy = taskLog({ title: ciTitle("deploy-preview") }); + await emitLines( + deploy, + [ + "Deploying to Vercel...", + `${pc.dim("Uploading build outputs...")}`, + `${pc.dim("Assigning preview domain...")}`, + `${pc.dim("Running checks...")}`, + `${pc.dim("Preview ready.")}`, + ], + 500, + ); + await sleep(400); + deploy.success( + ciSuccess( + "deploy-preview", + `${pc.green("ready")} ${pc.dim("(50s) →")} ${pc.cyan("https://better-hub-git-feat-custom-storage.vercel.app")}`, + ), + ); +} diff --git a/packages/cli/src/commands/create-repo.ts b/packages/cli/src/commands/create-repo.ts new file mode 100644 index 00000000..0812adf9 --- /dev/null +++ b/packages/cli/src/commands/create-repo.ts @@ -0,0 +1,305 @@ +import { Command } from "commander"; +import { existsSync, mkdirSync } from "node:fs"; +import { resolve, isAbsolute, basename, dirname } from "node:path"; +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { + cancel, + confirm, + group, + isCancel, + log, + outro, + select, + spinner, + text, +} from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { registerRepo } from "../lib/repo-registry.js"; +import { exec, execSync } from "node:child_process"; + +export const createRepoCommand = new Command("create") + .alias("init") + .description("Create a new repository") + .option("-n, --name ", "Repository name") + .option("-s, --slug ", "Repository slug (owner/name)") + .option("-d, --description ", "Repository description") + .option("-v, --visibility ", "public or private", "public") + .action(async (opts: { slug?: string; description?: string; visibility: string }) => { + requireAuth(); + const authClient = getAuthClient(); + const session = await authClient.getSession(); + + if (session.error) { + outro(pc.red(`Failed to get session: ${session.error.message}`)); + process.exit(1); + } + if (!session.data) { + outro(pc.red("Not logged in. Run `better-hub auth login` first.")); + process.exit(1); + } + + betterHubIntro("Create a new repository"); + + const { + description, + name, + path: path_, + slug, + visibility, + segment, + } = await group( + { + name: () => { + return text({ + message: `Repository ${pc.bold("name")}: ${pc.dim("(not the slug)")}`, + validate(value) { + if (!value) return "Name is required"; + }, + }); + }, + segment: async ({ results }) => { + const initial = results.name + ?.toLowerCase() + .replace(/ /g, "-") + .replace(/[^a-zA-Z0-9-_]/g, ""); + + const segment = await text({ + message: `Repository ${pc.bold("slug")}:`, + initialValue: initial ?? "", + validate(value) { + if (!value) return "Slug is required"; + if (!/^[a-zA-Z0-9-_]+$/.test(value)) { + return "Slug can only contain letters, numbers, hyphens and underscores"; + } + }, + }); + + if (isCancel(segment)) { + return segment; + } + return segment; + }, + slug: async ({ results }) => { + const organizations = await authClient.organization.list(); + if (organizations.error) { + outro( + pc.red( + `Failed to list organizations: ${organizations.error.message}`, + ), + ); + process.exit(1); + } + if (!organizations.data.length) { + outro( + pc.red( + "No organizations found. Please sign into our dashboard.", + ), + ); + process.exit(1); + } + if (organizations.data.length === 1) { + log.step( + `Select an ${pc.bold("organization")}:\n${pc.dim(organizations.data[0]!.slug)}`, + ); + return `${organizations.data[0]!.slug}/${results.segment}`; + } + const organization = await select({ + message: `Select an ${pc.bold("organization")}:`, + options: organizations.data.map((organization) => ({ + label: organization.name, + value: organization.slug, + })), + }); + if (isCancel(organization)) { + return organization; + } + return `${organization}/${results.segment}`; + }, + description: async () => { + const description = await text({ + message: `Repository ${pc.bold("description")}: ${pc.dim("(optional)")}`, + defaultValue: "Skipped", + }); + if (isCancel(description)) { + return description; + } + if (description === "Skipped") { + return undefined; + } + return description; + }, + visibility: () => { + return confirm({ + message: `Repository ${pc.bold("visibility")}:`, + active: "public", + inactive: "private", + }); + }, + path: async ({ results }) => { + const cwd = process.cwd(); + const confirmed = await confirm({ + message: `Create the repository in this directory? ${pc.dim(`(${cwd})`)}`, + initialValue: true, + }); + if (isCancel(confirmed)) { + return confirmed; + } + if (confirmed) return cwd; + const newPath = await text({ + message: `Directory path ${pc.dim("(relative or absolute)")}:`, + placeholder: "./my-project", + initialValue: `./${results.segment}`, + validate(value) { + if (!value?.trim()) + return "Path is required"; + }, + }); + if (isCancel(newPath)) { + return newPath; + } + const resolved = isAbsolute(newPath) + ? resolve(newPath) + : resolve(cwd, newPath); + if (!existsSync(resolved)) { + const dirName = basename(resolved); + const dirParentPath = dirname(resolved); + const shouldCreate = await confirm({ + message: `Directory ${pc.dim(dirParentPath + "/")}${pc.underline(pc.cyan(dirName))} doesn't exist, create it?`, + initialValue: true, + }); + if (isCancel(shouldCreate)) { + cancel("Operation cancelled."); + process.exit(0); + } + if (!shouldCreate) { + cancel( + "Cannot continue without a valid directory.", + ); + process.exit(0); + } + mkdirSync(resolved, { recursive: true }); + } + return resolved; + }, + }, + { + onCancel: () => { + cancel("Operation cancelled."); + process.exit(0); + }, + }, + ); + const path = path_ as string; + + const s = spinner({}); + s.start("Creating repository..."); + + const repo = await authClient.storage.createRepo({ + name, + slug: slug as `${string}/${string}`, + visibility: visibility ? "public" : "private", + description, + }); + if (repo.error) { + s.stop(`${pc.bold("Repository creation failed!")} ${pc.red("✗")}`); + if (repo.error.code === "REPOSITORY_ALREADY_EXISTS") { + const msg = `Repository already exists. Please choose a different slug.`; + outro(pc.red(msg)); + process.exit(1); + } + const msg = `Failed to create repository: ${pc.bold(repo.error.message)}`; + outro(pc.red(msg)); + console.error(repo.error); + process.exit(1); + } + s.stop(`${pc.bold("Repository created!")} ${pc.green("✓")}`); + + const hasGitFolder = (() => { + const raw = execSync(`git rev-parse --is-inside-work-tree`, { + cwd: path, + }); + const result = raw.toString().trim(); + return result === "true"; + })(); + + let gitCLIDetails: string[] = []; + let shouldInit = true; + if (hasGitFolder) { + log.warn("Detected existing Git repository."); + const confirmed = await confirm({ + message: `Initialize a new Git repository in the project directory?`, + initialValue: true, + }); + if (isCancel(confirmed)) { + return confirmed; + } + if (!confirmed) { + shouldInit = false; + } + } + + const defaultBranch = repo.data.defaultBranch || "main"; + + if (shouldInit) { + execSync(`git init -b "${defaultBranch}"`, { cwd: path }); + gitCLIDetails.push(pc.dim("✓ Initialized Git repository")); + } else { + gitCLIDetails.push(pc.dim("→ Using existing Git repository")); + } + + if (repo.data.remoteURL) { + execSync(`cd ${path} && git remote add better-hub ${repo.data.remoteURL}`, { + cwd: path, + }); + gitCLIDetails.push(pc.dim("✓ Registered remote repository")); + } else { + gitCLIDetails.push( + pc.dim( + "→ No remote repository recieved, skipping remote repository addition...", + ), + ); + } + + log.info(`${pc.bold("Running Git")}`); + log.message(gitCLIDetails.join("\n")); + + registerRepo(slug as string, path); + + const url = `https://better-hub.com/s/${slug}`; + log.info( + [ + `${pc.bold(pc.white(name))}`, + description ? `${pc.gray(description)}` : null, + ``, + `${pc.dim("→")} ${pc.yellow(` ${slug}`)}`, + `${pc.dim("→")} ${pc.magenta(`⎇ ${defaultBranch}`)}`, + `${pc.dim("→")} ${pc.cyan(`${pc.underline(`${url}`)}`)}`, + ] + .filter((x) => !(x !== "" && !x)) + .join("\n"), + ); + + const commands: [string, string][] = [ + ["bh push", "Stage, commit & push your changes"], + ["bh list", "List your repositories"], + [`bh cd ${segment}`, "Change your working directory to this repository"], + ]; + + const maxCmd = Math.max(...commands.map(([cmd]) => cmd.length)); + log.info(`${pc.bold("Next steps")}`); + log.message( + `${pc.gray(`Your repository is initiated, you can now start working on your project!`)}`, + ); + log.message( + commands + .map( + ([cmd, desc]) => + `${pc.dim("$")} ${pc.cyan(cmd.padEnd(maxCmd))} ${pc.dim(desc)}`, + ) + .join("\n"), + ); + + outro(pc.green("Happy Hacking!")); + }); diff --git a/packages/cli/src/commands/delete.ts b/packages/cli/src/commands/delete.ts new file mode 100644 index 00000000..8b84e66d --- /dev/null +++ b/packages/cli/src/commands/delete.ts @@ -0,0 +1,147 @@ +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { cancel, confirm, isCancel, log, outro, select, spinner } from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { getRepoPath, syncRegistry, unregisterRepo } from "../lib/repo-registry.js"; +import fs from "node:fs/promises"; +import { existsSync } from "node:fs"; +import { Command } from "commander"; + +export const deleteRepoCommand = new Command("delete") + .alias("remove") + .alias("rm") + .description("Delete a repository") + .option("-s, --slug ", "Repository slug (owner/name) to delete") + .action(async (opts: { slug?: string }) => { + requireAuth(); + const authClient = getAuthClient(); + const session = await authClient.getSession(); + + if (session.error) { + outro(pc.red(`Failed to get session: ${session.error.message}`)); + process.exit(1); + } + if (!session.data) { + outro(pc.red("Not logged in. Run `better-hub auth login` first.")); + process.exit(1); + } + + betterHubIntro("Delete a repository"); + + const s = spinner({}); + s.start("Fetching repositories..."); + + const repos = await authClient.storage.listRepo(); + if (repos.error) { + s.stop(`${pc.bold("Failed to fetch repositories")} ${pc.red("✗")}`); + outro(pc.red(repos.error.message)); + process.exit(1); + } + const serverSlugs = new Set((repos.data ?? []).map((r) => r.slug)); + syncRegistry(serverSlugs); + + if (!repos.data?.length) { + s.stop(`${pc.bold("No repositories found")} ${pc.red("✗")}`); + outro(pc.dim("You don't have any repositories to delete.")); + process.exit(0); + } + + s.stop(`${pc.bold("Repositories loaded")} ${pc.green("✓")}`); + + let targetRepo: (typeof repos.data)[number] | undefined; + + if (opts.slug) { + targetRepo = repos.data.find((r) => r.slug === opts.slug); + if (!targetRepo) { + outro(pc.red(`Repository "${opts.slug}" not found.`)); + process.exit(1); + } + } else { + const selected = await select({ + message: `Select a repository to ${pc.bold(pc.red("delete"))}:`, + options: repos.data.map((r) => ({ + label: `${r.name} ${pc.dim(`(${r.slug})`)}`, + value: r.id, + hint: r.visibility, + })), + }); + + if (isCancel(selected)) { + cancel("Operation cancelled."); + process.exit(0); + } + + targetRepo = repos.data.find((r) => r.id === selected); + } + + if (!targetRepo) { + outro(pc.red("Repository not found.")); + process.exit(1); + } + + log.warn( + `You are about to delete ${pc.bold(pc.red(targetRepo.name))} ${pc.dim(`(${targetRepo.slug})`)}`, + ); + + const confirmed = await confirm({ + message: `Are you sure? ${pc.dim("This action cannot be undone.")}`, + initialValue: false, + active: pc.red("Confirm Deletion"), + inactive: pc.green("Cancel"), + }); + + if (isCancel(confirmed) || !confirmed) { + cancel("Deletion cancelled."); + process.exit(0); + } + + s.start(`${pc.bold("Deleting repository")} ${pc.dim(`(${targetRepo.slug})`)}...`); + + const result = await authClient.storage.deleteRepo({ + id: targetRepo.id, + }); + + if (result.error) { + s.stop( + `${pc.bold("Deletion failed")} ${pc.red("✗")} ${pc.dim(`(${targetRepo.id})`)}`, + ); + outro(pc.red(`Failed to delete repository: ${result.error.message}`)); + console.error(result.error); + process.exit(1); + } + + const localPath = getRepoPath(targetRepo.slug); + unregisterRepo(targetRepo.slug); + + s.stop(`${pc.bold("Repository deleted")} ${pc.green("✓")}`); + + if (localPath && existsSync(localPath)) { + const deleteLocal = await confirm({ + message: `Delete local files at ${pc.dim(localPath)}?`, + initialValue: false, + active: pc.red("Yes"), + inactive: pc.green("No"), + }); + + if (!isCancel(deleteLocal) && deleteLocal) { + const ds = spinner({}); + ds.start("Removing local files..."); + try { + await fs.rm(localPath, { recursive: true, force: true }); + ds.stop( + `${pc.bold("Local files removed")} ${pc.green("✓")}`, + ); + } catch (err) { + ds.stop( + `${pc.bold("Failed to remove local files")} ${pc.red("✗")}`, + ); + log.error( + `Could not delete ${pc.dim(localPath)}: ${err instanceof Error ? err.message : String(err)}`, + ); + } + } + } + + outro(pc.green(`${pc.bold(targetRepo.name)} has been deleted.`)); + }); diff --git a/packages/cli/src/commands/list-repo.ts b/packages/cli/src/commands/list-repo.ts new file mode 100644 index 00000000..99b7ae4c --- /dev/null +++ b/packages/cli/src/commands/list-repo.ts @@ -0,0 +1,66 @@ +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { log, outro, spinner } from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { syncRegistry } from "../lib/repo-registry.js"; +import { Command } from "commander"; + +export const listRepoCommand = new Command("list") + .alias("ls") + .description("List your repositories") + .action(async () => { + requireAuth(); + const authClient = getAuthClient(); + const session = await authClient.getSession(); + + if (session.error) { + outro(pc.red(`Failed to get session: ${session.error.message}`)); + process.exit(1); + } + if (!session.data) { + outro(pc.red("Not logged in. Run `better-hub auth login` first.")); + process.exit(1); + } + + betterHubIntro("Your repositories"); + + const s = spinner({}); + s.start("Fetching repositories..."); + + const repos = await authClient.storage.listRepo(); + if (repos.error) { + s.stop(`${pc.bold("Failed to fetch repositories")} ${pc.red("✗")}`); + outro(pc.red(repos.error.message)); + process.exit(1); + } + + const serverSlugs = new Set((repos.data ?? []).map((r) => r.slug)); + syncRegistry(serverSlugs); + + if (!repos.data?.length) { + s.stop(`${pc.bold("No repositories found")} ${pc.red("✗")}`); + outro(pc.dim("Create one with `bh repo create`.")); + process.exit(0); + } + + s.stop( + `${pc.bold(`${repos.data.length} ${repos.data.length === 1 ? "repository" : "repositories"} found`)} ${pc.green("✓")}`, + ); + + const maxName = Math.max(...repos.data.map((r) => r.name.length)); + + log.message( + repos.data + .map((r) => { + const visibility = + r.visibility === "private" + ? pc.yellow("private") + : pc.green("public"); + return ` ${pc.bold(r.name.padEnd(maxName))} ${pc.dim(r.slug)} ${visibility}`; + }) + .join("\n"), + ); + + outro(pc.dim(`Run ${pc.cyan("bh repo create")} to add a new repository.`)); + }); diff --git a/packages/cli/src/commands/repo.ts b/packages/cli/src/commands/repo.ts new file mode 100644 index 00000000..ce865675 --- /dev/null +++ b/packages/cli/src/commands/repo.ts @@ -0,0 +1,246 @@ +import { Command } from "commander"; +import { existsSync, mkdirSync } from "node:fs"; +import { resolve, isAbsolute, basename, dirname } from "node:path"; +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { + cancel, + confirm, + group, + isCancel, + log, + outro, + select, + spinner, + text, +} from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; + +export const repoCommand = new Command("repo").description("Manage repositories"); + +repoCommand + .command("create") + .alias("init") + .description("Create a new repository") + .option("-n, --name ", "Repository name") + .option("-s, --slug ", "Repository slug (owner/name)") + .option("-d, --description ", "Repository description") + .option("-v, --visibility ", "public or private", "public") + .action(async (opts: { slug?: string; description?: string; visibility: string }) => { + requireAuth(); + const authClient = getAuthClient(); + betterHubIntro("Create a new repository"); + + const session = await authClient.getSession(); + + if (session.error) { + outro(pc.red(`Failed to get session: ${session.error.message}`)); + process.exit(1); + } + if (!session.data) { + outro(pc.red("Not logged in. Run `better-hub auth login` first.")); + process.exit(1); + } + + const { description, name, path, segment, slug, visibility } = await group( + { + name: () => { + return text({ + message: `Repository ${pc.bold("name")}: ${pc.dim("(not the slug)")}`, + validate(value) { + if (!value) return "Name is required"; + }, + }); + }, + segment: async ({ results }) => { + const initial = results.name + ?.toLowerCase() + .replace(/ /g, "-") + .replace(/[^a-zA-Z0-9-_]/g, ""); + + const segment = await text({ + message: `Repository ${pc.bold("slug")}:`, + initialValue: initial ?? "", + validate(value) { + if (!value) return "Slug is required"; + if (!/^[a-zA-Z0-9-_]+$/.test(value)) { + return "Slug can only contain letters, numbers, hyphens and underscores"; + } + }, + }); + + if (isCancel(segment)) { + return segment; + } + return segment; + }, + slug: async ({ results }) => { + const organizations = await authClient.organization.list(); + if (organizations.error) { + outro( + pc.red( + `Failed to list organizations: ${organizations.error.message}`, + ), + ); + process.exit(1); + } + if (!organizations.data.length) { + outro( + pc.red( + "No organizations found. Please sign into our dashboard.", + ), + ); + process.exit(1); + } + if (organizations.data.length === 1) { + log.step( + `Select an ${pc.bold("organization")}:\n${pc.dim(organizations.data[0]!.slug)}`, + ); + return `${organizations.data[0]!.slug}/${results.segment}`; + } + const organization = await select({ + message: `Select an ${pc.bold("organization")}:`, + options: organizations.data.map((organization) => ({ + label: organization.name, + value: organization.slug, + })), + }); + if (isCancel(organization)) { + return organization; + } + return `${organization}/${results.segment}`; + }, + description: async () => { + const description = await text({ + message: `Repository ${pc.bold("description")}: ${pc.dim("(optional)")}`, + defaultValue: "Skipped", + }); + if (isCancel(description)) { + return description; + } + if (description === "Skipped") { + return undefined; + } + return description; + }, + visibility: () => { + return confirm({ + message: `Repository ${pc.bold("visibility")}:`, + active: "public", + inactive: "private", + }); + }, + path: async ({ results }) => { + const cwd = process.cwd(); + const confirmed = await confirm({ + message: `Create the repository in this directory? ${pc.dim(`(${cwd})`)}`, + initialValue: true, + }); + if (isCancel(confirmed)) { + return confirmed; + } + if (confirmed) return cwd; + const newPath = await text({ + message: `Directory path ${pc.dim("(relative or absolute)")}:`, + placeholder: "./my-project", + initialValue: `./${results.segment}`, + validate(value) { + if (!value?.trim()) + return "Path is required"; + }, + }); + if (isCancel(newPath)) { + return newPath; + } + const resolved = isAbsolute(newPath) + ? resolve(newPath) + : resolve(cwd, newPath); + if (!existsSync(resolved)) { + const dirName = basename(resolved); + const dirParentPath = dirname(resolved); + const shouldCreate = await confirm({ + message: `Directory ${pc.dim(dirParentPath + "/")}${pc.underline(pc.cyan(dirName))} doesn't exist, create it?`, + initialValue: true, + }); + if (isCancel(shouldCreate)) { + cancel("Operation cancelled."); + process.exit(0); + } + if (!shouldCreate) { + cancel( + "Cannot continue without a valid directory.", + ); + process.exit(0); + } + mkdirSync(resolved, { recursive: true }); + } + return resolved; + }, + }, + { + onCancel: () => { + cancel("Operation cancelled."); + process.exit(0); + }, + }, + ); + + const s = spinner({}); + s.start("Creating repository..."); + const repo = await authClient.storage.createRepo({ + name, + slug: slug as `${string}/${string}`, + visibility: visibility ? "public" : "private", + description, + }); + if (repo.error) { + s.stop(`${pc.bold("Repository creation failed!")} ${pc.red("✗")}`); + if (repo.error.code === "REPOSITORY_ALREADY_EXISTS") { + const msg = `Repository already exists. Please choose a different slug.`; + outro(pc.red(msg)); + process.exit(1); + } + const msg = `Failed to create repository: ${pc.bold(repo.error.message)}`; + outro(pc.red(msg)); + console.error(repo.error); + process.exit(1); + } + s.stop(`${pc.bold("Repository created!")} ${pc.green("✓")}`); + + const url = `https://better-hub.com/s/${slug}`; + log.info( + [ + `${pc.bold(pc.white(name))}`, + description ? `${pc.gray(description)}` : null, + ``, + `${pc.dim("→")} ${pc.yellow(` ${slug}`)}`, + `${pc.dim("→")} ${pc.magenta(`⎇ main`)}`, + `${pc.dim("→")} ${pc.cyan(`${pc.underline(`${url}`)}`)}`, + ] + .filter((x) => !(x !== "" && !x)) + .join("\n"), + ); + + const commands: [string, string][] = [ + ["bh push", "Stage, commit & push your changes"], + ["bh push -m", "Commit with an AI-generated message"], + ["bh repo list", "List your repositories"], + ]; + + const maxCmd = Math.max(...commands.map(([cmd]) => cmd.length)); + log.info(`${pc.bold("Next steps")}`); + log.message( + `${pc.gray(`Your repository is initiated, you can now start working on your project!`)}`, + ); + log.message( + commands + .map( + ([cmd, desc]) => + `${pc.dim("$")} ${pc.cyan(cmd.padEnd(maxCmd))} ${pc.dim(desc)}`, + ) + .join("\n"), + ); + + outro(pc.green("Happy Hacking!")); + }); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts new file mode 100644 index 00000000..41d112a4 --- /dev/null +++ b/packages/cli/src/index.ts @@ -0,0 +1,22 @@ +#!/usr/bin/env node +import { Command } from "commander"; +import { authCommand } from "./commands/auth.js"; +import { cdCommand } from "./commands/cd.js"; +import { commitCommand } from "./commands/commit.js"; +import { createRepoCommand } from "./commands/create-repo.js"; +import { deleteRepoCommand } from "./commands/delete.js"; +import { listRepoCommand } from "./commands/list-repo.js"; + +const program = new Command() + .name("better-hub") + .description("CLI for Better Hub — manage repos, auth, and more from your terminal") + .version("0.1.0"); + +program.addCommand(authCommand); +program.addCommand(cdCommand); +program.addCommand(createRepoCommand); +program.addCommand(commitCommand); +program.addCommand(deleteRepoCommand); +program.addCommand(listRepoCommand); + +program.parse(); diff --git a/packages/cli/src/lib/auth-client.ts b/packages/cli/src/lib/auth-client.ts new file mode 100644 index 00000000..1dcdb534 --- /dev/null +++ b/packages/cli/src/lib/auth-client.ts @@ -0,0 +1,15 @@ +import { createAuthClient } from "better-auth/client"; +import { deviceAuthorizationClient, organizationClient } from "better-auth/client/plugins"; +import { getBaseUrl, getToken } from "./config.js"; +import { storageClient } from "@better-hub/storage/client"; + +export function getAuthClient() { + const token = getToken(); + return createAuthClient({ + baseURL: getBaseUrl(), + plugins: [deviceAuthorizationClient(), storageClient(), organizationClient()], + fetchOptions: token ? { headers: { authorization: `Bearer ${token}` } } : undefined, + }); +} + +export const CLIENT_ID = "better-hub-cli"; diff --git a/packages/cli/src/lib/client.ts b/packages/cli/src/lib/client.ts new file mode 100644 index 00000000..cda7fb0b --- /dev/null +++ b/packages/cli/src/lib/client.ts @@ -0,0 +1,19 @@ +import { getToken } from "./config.js"; + +export class ApiError extends Error { + constructor( + public status: number, + message: string, + ) { + super(message); + this.name = "ApiError"; + } +} + +export function requireAuth(): string { + const token = getToken(); + if (!token) { + throw new ApiError(401, "Not logged in. Run `better-hub auth login` first."); + } + return token; +} diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/lib/config.ts new file mode 100644 index 00000000..bf4142d4 --- /dev/null +++ b/packages/cli/src/lib/config.ts @@ -0,0 +1,62 @@ +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; + +interface Config { + baseUrl: string; + auth?: { + token: string; + expiresAt?: string; + }; +} + +const CONFIG_DIR = join(homedir(), ".better-hub"); +const CONFIG_FILE = join(CONFIG_DIR, "config.json"); + +const DEFAULT_CONFIG: Config = { + baseUrl: "https://www.better-hub.com", +}; + +function ensureConfigDir() { + if (!existsSync(CONFIG_DIR)) { + mkdirSync(CONFIG_DIR, { recursive: true }); + } +} + +export function readConfig(): Config { + ensureConfigDir(); + if (!existsSync(CONFIG_FILE)) { + return { ...DEFAULT_CONFIG }; + } + try { + const raw = readFileSync(CONFIG_FILE, "utf-8"); + return { ...DEFAULT_CONFIG, ...JSON.parse(raw) }; + } catch { + return { ...DEFAULT_CONFIG }; + } +} + +export function writeConfig(config: Config) { + ensureConfigDir(); + writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n"); +} + +export function clearAuth() { + const config = readConfig(); + delete config.auth; + writeConfig(config); +} + +export function setAuth(token: string, expiresAt?: string) { + const config = readConfig(); + config.auth = expiresAt ? { token, expiresAt } : { token }; + writeConfig(config); +} + +export function getToken(): string | null { + return readConfig().auth?.token ?? null; +} + +export function getBaseUrl(): string { + return process.env["BETTER_HUB_URL"] ?? readConfig().baseUrl; +} diff --git a/packages/cli/src/lib/device-auth.ts b/packages/cli/src/lib/device-auth.ts new file mode 100644 index 00000000..7429b0ab --- /dev/null +++ b/packages/cli/src/lib/device-auth.ts @@ -0,0 +1,135 @@ +import pc from "picocolors"; +import { getBaseUrl } from "./config.js"; +import { openUrl } from "./open-url.js"; +import { getAuthClient, CLIENT_ID } from "./auth-client.js"; +import { spinner } from "./spinner.js"; + +const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code"; + +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +function extractErrorDetail(error: unknown): string { + if (!error || typeof error !== "object") return String(error); + const e = error as Record; + if (e["message"] && typeof e["message"] === "string") return e["message"]; + if (e["error_description"] && typeof e["error_description"] === "string") + return e["error_description"]; + if (e["statusText"] && typeof e["statusText"] === "string") + return `${e["status"] ?? ""} ${e["statusText"]}`.trim(); + return JSON.stringify(error); +} + +export async function deviceAuthFlow(): Promise { + const s = spinner("Requesting device code..."); + const baseUrl = getBaseUrl(); + + let data: Awaited["device"]["code"]>>["data"]; + try { + const client = getAuthClient(); + const res = await client.device.code({ client_id: CLIENT_ID }); + if (res.error || !res.data) { + const detail = extractErrorDetail(res.error); + s.stop(` ${pc.red("✗")} Device code request failed`); + throw new Error(`Server ${pc.dim(`(${baseUrl})`)} responded: ${detail}`); + } + data = res.data; + } catch (err) { + if (err instanceof Error && err.message.startsWith("Server ")) throw err; + s.stop(` ${pc.red("✗")} Could not reach server`); + throw new Error( + `Could not connect to ${pc.dim(baseUrl)} — ${err instanceof Error ? err.message : "network error"}`, + ); + } + + const { + device_code, + user_code, + verification_uri, + verification_uri_complete, + interval = 5, + } = data; + + s.stop(` ${pc.green("✓")} Device code received`); + + const code = formatUserCode(user_code); + const fullUrl = verification_uri_complete || verification_uri; + const displayUrl = fullUrl.startsWith("http") ? fullUrl : `${baseUrl}${fullUrl}`; + + console.log(); + console.log(` ${pc.bold("Your one-time code")}`); + console.log(); + console.log(` ${pc.bold(pc.cyan(code))}`); + console.log(); + console.log(` ${pc.dim("Opening")} ${pc.underline(displayUrl)}`); + console.log(); + + await openUrl(displayUrl); + + const accessToken = await pollForToken(getAuthClient(), device_code, interval); + return accessToken; +} + +async function pollForToken( + client: ReturnType, + deviceCode: string, + interval: number, +): Promise { + let pollInterval = interval; + const s = spinner("Waiting for authorization in browser..."); + + while (true) { + await sleep(pollInterval * 1000); + + const { data, error } = await client.device.token({ + grant_type: GRANT_TYPE, + device_code: deviceCode, + client_id: CLIENT_ID, + }); + + if (data?.access_token) { + s.stop(` ${pc.green("✓")} Authorization received`); + return data.access_token; + } + + if (error) { + const err = error as { + error?: string; + error_description?: string; + }; + switch (err.error) { + case "authorization_pending": + break; + case "slow_down": + pollInterval += 5; + s.update( + `Waiting for authorization... (slowed to ${pollInterval}s)`, + ); + break; + case "access_denied": + s.stop(` ${pc.red("✗")} Authorization denied by user`); + throw new Error("You denied the authorization request."); + case "expired_token": + s.stop(` ${pc.red("✗")} Code expired`); + throw new Error( + "The device code expired before it was approved. Run login again.", + ); + default: + s.stop(` ${pc.red("✗")} Unexpected error`); + throw new Error( + err.error_description ?? + err.error ?? + "Unknown error from server", + ); + } + } + } +} + +function formatUserCode(code: string): string { + if (code.length === 8 && !code.includes("-")) { + return `${code.slice(0, 4)}-${code.slice(4)}`; + } + return code; +} diff --git a/packages/cli/src/lib/intro.ts b/packages/cli/src/lib/intro.ts new file mode 100644 index 00000000..324034c8 --- /dev/null +++ b/packages/cli/src/lib/intro.ts @@ -0,0 +1,6 @@ +import { intro } from "@clack/prompts"; +import pc from "picocolors"; +export const betterHubIntro = (msg: string) => { + console.log(); + intro(`${pc.bgCyanBright(pc.black(" Better Hub "))}${pc.dim(` `)}${pc.gray(`${msg}`)}`); +}; diff --git a/packages/cli/src/lib/open-url.ts b/packages/cli/src/lib/open-url.ts new file mode 100644 index 00000000..e4d36776 --- /dev/null +++ b/packages/cli/src/lib/open-url.ts @@ -0,0 +1,5 @@ +import open from "open"; + +export function openUrl(url: string): Promise { + return open(url).then(() => {}); +} diff --git a/packages/cli/src/lib/repo-registry.ts b/packages/cli/src/lib/repo-registry.ts new file mode 100644 index 00000000..b2ac66c0 --- /dev/null +++ b/packages/cli/src/lib/repo-registry.ts @@ -0,0 +1,106 @@ +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { Fzf } from "fzf"; + +export interface RepoEntry { + slug: string; + path: string; + createdAt: string; +} + +interface RepoRegistry { + repos: RepoEntry[]; +} + +const REGISTRY_DIR = join(homedir(), ".better-hub"); +const REGISTRY_FILE = join(REGISTRY_DIR, "repos.json"); + +function ensureRegistryDir() { + if (!existsSync(REGISTRY_DIR)) { + mkdirSync(REGISTRY_DIR, { recursive: true }); + } +} + +function readRegistry(): RepoRegistry { + ensureRegistryDir(); + if (!existsSync(REGISTRY_FILE)) { + return { repos: [] }; + } + try { + const raw = readFileSync(REGISTRY_FILE, "utf-8"); + return JSON.parse(raw) as RepoRegistry; + } catch { + return { repos: [] }; + } +} + +function writeRegistry(registry: RepoRegistry) { + ensureRegistryDir(); + writeFileSync(REGISTRY_FILE, JSON.stringify(registry, null, 2) + "\n"); +} + +export function registerRepo(slug: string, path: string): RepoEntry { + const registry = readRegistry(); + const existing = registry.repos.findIndex((r) => r.slug === slug); + + const entry: RepoEntry = { + slug, + path, + createdAt: new Date().toISOString(), + }; + + if (existing !== -1) { + registry.repos[existing] = entry; + } else { + registry.repos.push(entry); + } + + writeRegistry(registry); + return entry; +} + +export function unregisterRepo(slug: string): boolean { + const registry = readRegistry(); + const before = registry.repos.length; + registry.repos = registry.repos.filter((r) => r.slug !== slug); + if (registry.repos.length === before) return false; + writeRegistry(registry); + return true; +} + +export function getRepoPath(slug: string): string | null { + const registry = readRegistry(); + return registry.repos.find((r) => r.slug === slug)?.path ?? null; +} + +export function listRegisteredRepos(): RepoEntry[] { + return readRegistry().repos; +} + +/** + * Removes local registry entries whose slugs aren't in the given set of + * server-known slugs. Returns the number of pruned entries. + */ +export function syncRegistry(serverSlugs: Set): number { + const registry = readRegistry(); + const before = registry.repos.length; + registry.repos = registry.repos.filter((r) => serverSlugs.has(r.slug)); + const pruned = before - registry.repos.length; + if (pruned > 0) writeRegistry(registry); + return pruned; +} + +export interface FuzzyMatch { + entry: RepoEntry; + score: number; +} + +export function fuzzyFindRepos(query: string): FuzzyMatch[] { + const repos = readRegistry().repos; + const fzf = new Fzf(repos, { selector: (r) => r.slug }); + return fzf.find(query).map((result) => ({ + entry: result.item, + score: result.score, + })); +} diff --git a/packages/cli/src/lib/spinner.ts b/packages/cli/src/lib/spinner.ts new file mode 100644 index 00000000..93af38b2 --- /dev/null +++ b/packages/cli/src/lib/spinner.ts @@ -0,0 +1,33 @@ +const FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + +export interface Spinner { + update(text: string): void; + stop(finalText?: string): void; +} + +export function spinner(text: string): Spinner { + let i = 0; + let current = text; + const stream = process.stderr; + + const write = () => { + stream.write(`\r\x1B[K \x1B[2m${FRAMES[i]}\x1B[22m ${current}`); + i = (i + 1) % FRAMES.length; + }; + + write(); + const timer = setInterval(write, 80); + + return { + update(t: string) { + current = t; + }, + stop(finalText?: string) { + clearInterval(timer); + stream.write(`\r\x1B[K`); + if (finalText) { + stream.write(`${finalText}\n`); + } + }, + }; +} diff --git a/packages/cli/src/lib/utils.ts b/packages/cli/src/lib/utils.ts new file mode 100644 index 00000000..41c02f49 --- /dev/null +++ b/packages/cli/src/lib/utils.ts @@ -0,0 +1,3 @@ +export const sleep = async (ms: number) => { + return new Promise((resolve) => setTimeout(resolve, ms)); +}; diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json new file mode 100644 index 00000000..75bcb9b0 --- /dev/null +++ b/packages/cli/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "declaration": false, + "declarationMap": false, + "verbatimModuleSyntax": false + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/storage/package.json b/packages/storage/package.json new file mode 100644 index 00000000..af324bce --- /dev/null +++ b/packages/storage/package.json @@ -0,0 +1,40 @@ +{ + "name": "@better-hub/storage", + "version": "0.1.0", + "description": "Git storage plugin for Better Hub — repo creation, access control, and Code.Storage integration", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/better-auth/better-hub.git", + "directory": "packages/storage" + }, + "files": [ + "dist" + ], + "type": "module", + "exports": { + ".": "./dist/index.mjs", + "./adapter": "./dist/adapter.mjs", + "./client": "./dist/client.mjs", + "./db-schema": "./dist/db-schema.mjs", + "./plugin": "./dist/plugin.mjs", + "./package.json": "./package.json" + }, + "scripts": { + "build": "tsdown", + "dev": "tsc --watch --emitDeclarationOnly", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@pierre/storage": "^1.3.2", + "better-auth": "catalog:", + "zod": "^4.3.6" + }, + "devDependencies": { + "@types/node": "^25.3.0", + "tsdown": "latest" + }, + "inlinedDependencies": { + "better-call": "1.3.2" + } +} diff --git a/packages/storage/src/adapter.ts b/packages/storage/src/adapter.ts new file mode 100644 index 00000000..7577c86a --- /dev/null +++ b/packages/storage/src/adapter.ts @@ -0,0 +1,113 @@ +import type { GenericEndpointContext, User } from "better-auth"; +import { storage } from "."; +import type { + RepositoryMember, + Repository, + RepositoryMemberInput, + RepositoryInput, + Visibility, +} from "./db-schema"; + +export const storageAdapter = (ctx: GenericEndpointContext) => { + return { + createRepo: async (options: { + name: string; + slug: `${string}/${string}`; + user: User; + visibility: Visibility; + description?: string | undefined; + }) => { + const adapter = ctx.context.adapter; + const repo = await storage.createRepo(); + + const repositoryData: RepositoryInput = { + name: options.name, + description: options.description, + slug: options.slug, + visibility: options.visibility, + createdAt: new Date(), + id: repo.id, + }; + const repositoryMemberData: RepositoryMemberInput = { + userId: options.user.id, + repositoryId: repo.id, + createdAt: new Date(), + }; + + const checkExisting = await adapter.findOne({ + model: "repository", + where: [{ field: "slug", value: options.slug }], + select: ["id"], + }); + + if (checkExisting) { + return ctx.error("BAD_REQUEST", { + message: "Repository already exists", + code: "REPOSITORY_ALREADY_EXISTS", + }); + } + + const result = await adapter.transaction(async (tx) => { + const repository = await tx.create({ + model: "repository", + data: repositoryData as Repository, + forceAllowId: true, + }); + const repositoryMember = await tx.create({ + model: "repositoryMember", + data: repositoryMemberData, + }); + return { repository, repositoryMember }; + }); + return result; + }, + checkRepoExistsBySlug: async (slug: `${string}/${string}`) => { + const adapter = ctx.context.adapter; + const checkExisting = await adapter.findOne({ + model: "repository", + where: [{ field: "slug", value: slug }], + select: ["id"], + }); + return !!checkExisting; + }, + checkRepoExistsById: async (id: string) => { + const adapter = ctx.context.adapter; + const checkExisting = await adapter.findOne({ + model: "repository", + where: [{ field: "id", value: id }], + select: ["id"], + }); + return !!checkExisting; + }, + deleteRepo: async (id: string) => { + const adapter = ctx.context.adapter; + await adapter.delete({ + model: "repository", + where: [{ field: "id", value: id }], + }); + await adapter.deleteMany({ + model: "repositoryMember", + where: [{ field: "repositoryId", value: id }], + }); + }, + listRepos: async (userId: string) => { + const adapter = ctx.context.adapter; + const repositoryMembers = await adapter.findMany({ + model: "repositoryMember", + where: [{ field: "userId", value: userId }], + }); + if (!repositoryMembers.length) return []; + const repos = await adapter.findMany({ + model: "repository", + where: [ + { + field: "id", + value: repositoryMembers.map((r) => r.repositoryId), + operator: "in", + }, + ], + }); + return repos; + }, + }; +}; diff --git a/packages/storage/src/client.ts b/packages/storage/src/client.ts new file mode 100644 index 00000000..ace6e2d5 --- /dev/null +++ b/packages/storage/src/client.ts @@ -0,0 +1,12 @@ +import type { BetterAuthClientPlugin } from "better-auth"; +import type { storagePlugin } from "./plugin"; + +export const storageClient = () => { + return { + id: "storage-client", + $InferServerPlugin: {} as ReturnType, + pathMethods: { + "/storage/delete-repo": "POST", + }, + } satisfies BetterAuthClientPlugin; +}; diff --git a/packages/storage/src/db-schema.ts b/packages/storage/src/db-schema.ts new file mode 100644 index 00000000..10de5fae --- /dev/null +++ b/packages/storage/src/db-schema.ts @@ -0,0 +1,96 @@ +import type { BetterAuthDBSchema, InferDBFieldsOutput } from "better-auth"; +import * as z from "zod/v4"; + +export const storageSchema = { + repository: { + fields: { + name: { + type: "string", + required: true, + }, + // slug example: `/` + slug: { + type: "string", + required: true, + unique: true, + validator: { + input: z.templateLiteral([ + z + .string() + .min(1) + .max(100) + .regex(/^[-a-z0-9]+$/), + "/", + z + .string() + .min(1) + .max(100) + .regex(/^[-a-z0-9]+$/), + ]), + }, + }, + createdAt: { + type: "date", + required: true, + }, + updatedAt: { + type: "date", + required: false, + }, + description: { + type: "string", + required: false, + }, + visibility: { + type: "string", + required: true, + }, + }, + modelName: "repository", + }, + repositoryMember: { + fields: { + repositoryId: { + type: "string", + required: true, + references: { + model: "repository", + field: "id", + }, + }, + userId: { + type: "string", + required: true, + references: { + model: "user", + field: "id", + }, + }, + createdAt: { + type: "date", + required: true, + }, + updatedAt: { + type: "date", + required: false, + }, + }, + modelName: "repositoryMember", + }, +} satisfies BetterAuthDBSchema; +type StorageSchema = typeof storageSchema; + +// Helpers +type ID = { id: string }; +export type GetFields = InferDBFieldsOutput< + StorageSchema[T]["fields"] +>; + +// Specific Types +export type Visibility = "public" | "private"; + +// Model Types +export type Repository = GetFields<"repository"> & { visibility: Visibility } & ID; +export type RepositoryInput = GetFields<"repository"> & { visibility: Visibility } & ID; // ID is included - we map our own IDs to Code.Storage repo IDs +export type RepositoryMember = GetFields<"repositoryMember"> & ID; +export type RepositoryMemberInput = GetFields<"repositoryMember">; diff --git a/apps/web/src/lib/storage/index.ts b/packages/storage/src/index.ts similarity index 70% rename from apps/web/src/lib/storage/index.ts rename to packages/storage/src/index.ts index d0048bfc..af12eeb6 100644 --- a/apps/web/src/lib/storage/index.ts +++ b/packages/storage/src/index.ts @@ -2,5 +2,5 @@ import { GitStorage } from "@pierre/storage"; export const storage = new GitStorage({ name: "better-hub", - key: process.env.GIT_STORAGE_PRIVATE_KEY!, + key: process.env["GIT_STORAGE_PRIVATE_KEY"]!, }); diff --git a/packages/storage/src/lib/middleware.ts b/packages/storage/src/lib/middleware.ts new file mode 100644 index 00000000..17154869 --- /dev/null +++ b/packages/storage/src/lib/middleware.ts @@ -0,0 +1,8 @@ +import { createAuthMiddleware } from "better-auth/api"; +import type { parseSlugInit } from "./parse-slug"; + +export const storageMiddleware = createAuthMiddleware(async () => { + return {} as { + parseSlug: ReturnType; + }; +}); diff --git a/packages/storage/src/lib/parse-slug.ts b/packages/storage/src/lib/parse-slug.ts new file mode 100644 index 00000000..5f6e246a --- /dev/null +++ b/packages/storage/src/lib/parse-slug.ts @@ -0,0 +1,52 @@ +import type { AuthContext } from "better-auth"; +import type { Organization } from "better-auth/plugins"; +import type { Repository } from "../db-schema"; + +export const parseSlugInit = + (ctx: AuthContext) => + /** + * Helper to parse a string slug into [organization, repository] + * Additionally, you can pass `getOrg` or `getRepo` to get the organization or repository object instead of the slug + * @returns + */ + async ( + slug: `${string}/${string}`, + options?: { getOrg?: O; getRepo?: R }, + ): Promise< + [ + organization: (O extends true ? Organization : string) | null, + repository: (R extends true ? Repository : string) | null, + ] + > => { + const adapter = ctx.adapter; + const [organization, repository] = slug.split("/"); + let result: Record<"organization" | "repository", any> = { + organization: null, + repository: null, + }; + + if (!organization) { + result.organization = null; + } else if (options?.getOrg) { + const organizationValue = await adapter.findOne({ + model: "organization", + where: [{ field: "slug", value: organization }], + }); + result.organization = organizationValue; + } else { + result.organization = organization; + } + + if (!repository) { + result.repository = null; + } else if (options?.getRepo) { + const repositoryValue = await adapter.findOne({ + model: "repository", + where: [{ field: "slug", value: repository }], + }); + result.repository = repositoryValue; + } else { + result.repository = repository; + } + return [result.organization, result.repository] as any; + }; diff --git a/packages/storage/src/plugin.ts b/packages/storage/src/plugin.ts new file mode 100644 index 00000000..08208e47 --- /dev/null +++ b/packages/storage/src/plugin.ts @@ -0,0 +1,22 @@ +import type { BetterAuthPlugin } from "better-auth"; +import { storageSchema } from "./db-schema"; +import { parseSlugInit } from "./lib/parse-slug"; +import { createRepo } from "./routes/create-repo"; +import { listRepo } from "./routes/list-repo"; +import { deleteRepo } from "./routes/delete-repo"; + +export const storagePlugin = () => { + return { + id: "storage", + schema: storageSchema, + init(ctx) { + return { + context: { + ...ctx, + parseSlug: parseSlugInit(ctx), + }, + }; + }, + endpoints: { createRepo: createRepo, listRepo: listRepo, deleteRepo: deleteRepo }, + } satisfies BetterAuthPlugin; +}; diff --git a/packages/storage/src/routes/create-repo.ts b/packages/storage/src/routes/create-repo.ts new file mode 100644 index 00000000..658c6a3e --- /dev/null +++ b/packages/storage/src/routes/create-repo.ts @@ -0,0 +1,66 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import { storageAdapter } from "../adapter"; +import * as z from "zod/v4"; +import { slugSchema } from "../zod-schema"; +import { storageMiddleware } from "../lib/middleware"; +import { storage } from ".."; + +const body = z.object({ + name: z.string().min(1), + slug: slugSchema, + description: z.string().optional(), + visibility: z.enum(["public", "private"]), +}); + +export const createRepo = createAuthEndpoint( + "/storage/create-repo", + { + method: "POST", + use: [sessionMiddleware, storageMiddleware], + body, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const { user } = ctx.context.session; + const data = { ...ctx.body, user }; + + const [org, repo] = await ctx.context.parseSlug(data.slug, { getOrg: true }); + + if (!org) { + throw ctx.error("BAD_REQUEST", { + message: "Organization not found", + code: "ORGANIZATION_NOT_FOUND", + }); + } + if (!repo) { + throw ctx.error("BAD_REQUEST", { + message: "Repository slug is invalid", + code: "INVALID_REPOSITORY_SLUG", + }); + } + + const result = await adapter.createRepo(data); + if ("repository" in result) { + const repository = await storage.createRepo({ + id: result.repository.id, + }); + const remoteURL = await repository.getRemoteURL({ + permissions: ["git:read", "git:write", "org:read", "repo:write"], + }); + + const defaultBranch = repository.defaultBranch; + + const value = { + remoteURL, + defaultBranch, + repository: result.repository, + }; + + console.log(`Repository created:`, value); + + return value; + } + + throw result; + }, +); diff --git a/packages/storage/src/routes/delete-repo.ts b/packages/storage/src/routes/delete-repo.ts new file mode 100644 index 00000000..0d926901 --- /dev/null +++ b/packages/storage/src/routes/delete-repo.ts @@ -0,0 +1,46 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import { storageMiddleware } from "../lib/middleware"; +import { storage } from ".."; +import * as z from "zod/v4"; +import { storageAdapter } from "../adapter"; + +const body = z.object({ + id: z.string(), +}); + +export const deleteRepo = createAuthEndpoint( + "/storage/delete-repo", + { + method: "POST", + use: [sessionMiddleware, storageMiddleware], + body, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + + // TODO: Authorization check to ensure user has perms to delete the repo + + console.log(`checking if repo exists ${ctx.body.id}`); + const repoExists = await adapter.checkRepoExistsById(ctx.body.id); + console.log(`repo exists ${repoExists}`); + if (!repoExists) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found", + code: "REPOSITORY_NOT_FOUND", + }); + } + await adapter.deleteRepo(ctx.body.id); + try { + await storage.deleteRepo({ + id: ctx.body.id, + }); + } catch { + throw ctx.error("NOT_FOUND", { + message: "Repository not found", + code: "REPOSITORY_NOT_FOUND", + }); + } + + return ctx.json({ success: true }); + }, +); diff --git a/packages/storage/src/routes/list-repo.ts b/packages/storage/src/routes/list-repo.ts new file mode 100644 index 00000000..6f248ea2 --- /dev/null +++ b/packages/storage/src/routes/list-repo.ts @@ -0,0 +1,16 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import { storageMiddleware } from "../lib/middleware"; +import { storageAdapter } from "../adapter"; + +export const listRepo = createAuthEndpoint( + "/storage/list-repo", + { + method: "GET", + use: [sessionMiddleware, storageMiddleware], + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const repos = await adapter.listRepos(ctx.context.session.user.id); + return repos; + }, +); diff --git a/packages/storage/src/zod-schema.ts b/packages/storage/src/zod-schema.ts new file mode 100644 index 00000000..3e5df4e4 --- /dev/null +++ b/packages/storage/src/zod-schema.ts @@ -0,0 +1,8 @@ +import * as z from "zod/v4"; + +const slugSegmentSchema = z + .string() + .min(1) + .max(100) + .regex(/^[a-z0-9-_]+$/); +export const slugSchema = z.templateLiteral([slugSegmentSchema, "/", slugSegmentSchema]); diff --git a/packages/storage/tsconfig.json b/packages/storage/tsconfig.json new file mode 100644 index 00000000..a0938e51 --- /dev/null +++ b/packages/storage/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "noEmit": false + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/storage/tsdown.config.ts b/packages/storage/tsdown.config.ts new file mode 100644 index 00000000..fe5b41d3 --- /dev/null +++ b/packages/storage/tsdown.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: [ + "src/index.ts", + "src/client.ts", + "src/plugin.ts", + "src/adapter.ts", + "src/db-schema.ts", + ], + format: "esm", + dts: true, + clean: true, + exports: true, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index f046bae9..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,15289 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@types/node': - specifier: ^25.3.0 - version: 25.3.0 - lint-staged: - specifier: ^16.2.7 - version: 16.2.7 - oxfmt: - specifier: ^0.34.0 - version: 0.34.0 - oxlint: - specifier: ^1.43.0 - version: 1.49.0 - simple-git-hooks: - specifier: ^2.13.1 - version: 2.13.1 - typescript: - specifier: ^5.7.0 - version: 5.9.3 - - apps/web: - dependencies: - '@ai-sdk/anthropic': - specifier: ^3.0.44 - version: 3.0.46(zod@4.3.6) - '@ai-sdk/react': - specifier: ^3.0.99 - version: 3.0.99(react@19.2.4)(zod@4.3.6) - '@aws-sdk/client-s3': - specifier: ^3.998.0 - version: 3.998.0 - '@aws-sdk/s3-request-presigner': - specifier: ^3.998.0 - version: 3.998.0 - '@better-auth/infra': - specifier: ^0.1.8 - version: 0.1.8(@better-auth/utils@0.3.1)(better-auth@1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(kysely@0.28.11)(nanostores@1.1.0)(zod@4.3.6) - '@better-auth/stripe': - specifier: 1.5.0-beta.18 - version: 1.5.0-beta.18(b897a05a0ee982447836563041d27c5f) - '@better-auth/utils': - specifier: ^0.3.1 - version: 0.3.1 - '@mixedbread-ai/sdk': - specifier: ^2.2.11 - version: 2.2.11 - '@octokit/rest': - specifier: ^22.0.1 - version: 22.0.1 - '@openrouter/ai-sdk-provider': - specifier: ^2.2.3 - version: 2.2.3(ai@6.0.97(zod@4.3.6))(zod@4.3.6) - '@prisma/adapter-pg': - specifier: ^7.4.1 - version: 7.4.1 - '@prisma/client': - specifier: ^7.4.1 - version: 7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) - '@radix-ui/react-avatar': - specifier: ^1.1.11 - version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-dialog': - specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-dropdown-menu': - specifier: ^2.1.16 - version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-popover': - specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': - specifier: ^1.2.4 - version: 1.2.4(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-tooltip': - specifier: ^1.2.8 - version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-visually-hidden': - specifier: ^1.2.4 - version: 1.2.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@sentry/nextjs': - specifier: ^10 - version: 10.40.0(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(webpack@5.105.2) - '@tanstack/react-hotkeys': - specifier: ^0.3.0 - version: 0.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tanstack/react-query': - specifier: ^5.90.21 - version: 5.90.21(react@19.2.4) - '@tiptap/extension-link': - specifier: ^3.19.0 - version: 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-mention': - specifier: ^3.19.0 - version: 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)(@tiptap/suggestion@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-placeholder': - specifier: ^3.19.0 - version: 3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/react': - specifier: ^3.19.0 - version: 3.20.0(@floating-ui/dom@1.7.5)(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tiptap/starter-kit': - specifier: ^3.19.0 - version: 3.20.0 - '@tiptap/suggestion': - specifier: ^3.19.0 - version: 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@upstash/redis': - specifier: ^1.36.2 - version: 1.36.2 - '@vercel/analytics': - specifier: ^1.6.1 - version: 1.6.1(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) - '@vercel/functions': - specifier: ^3.4.2 - version: 3.4.2(@aws-sdk/credential-provider-web-identity@3.972.12) - ai: - specifier: ^6.0.97 - version: 6.0.97(zod@4.3.6) - auth: - specifier: 1.5.0-beta.18 - version: 1.5.0-beta.18(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(nanostores@1.1.0)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - better-all: - specifier: ^0.0.7 - version: 0.0.7 - better-auth: - specifier: 1.5.0-beta.18 - version: 1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - cmdk: - specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - dotenv: - specifier: ^17.3.1 - version: 17.3.1 - e2b: - specifier: ^2.12.1 - version: 2.12.1 - foxact: - specifier: ^0.2.52 - version: 0.2.52(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - inngest: - specifier: ^3.52.3 - version: 3.52.3(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@vercel/node@5.6.6(rollup@4.59.0))(hono@4.11.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(zod@4.3.6) - lucide-react: - specifier: ^0.575.0 - version: 0.575.0(react@19.2.4) - motion: - specifier: ^12.34.3 - version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - next: - specifier: 16.1.6 - version: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - next-themes: - specifier: ^0.4.6 - version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - nuqs: - specifier: ^2.8.8 - version: 2.8.8(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) - pg: - specifier: ^8.18.0 - version: 8.18.0 - prisma: - specifier: ^7.4.1 - version: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - react: - specifier: 19.2.4 - version: 19.2.4 - react-dom: - specifier: 19.2.4 - version: 19.2.4(react@19.2.4) - react-markdown: - specifier: ^10.1.0 - version: 10.1.0(@types/react@19.2.14)(react@19.2.4) - rehype-raw: - specifier: ^7.0.0 - version: 7.0.0 - rehype-sanitize: - specifier: ^6.0.0 - version: 6.0.0 - rehype-stringify: - specifier: ^10.0.1 - version: 10.0.1 - remark-gfm: - specifier: ^4.0.1 - version: 4.0.1 - remark-parse: - specifier: ^11.0.0 - version: 11.0.0 - remark-rehype: - specifier: ^11.1.2 - version: 11.1.2 - shiki: - specifier: ^3.22.0 - version: 3.22.0 - stripe: - specifier: ^20.4.0 - version: 20.4.0(@types/node@25.3.0) - supermemory: - specifier: ^4.11.1 - version: 4.11.1 - tailwind-merge: - specifier: ^3.4.1 - version: 3.5.0 - tiptap-markdown: - specifier: ^0.9.0 - version: 0.9.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - tw-animate-css: - specifier: ^1.4.0 - version: 1.4.0 - unified: - specifier: ^11.0.5 - version: 11.0.5 - vercel: - specifier: ^50.22.1 - version: 50.22.1(rollup@4.59.0)(typescript@5.9.3) - zod: - specifier: ^4.3.6 - version: 4.3.6 - devDependencies: - '@tailwindcss/postcss': - specifier: ^4 - version: 4.2.0 - '@types/pg': - specifier: ^8.16.0 - version: 8.16.0 - '@types/react': - specifier: ^19 - version: 19.2.14 - '@types/react-dom': - specifier: ^19 - version: 19.2.3(@types/react@19.2.14) - tailwindcss: - specifier: ^4 - version: 4.2.0 - -packages: - - '@ai-sdk/anthropic@3.0.46': - resolution: {integrity: sha512-zXJPiNHaIiQ6XUqLeSYZ3ZbSzjqt1pNWEUf2hlkXlmmw8IF8KI0ruuGaDwKCExmtuNRf0E4TDxhsc9wRgWTzpw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/gateway@3.0.53': - resolution: {integrity: sha512-QT3FEoNARMRlk8JJVR7L98exiK9C8AGfrEJVbRxBT1yIXKs/N19o/+PsjTRVsARgDJNcy9JbJp1FspKucEat0Q==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@4.0.15': - resolution: {integrity: sha512-8XiKWbemmCbvNN0CLR9u3PQiet4gtEVIrX4zzLxnCj06AwsEDJwJVBbKrEI4t6qE8XRSIvU2irka0dcpziKW6w==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider@3.0.8': - resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} - engines: {node: '>=18'} - - '@ai-sdk/react@3.0.99': - resolution: {integrity: sha512-xMsp5br4Dpr/3BYq/jrE8q4YLgViU1KHVq8VB0+dzdLJFU3jKA83uoxpbWqzV/edQOBPgGBSb2CgmV5v77rvzA==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@authenio/xml-encryption@2.0.2': - resolution: {integrity: sha512-cTlrKttbrRHEw3W+0/I609A2Matj5JQaRvfLtEIGZvlN0RaPi+3ANsMeqAyCAVlH/lUIW2tmtBlSMni74lcXeg==} - engines: {node: '>=12'} - - '@aws-crypto/crc32@5.2.0': - resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} - engines: {node: '>=16.0.0'} - - '@aws-crypto/crc32c@5.2.0': - resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==} - - '@aws-crypto/sha1-browser@5.2.0': - resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==} - - '@aws-crypto/sha256-browser@5.2.0': - resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} - - '@aws-crypto/sha256-js@5.2.0': - resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} - engines: {node: '>=16.0.0'} - - '@aws-crypto/supports-web-crypto@5.2.0': - resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} - - '@aws-crypto/util@5.2.0': - resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - - '@aws-sdk/client-s3@3.998.0': - resolution: {integrity: sha512-XkJ6GN+egutEHSa9+t4OngCRyyP6Zl+4FX+hN7rDqlLjPuK++NHdMVrRSaVq1/H1m0+Nif0Rtz1BiTYP/htmvg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/core@3.973.14': - resolution: {integrity: sha512-iAQ1jIGESTVjoqNNY9VlsE9FnCz+Hc8s+dgurF6WrgFyVIw+uggH+V102RFhwjRv4dLSSLfzjDwvQnLszov7TQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/crc64-nvme@3.972.2': - resolution: {integrity: sha512-mhTYqkvoC9pm8Lm7KWmH/BDXylzwOTnqqbix4mUG/AODazcigIKRYkzPc2bld6q4h9q1asQCiPC2S1Q6rvSjIQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-env@3.972.12': - resolution: {integrity: sha512-WPtj/iAYHHd+NDM6AZoilZwUz0nMaPxbTPGLA7nhyIYRZN2L8trqfbNvm7g/Jr3gzfKp1LpO6AtBTnrhz9WW2g==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-http@3.972.14': - resolution: {integrity: sha512-umtjCicH2o/Fcc8Fu1562UkDyt6gql4czTYVlUfHfAM8S4QEKggzmtHYYYpPfQcjFj1ajyy68ahYSuF67x4ptQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-ini@3.972.12': - resolution: {integrity: sha512-qjzgnMl6GIBbVeK74jBqSF07+s6kyeZl5R88qjMs302JlqkxE57jkvflDmZ9I017ffEWqIUa9/M4Hfp28qyu1g==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-login@3.972.12': - resolution: {integrity: sha512-AO57y46PzG24bJzxWLk+FYJG6MzxvXoFXnOKnmKUGV43ub4/FS/4Rz7zCC6ThqUotgqEFd30l5LTAd65RP65pg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-node@3.972.13': - resolution: {integrity: sha512-ME2sgus+gFRtiudy5Xqj9iT/tj8lHOIGrFgktuO5skJU4EngOvTZ1Hpj8mknrW4FgWXmpWhc88NtEscUuuDpKw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-process@3.972.12': - resolution: {integrity: sha512-msxrHBpVP5AOIDohNPCINUtL47f7XI1TEru3N13uM3nWUMvIRA1vFa8Tlxbxm1EntPPvLAxRmvE5EbjDjOZkbw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-sso@3.972.12': - resolution: {integrity: sha512-D5iC5546hJyhobJN0szOT4KVeJQ8z/meZq2B3lEDZFcvHONKw+tzq36DAJUy3qLTueeB2geSxiHXngQlA11eoA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.972.12': - resolution: {integrity: sha512-yluBahBVsduoA/zgV0NAXtwwXvQ6tNn95dNA3Hg+vISdiPWA46QY0d9PLO2KpNbjtm+1oGcWxemS4fYTwJ0W1w==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-bucket-endpoint@3.972.5': - resolution: {integrity: sha512-4+PMX1vuPoALVhuyW7M2GkV9XrkUeuqhuXPs1IkGo2/5dFM8TxM7gnB/evSNVF/o6NXwnO4Sc+6UtGCDhI6RLg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-expect-continue@3.972.5': - resolution: {integrity: sha512-8dM11mmRZ8ZrDdkBL5q7Rslhua/nASrUhis2BJuwz2hJ+QsyyuOtr2vvc83fM91YXq18oe26bZI9tboroSo4NA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-flexible-checksums@3.973.0': - resolution: {integrity: sha512-RAYonYq4Tk93fB+QlLlCEaB1nHSM4lTWq4KBJ7s5bh6y30uGaVTmFELSeWlfLVJipyJ/T1FBWmrYETMcNsESoQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-host-header@3.972.5': - resolution: {integrity: sha512-dVA0m1cEQ2iA6yB19aHvWNeUVTuvTt3AXzT0aiIu2uxk0S7AcmwDCDaRgYa/v+eFHcJVxEnpYTozqA7X62xinw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-location-constraint@3.972.5': - resolution: {integrity: sha512-BC8MQUaG78oEGOjDdyGBLQCbio/KNeeMcbN8GZumW6yowe5MHyt//FJr8sipA1/hLOZ++lfpGk9bdaSo7LUpOw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-logger@3.972.5': - resolution: {integrity: sha512-03RqplLZjUTkYi0dDPR/bbOLnDLFNdaVvNENgA3XK7Ph1MhEBhUYlgoGfOyRAKApDZ+WG4ykOoA8jI8J04jmFA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-recursion-detection@3.972.5': - resolution: {integrity: sha512-2QSuuVkpHTe84+mDdnFjHX8rAP3g0yYwLVAhS3lQN1rW5Z/zNsf8/pYQrLjLO4n4sPCsUAkTa0Vrod0lk+o1Tg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-sdk-s3@3.972.14': - resolution: {integrity: sha512-qnNWgL2WLZbWQmrr+yB23ivo/L7POJxxFlQxhfDGM/NQ4OfG7YORtqwLps0mOMI8pH22kVeoNu+PB8cgRXLoqQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-ssec@3.972.5': - resolution: {integrity: sha512-AfQgwVjK071d1F75jX49CE5KJTlAWwMKqHJoGzf8nUD04iSHw+93rzKSGAFHu3v06k32algI6pF+ctqV/Fjc1A==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-user-agent@3.972.14': - resolution: {integrity: sha512-PzDz+yRAQuIzd+4ZY3s6/TYRzlNKAn4Gae3E5uLV7NnYHqrZHFoAfKE4beXcu3C51pA2/FQ3X2qOGSYqUoN1WQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/nested-clients@3.996.2': - resolution: {integrity: sha512-W+u6EM8WRxOIhAhR2mXMHSaUygqItpTehkgxLwJngXqr9RlAR4t6CtECH7o7QK0ct3oyi5Z8ViDHtPbel+D2Rg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/region-config-resolver@3.972.5': - resolution: {integrity: sha512-AOitrygDwfTNCLCW7L+GScDy1p49FZ6WutTUFWROouoPetfVNmpL4q8TWD3MhfY/ynhoGhleUQENrBH374EU8w==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/s3-request-presigner@3.998.0': - resolution: {integrity: sha512-Kx9uIEO1iY+zlO7SXQR2LwH2MmtDcHGJJPLT6C+0C8DM16kNei0pXC5y3OyHp3x63YMpKpkRNjphCdi5/wy0Ug==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/signature-v4-multi-region@3.996.2': - resolution: {integrity: sha512-fUWHKtgeTfTEML5gi3yugy7caaoe7/8YdM/H0gQXuSDYNL3hORyGST5RyLnhfVDeNgypANLpIP6wzzIq74kEwQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/token-providers@3.998.0': - resolution: {integrity: sha512-JFzi44tQnENZQ+1DYcHfoa/wTRKkccz0VsNMow0rvsxZtqUEkeV2pYFbir35mHTyUKju9995ay1MAGxLt1dpRA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/types@3.973.3': - resolution: {integrity: sha512-tma6D8/xHZHJEUqmr6ksZjZ0onyIUqKDQLyp50ttZJmS0IwFYzxBgp5CxFvpYAnah52V3UtgrqGA6E83gtT7NQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-arn-parser@3.972.2': - resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-endpoints@3.996.2': - resolution: {integrity: sha512-83E6T1CKi0/IozPzqRBKqduW0mS4UQdI3soBH6CG7UgupTADWunqEMOTuPWCs9XGjpJJ4ujj+yu7pn8svhp5yg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-format-url@3.972.5': - resolution: {integrity: sha512-PccfrPQVOEQSL8xaSvu988ESMlqdH1Qfk3AWPZksCOYPHyzYeUV988E+DBachXNV7tBVTUvK85cZYEZu7JtPxQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-locate-window@3.965.4': - resolution: {integrity: sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-user-agent-browser@3.972.5': - resolution: {integrity: sha512-2ja1WqtuBaEAMgVoHYuWx393DF6ULqdt3OozeO7BosqouYaoU47Adtp9vEF+GImSG/Q8A+dqfwDULTTdMkHGUQ==} - - '@aws-sdk/util-user-agent-node@3.972.13': - resolution: {integrity: sha512-PHErmuu+v6iAST48zcsB2cYwDKW45gk6qCp49t1p0NGZ4EaFPr/tA5jl0X/ekDwvWbuT0LTj++fjjdVQAbuh0Q==} - engines: {node: '>=20.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - - '@aws-sdk/xml-builder@3.972.7': - resolution: {integrity: sha512-9GF86s6mHuc1TYCbuKatMDWl2PyK3KIkpRaI7ul2/gYZPfaLzKZ+ISHhxzVb9KVeakf75tUQe6CXW2gugSCXNw==} - engines: {node: '>=20.0.0'} - - '@aws/lambda-invoke-store@0.2.3': - resolution: {integrity: sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==} - engines: {node: '>=18.0.0'} - - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.28.6': - resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.28.5': - resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.28.6': - resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-commonjs@7.28.6': - resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-display-name@7.28.0': - resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-development@7.27.1': - resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx@7.28.6': - resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-pure-annotations@7.27.1': - resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.28.6': - resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-react@7.28.5': - resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-typescript@7.28.5': - resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@better-auth/core@1.5.0-beta.16': - resolution: {integrity: sha512-eGM4Q2Btj6WNh/9jGTUIFsvFPt4kUsRa9/3tDSPfY/M3OkCUFkscANTeq/AVyJkBMO/IG2pQ8F48Hy1CBn7eyw==} - peerDependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - better-call: 1.3.2 - jose: ^6.1.0 - kysely: ^0.28.5 - nanostores: ^1.0.1 - - '@better-auth/core@1.5.0-beta.18': - resolution: {integrity: sha512-bwR8uH10PiEK6lQhmF37VzUc+bmY79KKHd0UGuM4Bi5INEivYCZjpI2pKUB+aVgnxKjovpbUYjoB+NpuwTXK0A==} - peerDependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - better-call: 1.3.2 - jose: ^6.1.0 - kysely: ^0.28.5 - nanostores: ^1.0.1 - - '@better-auth/core@1.5.0-beta.20': - resolution: {integrity: sha512-6RmDZ6kU85u1BR/H6OPjV3Z9LrfnCXKVEXFCjOUy0lgNOLRD2QOL59fgu2rpGc85aDxjDi2ddRPrSfvySGnybg==} - peerDependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - better-call: 1.3.2 - jose: ^6.1.0 - kysely: ^0.28.5 - nanostores: ^1.0.1 - - '@better-auth/drizzle-adapter@1.5.0-beta.16': - resolution: {integrity: sha512-ArM+7rWepLN7kFXIDmkV9CFBblBhfwOVIzPJgv7ZaWnAsjGj5oLhSkBQXvAfw0W/2UK1yziSuD4/HqiqKuEl7Q==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - '@better-auth/utils': ^0.3.0 - drizzle-orm: '>=0.41.0' - - '@better-auth/drizzle-adapter@1.5.0-beta.18': - resolution: {integrity: sha512-lj8hmlJrV6Uoc3pBxTx+qKNJq0NU3AMXNVg5bxLoc6fp/ibQM6ROFT30XDYX/X5YG342oYAWAuwP0Pu7LjWonw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - '@better-auth/utils': ^0.3.0 - drizzle-orm: '>=0.41.0' - - '@better-auth/infra@0.1.8': - resolution: {integrity: sha512-kRQLeHf6OPGuys7bF3Q0qCwebOlvu0hdmr2OHb2ZPbKo3gLE58HHH/s8Y1ZiO8H5tH+rt2a8AyE3+vLDW5NDoQ==} - peerDependencies: - better-auth: '>=1.4.15' - zod: '>=4.1.12' - - '@better-auth/kysely-adapter@1.5.0-beta.16': - resolution: {integrity: sha512-I/JdEWaFFrQZSGwbr5NmG6CFSA2zqiQqOZODQN35jAKXcCRHl7ArMvBgEybxnposJfND857TsOGf6yGWlqDTJw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - '@better-auth/utils': ^0.3.0 - kysely: ^0.27.0 || ^0.28.0 - - '@better-auth/kysely-adapter@1.5.0-beta.18': - resolution: {integrity: sha512-iJmjio4Wxp3/XH4sgVOUA6AJz3arFeqrqThLyZP+CLcvqva57BhtVjqBgkwCpGgzjQyuKh2yUdtNVcg2OjdEUg==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - '@better-auth/utils': ^0.3.0 - kysely: ^0.27.0 || ^0.28.0 - - '@better-auth/memory-adapter@1.5.0-beta.16': - resolution: {integrity: sha512-aldCjQS8c6MRTe7xzIYNUJyNHTUVXKnLjp/LkufZjzB2mgews0nTLhJNRN06qlGM4wZwt2xZArDYgZmmIBJp+Q==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - '@better-auth/utils': ^0.3.0 - - '@better-auth/memory-adapter@1.5.0-beta.18': - resolution: {integrity: sha512-vm3QTBWS4isJBTdKADfwNNt52C5yvdTruTHNqanujA/NnfGlEwv3T4qUKct/aUNcsWurj9Bd+ns65HBR2JwcfQ==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - '@better-auth/utils': ^0.3.0 - - '@better-auth/mongo-adapter@1.5.0-beta.16': - resolution: {integrity: sha512-9FxlAt0/q0Aozg201WsefMGupsXL2bDD1RaIHCJsuhviWybWqf8GIlNabir9q4h93Y8iv2pjS/wRa0dAbgZnjw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - '@better-auth/utils': ^0.3.0 - mongodb: ^6.0.0 || ^7.0.0 - - '@better-auth/mongo-adapter@1.5.0-beta.18': - resolution: {integrity: sha512-Y8lPbB63w4dmIdycHnQtoaUkEc0wlwxVD+mEjCZ8Q4uzLWs0W7+DKYlGe81r5pmz+T++H1eSm6Md/c2EEsPkvQ==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - '@better-auth/utils': ^0.3.0 - mongodb: ^6.0.0 || ^7.0.0 - - '@better-auth/prisma-adapter@1.5.0-beta.16': - resolution: {integrity: sha512-5xBsHd1LIhtIZGJ6D1m7GRKQ15pN1cX0N4yTY5BTvssmqGBUu2mKNmgcERESoENO5VAGpmd6Gky+nG/9hvH4vQ==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - '@better-auth/utils': ^0.3.0 - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 - prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@better-auth/prisma-adapter@1.5.0-beta.18': - resolution: {integrity: sha512-B6l2geVm/NSDcElI4jtT3I5ZtzSz27HismeG7GPveJ11zeDztZBugD3ulJguAsuS+NGbmc8PHyOJ3nCeJm7ZjA==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - '@better-auth/utils': ^0.3.0 - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 - prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@better-auth/sso@1.5.0-beta.20': - resolution: {integrity: sha512-seYOvqpqxYHLVa2gfEg2WtyHNjbNr6epk7dx/Qf/oTHYj4N0psKv5vGJ4KNiuCjh68qJDSe9tXo0nUHXIgToNw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.20 - '@better-auth/utils': 0.3.1 - better-auth: 1.5.0-beta.20 - better-call: 1.3.2 - - '@better-auth/stripe@1.5.0-beta.18': - resolution: {integrity: sha512-pErBWGGyDiuEhJkbfvpx0QAclOx/gd8sgUejsZ2vFCBU+EJEMLgfXeDppOOOM8Yeuk2AqvYN4IqxNBQ0fKbQhw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - better-auth: 1.5.0-beta.18 - better-call: 1.3.2 - stripe: ^18 || ^19 || ^20 - - '@better-auth/telemetry@1.5.0-beta.16': - resolution: {integrity: sha512-EiNe7xSQkuypvR9i/C10M/DhoLyba+Ptdeczrj1z8Z+2/bP65utkwQ/Vq0j0zw7K8IgRp7CuMtrDa4j8Fp08Xw==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.16 - - '@better-auth/telemetry@1.5.0-beta.18': - resolution: {integrity: sha512-+ihwfSllAD5Xh3AWn83coEt7dXighu6Gpgixvqtpvawtsu5ITLViLHyy9yRmLtkRWui4+YhOZqHjaIBeA4Gcew==} - peerDependencies: - '@better-auth/core': 1.5.0-beta.18 - - '@better-auth/utils@0.3.1': - resolution: {integrity: sha512-+CGp4UmZSUrHHnpHhLPYu6cV+wSUSvVbZbNykxhUDocpVNTo9uFFxw/NqJlh1iC4wQ9HKKWGCKuZ5wUgS0v6Kg==} - - '@better-fetch/fetch@1.1.19-beta.1': - resolution: {integrity: sha512-KAkXqvjO2x4U+STKDMGcKSMf+xJ/xUEBKV6DrOtjoiBBmmEVLNKzrEc3gkqwXSbCj7PllzqhSvYOmxEFwHoMFw==} - - '@better-fetch/fetch@1.1.21': - resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} - - '@bufbuild/protobuf@2.11.0': - resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} - - '@bytecodealliance/preview2-shim@0.17.6': - resolution: {integrity: sha512-n3cM88gTen5980UOBAD6xDcNNL3ocTK8keab21bpx1ONdA+ARj7uD1qoFxOWCyKlkpSi195FH+GeAut7Oc6zZw==} - - '@chevrotain/cst-dts-gen@10.5.0': - resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} - - '@chevrotain/gast@10.5.0': - resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} - - '@chevrotain/types@10.5.0': - resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} - - '@chevrotain/utils@10.5.0': - resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} - - '@clack/core@0.5.0': - resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} - - '@clack/prompts@0.11.0': - resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} - - '@connectrpc/connect-web@2.0.0-rc.3': - resolution: {integrity: sha512-w88P8Lsn5CCsA7MFRl2e6oLY4J/5toiNtJns/YJrlyQaWOy3RO8pDgkz+iIkG98RPMhj2thuBvsd3Cn4DKKCkw==} - peerDependencies: - '@bufbuild/protobuf': ^2.2.0 - '@connectrpc/connect': 2.0.0-rc.3 - - '@connectrpc/connect@2.0.0-rc.3': - resolution: {integrity: sha512-ARBt64yEyKbanyRETTjcjJuHr2YXorzQo0etyS5+P6oSeW8xEuzajA9g+zDnMcj1hlX2dQE93foIWQGfpru7gQ==} - peerDependencies: - '@bufbuild/protobuf': ^2.2.0 - - '@edge-runtime/format@2.2.1': - resolution: {integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==} - engines: {node: '>=16'} - - '@edge-runtime/node-utils@2.3.0': - resolution: {integrity: sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==} - engines: {node: '>=16'} - - '@edge-runtime/ponyfill@2.4.2': - resolution: {integrity: sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==} - engines: {node: '>=16'} - - '@edge-runtime/primitives@4.1.0': - resolution: {integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==} - engines: {node: '>=16'} - - '@edge-runtime/vm@3.2.0': - resolution: {integrity: sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==} - engines: {node: '>=16'} - - '@electric-sql/pglite-socket@0.0.20': - resolution: {integrity: sha512-J5nLGsicnD9wJHnno9r+DGxfcZWh+YJMCe0q/aCgtG6XOm9Z7fKeite8IZSNXgZeGltSigM9U/vAWZQWdgcSFg==} - hasBin: true - peerDependencies: - '@electric-sql/pglite': 0.3.15 - - '@electric-sql/pglite-tools@0.2.20': - resolution: {integrity: sha512-BK50ZnYa3IG7ztXhtgYf0Q7zijV32Iw1cYS8C+ThdQlwx12V5VZ9KRJ42y82Hyb4PkTxZQklVQA9JHyUlex33A==} - peerDependencies: - '@electric-sql/pglite': 0.3.15 - - '@electric-sql/pglite@0.3.15': - resolution: {integrity: sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ==} - - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - - '@esbuild/aix-ppc64@0.27.0': - resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.0': - resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.0': - resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.0': - resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.0': - resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.0': - resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.0': - resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.0': - resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.0': - resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.0': - resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.0': - resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.0': - resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.0': - resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.0': - resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.0': - resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.0': - resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.0': - resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.0': - resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.0': - resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.0': - resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.0': - resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.0': - resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.0': - resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.0': - resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.0': - resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.0': - resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@fastify/otel@0.16.0': - resolution: {integrity: sha512-2304BdM5Q/kUvQC9qJO1KZq3Zn1WWsw+WWkVmFEaj1UE2hEIiuFqrPeglQOwEtw/ftngisqfQ3v70TWMmwhhHA==} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@floating-ui/core@1.7.4': - resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - - '@floating-ui/dom@1.7.5': - resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - - '@floating-ui/react-dom@2.1.7': - resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - - '@grpc/grpc-js@1.14.3': - resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} - engines: {node: '>=12.10.0'} - - '@grpc/proto-loader@0.8.0': - resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==} - engines: {node: '>=6'} - hasBin: true - - '@hono/node-server@1.19.9': - resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - - '@iarna/toml@2.2.5': - resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} - - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} - cpu: [riscv64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [riscv64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@inngest/ai@0.1.7': - resolution: {integrity: sha512-5xWatW441jacGf9czKEZdgAmkvoy7GS2tp7X8GSbdGeRXzjisHR6vM+q8DQbv6rqRsmQoCQ5iShh34MguELvUQ==} - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.1': - resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} - engines: {node: 20 || >=22} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@isaacs/cliui@9.0.0': - resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} - engines: {node: '>=18'} - - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - - '@jpwilliams/waitgroup@2.1.1': - resolution: {integrity: sha512-0CxRhNfkvFCTLZBKGvKxY2FYtYW1yWhO2McLqBL0X5UWvYjIf9suH8anKW/DNutl369A75Ewyoh2iJMwBZ2tRg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@js-sdsl/ordered-map@4.4.2': - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - - '@mapbox/node-pre-gyp@2.0.3': - resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} - engines: {node: '>=18'} - hasBin: true - - '@mixedbread-ai/sdk@2.2.11': - resolution: {integrity: sha512-NJiY6BVPR+s/DTzUPQS1Pv418trOmII/8hftmIqxXlYaKbIrgJimQfwCW9M6Y21YPcMA8zTQGYZHm4IWlMjIQw==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - - '@mongodb-js/saslprep@1.4.6': - resolution: {integrity: sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==} - - '@mrleebo/prisma-ast@0.13.1': - resolution: {integrity: sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==} - engines: {node: '>=16'} - - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - - '@next/env@16.1.6': - resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==} - - '@next/swc-darwin-arm64@16.1.6': - resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@16.1.6': - resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@16.1.6': - resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@16.1.6': - resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@16.1.6': - resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@16.1.6': - resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@16.1.6': - resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@16.1.6': - resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@noble/ciphers@2.1.1': - resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==} - 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'} - - '@octokit/auth-token@6.0.0': - resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} - engines: {node: '>= 20'} - - '@octokit/core@7.0.6': - resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} - engines: {node: '>= 20'} - - '@octokit/endpoint@11.0.3': - resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} - engines: {node: '>= 20'} - - '@octokit/graphql@9.0.3': - resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} - engines: {node: '>= 20'} - - '@octokit/openapi-types@27.0.0': - resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} - - '@octokit/plugin-paginate-rest@14.0.0': - resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/plugin-request-log@6.0.0': - resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/plugin-rest-endpoint-methods@17.0.0': - resolution: {integrity: sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/request-error@7.1.0': - resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} - engines: {node: '>= 20'} - - '@octokit/request@10.0.7': - resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} - engines: {node: '>= 20'} - - '@octokit/rest@22.0.1': - resolution: {integrity: sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==} - engines: {node: '>= 20'} - - '@octokit/types@16.0.0': - resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - - '@openrouter/ai-sdk-provider@2.2.3': - resolution: {integrity: sha512-NovC+BaCfEeJwhToDrs8JeDYXXlJdEyz7lcxkjtyePSE4eoAKik872SyDK0MzXKcz8MRkv7XlNhPI6zz4TQp0g==} - engines: {node: '>=18'} - peerDependencies: - ai: ^6.0.0 - zod: ^3.25.0 || ^4.0.0 - - '@opentelemetry/api-logs@0.203.0': - resolution: {integrity: sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.207.0': - resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.208.0': - resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.211.0': - resolution: {integrity: sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.212.0': - resolution: {integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/auto-instrumentations-node@0.70.0': - resolution: {integrity: sha512-gSt1gxQLnGL62Xoh+9A6OZksSeYAKunnzR5VKks6esI+aTTZTLveVO6sq4BoUIMUV2WtsmuEGrcUwynU7cctGw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.4.1 - '@opentelemetry/core': ^2.0.0 - - '@opentelemetry/configuration@0.212.0': - resolution: {integrity: sha512-D8sAY6RbqMa1W8lCeiaSL2eMCW2MF87QI3y+I6DQE1j+5GrDMwiKPLdzpa/2/+Zl9v1//74LmooCTCJBvWR8Iw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@opentelemetry/context-async-hooks@2.5.1': - resolution: {integrity: sha512-MHbu8XxCHcBn6RwvCt2Vpn1WnLMNECfNKYB14LI5XypcgH4IE0/DiVifVR9tAkwPMyLXN8dOoPJfya3IryLQVw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/core@2.5.0': - resolution: {integrity: sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/core@2.5.1': - resolution: {integrity: sha512-Dwlc+3HAZqpgTYq0MUyZABjFkcrKTePwuiFVLjahGD8cx3enqihmpAmdgNFO1R4m/sIe5afjJrA25Prqy4NXlA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/exporter-logs-otlp-grpc@0.212.0': - resolution: {integrity: sha512-/0bk6fQG+eSFZ4L6NlckGTgUous/ib5+OVdg0x4OdwYeHzV3lTEo3it1HgnPY6UKpmX7ki+hJvxjsOql8rCeZA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-logs-otlp-http@0.212.0': - resolution: {integrity: sha512-JidJasLwG/7M9RTxV/64xotDKmFAUSBc9SNlxI32QYuUMK5rVKhHNWMPDzC7E0pCAL3cu+FyiKvsTwLi2KqPYw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-logs-otlp-proto@0.212.0': - resolution: {integrity: sha512-RpKB5UVfxc7c6Ta1UaCrxXDTQ0OD7BCGT66a97Q5zR1x3+9fw4dSaiqMXT/6FAWj2HyFbem6Rcu1UzPZikGTWQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-metrics-otlp-grpc@0.212.0': - resolution: {integrity: sha512-/6Gqf9wpBq22XsomR1i0iPGnbQtCq2Vwnrq5oiDPjYSqveBdK1jtQbhGfmpK2mLLxk4cPDtD1ZEYdIou5K8EaA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-metrics-otlp-http@0.212.0': - resolution: {integrity: sha512-8hgBw3aTTRpSTkU4b9MLf/2YVLnfWp+hfnLq/1Fa2cky+vx6HqTodo+Zv1GTIrAKMOOwgysOjufy0gTxngqeBg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-metrics-otlp-proto@0.212.0': - resolution: {integrity: sha512-C7I4WN+ghn3g7SnxXm2RK3/sRD0k/BYcXaK6lGU3yPjiM7a1M25MLuM6zY3PeVPPzzTZPfuS7+wgn/tHk768Xw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-prometheus@0.212.0': - resolution: {integrity: sha512-hJFLhCJba5MW5QHexZMHZdMhBfNqNItxOsN0AZojwD1W2kU9xM+BEICowFGJFo/vNV+I2BJvTtmuKafeDSAo7Q==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-trace-otlp-grpc@0.212.0': - resolution: {integrity: sha512-9xTuYWp8ClBhljDGAoa0NSsJcsxJsC9zCFKMSZJp1Osb9pjXCMRdA6fwXtlubyqe7w8FH16EWtQNKx/FWi+Ghw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-trace-otlp-http@0.212.0': - resolution: {integrity: sha512-v/0wMozNoiEPRolzC4YoPo4rAT0q8r7aqdnRw3Nu7IDN0CGFzNQazkfAlBJ6N5y0FYJkban7Aw5WnN73//6YlA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-trace-otlp-proto@0.212.0': - resolution: {integrity: sha512-d1ivqPT0V+i0IVOOdzGaLqonjtlk5jYrW7ItutWzXL/Mk+PiYb59dymy/i2reot9dDnBFWfrsvxyqdutGF5Vig==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/exporter-zipkin@2.5.1': - resolution: {integrity: sha512-Me6JVO7WqXGXsgr4+7o+B7qwKJQbt0c8WamFnxpkR43avgG9k/niTntwCaXiXUTjonWy0+61ZuX6CGzj9nn8CQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/instrumentation-amqplib@0.58.0': - resolution: {integrity: sha512-fjpQtH18J6GxzUZ+cwNhWUpb71u+DzT7rFkg5pLssDGaEber91Y2WNGdpVpwGivfEluMlNMZumzjEqfg8DeKXQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-amqplib@0.59.0': - resolution: {integrity: sha512-xscSgOJA+GHphESDZxBHNk/zjNaEgoeufMwmiqYdL+qM27Xw3BbR9vN6Ucbq9dW6Y+oYUPgTTj17qf+Za4+uzg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-aws-lambda@0.64.0': - resolution: {integrity: sha512-vYhM/a8fG34/Dl/Q9gfv5Ih3OFPgqeyn79S8FN+Xs/QZw6h6L8a1lDa3CyigyicOXLCmVIM7Fc9vFD4BGqgGLA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-aws-sdk@0.67.0': - resolution: {integrity: sha512-btpwJnZ2RBXDh/pTpfVpInpBu9Pedi+lbLKbt3naB344SggbbYnIdT7u8EzmGIApWi9EV91vw7hm896I7nESQA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-bunyan@0.57.0': - resolution: {integrity: sha512-W4zLz1Y9ptCsdL+QMXR7xQaBHkJivLBmVlLCjUe23rX4V8E65fGAtlIJSKTKAfz4aEgtWgQAGMdkeqACwG0Caw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-cassandra-driver@0.57.0': - resolution: {integrity: sha512-xLwrK+XnN32IB5i6t/a2j+SVdjlq/BIgjpVRkke4HAsKjoSMy1GeSI+ZOiJffRLFb4MojcvH4RG2+nEg1uC6Zg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-connect@0.54.0': - resolution: {integrity: sha512-43RmbhUhqt3uuPnc16cX6NsxEASEtn8z/cYV8Zpt6EP4p2h9s4FNuJ4Q9BbEQ2C0YlCCB/2crO1ruVz/hWt8fA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-connect@0.55.0': - resolution: {integrity: sha512-UfGw7ubKKZBoTRjxi5KlfeECEaXZinS20RdRNlZE5tVF+O17hJOnrcGwAoQAHp6eYmxI2jW9IQ4t6450gnNF9g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-cucumber@0.27.0': - resolution: {integrity: sha512-4zQ27TZMsfS7senBXqR6TaBPvfnlvI3ZfJU+RHHttzslWqK3rrSUYkgCWO79MnJpw5GtLz+V4NV2gpt/zRiCCA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/instrumentation-dataloader@0.28.0': - resolution: {integrity: sha512-ExXGBp0sUj8yhm6Znhf9jmuOaGDsYfDES3gswZnKr4MCqoBWQdEFn6EoDdt5u+RdbxQER+t43FoUihEfTSqsjA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-dataloader@0.29.0': - resolution: {integrity: sha512-220WjRb1G1UiAKbVblSMxwxxFdpyB4wj1XYIO9BJs5r62Azj2dL5fyZiXK3/WO6wB3uLul9R946iKI1bpPxktQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-dns@0.55.0': - resolution: {integrity: sha512-cfWLaFi22V+sQrKY7t6QroYzT3kO9m3PpkN1OXYmuCyfwxQaXOVlF8NSAHtua/RQYw0aQl+2fe6JOWyJdEZiwA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-express@0.59.0': - resolution: {integrity: sha512-pMKV/qnHiW/Q6pmbKkxt0eIhuNEtvJ7sUAyee192HErlr+a1Jx+FZ3WjfmzhQL1geewyGEiPGkmjjAgNY8TgDA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-express@0.60.0': - resolution: {integrity: sha512-KghHCDqKq0D7iuPIVCuPSXut5WVAI6uwKcPrhwTUJL5VE2LC18id2vKoiAm1V8XvVlgIGAiECtEvbrFwkTCj3g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-fastify@0.56.0': - resolution: {integrity: sha512-zotOPoZsWtMF47BjottK23XaaBSmVuwG5D/R3FlGfAAwMNFoDR3IY1OGO9v9KfOU/1/xDVkxsQ22NFfu9lE8aA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-fs@0.30.0': - resolution: {integrity: sha512-n3Cf8YhG7reaj5dncGlRIU7iT40bxPOjsBEA5Bc1a1g6e9Qvb+JFJ7SEiMlPbUw4PBmxE3h40ltE8LZ3zVt6OA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-fs@0.31.0': - resolution: {integrity: sha512-C7tdXGDnkMgLVlE79VSekB+Y+P345zKUigvFMs5M7U0GIYA8ERx3FS0aAcY/ICIq9YwRmH2uuMb++Br5M2vNUg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-generic-pool@0.54.0': - resolution: {integrity: sha512-8dXMBzzmEdXfH/wjuRvcJnUFeWzZHUnExkmFJ2uPfa31wmpyBCMxO59yr8f/OXXgSogNgi/uPo9KW9H7LMIZ+g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-generic-pool@0.55.0': - resolution: {integrity: sha512-7hWiyLbEX/dIS4LZy/h8VaAQPs8oBeEqsrysDWbos0b9PF414L6Rsbi2um/omtxIs+GTvsbuqDscWigeaxyWdA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-graphql@0.58.0': - resolution: {integrity: sha512-+yWVVY7fxOs3j2RixCbvue8vUuJ1inHxN2q1sduqDB0Wnkr4vOzVKRYl/Zy7B31/dcPS72D9lo/kltdOTBM3bQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-graphql@0.59.0': - resolution: {integrity: sha512-NvoUH1CKqfKVUSwCVq1MnIBI29Zd84EwSoBwdWUqyyWK8oTEqzGcnaUli1obYzzZPHijApvHUtV848p1piPmXg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-grpc@0.212.0': - resolution: {integrity: sha512-r1t7LNKWVhSQMUrBdDJtooFmmLZ93kGuFixqeXPoUP8W+chJCxhey9l0c0+L3xriNdyB7TzvkKHhPXUDevgVEA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-hapi@0.57.0': - resolution: {integrity: sha512-Os4THbvls8cTQTVA8ApLfZZztuuqGEeqog0XUnyRW7QVF0d/vOVBEcBCk1pazPFmllXGEdNbbat8e2fYIWdFbw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-hapi@0.58.0': - resolution: {integrity: sha512-reuRApR2KHm2VsfyDgsrLhNE+IOy4uIU6n3oMjUleReHacEEZmf4vXxdt4/qcmJ6GoUXnRN2AOu3s5N3pMrgYA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-http@0.211.0': - resolution: {integrity: sha512-n0IaQ6oVll9PP84SjbOCwDjaJasWRHi6BLsbMLiT6tNj7QbVOkuA5sk/EfZczwI0j5uTKl1awQPivO/ldVtsqA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-http@0.212.0': - resolution: {integrity: sha512-t2nt16Uyv9irgR+tqnX96YeToOStc3X5js7Ljn3EKlI2b4Fe76VhMkTXtsTQ0aId6AsYgefrCRnXSCo/Fn/vww==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-ioredis@0.59.0': - resolution: {integrity: sha512-875UxzBHWkW+P4Y45SoFM2AR8f8TzBMD8eO7QXGCyFSCUMP5s9vtt/BS8b/r2kqLyaRPK6mLbdnZznK3XzQWvw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-ioredis@0.60.0': - resolution: {integrity: sha512-R+nnbPD9l2ruzu248qM3YDWzpdmWVaFFFv08lQqsc0EP4pT/B1GGUg06/tHOSo3L5njB2eejwyzpkvJkjaQEMA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-kafkajs@0.20.0': - resolution: {integrity: sha512-yJXOuWZROzj7WmYCUiyT27tIfqBrVtl1/TwVbQyWPz7rL0r1Lu7kWjD0PiVeTCIL6CrIZ7M2s8eBxsTAOxbNvw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-kafkajs@0.21.0': - resolution: {integrity: sha512-lkLrILnKGO7SHw1xPJnuGx2S4XwbKmQiJyzUGuEImRoU/6Gj0Nka0lkbeRd4ANN20dxr/mLdXIsUsk6DzTrX6A==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-knex@0.55.0': - resolution: {integrity: sha512-FtTL5DUx5Ka/8VK6P1VwnlUXPa3nrb7REvm5ddLUIeXXq4tb9pKd+/ThB1xM/IjefkRSN3z8a5t7epYw1JLBJQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-knex@0.56.0': - resolution: {integrity: sha512-pKqtY5lbAQ70MC5K/BJeAA1t2gAUlRBZBAJ5ergRUNs5jw8zbdOXEZOLztiuNvQqD2z4a9N0Tkde9JMFm2pKMQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-koa@0.59.0': - resolution: {integrity: sha512-K9o2skADV20Skdu5tG2bogPKiSpXh4KxfLjz6FuqIVvDJNibwSdu5UvyyBzRVp1rQMV6UmoIk6d3PyPtJbaGSg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@opentelemetry/instrumentation-koa@0.60.0': - resolution: {integrity: sha512-UOmu2y2LHgPzKsm9xd0sCQJimr11YP4MKFc190Do1ufd8qds7Zd5BI3f6TudqYhH9dUIhojsQyUaS6K4nv5FsQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@opentelemetry/instrumentation-lru-memoizer@0.55.0': - resolution: {integrity: sha512-FDBfT7yDGcspN0Cxbu/k8A0Pp1Jhv/m7BMTzXGpcb8ENl3tDj/51U65R5lWzUH15GaZA15HQ5A5wtafklxYj7g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-lru-memoizer@0.56.0': - resolution: {integrity: sha512-vXtOValhKRgWA9tLAiTU3P37Q31OveRuM2N5iLSVHl4GzkMBQ5p50A9kSKvt5gReL6BzFDXPCM9ItJiAhSS2KQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-memcached@0.55.0': - resolution: {integrity: sha512-kdhW/j5X+vNCAvHVc50PZfvE7diUScg1ZkBaNFRygY3Z6IUjgPLR0luWQMDPSFun6AVo1HaMDPxbUqJrot6qrA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongodb@0.64.0': - resolution: {integrity: sha512-pFlCJjweTqVp7B220mCvCld1c1eYKZfQt1p3bxSbcReypKLJTwat+wbL2YZoX9jPi5X2O8tTKFEOahO5ehQGsA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongodb@0.65.0': - resolution: {integrity: sha512-hOAJRs5vrY7fZolSYUXmf29Y+HFDHWrek0DeLq82uwMPjPSda7h6oumQnqEX5olzw357q/QG39/uJdkclJ/JUg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongoose@0.57.0': - resolution: {integrity: sha512-MthiekrU/BAJc5JZoZeJmo0OTX6ycJMiP6sMOSRTkvz5BrPMYDqaJos0OgsLPL/HpcgHP7eo5pduETuLguOqcg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongoose@0.58.0': - resolution: {integrity: sha512-3L0Fqo1y2oreISFPWaqdt/bg3NhLgrkn5U/E/9RNG1QaM81drTMBCHseMY1q8SlejjE43ZWOy+0KbmRBlUPJ+g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql2@0.57.0': - resolution: {integrity: sha512-nHSrYAwF7+aV1E1V9yOOP9TchOodb6fjn4gFvdrdQXiRE7cMuffyLLbCZlZd4wsspBzVwOXX8mpURdRserAhNA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql2@0.58.0': - resolution: {integrity: sha512-EubjV1XZb7XHrENqF7TW2lnah+KN0LddMneKNAB8PjGVKL5lJkVV/vhJ6EIcUNn9nCWmAwZ3GRcFVEDKCnyXfQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql@0.57.0': - resolution: {integrity: sha512-HFS/+FcZ6Q7piM7Il7CzQ4VHhJvGMJWjx7EgCkP5AnTntSN5rb5Xi3TkYJHBKeR27A0QqPlGaCITi93fUDs++Q==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql@0.58.0': - resolution: {integrity: sha512-wZDrBCL3WfJclV6KywWVV3/B2ZiUYmDQdgyu3pq4jK/5qSfoDmezHzT/Nayln5MVVWMAGXIMLrCj8BKa6jaKQQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-nestjs-core@0.58.0': - resolution: {integrity: sha512-0lE9oW8j6nmvBHJoOxIQgKzMQQYNfX1nhiWZdXD0sNAMFsWBtvECWS7NAPSroKrEP53I04TcHCyyhcK4I9voXg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-net@0.56.0': - resolution: {integrity: sha512-h69x7U6f86mP3gGWWTaMkQZk0K3tBvpVMIU7E0q2kkVw6eZ5TqFm9rkaEy38moQmixiDFQ9j/2/cwxG9P7ZEeA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-openai@0.10.0': - resolution: {integrity: sha512-0lV2zxge2mMaruVCw/bmypWVu+aJ76rc0HBvAVFCPUI3zzJdgBZJZafGIHZ1IB2F6VvrDFL+JstEnle6V8brvA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-oracledb@0.37.0': - resolution: {integrity: sha512-OzMghtAEAEkXlkUrZI4QcXSZq0MILeU6WC0/N5+1MSkuIkruIeaRw99/RtyS2of8vlPDa8XbbXl32Q1RM3wSyg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-pg@0.63.0': - resolution: {integrity: sha512-dKm/ODNN3GgIQVlbD6ZPxwRc3kleLf95hrRWXM+l8wYo+vSeXtEpQPT53afEf6VFWDVzJK55VGn8KMLtSve/cg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-pg@0.64.0': - resolution: {integrity: sha512-NbfB/rlfsRI3zpTjnbvJv3qwuoGLsN8FxR/XoI+ZTn1Rs62x1IenO+TSSvk4NO+7FlXpd2MiOe8LT/oNbydHGA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-pino@0.58.0': - resolution: {integrity: sha512-rgy+tA7cDjuSq6dXAO40OiYP25azIDHMBtxG3RzSmCBVEYdjggl6btyuLVasX6VkOOhP2gf6PBuLMNxVwaIqAw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-redis@0.59.0': - resolution: {integrity: sha512-JKv1KDDYA2chJ1PC3pLP+Q9ISMQk6h5ey+99mB57/ARk0vQPGZTTEb4h4/JlcEpy7AYT8HIGv7X6l+br03Neeg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-redis@0.60.0': - resolution: {integrity: sha512-Ea/GffmmzIVHc9geaMjT94IR7poVZzIv4Kk/Lw0tbxGD3cBYcMUsLFVajKxpZsE1NRCECFpidAWeifCIKD0inw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-restify@0.57.0': - resolution: {integrity: sha512-kO6MsZFU+RdXOKhsKw8SOSBYGYCdFSlza+mpBQRl1DQmveZcnidchv4V5JQPtNgHxCGH+1n3hDpLdxdGUbJPNA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-router@0.56.0': - resolution: {integrity: sha512-PHECDGQElLazI/QbHU16C5m9fDC7DGJk+jLIwO5ca6bcp7bXhUPPUTT78l7da2pDsrz4mhv5ytYNZmBbW/Q3rA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-runtime-node@0.25.0': - resolution: {integrity: sha512-XaCmwBSui5KeTn8M6OzaEn1rEsNWtUkjuc1ylg0tqQTLHibNQ0n7f8v4zdF6x/nBV1OnsiYlN8RLHauGemv/TA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-socket.io@0.58.0': - resolution: {integrity: sha512-/xuN5YxixNgB+KQJM67UETwB+3F3OTfI4cqH4z9AbHRfFBlddlMOIIpPr3CdrwQGhMd7rrv3t8NBLxv5/UvF1w==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-tedious@0.30.0': - resolution: {integrity: sha512-bZy9Q8jFdycKQ2pAsyuHYUHNmCxCOGdG6eg1Mn75RvQDccq832sU5OWOBnc12EFUELI6icJkhR7+EQKMBam2GA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-tedious@0.31.0': - resolution: {integrity: sha512-HoF2EtcyP3JR4R3jLPHohZ9lFcj1QLJyGmFfLKDTvUUjPiFuK4XZ6L1OV9HhaqvN0xY+tWKfNdCPS3r33rd0Xw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-undici@0.21.0': - resolution: {integrity: sha512-gok0LPUOTz2FQ1YJMZzaHcOzDFyT64XJ8M9rNkugk923/p6lDGms/cRW1cqgqp6N6qcd6K6YdVHwPEhnx9BWbw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.7.0 - - '@opentelemetry/instrumentation-undici@0.22.0': - resolution: {integrity: sha512-yb6vEWUPOrD5i7yR1XceEEqiVHbMgr5YnUPnom5eQVCjvrTkEVswyrf9i+vvJR+28wrNqILIIphWgOOx6BjnTQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.7.0 - - '@opentelemetry/instrumentation-winston@0.56.0': - resolution: {integrity: sha512-ITIA0Qe61CQ6FQU/bN23pNBvJ+5U0ofoASMOOYrODtXyV9wI267AigNTTwDmv2Myt8dPEFvvVFJZKhiZLIpehA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.203.0': - resolution: {integrity: sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.207.0': - resolution: {integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.208.0': - resolution: {integrity: sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.211.0': - resolution: {integrity: sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.212.0': - resolution: {integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/otlp-exporter-base@0.212.0': - resolution: {integrity: sha512-HoMv5pQlzbuxiMS0hN7oiUtg8RsJR5T7EhZccumIWxYfNo/f4wFc7LPDfFK6oHdG2JF/+qTocfqIHoom+7kLpw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/otlp-grpc-exporter-base@0.212.0': - resolution: {integrity: sha512-YidOSlzpsun9uw0iyIWrQp6HxpMtBlECE3tiHGAsnpEqJWbAUWcMnIffvIuvTtTQ1OyRtwwaE79dWSQ8+eiB7g==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/otlp-transformer@0.212.0': - resolution: {integrity: sha512-bj7zYFOg6Db7NUwsRZQ/WoVXpAf41WY2gsd3kShSfdpZQDRKHWJiRZIg7A8HvWsf97wb05rMFzPbmSHyjEl9tw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/propagator-b3@2.5.1': - resolution: {integrity: sha512-AU6sZgunZrZv/LTeHP+9IQsSSH5p3PtOfDPe8VTdwYH69nZCfvvvXehhzu+9fMW2mgJMh5RVpiH8M9xuYOu5Dg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/propagator-jaeger@2.5.1': - resolution: {integrity: sha512-8+SB94/aSIOVGDUPRFSBRHVUm2A8ye1vC6/qcf/D+TF4qat7PC6rbJhRxiUGDXZtMtKEPM/glgv5cBGSJQymSg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/redis-common@0.38.2': - resolution: {integrity: sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==} - engines: {node: ^18.19.0 || >=20.6.0} - - '@opentelemetry/resource-detector-alibaba-cloud@0.33.2': - resolution: {integrity: sha512-EaS54zwYmOg9Ttc79juaktpCBYqyh2IquXl534sLls+c1/pc8LZfWPMqytFt+iBvSPQ6ajraUnvi6cun4AhSjQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/resource-detector-aws@2.12.0': - resolution: {integrity: sha512-VelueKblsnQEiBVqEYcvM9VEb+B8zN6nftltdO9HAD7qi/OlicP4z/UGJ9EeW2m++WabdMoj0G3QVL8YV0P9tw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/resource-detector-azure@0.20.0': - resolution: {integrity: sha512-iRy+O2cB6DOlQ/OONaK+L8Cp8nLS89dZVRp6KgnFAfzykXuq9Ws/ygJKcU3CCmjkgY5j2Vk3uVTre/E35bWhYg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/resource-detector-container@0.8.3': - resolution: {integrity: sha512-5J0JP2cy655rBKM9Doz26ffO3rG+Xqm7OXeNXkckzmc3JmL6Bj3dPBKugPYsfemhEIqtf7INH9UmPQqTMuWoHg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/resource-detector-gcp@0.47.0': - resolution: {integrity: sha512-57T/kRVdU0ch1P4KPEkmU2b5mWNlUs8hHgqrBYVF+fNZMc1jMdL1mANZhEzoLtWKIeoCEy+57Itt7RkXAYNJiQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - - '@opentelemetry/resources@2.5.1': - resolution: {integrity: sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/sdk-logs@0.212.0': - resolution: {integrity: sha512-qglb5cqTf0mOC1sDdZ7nfrPjgmAqs2OxkzOPIf2+Rqx8yKBK0pS7wRtB1xH30rqahBIut9QJDbDePyvtyqvH/Q==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.4.0 <1.10.0' - - '@opentelemetry/sdk-metrics@2.5.1': - resolution: {integrity: sha512-RKMn3QKi8nE71ULUo0g/MBvq1N4icEBo7cQSKnL3URZT16/YH3nSVgWegOjwx7FRBTrjOIkMJkCUn/ZFIEfn4A==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.9.0 <1.10.0' - - '@opentelemetry/sdk-node@0.212.0': - resolution: {integrity: sha512-tJzVDk4Lo44MdgJLlP+gdYdMnjxSNsjC/IiTxj5CFSnsjzpHXwifgl3BpUX67Ty3KcdubNVfedeBc/TlqHXwwg==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/sdk-trace-base@2.5.1': - resolution: {integrity: sha512-iZH3Gw8cxQn0gjpOjJMmKLd9GIaNh/E3v3ST67vyzLSxHBs14HsG4dy7jMYyC5WXGdBVEcM7U/XTF5hCQxjDMw==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/sdk-trace-node@2.5.1': - resolution: {integrity: sha512-9lopQ6ZoElETOEN0csgmtEV5/9C7BMfA7VtF4Jape3i954b6sTY2k3Xw3CxUTKreDck/vpAuJM+EDo4zheUw+A==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/semantic-conventions@1.39.0': - resolution: {integrity: sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==} - engines: {node: '>=14'} - - '@opentelemetry/sql-common@0.41.2': - resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.1.0 - - '@oxc-project/types@0.110.0': - resolution: {integrity: sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow==} - - '@oxc-transform/binding-android-arm-eabi@0.111.0': - resolution: {integrity: sha512-NdFLicvorfHYu0g2ftjVJaH7+Dz27AQUNJOq8t/ofRUoWmczOodgUCHx8C1M1htCN4ZmhS/FzfSy6yd/UngJGg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxc-transform/binding-android-arm64@0.111.0': - resolution: {integrity: sha512-J2v9ajarD2FYlhHtjbgZUFsS2Kvi27pPxDWLGCy7i8tO60xBoozX9/ktSgbiE/QsxKaUhfv4zVKppKWUo71PmQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxc-transform/binding-darwin-arm64@0.111.0': - resolution: {integrity: sha512-2UYmExxpXzmiHTldhNlosWqG9Nc4US51K0GB9RLcGlTE23WO33vVo1NVAKwxPE+KYuhffwDnRYTovTMUjzwvZA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxc-transform/binding-darwin-x64@0.111.0': - resolution: {integrity: sha512-c4YRwfLV8Pj/ToiTCbndZaHxM2BD4W3bltr/fjXZcGypEK+U2RZFDL7tIZYT/tyneAC9hCORZKDaKhLLNuzPtA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxc-transform/binding-freebsd-x64@0.111.0': - resolution: {integrity: sha512-prvf32IcEuLnLZbNVomFosBu0CaZpyj3YsZ6epbOgJy8iJjfLsXBb+PrkO/NBKzjuJoJa2+u7jFKRE0KT7gSOw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxc-transform/binding-linux-arm-gnueabihf@0.111.0': - resolution: {integrity: sha512-+se3579Wp7VOk8TnTZCpT+obTAyzOw2b/UuoM0+51LtbzCSfjKxd4A+o7zRl7GyPrPZvx57KdbMOC9rWB1xNrw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-transform/binding-linux-arm-musleabihf@0.111.0': - resolution: {integrity: sha512-8faC99pStqaSDPK/vBgaagAHUeL0LcIzfeSjSiDTtvPGc3AwZIeqC1tx3CP15a6tWXjdgS/IUw4IjfD5HweBlg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-transform/binding-linux-arm64-gnu@0.111.0': - resolution: {integrity: sha512-HtfQv8j796gzI5WR/RaP6IMwFpiL0vYeDrUA1hYhlPzTHKYan/B+NlhJkKOI1v24yAl/yEnFmb0pxIxLNqBqBA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxc-transform/binding-linux-arm64-musl@0.111.0': - resolution: {integrity: sha512-ARyfcMCIxVLDgLf6FQ8Oo1/TFySpnquV+vuSb4SFQZfYDqgMklzwv0NYXxWD0aB6enElyMDs6pQJBzusEKCkOg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxc-transform/binding-linux-ppc64-gnu@0.111.0': - resolution: {integrity: sha512-PKpVRrSvBNK3tv9vwxn7Fay+QWZmprPGlEqJcseBJllQc5mFMD4Q/w44chu5iR9ZLsDeSHzmNWrgMLo4J0sP2A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@oxc-transform/binding-linux-riscv64-gnu@0.111.0': - resolution: {integrity: sha512-9bUml6rMgk+8GF5rvNMweFspkzSiCjqpV6HduwiUyexqfGKrmjq9IZOxxvnzkE2RGdQzP507NNDoVNYIoGQYuA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxc-transform/binding-linux-riscv64-musl@0.111.0': - resolution: {integrity: sha512-tzGCohGxaeH6KRJjfYZd4mHCoGjCai6N+zZi1Oj+tSDMAAdyvs1dRzYb8PNUGnybCg3Te4M0jLPzWZaSmnKraQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxc-transform/binding-linux-s390x-gnu@0.111.0': - resolution: {integrity: sha512-sRG1KIfZ0ML9ToEygm5aM/5GJeBA05uHlgW3M0Rx/DNWMJhuahLmqWuB02aWSmijndLfEKXLLXIWhvWupRG8lg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - - '@oxc-transform/binding-linux-x64-gnu@0.111.0': - resolution: {integrity: sha512-T0Kmvk+OdlUdABdXlDIf3MQReMzFfC75NEI9x8jxy5pKooACEFg0k0V8gyR3gq4DzbDCfucqFQDWNvSgIopAbQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxc-transform/binding-linux-x64-musl@0.111.0': - resolution: {integrity: sha512-EgoutsP3YfqzN8a9vpc9+XLr0bmBl0dA3uOMiP77+exATCPxJBkJErGmQkqk6RtTp5XqX6q6mB45qWQyKk6+pA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxc-transform/binding-openharmony-arm64@0.111.0': - resolution: {integrity: sha512-d8J+ejc0j5WODbVwR/QxFaI65YMwvG0W53vcVCHwa6ja1QI5lpe7sislrefG2EFYgnY47voMRzlXab5d4gEcDw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxc-transform/binding-wasm32-wasi@0.111.0': - resolution: {integrity: sha512-HtyIZO8IwuZgXkyb56rysLz1OLbfLhEu8A3BeuyJXzUseAj96yuxgGt3cu3QYX9AXb9pfRfA3c/fvlhsDugyTQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-transform/binding-win32-arm64-msvc@0.111.0': - resolution: {integrity: sha512-YeP80Riptc0MkVVBnzbmoFuHVLUq278+MbwNo9sTLALmzTIJxJqN029xRZbG+Bun7aLsoZhmRnm3J5JZ1NcP5w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxc-transform/binding-win32-ia32-msvc@0.111.0': - resolution: {integrity: sha512-A6ztCXpoSHt6PbvGAFqB0MLOcGG7ZJrrPXY1iB0zfOB1atLgI8oNePGxPl03XSbwpiTsFJ1oo8rj9DXcBzgT9g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxc-transform/binding-win32-x64-msvc@0.111.0': - resolution: {integrity: sha512-QddKW4kBH0Wof6Y65eYCNHM4iOGmCTWLLcNYY1FGswhzmTYOUVXajNROR+iCXAOFnOF0ldtsR79SyqgyHH1Bgg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@oxfmt/binding-android-arm-eabi@0.34.0': - resolution: {integrity: sha512-sqkqjh/Z38l+duOb1HtVqJTAj1grt2ttkobCopC/72+a4Xxz4xUgZPFyQ4HxrYMvyqO/YA0tvM1QbfOu70Gk1Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxfmt/binding-android-arm64@0.34.0': - resolution: {integrity: sha512-1KRCtasHcVcGOMwfOP9d5Bus2NFsN8yAYM5cBwi8LBg5UtXC3C49WHKrlEa8iF1BjOS6CR2qIqiFbGoA0DJQNQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxfmt/binding-darwin-arm64@0.34.0': - resolution: {integrity: sha512-b+Rmw9Bva6e/7PBES2wLO8sEU7Mi0+/Kv+pXSe/Y8i4fWNftZZlGwp8P01eECaUqpXATfSgNxdEKy7+ssVNz7g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxfmt/binding-darwin-x64@0.34.0': - resolution: {integrity: sha512-QGjpevWzf1T9COEokZEWt80kPOtthW1zhRbo7x4Qoz646eTTfi6XsHG2uHeDWJmTbgBoJZPMgj2TAEV/ppEZaA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxfmt/binding-freebsd-x64@0.34.0': - resolution: {integrity: sha512-VMSaC02cG75qL59M9M/szEaqq/RsLfgpzQ4nqUu8BUnX1zkiZIW2gTpUv3ZJ6qpWnHxIlAXiRZjQwmcwpvtbcg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxfmt/binding-linux-arm-gnueabihf@0.34.0': - resolution: {integrity: sha512-Klm367PFJhH6vYK3vdIOxFepSJZHPaBfIuqwxdkOcfSQ4qqc/M8sgK0UTFnJWWTA/IkhMIh1kW6uEqiZ/xtQqg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm-musleabihf@0.34.0': - resolution: {integrity: sha512-nqn0QueVXRfbN9m58/E9Zij0Ap8lzayx591eWBYn0sZrGzY1IRv9RYS7J/1YUXbb0Ugedo0a8qIWzUHU9bWQuA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm64-gnu@0.34.0': - resolution: {integrity: sha512-DDn+dcqW+sMTCEjvLoQvC/VWJjG7h8wcdN/J+g7ZTdf/3/Dx730pQElxPPGsCXPhprb11OsPyMp5FwXjMY3qvA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxfmt/binding-linux-arm64-musl@0.34.0': - resolution: {integrity: sha512-H+F8+71gHQoGTFPPJ6z4dD0Fzfzi0UP8Zx94h5kUmIFThLvMq5K1Y/bUUubiXwwHfwb5C3MPjUpYijiy0rj51Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxfmt/binding-linux-ppc64-gnu@0.34.0': - resolution: {integrity: sha512-dIGnzTNhCXqQD5pzBwduLg8pClm+t8R53qaE9i5h8iua1iaFAJyLffh4847CNZSlASb7gn1Ofuv7KoG/EpoGZg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@oxfmt/binding-linux-riscv64-gnu@0.34.0': - resolution: {integrity: sha512-FGQ2GTTooilDte/ogwWwkHuuL3lGtcE3uKM2EcC7kOXNWdUfMY6Jx3JCodNVVbFoybv4A+HuCj8WJji2uu1Ceg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxfmt/binding-linux-riscv64-musl@0.34.0': - resolution: {integrity: sha512-2dGbGneJ7ptOIVKMwEIHdCkdZEomh74X3ggo4hCzEXL/rl9HwfsZDR15MkqfQqAs6nVXMvtGIOMxjDYa5lwKaA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxfmt/binding-linux-s390x-gnu@0.34.0': - resolution: {integrity: sha512-cCtGgmrTrxq3OeSG0UAO+w6yLZTMeOF4XM9SAkNrRUxYhRQELSDQ/iNPCLyHhYNi38uHJQbS5RQweLUDpI4ajA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - - '@oxfmt/binding-linux-x64-gnu@0.34.0': - resolution: {integrity: sha512-7AvMzmeX+k7GdgitXp99GQoIV/QZIpAS7rwxQvC/T541yWC45nwvk4mpnU8N+V6dE5SPEObnqfhCjO80s7qIsg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxfmt/binding-linux-x64-musl@0.34.0': - resolution: {integrity: sha512-uNiglhcmivJo1oDMh3hoN/Z0WsbEXOpRXZdQ3W/IkOpyV8WF308jFjSC1ZxajdcNRXWej0zgge9QXba58Owt+g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxfmt/binding-openharmony-arm64@0.34.0': - resolution: {integrity: sha512-5eFsTjCyji25j6zznzlMc+wQAZJoL9oWy576xhqd2efv+N4g1swIzuSDcb1dz4gpcVC6veWe9pAwD7HnrGjLwg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxfmt/binding-win32-arm64-msvc@0.34.0': - resolution: {integrity: sha512-6id8kK0t5hKfbV6LHDzRO21wRTA6ctTlKGTZIsG/mcoir0rssvaYsedUymF4HDj7tbCUlnxCX/qOajKlEuqbIw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxfmt/binding-win32-ia32-msvc@0.34.0': - resolution: {integrity: sha512-QHaz+w673mlYqn9v/+fuiKZpjkmagleXQ+NygShDv8tdHpRYX2oYhTJwwt9j1ZfVhRgza1EIUW3JmzCXmtPdhQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxfmt/binding-win32-x64-msvc@0.34.0': - resolution: {integrity: sha512-CXKQM/VaF+yuvGru8ktleHLJoBdjBtTFmAsLGePiESiTN0NjCI/PiaiOCfHMJ1HdP1LykvARUwMvgaN3tDhcrg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@oxlint/binding-android-arm-eabi@1.49.0': - resolution: {integrity: sha512-2WPoh/2oK9r/i2R4o4J18AOrm3HVlWiHZ8TnuCaS4dX8m5ZzRmHW0I3eLxEurQLHWVruhQN7fHgZnah+ag5iQg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxlint/binding-android-arm64@1.49.0': - resolution: {integrity: sha512-YqJAGvNB11EzoKm1euVhZntb79alhMvWW/j12bYqdvVxn6xzEQWrEDCJg9BPo3A3tBCSUBKH7bVkAiCBqK/L1w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxlint/binding-darwin-arm64@1.49.0': - resolution: {integrity: sha512-WFocCRlvVkMhChCJ2qpJfp1Gj/IjvyjuifH9Pex8m8yHonxxQa3d8DZYreuDQU3T4jvSY8rqhoRqnpc61Nlbxw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxlint/binding-darwin-x64@1.49.0': - resolution: {integrity: sha512-BN0KniwvehbUfYztOMwEDkYoojGm/narf5oJf+/ap+6PnzMeWLezMaVARNIS0j3OdMkjHTEP8s3+GdPJ7WDywQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxlint/binding-freebsd-x64@1.49.0': - resolution: {integrity: sha512-SnkAc/DPIY6joMCiP/+53Q+N2UOGMU6ULvbztpmvPJNF/jYPGhNbKtN982uj2Gs6fpbxYkmyj08QnpkD4fbHJA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxlint/binding-linux-arm-gnueabihf@1.49.0': - resolution: {integrity: sha512-6Z3EzRvpQVIpO7uFhdiGhdE8Mh3S2VWKLL9xuxVqD6fzPhyI3ugthpYXlCChXzO8FzcYIZ3t1+Kau+h2NY1hqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm-musleabihf@1.49.0': - resolution: {integrity: sha512-wdjXaQYAL/L25732mLlngfst4Jdmi/HLPVHb3yfCoP5mE3lO/pFFrmOJpqWodgv29suWY74Ij+RmJ/YIG5VuzQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm64-gnu@1.49.0': - resolution: {integrity: sha512-oSHpm8zmSvAG1BWUumbDRSg7moJbnwoEXKAkwDf/xTQJOzvbUknq95NVQdw/AduZr5dePftalB8rzJNGBogUMg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxlint/binding-linux-arm64-musl@1.49.0': - resolution: {integrity: sha512-xeqkMOARgGBlEg9BQuPDf6ZW711X6BT5qjDyeM5XNowCJeTSdmMhpePJjTEiVbbr3t21sIlK8RE6X5bc04nWyQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@oxlint/binding-linux-ppc64-gnu@1.49.0': - resolution: {integrity: sha512-uvcqRO6PnlJGbL7TeePhTK5+7/JXbxGbN+C6FVmfICDeeRomgQqrfVjf0lUrVpUU8ii8TSkIbNdft3M+oNlOsQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@oxlint/binding-linux-riscv64-gnu@1.49.0': - resolution: {integrity: sha512-Dw1HkdXAwHNH+ZDserHP2RzXQmhHtpsYYI0hf8fuGAVCIVwvS6w1+InLxpPMY25P8ASRNiFN3hADtoh6lI+4lg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxlint/binding-linux-riscv64-musl@1.49.0': - resolution: {integrity: sha512-EPlMYaA05tJ9km/0dI9K57iuMq3Tw+nHst7TNIegAJZrBPtsOtYaMFZEaWj02HA8FI5QvSnRHMt+CI+RIhXJBQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - - '@oxlint/binding-linux-s390x-gnu@1.49.0': - resolution: {integrity: sha512-yZiQL9qEwse34aMbnMb5VqiAWfDY+fLFuoJbHOuzB1OaJZbN1MRF9Nk+W89PIpGr5DNPDipwjZb8+Q7wOywoUQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - - '@oxlint/binding-linux-x64-gnu@1.49.0': - resolution: {integrity: sha512-CcCDwMMXSchNkhdgvhVn3DLZ4EnBXAD8o8+gRzahg+IdSt/72y19xBgShJgadIRF0TsRcV/MhDUMwL5N/W54aQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxlint/binding-linux-x64-musl@1.49.0': - resolution: {integrity: sha512-u3HfKV8BV6t6UCCbN0RRiyqcymhrnpunVmLFI8sEa5S/EBu+p/0bJ3D7LZ2KT6PsBbrB71SWq4DeFrskOVgIZg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@oxlint/binding-openharmony-arm64@1.49.0': - resolution: {integrity: sha512-dRDpH9fw+oeUMpM4br0taYCFpW6jQtOuEIec89rOgDA1YhqwmeRcx0XYeCv7U48p57qJ1XZHeMGM9LdItIjfzA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxlint/binding-win32-arm64-msvc@1.49.0': - resolution: {integrity: sha512-6rrKe/wL9tn0qnOy76i1/0f4Dc3dtQnibGlU4HqR/brVHlVjzLSoaH0gAFnLnznh9yQ6gcFTBFOPrcN/eKPDGA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxlint/binding-win32-ia32-msvc@1.49.0': - resolution: {integrity: sha512-CXHLWAtLs2xG/aVy1OZiYJzrULlq0QkYpI6cd7VKMrab+qur4fXVE/B1Bp1m0h1qKTj5/FTGg6oU4qaXMjS/ug==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxlint/binding-win32-x64-msvc@1.49.0': - resolution: {integrity: sha512-VteIelt78kwzSglOozaQcs6BCS4Lk0j+QA+hGV0W8UeyaqQ3XpbZRhDU55NW1PPvCy1tg4VXsTlEaPovqto7nQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@prisma/adapter-pg@7.4.1': - resolution: {integrity: sha512-AH9XrqvSoBAaStn0Gm/sAnF97pDKz8uLpNmn51j1S9O9dhUva6LIxGdoDiiU9VXRIR89wAJXsvJSy+mK40m2xw==} - - '@prisma/client-runtime-utils@7.4.1': - resolution: {integrity: sha512-8fy74OMYC7mt9cJ2MncIDk1awPRgmtXVvwTN2FlW4JVhbck8Dgt0wTkhPG85myfj4ZeP2stjF9Sdg12n5HrpQg==} - - '@prisma/client@5.22.0': - resolution: {integrity: sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==} - engines: {node: '>=16.13'} - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true - - '@prisma/client@7.4.1': - resolution: {integrity: sha512-pgIll2W1NVdof37xLeyySW+yfQ4rI+ERGCRwnO3BjVOx42GpYq6jhTyuALK8VKirvJJIvImgfGDA2qwhYVvMuA==} - engines: {node: ^20.19 || ^22.12 || >=24.0} - peerDependencies: - prisma: '*' - typescript: '>=5.4.0' - peerDependenciesMeta: - prisma: - optional: true - typescript: - optional: true - - '@prisma/config@7.4.1': - resolution: {integrity: sha512-vteSXm8N46bo3FW9MhPGVHAj+KRgrR6TWtlSk6GqToCKjTnOexXdPZyiDyEsfVW38YhqEmVl6w/6iHN8uYVJcw==} - - '@prisma/debug@7.2.0': - resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} - - '@prisma/debug@7.4.1': - resolution: {integrity: sha512-qEtzO8oLouRv18JDQUC3G3Gnv+fGVscHZm/x1DBB/WT+kOvPDQLM2woX6IGgWnSMYYlrxjuALshT7G/blvY0bQ==} - - '@prisma/dev@0.20.0': - resolution: {integrity: sha512-ovlBYwWor0OzG+yH4J3Ot+AneD818BttLA+Ii7wjbcLHUrnC4tbUPVGyNd3c/+71KETPKZfjhkTSpdS15dmXNQ==} - - '@prisma/driver-adapter-utils@7.4.1': - resolution: {integrity: sha512-gEZOC2tnlHaZNbHUdbK8YvQphq2tKq/Ovu1YixJ/hPSutDAvNzC3R+xUeBuJ4AJp236eELMzwxb7rgo3UbRkTg==} - - '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': - resolution: {integrity: sha512-fUxVd1TjOW8K4XsZ8dAm88sDW5Ry7AxWDfsYEWwScS6Fjo3caKC6hgNumUfsmsy0Il9LjDn5X0PpVXNt3iwayw==} - - '@prisma/engines@7.4.1': - resolution: {integrity: sha512-BZEBdHvNJx5PzIG37EI/Zi5UUI5hGWjkYsQmKa7OIK6evAvebOTwutjS/VRI6cA6grmA52eLZR+oekGRMqkKxQ==} - - '@prisma/fetch-engine@7.4.1': - resolution: {integrity: sha512-Z9kbuxX2bvEsyeS3LZEiEnxG0lVtZbpYgaAnPj69N+A9f2De8Lta0EoFtld9zhfERVPIQWhSWUc8himky3qYdA==} - - '@prisma/get-platform@7.2.0': - resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} - - '@prisma/get-platform@7.4.1': - resolution: {integrity: sha512-kN4tmkQzlgm/KtE+jTNSYjsDxxe/5i6GApPI32BN9T0tlgsgSBtDJbjGBICttkAIjsh73dXf8raPKxO/2n2UUg==} - - '@prisma/instrumentation@7.2.0': - resolution: {integrity: sha512-Rh9Z4x5kEj1OdARd7U18AtVrnL6rmLSI0qYShaB4W7Wx5BKbgzndWF+QnuzMb7GLfVdlT5aYCXoPQVYuYtVu0g==} - peerDependencies: - '@opentelemetry/api': ^1.8 - - '@prisma/query-plan-executor@7.2.0': - resolution: {integrity: sha512-EOZmNzcV8uJ0mae3DhTsiHgoNCuu1J9mULQpGCh62zN3PxPTd+qI9tJvk5jOst8WHKQNwJWR3b39t0XvfBB0WQ==} - - '@prisma/studio-core@0.13.1': - resolution: {integrity: sha512-agdqaPEePRHcQ7CexEfkX1RvSH9uWDb6pXrZnhCRykhDFAV0/0P3d07WtfiY8hZWb7oRU4v+NkT4cGFHkQJIPg==} - peerDependencies: - '@types/react': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-avatar@1.1.11': - resolution: {integrity: sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context@1.1.3': - resolution: {integrity: sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-dropdown-menu@2.1.16': - resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.4': - resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.4': - resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-is-hydrated@0.1.0': - resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-visually-hidden@1.2.4': - resolution: {integrity: sha512-kaeiyGCe844dkb9AVF+rb4yTyb1LiLN/e3es3nLiRyN4dC8AduBYPMnnNlDjX2VDOcvDEiPnRNMJeWCfsX0txg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - - '@remirror/core-constants@3.0.0': - resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - - '@renovatebot/pep440@4.2.1': - resolution: {integrity: sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw==} - engines: {node: ^20.9.0 || ^22.11.0 || ^24, pnpm: ^10.0.0} - - '@rolldown/binding-android-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-rc.1': - resolution: {integrity: sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.0.0-rc.1': - resolution: {integrity: sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1': - resolution: {integrity: sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1': - resolution: {integrity: sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.1': - resolution: {integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.1': - resolution: {integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.1': - resolution: {integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.1': - resolution: {integrity: sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1': - resolution: {integrity: sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.1': - resolution: {integrity: sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.0-rc.1': - resolution: {integrity: sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA==} - - '@rollup/plugin-commonjs@28.0.1': - resolution: {integrity: sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} - cpu: [x64] - os: [win32] - - '@sentry-internal/browser-utils@10.40.0': - resolution: {integrity: sha512-3CDeVNBXYOIvBVdT0SOdMZx5LzYDLuhGK/z7A14sYZz4Cd2+f4mSeFDaEOoH/g2SaY2CKR5KGkAADy8IyjZ21w==} - engines: {node: '>=18'} - - '@sentry-internal/feedback@10.40.0': - resolution: {integrity: sha512-V/ixkcdCNMo04KgsCEeNEu966xUUTD6czKT2LOAO5siZACqFjT/Rp9VR1n7QQrVo3sL7P3QNiTHtX0jaeWbwzg==} - engines: {node: '>=18'} - - '@sentry-internal/replay-canvas@10.40.0': - resolution: {integrity: sha512-wzQwilFHO2baeCt0dTMf0eW+rgK8O+mkisf9sQzPXzG3Krr/iVtFg1T5T1Th3YsCsEdn6yQ3hcBPLEXjMSvccg==} - engines: {node: '>=18'} - - '@sentry-internal/replay@10.40.0': - resolution: {integrity: sha512-vsH2Ut0KIIQIHNdS3zzEGLJ2C9btbpvJIWAVk7l7oft66JzlUNC89qNaQ5SAypjLQx4Ln2V/ZTqfEoNzXOAsoQ==} - engines: {node: '>=18'} - - '@sentry/babel-plugin-component-annotate@5.1.0': - resolution: {integrity: sha512-deEZGTxPMiVNcHXzYMcKEp2uGGU3Q+055nVH6vPHnzuxGoRNZRe2YZ5B1yP9gFD+LJGku8dJ4y3bs1iJrLGPtQ==} - engines: {node: '>= 14'} - - '@sentry/browser@10.40.0': - resolution: {integrity: sha512-nCt3FKUMFad0C6xl5wCK0Jz+qT4Vev4fv6HJRn0YoNRRDQCfsUVxAz7pNyyiPNGM/WCDp9wJpGJsRvbBRd2anw==} - engines: {node: '>=18'} - - '@sentry/bundler-plugin-core@5.1.0': - resolution: {integrity: sha512-/GDzz+UbT7fO3AbvquHDWuqYXWKv2tzCQZddzMYNv36P9wpof5SFELGG6HnfqFb5l2PeHNrVTtp2rrPBQO/OXw==} - engines: {node: '>= 14'} - - '@sentry/cli-darwin@2.58.5': - resolution: {integrity: sha512-lYrNzenZFJftfwSya7gwrHGxtE+Kob/e1sr9lmHMFOd4utDlmq0XFDllmdZAMf21fxcPRI1GL28ejZ3bId01fQ==} - engines: {node: '>=10'} - os: [darwin] - - '@sentry/cli-linux-arm64@2.58.5': - resolution: {integrity: sha512-/4gywFeBqRB6tR/iGMRAJ3HRqY6Z7Yp4l8ZCbl0TDLAfHNxu7schEw4tSnm2/Hh9eNMiOVy4z58uzAWlZXAYBQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux, freebsd, android] - - '@sentry/cli-linux-arm@2.58.5': - resolution: {integrity: sha512-KtHweSIomYL4WVDrBrYSYJricKAAzxUgX86kc6OnlikbyOhoK6Fy8Vs6vwd52P6dvWPjgrMpUYjW2M5pYXQDUw==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux, freebsd, android] - - '@sentry/cli-linux-i686@2.58.5': - resolution: {integrity: sha512-G7261dkmyxqlMdyvyP06b+RTIVzp1gZNgglj5UksxSouSUqRd/46W/2pQeOMPhloDYo9yLtCN2YFb3Mw4aUsWw==} - engines: {node: '>=10'} - cpu: [x86, ia32] - os: [linux, freebsd, android] - - '@sentry/cli-linux-x64@2.58.5': - resolution: {integrity: sha512-rP04494RSmt86xChkQ+ecBNRYSPbyXc4u0IA7R7N1pSLCyO74e5w5Al+LnAq35cMfVbZgz5Sm0iGLjyiUu4I1g==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux, freebsd, android] - - '@sentry/cli-win32-arm64@2.58.5': - resolution: {integrity: sha512-AOJ2nCXlQL1KBaCzv38m3i2VmSHNurUpm7xVKd6yAHX+ZoVBI8VT0EgvwmtJR2TY2N2hNCC7UrgRmdUsQ152bA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@sentry/cli-win32-i686@2.58.5': - resolution: {integrity: sha512-EsuboLSOnlrN7MMPJ1eFvfMDm+BnzOaSWl8eYhNo8W/BIrmNgpRUdBwnWn9Q2UOjJj5ZopukmsiMYtU/D7ml9g==} - engines: {node: '>=10'} - cpu: [x86, ia32] - os: [win32] - - '@sentry/cli-win32-x64@2.58.5': - resolution: {integrity: sha512-IZf+XIMiQwj+5NzqbOQfywlOitmCV424Vtf9c+ep61AaVScUFD1TSrQbOcJJv5xGxhlxNOMNgMeZhdexdzrKZg==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@sentry/cli@2.58.5': - resolution: {integrity: sha512-tavJ7yGUZV+z3Ct2/ZB6mg339i08sAk6HDkgqmSRuQEu2iLS5sl9HIvuXfM6xjv8fwlgFOSy++WNABNAcGHUbg==} - engines: {node: '>= 10'} - hasBin: true - - '@sentry/core@10.40.0': - resolution: {integrity: sha512-/wrcHPp9Avmgl6WBimPjS4gj810a1wU5oX9fF1bzJfeIIbF3jTsAbv0oMbgDp0cSDnkwv2+NvcPnn3+c5J6pBA==} - engines: {node: '>=18'} - - '@sentry/nextjs@10.40.0': - resolution: {integrity: sha512-0aID+iQ/8oEfmB2j8RRnQqio0AQcxTMiuEV+ev8K64UqJOb64cXNGBYP7fAankd0/jQOvIOuHvZhoZi9pwiRbg==} - engines: {node: '>=18'} - peerDependencies: - next: ^13.2.0 || ^14.0 || ^15.0.0-rc.0 || ^16.0.0-0 - - '@sentry/node-core@10.40.0': - resolution: {integrity: sha512-ciZGOF54rJH9Fkg7V3v4gmWVufnJRqQQOrn0KStuo49vfPQAJLGePDx+crQv0iNVoLc6Hmrr6E7ebNHSb4NSAw==} - engines: {node: '>=18'} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.1.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/instrumentation': '>=0.57.1 <1' - '@opentelemetry/resources': ^1.30.1 || ^2.1.0 - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - '@opentelemetry/semantic-conventions': ^1.39.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@opentelemetry/context-async-hooks': - optional: true - '@opentelemetry/core': - optional: true - '@opentelemetry/instrumentation': - optional: true - '@opentelemetry/resources': - optional: true - '@opentelemetry/sdk-trace-base': - optional: true - '@opentelemetry/semantic-conventions': - optional: true - - '@sentry/node@10.40.0': - resolution: {integrity: sha512-HQETLoNZTUUM8PBxFPT4X0qepzk5NcyWg3jyKUmF7Hh/19KSJItBXXZXxx+8l3PC2eASXUn70utXi65PoXEHWA==} - engines: {node: '>=18'} - - '@sentry/opentelemetry@10.40.0': - resolution: {integrity: sha512-Zx6T258qlEhQfdghIlazSTbK7uRO0pXWw4/4/VPR8pMOiRPh8dAoJg8AB0L55PYPMpVdXxNf7L9X0EZoDYibJw==} - engines: {node: '>=18'} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.1.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - '@opentelemetry/semantic-conventions': ^1.39.0 - - '@sentry/react@10.40.0': - resolution: {integrity: sha512-3T5W/e3QJMimXRIOx8xMEZbxeIuFiKlXvHLcMTLGygGBYnxQGeb8Oz/8heov+3zF1JoCIxeVQNFW0woySApfyA==} - engines: {node: '>=18'} - peerDependencies: - react: ^16.14.0 || 17.x || 18.x || 19.x - - '@sentry/vercel-edge@10.40.0': - resolution: {integrity: sha512-DdW8F5NE69Wm1CdKTaElFBtTsEzZZlYWs6tkHPY6GapQ97XY+71zu73cx7jFJgCGG/W4l0Em/BQlzNcw4U0V9A==} - engines: {node: '>=18'} - - '@sentry/webpack-plugin@5.1.0': - resolution: {integrity: sha512-GTLnr32ZIu6Gliy0z1J8N2S+WgWl5V1QeQj2BCpqA04hBOG1KK+dOX9z8yUKv2e5jvSQzpoyNNg3fBn08952cg==} - engines: {node: '>= 14'} - peerDependencies: - webpack: '>=5.0.0' - - '@shikijs/core@3.22.0': - resolution: {integrity: sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==} - - '@shikijs/engine-javascript@3.22.0': - resolution: {integrity: sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==} - - '@shikijs/engine-oniguruma@3.22.0': - resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} - - '@shikijs/langs@3.22.0': - resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} - - '@shikijs/themes@3.22.0': - resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} - - '@shikijs/types@3.22.0': - resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} - - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - - '@sinclair/typebox@0.25.24': - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - - '@smithy/abort-controller@4.2.10': - resolution: {integrity: sha512-qocxM/X4XGATqQtUkbE9SPUB6wekBi+FyJOMbPj0AhvyvFGYEmOlz6VB22iMePCQsFmMIvFSeViDvA7mZJG47g==} - engines: {node: '>=18.0.0'} - - '@smithy/chunked-blob-reader-native@4.2.2': - resolution: {integrity: sha512-QzzYIlf4yg0w5TQaC9VId3B3ugSk1MI/wb7tgcHtd7CBV9gNRKZrhc2EPSxSZuDy10zUZ0lomNMgkc6/VVe8xg==} - engines: {node: '>=18.0.0'} - - '@smithy/chunked-blob-reader@5.2.1': - resolution: {integrity: sha512-y5d4xRiD6TzeP5BWlb+Ig/VFqF+t9oANNhGeMqyzU7obw7FYgTgVi50i5JqBTeKp+TABeDIeeXFZdz65RipNtA==} - engines: {node: '>=18.0.0'} - - '@smithy/config-resolver@4.4.9': - resolution: {integrity: sha512-ejQvXqlcU30h7liR9fXtj7PIAau1t/sFbJpgWPfiYDs7zd16jpH0IsSXKcba2jF6ChTXvIjACs27kNMc5xxE2Q==} - engines: {node: '>=18.0.0'} - - '@smithy/core@3.23.6': - resolution: {integrity: sha512-4xE+0L2NrsFKpEVFlFELkIHQddBvMbQ41LRIP74dGCXnY1zQ9DgksrBcRBDJT+iOzGy4VEJIeU3hkUK5mn06kg==} - engines: {node: '>=18.0.0'} - - '@smithy/credential-provider-imds@4.2.10': - resolution: {integrity: sha512-3bsMLJJLTZGZqVGGeBVFfLzuRulVsGTj12BzRKODTHqUABpIr0jMN1vN3+u6r2OfyhAQ2pXaMZWX/swBK5I6PQ==} - engines: {node: '>=18.0.0'} - - '@smithy/eventstream-codec@4.2.10': - resolution: {integrity: sha512-A4ynrsFFfSXUHicfTcRehytppFBcY3HQxEGYiyGktPIOye3Ot7fxpiy4VR42WmtGI4Wfo6OXt/c1Ky1nUFxYYQ==} - engines: {node: '>=18.0.0'} - - '@smithy/eventstream-serde-browser@4.2.10': - resolution: {integrity: sha512-0xupsu9yj9oDVuQ50YCTS9nuSYhGlrwqdaKQel9y2Fz7LU9fNErVlw9N0o4pm4qqvWEGbSTI4HKc6XJfB30MVw==} - engines: {node: '>=18.0.0'} - - '@smithy/eventstream-serde-config-resolver@4.3.10': - resolution: {integrity: sha512-8kn6sinrduk0yaYHMJDsNuiFpXwQwibR7n/4CDUqn4UgaG+SeBHu5jHGFdU9BLFAM7Q4/gvr9RYxBHz9/jKrhA==} - engines: {node: '>=18.0.0'} - - '@smithy/eventstream-serde-node@4.2.10': - resolution: {integrity: sha512-uUrxPGgIffnYfvIOUmBM5i+USdEBRTdh7mLPttjphgtooxQ8CtdO1p6K5+Q4BBAZvKlvtJ9jWyrWpBJYzBKsyQ==} - engines: {node: '>=18.0.0'} - - '@smithy/eventstream-serde-universal@4.2.10': - resolution: {integrity: sha512-aArqzOEvcs2dK+xQVCgLbpJQGfZihw8SD4ymhkwNTtwKbnrzdhJsFDKuMQnam2kF69WzgJYOU5eJlCx+CA32bw==} - engines: {node: '>=18.0.0'} - - '@smithy/fetch-http-handler@5.3.11': - resolution: {integrity: sha512-wbTRjOxdFuyEg0CpumjZO0hkUl+fetJFqxNROepuLIoijQh51aMBmzFLfoQdwRjxsuuS2jizzIUTjPWgd8pd7g==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-blob-browser@4.2.11': - resolution: {integrity: sha512-DrcAx3PM6AEbWZxsKl6CWAGnVwiz28Wp1ZhNu+Hi4uI/6C1PIZBIaPM2VoqBDAsOWbM6ZVzOEQMxFLLdmb4eBQ==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-node@4.2.10': - resolution: {integrity: sha512-1VzIOI5CcsvMDvP3iv1vG/RfLJVVVc67dCRyLSB2Hn9SWCZrDO3zvcIzj3BfEtqRW5kcMg5KAeVf1K3dR6nD3w==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-stream-node@4.2.10': - resolution: {integrity: sha512-w78xsYrOlwXKwN5tv1GnKIRbHb1HygSpeZMP6xDxCPGf1U/xDHjCpJu64c5T35UKyEPwa0bPeIcvU69VY3khUA==} - engines: {node: '>=18.0.0'} - - '@smithy/invalid-dependency@4.2.10': - resolution: {integrity: sha512-vy9KPNSFUU0ajFYk0sDZIYiUlAWGEAhRfehIr5ZkdFrRFTAuXEPUd41USuqHU6vvLX4r6Q9X7MKBco5+Il0Org==} - engines: {node: '>=18.0.0'} - - '@smithy/is-array-buffer@2.2.0': - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} - - '@smithy/is-array-buffer@4.2.1': - resolution: {integrity: sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==} - engines: {node: '>=18.0.0'} - - '@smithy/md5-js@4.2.10': - resolution: {integrity: sha512-Op+Dh6dPLWTjWITChFayDllIaCXRofOed8ecpggTC5fkh8yXes0vAEX7gRUfjGK+TlyxoCAA05gHbZW/zB9JwQ==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-content-length@4.2.10': - resolution: {integrity: sha512-TQZ9kX5c6XbjhaEBpvhSvMEZ0klBs1CFtOdPFwATZSbC9UeQfKHPLPN9Y+I6wZGMOavlYTOlHEPDrt42PMSH9w==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-endpoint@4.4.20': - resolution: {integrity: sha512-9W6Np4ceBP3XCYAGLoMCmn8t2RRVzuD1ndWPLBbv7H9CrwM9Bprf6Up6BM9ZA/3alodg0b7Kf6ftBK9R1N04vw==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-retry@4.4.37': - resolution: {integrity: sha512-/1psZZllBBSQ7+qo5+hhLz7AEPGLx3Z0+e3ramMBEuPK2PfvLK4SrncDB9VegX5mBn+oP/UTDrM6IHrFjvX1ZA==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-serde@4.2.11': - resolution: {integrity: sha512-STQdONGPwbbC7cusL60s7vOa6He6A9w2jWhoapL0mgVjmR19pr26slV+yoSP76SIssMTX/95e5nOZ6UQv6jolg==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-stack@4.2.10': - resolution: {integrity: sha512-pmts/WovNcE/tlyHa8z/groPeOtqtEpp61q3W0nW1nDJuMq/x+hWa/OVQBtgU0tBqupeXq0VBOLA4UZwE8I0YA==} - engines: {node: '>=18.0.0'} - - '@smithy/node-config-provider@4.3.10': - resolution: {integrity: sha512-UALRbJtVX34AdP2VECKVlnNgidLHA2A7YgcJzwSBg1hzmnO/bZBHl/LDQQyYifzUwp1UOODnl9JJ3KNawpUJ9w==} - engines: {node: '>=18.0.0'} - - '@smithy/node-http-handler@4.4.12': - resolution: {integrity: sha512-zo1+WKJkR9x7ZtMeMDAAsq2PufwiLDmkhcjpWPRRkmeIuOm6nq1qjFICSZbnjBvD09ei8KMo26BWxsu2BUU+5w==} - engines: {node: '>=18.0.0'} - - '@smithy/property-provider@4.2.10': - resolution: {integrity: sha512-5jm60P0CU7tom0eNrZ7YrkgBaoLFXzmqB0wVS+4uK8PPGmosSrLNf6rRd50UBvukztawZ7zyA8TxlrKpF5z9jw==} - engines: {node: '>=18.0.0'} - - '@smithy/protocol-http@5.3.10': - resolution: {integrity: sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-builder@4.2.10': - resolution: {integrity: sha512-HeN7kEvuzO2DmAzLukE9UryiUvejD3tMp9a1D1NJETerIfKobBUCLfviP6QEk500166eD2IATaXM59qgUI+YDA==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-parser@4.2.10': - resolution: {integrity: sha512-4Mh18J26+ao1oX5wXJfWlTT+Q1OpDR8ssiC9PDOuEgVBGloqg18Fw7h5Ct8DyT9NBYwJgtJ2nLjKKFU6RP1G1Q==} - engines: {node: '>=18.0.0'} - - '@smithy/service-error-classification@4.2.10': - resolution: {integrity: sha512-0R/+/Il5y8nB/By90o8hy/bWVYptbIfvoTYad0igYQO5RefhNCDmNzqxaMx7K1t/QWo0d6UynqpqN5cCQt1MCg==} - engines: {node: '>=18.0.0'} - - '@smithy/shared-ini-file-loader@4.4.5': - resolution: {integrity: sha512-pHgASxl50rrtOztgQCPmOXFjRW+mCd7ALr/3uXNzRrRoGV5G2+78GOsQ3HlQuBVHCh9o6xqMNvlIKZjWn4Euug==} - engines: {node: '>=18.0.0'} - - '@smithy/signature-v4@5.3.10': - resolution: {integrity: sha512-Wab3wW8468WqTKIxI+aZe3JYO52/RYT/8sDOdzkUhjnLakLe9qoQqIcfih/qxcF4qWEFoWBszY0mj5uxffaVXA==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.12.0': - resolution: {integrity: sha512-R8bQ9K3lCcXyZmBnQqUZJF4ChZmtWT5NLi6x5kgWx5D+/j0KorXcA0YcFg/X5TOgnTCy1tbKc6z2g2y4amFupQ==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.13.0': - resolution: {integrity: sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==} - engines: {node: '>=18.0.0'} - - '@smithy/url-parser@4.2.10': - resolution: {integrity: sha512-uypjF7fCDsRk26u3qHmFI/ePL7bxxB9vKkE+2WKEciHhz+4QtbzWiHRVNRJwU3cKhrYDYQE3b0MRFtqfLYdA4A==} - engines: {node: '>=18.0.0'} - - '@smithy/util-base64@4.3.1': - resolution: {integrity: sha512-BKGuawX4Doq/bI/uEmg+Zyc36rJKWuin3py89PquXBIBqmbnJwBBsmKhdHfNEp0+A4TDgLmT/3MSKZ1SxHcR6w==} - engines: {node: '>=18.0.0'} - - '@smithy/util-body-length-browser@4.2.1': - resolution: {integrity: sha512-SiJeLiozrAoCrgDBUgsVbmqHmMgg/2bA15AzcbcW+zan7SuyAVHN4xTSbq0GlebAIwlcaX32xacnrG488/J/6g==} - engines: {node: '>=18.0.0'} - - '@smithy/util-body-length-node@4.2.2': - resolution: {integrity: sha512-4rHqBvxtJEBvsZcFQSPQqXP2b/yy/YlB66KlcEgcH2WNoOKCKB03DSLzXmOsXjbl8dJ4OEYTn31knhdznwk7zw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-buffer-from@2.2.0': - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} - - '@smithy/util-buffer-from@4.2.1': - resolution: {integrity: sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==} - engines: {node: '>=18.0.0'} - - '@smithy/util-config-provider@4.2.1': - resolution: {integrity: sha512-462id/00U8JWFw6qBuTSWfN5TxOHvDu4WliI97qOIOnuC/g+NDAknTU8eoGXEPlLkRVgWEr03jJBLV4o2FL8+A==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-browser@4.3.36': - resolution: {integrity: sha512-R0smq7EHQXRVMxkAxtH5akJ/FvgAmNF6bUy/GwY/N20T4GrwjT633NFm0VuRpC+8Bbv8R9A0DoJ9OiZL/M3xew==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-node@4.2.39': - resolution: {integrity: sha512-otWuoDm35btJV1L8MyHrPl462B07QCdMTktKc7/yM+Psv6KbED/ziXiHnmr7yPHUjfIwE9S8Max0LO24Mo3ZVg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-endpoints@3.3.1': - resolution: {integrity: sha512-xyctc4klmjmieQiF9I1wssBWleRV0RhJ2DpO8+8yzi2LO1Z+4IWOZNGZGNj4+hq9kdo+nyfrRLmQTzc16Op2Vg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-hex-encoding@4.2.1': - resolution: {integrity: sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-middleware@4.2.10': - resolution: {integrity: sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-retry@4.2.10': - resolution: {integrity: sha512-HrBzistfpyE5uqTwiyLsFHscgnwB0kgv8vySp7q5kZ0Eltn/tjosaSGGDj/jJ9ys7pWzIP/icE2d+7vMKXLv7A==} - engines: {node: '>=18.0.0'} - - '@smithy/util-stream@4.5.15': - resolution: {integrity: sha512-OlOKnaqnkU9X+6wEkd7mN+WB7orPbCVDauXOj22Q7VtiTkvy7ZdSsOg4QiNAZMgI4OkvNf+/VLUC3VXkxuWJZw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-uri-escape@4.2.1': - resolution: {integrity: sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==} - engines: {node: '>=18.0.0'} - - '@smithy/util-utf8@2.3.0': - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} - - '@smithy/util-utf8@4.2.1': - resolution: {integrity: sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==} - engines: {node: '>=18.0.0'} - - '@smithy/util-waiter@4.2.10': - resolution: {integrity: sha512-4eTWph/Lkg1wZEDAyObwme0kmhEb7J/JjibY2znJdrYRgKbKqB7YoEhhJVJ4R1g/SYih4zuwX7LpJaM8RsnTVg==} - engines: {node: '>=18.0.0'} - - '@smithy/uuid@1.1.1': - resolution: {integrity: sha512-dSfDCeihDmZlV2oyr0yWPTUfh07suS+R5OB+FZGiv/hHyK3hrFBW5rR1UYjfa57vBsrP9lciFkRPzebaV1Qujw==} - engines: {node: '>=18.0.0'} - - '@standard-schema/spec@1.0.0': - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - - '@tailwindcss/node@4.2.0': - resolution: {integrity: sha512-Yv+fn/o2OmL5fh/Ir62VXItdShnUxfpkMA4Y7jdeC8O81WPB8Kf6TT6GSHvnqgSwDzlB5iT7kDpeXxLsUS0T6Q==} - - '@tailwindcss/oxide-android-arm64@4.2.0': - resolution: {integrity: sha512-F0QkHAVaW/JNBWl4CEKWdZ9PMb0khw5DCELAOnu+RtjAfx5Zgw+gqCHFvqg3AirU1IAd181fwOtJQ5I8Yx5wtw==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.2.0': - resolution: {integrity: sha512-I0QylkXsBsJMZ4nkUNSR04p6+UptjcwhcVo3Zu828ikiEqHjVmQL9RuQ6uT/cVIiKpvtVA25msu/eRV97JeNSA==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.2.0': - resolution: {integrity: sha512-6TmQIn4p09PBrmnkvbYQ0wbZhLtbaksCDx7Y7R3FYYx0yxNA7xg5KP7dowmQ3d2JVdabIHvs3Hx4K3d5uCf8xg==} - engines: {node: '>= 20'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.2.0': - resolution: {integrity: sha512-qBudxDvAa2QwGlq9y7VIzhTvp2mLJ6nD/G8/tI70DCDoneaUeLWBJaPcbfzqRIWraj+o969aDQKvKW9dvkUizw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0': - resolution: {integrity: sha512-7XKkitpy5NIjFZNUQPeUyNJNJn1CJeV7rmMR+exHfTuOsg8rxIO9eNV5TSEnqRcaOK77zQpsyUkBWmPy8FgdSg==} - engines: {node: '>= 20'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.2.0': - resolution: {integrity: sha512-Mff5a5Q3WoQR01pGU1gr29hHM1N93xYrKkGXfPw/aRtK4bOc331Ho4Tgfsm5WDGvpevqMpdlkCojT3qlCQbCpA==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-musl@4.2.0': - resolution: {integrity: sha512-XKcSStleEVnbH6W/9DHzZv1YhjE4eSS6zOu2eRtYAIh7aV4o3vIBs+t/B15xlqoxt6ef/0uiqJVB6hkHjWD/0A==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-gnu@4.2.0': - resolution: {integrity: sha512-/hlXCBqn9K6fi7eAM0RsobHwJYa5V/xzWspVTzxnX+Ft9v6n+30Pz8+RxCn7sQL/vRHHLS30iQPrHQunu6/vJA==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-musl@4.2.0': - resolution: {integrity: sha512-lKUaygq4G7sWkhQbfdRRBkaq4LY39IriqBQ+Gk6l5nKq6Ay2M2ZZb1tlIyRNgZKS8cbErTwuYSor0IIULC0SHw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-wasm32-wasi@4.2.0': - resolution: {integrity: sha512-xuDjhAsFdUuFP5W9Ze4k/o4AskUtI8bcAGU4puTYprr89QaYFmhYOPfP+d1pH+k9ets6RoE23BXZM1X1jJqoyw==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.2.0': - resolution: {integrity: sha512-2UU/15y1sWDEDNJXxEIrfWKC2Yb4YgIW5Xz2fKFqGzFWfoMHWFlfa1EJlGO2Xzjkq/tvSarh9ZTjvbxqWvLLXA==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.2.0': - resolution: {integrity: sha512-CrFadmFoc+z76EV6LPG1jx6XceDsaCG3lFhyLNo/bV9ByPrE+FnBPckXQVP4XRkN76h3Fjt/a+5Er/oA/nCBvQ==} - engines: {node: '>= 20'} - cpu: [x64] - os: [win32] - - '@tailwindcss/oxide@4.2.0': - resolution: {integrity: sha512-AZqQzADaj742oqn2xjl5JbIOzZB/DGCYF/7bpvhA8KvjUj9HJkag6bBuwZvH1ps6dfgxNHyuJVlzSr2VpMgdTQ==} - engines: {node: '>= 20'} - - '@tailwindcss/postcss@4.2.0': - resolution: {integrity: sha512-u6YBacGpOm/ixPfKqfgrJEjMfrYmPD7gEFRoygS/hnQaRtV0VCBdpkx5Ouw9pnaLRwwlgGCuJw8xLpaR0hOrQg==} - - '@tanstack/hotkeys@0.3.0': - resolution: {integrity: sha512-y2uawGLj/GrMNDffaaC0YS7tZPwchDbWAKnU/XObjtyQ4oRGVLyg/2PPbT/hWNQ2PbbrolB098NvlYM0OR3XSw==} - engines: {node: '>=18'} - - '@tanstack/query-core@5.90.20': - resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} - - '@tanstack/react-hotkeys@0.3.0': - resolution: {integrity: sha512-DkSu+8lDwUGzZLk1WVgT6XtfxTa7mFWOGmiDYK+2pe7GqbnuQgUIQPRdo82yCuHYzNoEJgjoYo/HJ8frD4mmcA==} - engines: {node: '>=18'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - '@tanstack/react-query@5.90.21': - resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} - peerDependencies: - react: ^18 || ^19 - - '@tanstack/react-store@0.9.1': - resolution: {integrity: sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - '@tanstack/store@0.9.1': - resolution: {integrity: sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg==} - - '@tiptap/core@3.20.0': - resolution: {integrity: sha512-aC9aROgia/SpJqhsXFiX9TsligL8d+oeoI8W3u00WI45s0VfsqjgeKQLDLF7Tu7hC+7F02teC84SAHuup003VQ==} - peerDependencies: - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-blockquote@3.20.0': - resolution: {integrity: sha512-LQzn6aGtL4WXz2+rYshl/7/VnP2qJTpD7fWL96GXAzhqviPEY1bJES7poqJb3MU/gzl8VJUVzVzU1VoVfUKlbA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-bold@3.20.0': - resolution: {integrity: sha512-sQklEWiyf58yDjiHtm5vmkVjfIc/cBuSusmCsQ0q9vGYnEF1iOHKhGpvnCeEXNeqF3fiJQRlquzt/6ymle3Iwg==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-bubble-menu@3.20.0': - resolution: {integrity: sha512-MDosUfs8Tj+nwg8RC+wTMWGkLJORXmbR6YZgbiX4hrc7G90Gopdd6kj6ht5/T8t7dLLaX7N0+DEHdUEPGED7dw==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-bullet-list@3.20.0': - resolution: {integrity: sha512-OcKMeopBbqWzhSi6o8nNz0aayogg1sfOAhto3NxJu3Ya32dwBFqmHXSYM6uW4jOphNvVPyjiq9aNRh3qTdd1dw==} - peerDependencies: - '@tiptap/extension-list': ^3.20.0 - - '@tiptap/extension-code-block@3.20.0': - resolution: {integrity: sha512-lBbmNek14aCjrHcBcq3PRqWfNLvC6bcRa2Osc6e/LtmXlcpype4f6n+Yx+WZ+f2uUh0UmDRCz7BEyUETEsDmlQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-code@3.20.0': - resolution: {integrity: sha512-TYDWFeSQ9umiyrqsT6VecbuhL8XIHkUhO+gEk0sVvH67ZLwjFDhAIIgWIr1/dbIGPcvMZM19E7xUUhAdIaXaOQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-document@3.20.0': - resolution: {integrity: sha512-oJfLIG3vAtZo/wg29WiBcyWt22KUgddpP8wqtCE+kY5Dw8znLR9ehNmVWlSWJA5OJUMO0ntAHx4bBT+I2MBd5w==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-dropcursor@3.20.0': - resolution: {integrity: sha512-d+cxplRlktVgZPwatnc34IArlppM0IFKS1J5wLk+ba1jidizsbMVh45tP/BTK2flhyfRqcNoB5R0TArhUpbkNQ==} - peerDependencies: - '@tiptap/extensions': ^3.20.0 - - '@tiptap/extension-floating-menu@3.20.0': - resolution: {integrity: sha512-rYs4Bv5pVjqZ/2vvR6oe7ammZapkAwN51As/WDbemvYDjfOGRqK58qGauUjYZiDzPOEIzI2mxGwsZ4eJhPW4Ig==} - peerDependencies: - '@floating-ui/dom': ^1.0.0 - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-gapcursor@3.20.0': - resolution: {integrity: sha512-P/LasfvG9/qFq43ZAlNbAnPnXC+/RJf49buTrhtFvI9Zg0+Lbpjx1oh6oMHB19T88Y28KtrckfFZ8aTSUWDq6w==} - peerDependencies: - '@tiptap/extensions': ^3.20.0 - - '@tiptap/extension-hard-break@3.20.0': - resolution: {integrity: sha512-rqvhMOw4f+XQmEthncbvDjgLH6fz8L9splnKZC7OeS0eX8b0qd7+xI1u5kyxF3KA2Z0BnigES++jjWuecqV6mA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-heading@3.20.0': - resolution: {integrity: sha512-JgJhurnCe3eN6a0lEsNQM/46R1bcwzwWWZEFDSb1P9dR8+t1/5v7cMZWsSInpD7R4/74iJn0+M5hcXLwCmBmYA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-horizontal-rule@3.20.0': - resolution: {integrity: sha512-6uvcutFMv+9wPZgptDkbRDjAm3YVxlibmkhWD5GuaWwS9L/yUtobpI3GycujRSUZ8D3q6Q9J7LqpmQtQRTalWA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-italic@3.20.0': - resolution: {integrity: sha512-/DhnKQF8yN8RxtuL8abZ28wd5281EaGoE2Oha35zXSOF1vNYnbyt8Ymkv/7u1BcWEWTvRPgaju0YCGXisPRLYw==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-link@3.20.0': - resolution: {integrity: sha512-qI/5A+R0ZWBxo/8HxSn1uOyr7odr3xHBZ/gzOR1GUJaZqjlJxkWFX0RtXMbLKEGEvT25o345cF7b0wFznEh8qA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-list-item@3.20.0': - resolution: {integrity: sha512-qEtjaaGPuqaFB4VpLrGDoIe9RHnckxPfu6d3rc22ap6TAHCDyRv05CEyJogqccnFceG/v5WN4znUBER8RWnWHA==} - peerDependencies: - '@tiptap/extension-list': ^3.20.0 - - '@tiptap/extension-list-keymap@3.20.0': - resolution: {integrity: sha512-Z4GvKy04Ms4cLFN+CY6wXswd36xYsT2p/YL0V89LYFMZTerOeTjFYlndzn6svqL8NV1PRT5Diw4WTTxJSmcJPA==} - peerDependencies: - '@tiptap/extension-list': ^3.20.0 - - '@tiptap/extension-list@3.20.0': - resolution: {integrity: sha512-+V0/gsVWAv+7vcY0MAe6D52LYTIicMSHw00wz3ISZgprSb2yQhJ4+4gurOnUrQ4Du3AnRQvxPROaofwxIQ66WQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/extension-mention@3.20.0': - resolution: {integrity: sha512-wUjsq7Za0JJdJzrGNG+g8nrCpek/85GQ0Rm9bka3PynIVRwus+xQqW6IyWVPBdl1BSkrbgMAUqtrfoh1ymznbg==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - '@tiptap/suggestion': ^3.20.0 - - '@tiptap/extension-ordered-list@3.20.0': - resolution: {integrity: sha512-jVKnJvrizLk7etwBMfyoj6H2GE4M+PD4k7Bwp6Bh1ohBWtfIA1TlngdS842Mx5i1VB2e3UWIwr8ZH46gl6cwMA==} - peerDependencies: - '@tiptap/extension-list': ^3.20.0 - - '@tiptap/extension-paragraph@3.20.0': - resolution: {integrity: sha512-mM99zK4+RnEXIMCv6akfNATAs0Iija6FgyFA9J9NZ6N4o8y9QiNLLa6HjLpAC+W+VoCgQIekyoF/Q9ftxmAYDQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-placeholder@3.20.0': - resolution: {integrity: sha512-ZhYD3L5m16ydSe2z8vqz+RdtAG/iOQaFHHedFct70tKRoLqi2ajF5kgpemu8DwpaRTcyiCN4G99J/+MqehKNjQ==} - peerDependencies: - '@tiptap/extensions': ^3.20.0 - - '@tiptap/extension-strike@3.20.0': - resolution: {integrity: sha512-0vcTZRRAiDfon3VM1mHBr9EFmTkkUXMhm0Xtdtn0bGe+sIqufyi+hUYTEw93EQOD9XNsPkrud6jzQNYpX2H3AQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-text@3.20.0': - resolution: {integrity: sha512-tf8bE8tSaOEWabCzPm71xwiUhyMFKqY9jkP5af3Kr1/F45jzZFIQAYZooHI/+zCHRrgJ99MQHKHe1ZNvODrKHQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extension-underline@3.20.0': - resolution: {integrity: sha512-LzNXuy2jwR/y+ymoUqC72TiGzbOCjioIjsDu0MNYpHuHqTWPK5aV9Mh0nbZcYFy/7fPlV1q0W139EbJeYBZEAQ==} - peerDependencies: - '@tiptap/core': ^3.20.0 - - '@tiptap/extensions@3.20.0': - resolution: {integrity: sha512-HIsXX942w3nbxEQBlMAAR/aa6qiMBEP7CsSMxaxmTIVAmW35p6yUASw6GdV1u0o3lCZjXq2OSRMTskzIqi5uLg==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tiptap/pm@3.20.0': - resolution: {integrity: sha512-jn+2KnQZn+b+VXr8EFOJKsnjVNaA4diAEr6FOazupMt8W8ro1hfpYtZ25JL87Kao/WbMze55sd8M8BDXLUKu1A==} - - '@tiptap/react@3.20.0': - resolution: {integrity: sha512-jFLNzkmn18zqefJwPje0PPd9VhZ7Oy28YHiSvSc7YpBnQIbuN/HIxZ2lrOsKyEHta0WjRZjfU5X1pGxlbcGwOA==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - - '@tiptap/starter-kit@3.20.0': - resolution: {integrity: sha512-W4+1re35pDNY/7rpXVg+OKo/Fa4Gfrn08Bq3E3fzlJw6gjE3tYU8dY9x9vC2rK9pd9NOp7Af11qCFDaWpohXkw==} - - '@tiptap/suggestion@3.20.0': - resolution: {integrity: sha512-OA9Fe+1Q/Ex0ivTcpRcVFiLnNsVdIBmiEoctt/gu4H2ayCYmZ906veioXNdc1m/3MtVVUIuEnvwwsrOZXlfDEw==} - peerDependencies: - '@tiptap/core': ^3.20.0 - '@tiptap/pm': ^3.20.0 - - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - - '@traceloop/ai-semantic-conventions@0.20.0': - resolution: {integrity: sha512-bvivhZU6U8TW4TKktYnjdTi+7GE4WxI8epaGjawalSKDunmxaA+4UVFQ+4tSCBvp2Scby+gnYNaTZSrtABfOlQ==} - engines: {node: '>=14'} - - '@traceloop/instrumentation-anthropic@0.20.0': - resolution: {integrity: sha512-xQcPxVrKr3yT9+ZEM3skYXikJc/ocZlGDIcsBQ3mMwL3Weq1QL7jx/uGLXvrSO2Yh0DWUjWI6Q/oiRCEUM6P8w==} - engines: {node: '>=14'} - - '@ts-morph/common@0.11.1': - resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - - '@types/aws-lambda@8.10.160': - resolution: {integrity: sha512-uoO4QVQNWFPJMh26pXtmtrRfGshPUSpMZGUyUQY20FhfHEElEBOPKgVmFs1z+kbpyBsRs2JnoOPT7++Z4GA9pA==} - - '@types/bunyan@1.8.11': - resolution: {integrity: sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - - '@types/estree-jsx@1.0.5': - resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/linkify-it@3.0.5': - resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} - - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - - '@types/markdown-it@13.0.9': - resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==} - - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - - '@types/mdurl@1.0.5': - resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} - - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - - '@types/memcached@2.2.10': - resolution: {integrity: sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/mysql@2.15.27': - resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} - - '@types/node@20.11.0': - resolution: {integrity: sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==} - - '@types/node@22.19.11': - resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==} - - '@types/node@25.3.0': - resolution: {integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==} - - '@types/oracledb@6.5.2': - resolution: {integrity: sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==} - - '@types/pg-pool@2.0.7': - resolution: {integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==} - - '@types/pg@8.15.6': - resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} - - '@types/pg@8.16.0': - resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} - - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - - '@types/tedious@4.0.14': - resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} - - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@types/use-sync-external-store@0.0.6': - resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - - '@types/webidl-conversions@7.0.3': - resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} - - '@types/whatwg-url@13.0.0': - resolution: {integrity: sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - '@upstash/redis@1.36.2': - resolution: {integrity: sha512-C0Yt8hc12vLaQYRG1fMci8iPrLtnTdbJG0HR5T8vKnvEP/1RdMMblsOJs5/jp0JXZJ1oSzMnQz4J9EVezNpI6A==} - - '@vercel/analytics@1.6.1': - resolution: {integrity: sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==} - peerDependencies: - '@remix-run/react': ^2 - '@sveltejs/kit': ^1 || ^2 - next: '>= 13' - react: ^18 || ^19 || ^19.0.0-rc - svelte: '>= 4' - vue: ^3 - vue-router: ^4 - peerDependenciesMeta: - '@remix-run/react': - optional: true - '@sveltejs/kit': - optional: true - next: - optional: true - react: - optional: true - svelte: - optional: true - vue: - optional: true - vue-router: - optional: true - - '@vercel/backends@0.0.36': - resolution: {integrity: sha512-V1//TxZMo3RTfkFE+yUa5lEl8jsxUDXh4/ljZSCDpSOqgam4ObLr5iENhMdZYoOon+FopEsP1LT3+9LkLZnuxg==} - peerDependencies: - typescript: ^4.0.0 || ^5.0.0 - - '@vercel/blob@2.3.0': - resolution: {integrity: sha512-oYWiJbWRQ7gz9Mj0X/NHFJ3OcLMOBzq/2b3j6zeNrQmtFo6dHwU8FAwNpxVIYddVMd+g8eqEi7iRueYx8FtM0Q==} - engines: {node: '>=20.0.0'} - - '@vercel/build-utils@13.4.3': - resolution: {integrity: sha512-Eu9EK1iO0zBbXEUc7CJ9ksauBW16nZ7tPfMvvSWiQ82+3C2oLlHf0q7tPevrk410h6iqG9NdUKRgkouajGGBZg==} - - '@vercel/cervel@0.0.23': - resolution: {integrity: sha512-TG6GpQd721qlI8/roUFOfNZZQzFzv/tZA00CnvVXmL1vV4/DN78QUuk0m5IPoX56emhOPjeJ0XFKq0cS0S1xeQ==} - hasBin: true - peerDependencies: - typescript: ^4.0.0 || ^5.0.0 - - '@vercel/detect-agent@1.1.0': - resolution: {integrity: sha512-Zfq6FbIcYl9gaAmVu6ROsqUiCNwpEj3Ljz/tMX5fl12Z95OFOxzf7vlO03WE5JBU/ri1tBDFHnW41dihMINOPQ==} - engines: {node: '>=14'} - - '@vercel/elysia@0.1.39': - resolution: {integrity: sha512-5ZxZAsCqznMlL3N3i7Ax/8RcSNdCBrIMF8RAVfc+NKNeEBKBwVrluJWMW2khNqhVKSt8niZe5UrcXAGIihPjCw==} - - '@vercel/error-utils@2.0.3': - resolution: {integrity: sha512-CqC01WZxbLUxoiVdh9B/poPbNpY9U+tO1N9oWHwTl5YAZxcqXmmWJ8KNMFItJCUUWdY3J3xv8LvAuQv2KZ5YdQ==} - - '@vercel/express@0.1.48': - resolution: {integrity: sha512-CVjWJ34rdh5VlQLzZZiHGVHZfGWFiBPVNu9uerItVdK3xrywoAKZONYZoYa8GKWhTdyG+jK8gavzmFXHXwv37w==} - - '@vercel/fastify@0.1.42': - resolution: {integrity: sha512-ob/GfKKvue74oGDncuodKQx6jA56DQRMFrQKW6kuOjW0pR1zrBiFk6fks9tYJ1s65If8McycSZUfZls++ouRaQ==} - - '@vercel/fun@1.3.0': - resolution: {integrity: sha512-8erw9uPe0dFg45THkNxmjtvMX143SkZebmjgSVbcM3XCkXu3RIiBaJMcMNG8aaS+rnTuw8+d4De9HVT0M/r3wg==} - engines: {node: '>= 18'} - - '@vercel/functions@3.4.2': - resolution: {integrity: sha512-WDsNNuGOOUhRYxfcSgk8nlXaYW/6u1Lw2eaKm0y4+gDPGK/hwmYIeP2hESfccuCiPXd5ZGO8Jz/V5Ud3ZByoUQ==} - engines: {node: '>= 20'} - peerDependencies: - '@aws-sdk/credential-provider-web-identity': '*' - peerDependenciesMeta: - '@aws-sdk/credential-provider-web-identity': - optional: true - - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': - resolution: {integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==} - - '@vercel/gatsby-plugin-vercel-builder@2.0.138': - resolution: {integrity: sha512-YM3rJ02Kcfhf2XmPUGxBAHJ7g3prU6Cr2jDV22FLdfg/I1E6ftG1uBf8bJgPUTIHdJRzHPc25qllccEacm3X6g==} - - '@vercel/go@3.4.1': - resolution: {integrity: sha512-VASkp8D3FG77zesloUiMSGMZhLkeYdSPlakyssTiU30UO3+ydbEP4SRKj9YhXNCYu7cY5xKY2gJx9PsoDhrW4g==} - - '@vercel/h3@0.1.48': - resolution: {integrity: sha512-ficubEC3+Me3D5XSme+K9cTBjDbgOdW4DchLHajfAcQERM6gZckl4W4orbBPz4k67M+bwLN6/aajXeDJVXjjBw==} - - '@vercel/hono@0.2.42': - resolution: {integrity: sha512-ljnUnpK2/2vXStes1NIex3aELmZ0gzz7J6ll4jJSHknSJgCOG6EW0YHvKe/KlIRhBZ6X0tt4MUDmQ1FWq6nZsQ==} - - '@vercel/hydrogen@1.3.5': - resolution: {integrity: sha512-7EE6yVKcCnjMb1io9y069GkLyGyIzRbW3Krm3Q7EEfJ3P46h9xe9v/O5UhBoPrwtqDUHxmDngZp9YyfgY8IITA==} - - '@vercel/koa@0.1.22': - resolution: {integrity: sha512-rTq411YrGAHmSJy0DQD9H7u7y3OKnmpqLczm2ckDH+JgaTX1HD6ZHmnoa1OqshrVMQRXcenWUecT4LPUvAA+kw==} - - '@vercel/nestjs@0.2.43': - resolution: {integrity: sha512-PWb55H+DT90DpBs+defa5UA8pQMDMP8nSNMNFyIYHJXf54ysGm3PLFzx90aQ2vZ95pGoSCMMJL7cQES+I2q4Qg==} - - '@vercel/next@4.15.31': - resolution: {integrity: sha512-mKuiYl1hzQlucFCM81OHT5Qg13nPMprufsINLs7OJ8TnvwBRKjaLIDnEAgKBWeJsBK+nBAVb/GPqjwKfT2G+6g==} - - '@vercel/nft@1.1.1': - resolution: {integrity: sha512-mKMGa7CEUcXU75474kOeqHbtvK1kAcu4wiahhmlUenB5JbTQB8wVlDI8CyHR3rpGo0qlzoRWqcDzI41FUoBJCA==} - engines: {node: '>=20'} - hasBin: true - - '@vercel/nft@1.3.0': - resolution: {integrity: sha512-i4EYGkCsIjzu4vorDUbqglZc5eFtQI2syHb++9ZUDm6TU4edVywGpVnYDein35x9sevONOn9/UabfQXuNXtuzQ==} - engines: {node: '>=20'} - hasBin: true - - '@vercel/node@5.6.6': - resolution: {integrity: sha512-grKDQzta6CUW1MyK5iJOb+hthvx5RXfuyQ4z02Xv95yL5Le4mi0nBR9XQ2m9gIKmXIFkVHqCYr7keWHPWjqs7A==} - - '@vercel/oidc@3.1.0': - resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} - engines: {node: '>= 20'} - - '@vercel/oidc@3.2.0': - resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} - engines: {node: '>= 20'} - - '@vercel/python-analysis@0.6.0': - resolution: {integrity: sha512-M7VAxXDOPIwJICMKU2+yeky4ZE1CMaeJDi45F1TNtlzETGlMbT8H/Cf9E/BK341gkubDuQRoraz6ndrVqg6SZQ==} - - '@vercel/python@6.15.1': - resolution: {integrity: sha512-X0MB2dWD2aH7DVM2Mmxg2bnUIjoMC0obs3IwWEZS1jKcZ02iwNhdYdyqtW2amg0yq/w/pdZFm19EviLSQrDTSA==} - - '@vercel/redwood@2.4.9': - resolution: {integrity: sha512-U7bYIuWfMEFMIcKKbX7lTT8pFNjig9Q3vLeCYRYQUrKVP8xLoUBXSEfW3ijtWJBUV8GmbZCDI30A16uUfNhN+g==} - - '@vercel/remix-builder@5.5.10': - resolution: {integrity: sha512-E4fqjBaztj/5JG8HCbvqO/JZyP3b+hpse+aAMb9twvgyIRfkkl+146liFF2I8/M/cc1PWkSfaqa8LF0+5x4egA==} - - '@vercel/ruby@2.3.1': - resolution: {integrity: sha512-r9WdHILtb3pca75RMPJnSeLSOhBtNt4qZgU+tqRfoS90vEa9Rr6EC2XaD/Wyfm2N5dHSlahASTgp8uPoN4aLZA==} - - '@vercel/rust@1.0.5': - resolution: {integrity: sha512-Y03g59nv1uT6Da+PvB/50WqJSHlaFZ9MSkG00R82dUcTySslMbQdOeaXymZtabrmU8zQYhWDb1/CwBki8sWnaQ==} - - '@vercel/static-build@2.8.40': - resolution: {integrity: sha512-h4/Z2orXHPGU0fw+K+x9D9JwVkhYZeJvKjYcTDwfvUGR4gTEEtcVB3+OKQBE2XJz6qR7i8KIP9SCK1VqbM+apg==} - - '@vercel/static-config@3.1.2': - resolution: {integrity: sha512-2d+TXr6K30w86a+WbMbGm2W91O0UzO5VeemZYBBUJbCjk/5FLLGIi8aV6RS2+WmaRvtcqNTn2pUA7nCOK3bGcQ==} - - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - - '@webassemblyjs/helper-buffer@1.14.1': - resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - - '@webassemblyjs/helper-numbers@1.13.2': - resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': - resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - - '@webassemblyjs/helper-wasm-section@1.14.1': - resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - - '@webassemblyjs/ieee754@1.13.2': - resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - - '@webassemblyjs/leb128@1.13.2': - resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - - '@webassemblyjs/utf8@1.13.2': - resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - - '@webassemblyjs/wasm-edit@1.14.1': - resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - - '@webassemblyjs/wasm-gen@1.14.1': - resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - - '@webassemblyjs/wasm-opt@1.14.1': - resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - - '@webassemblyjs/wasm-parser@1.14.1': - resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - - '@webassemblyjs/wast-printer@1.14.1': - resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - - '@xmldom/is-dom-node@1.0.1': - resolution: {integrity: sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q==} - engines: {node: '>= 16'} - - '@xmldom/xmldom@0.8.11': - resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} - engines: {node: '>=10.0.0'} - - '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - - '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} - - acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} - peerDependencies: - acorn: ^8 - - acorn-import-phases@1.0.4: - resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} - engines: {node: '>=10.13.0'} - peerDependencies: - acorn: ^8.14.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - ai@6.0.97: - resolution: {integrity: sha512-eZIAcBymwGhBwncRH/v9pillZNMeRCDkc4BwcvwXerXd7sxjVxRis3ZNCNCpP02pVH4NLs81ljm4cElC4vbNcQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv-keywords@5.1.0: - resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} - peerDependencies: - ajv: ^8.8.2 - - ajv@8.18.0: - resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - - ajv@8.6.3: - resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} - - ansi-escapes@7.3.0: - resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} - engines: {node: '>=18'} - - ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - 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@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==} - - arg@4.1.0: - resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - - async-listen@1.2.0: - resolution: {integrity: sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==} - - async-listen@3.0.0: - resolution: {integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==} - engines: {node: '>= 14'} - - async-listen@3.0.1: - resolution: {integrity: sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==} - engines: {node: '>= 14'} - - async-retry@1.3.3: - resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} - - async-sema@3.1.1: - resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - auth@1.5.0-beta.18: - resolution: {integrity: sha512-gjl/RF9JBZfZCFOEnyGC/EQWNEeZUyyr+lHjghj5qJyeeY+gCPE2UZ2vmyck7LQ2bZms+sZYtU8lWz6Hqo9LLg==} - hasBin: true - - aws-ssl-profiles@1.1.2: - resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} - engines: {node: '>= 6.0.0'} - - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.3: - resolution: {integrity: sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==} - engines: {node: 20 || >=22} - - baseline-browser-mapping@2.10.0: - resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} - engines: {node: '>=6.0.0'} - hasBin: true - - basic-ftp@5.1.0: - resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==} - engines: {node: '>=10.0.0'} - - before-after-hook@4.0.0: - resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} - - better-all@0.0.7: - resolution: {integrity: sha512-xgdUMWb88Qhz6RtC/PY/7QtR61K/JabCcbKhNYYuXC/IoY3c/bgYdIjVxyTHXR41KP8JQeP+6dg4zH4KOpwJzw==} - - better-auth@1.5.0-beta.16: - resolution: {integrity: sha512-hkpcNioqkgYs9MNRiK9fD/l8gaiFhODpf8U58v5efTZ2HrXbTfiWKfM2KxcOyFeF2SNdqal+cn762a0ym/3WGA==} - peerDependencies: - '@lynx-js/react': '*' - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 - '@sveltejs/kit': ^2.0.0 - '@tanstack/react-start': ^1.0.0 - '@tanstack/solid-start': ^1.0.0 - better-sqlite3: ^12.0.0 - drizzle-kit: '>=0.31.4' - drizzle-orm: '>=0.41.0' - mongodb: ^6.0.0 || ^7.0.0 - mysql2: ^3.0.0 - next: ^14.0.0 || ^15.0.0 || ^16.0.0 - pg: ^8.0.0 - prisma: ^5.0.0 || ^6.0.0 || ^7.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 - vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 - vue: ^3.0.0 - peerDependenciesMeta: - '@lynx-js/react': - optional: true - '@prisma/client': - optional: true - '@sveltejs/kit': - optional: true - '@tanstack/react-start': - optional: true - '@tanstack/solid-start': - optional: true - better-sqlite3: - optional: true - drizzle-kit: - optional: true - drizzle-orm: - optional: true - mongodb: - optional: true - mysql2: - optional: true - next: - optional: true - pg: - optional: true - prisma: - optional: true - react: - optional: true - react-dom: - optional: true - solid-js: - optional: true - svelte: - optional: true - vitest: - optional: true - vue: - optional: true - - better-auth@1.5.0-beta.18: - resolution: {integrity: sha512-08RpwE9f/WJcoe3GjgeUtLmLsY7Tmm57jAXO3sHGIG7EfWF3zN5EGpUl8P8rRnZS6tPGhX5h5wh+d6UYcyJEGQ==} - peerDependencies: - '@lynx-js/react': '*' - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 - '@sveltejs/kit': ^2.0.0 - '@tanstack/react-start': ^1.0.0 - '@tanstack/solid-start': ^1.0.0 - better-sqlite3: ^12.0.0 - drizzle-kit: '>=0.31.4' - drizzle-orm: '>=0.41.0' - mongodb: ^6.0.0 || ^7.0.0 - mysql2: ^3.0.0 - next: ^14.0.0 || ^15.0.0 || ^16.0.0 - pg: ^8.0.0 - prisma: ^5.0.0 || ^6.0.0 || ^7.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 - vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 - vue: ^3.0.0 - peerDependenciesMeta: - '@lynx-js/react': - optional: true - '@prisma/client': - optional: true - '@sveltejs/kit': - optional: true - '@tanstack/react-start': - optional: true - '@tanstack/solid-start': - optional: true - better-sqlite3: - optional: true - drizzle-kit: - optional: true - drizzle-orm: - optional: true - mongodb: - optional: true - mysql2: - optional: true - next: - optional: true - pg: - optional: true - prisma: - optional: true - react: - optional: true - react-dom: - optional: true - solid-js: - optional: true - svelte: - optional: true - vitest: - optional: true - vue: - optional: true - - better-call@1.1.0-beta.2: - resolution: {integrity: sha512-H0kqGDNT1ixkzboxg3fAYkpJ4HyIhNUID/OyC3fBEfwmHFBLwHpNRwRZYGGOcgcRQNIZtXlJGXaGvnFUhCS44Q==} - - better-call@1.3.2: - resolution: {integrity: sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw==} - peerDependencies: - zod: ^4.0.0 - peerDependenciesMeta: - zod: - optional: true - - bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bowser@2.14.1: - resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@5.0.2: - resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} - engines: {node: 20 || >=22} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - bson@7.2.0: - resolution: {integrity: sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==} - engines: {node: '>=20.19.0'} - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - bytes@3.1.0: - resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} - engines: {node: '>= 0.8'} - - c12@3.1.0: - resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} - peerDependencies: - magicast: ^0.3.5 - peerDependenciesMeta: - magicast: - optional: true - - c12@3.3.3: - resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} - peerDependencies: - magicast: '*' - peerDependenciesMeta: - magicast: - optional: true - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caniuse-lite@1.0.30001770: - resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} - - canonicalize@1.0.8: - resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==} - - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - - chevrotain@10.5.0: - resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} - - chokidar@4.0.0: - resolution: {integrity: sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==} - engines: {node: '>= 14.16.0'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} - - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - - chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} - engines: {node: '>=6.0'} - - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - citty@0.2.1: - resolution: {integrity: sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==} - - cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} - - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - - cjs-module-lexer@2.2.0: - resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} - - class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - - cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} - - cli-truncate@5.1.1: - resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} - engines: {node: '>=20'} - - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - cmdk@1.1.1: - resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - react-dom: ^18 || ^19 || ^19.0.0-rc - - code-block-writer@10.1.1: - resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - compare-versions@6.1.1: - resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - content-type@1.0.4: - resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} - engines: {node: '>= 0.6'} - - convert-hrtime@3.0.0: - resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} - engines: {node: '>=8'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-es@2.0.0: - resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} - - crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} - - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - 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.3.0: - resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - - deepmerge-ts@7.1.5: - resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} - engines: {node: '>=16.0.0'} - - default-browser-id@5.0.1: - resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} - engines: {node: '>=18'} - - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} - engines: {node: '>=18'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - - depd@1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - dockerfile-ast@0.7.1: - resolution: {integrity: sha512-oX/A4I0EhSkGqrFv0YuvPkBUSYp1XiY8O8zAKc8Djglx8ocz+JfOr8gP0ryRMC2myqvDLagmnZaU9ot1vG2ijw==} - - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} - - dotenv@17.3.1: - resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} - engines: {node: '>=12'} - - drizzle-orm@0.41.0: - resolution: {integrity: sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@libsql/client-wasm': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@prisma/client': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/sql.js': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - gel: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - prisma: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - e2b@2.12.1: - resolution: {integrity: sha512-qKYwS0VSZqvtWAT4OrCtOwRhhMlcd359zyFRGAZZ1wpYHHjr9zR872UCoDb/d5jFVUsREcUgktURc47XxfznPg==} - engines: {node: '>=20'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - edge-runtime@2.5.9: - resolution: {integrity: sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==} - engines: {node: '>=16'} - hasBin: true - - effect@3.18.4: - resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} - - electron-to-chromium@1.5.302: - resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} - - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - empathic@2.0.0: - resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} - engines: {node: '>=14'} - - end-of-stream@1.1.0: - resolution: {integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - enhanced-resolve@5.19.0: - resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} - engines: {node: '>=10.13.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} - - 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-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} - - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - - 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'} - - esbuild@0.27.0: - resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} - - events-intercept@2.0.0: - resolution: {integrity: sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} - - execa@3.2.0: - resolution: {integrity: sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==} - engines: {node: ^8.12.0 || >=9.7.0} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fast-check@3.23.2: - resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} - engines: {node: '>=8.0.0'} - - fast-content-type-parse@3.0.0: - resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-equals@5.4.0: - resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==} - engines: {node: '>=6.0.0'} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - - fast-xml-builder@1.0.0: - resolution: {integrity: sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==} - - fast-xml-parser@5.3.6: - resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==} - hasBin: true - - fast-xml-parser@5.4.1: - resolution: {integrity: sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==} - hasBin: true - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} - - formdata-node@6.0.3: - resolution: {integrity: sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==} - engines: {node: '>= 18'} - - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - - forwarded-parse@2.1.2: - resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} - - foxact@0.2.52: - resolution: {integrity: sha512-cc3ydJkM/mYkof1/ofI4VlVAiRyfsSDsHRC4UIAXQcnUXCuo0rXM66Zy1ggdxAXL03ikHnh3bPnQ7AYuI/Yzow==} - peerDependencies: - react: '*' - react-dom: '*' - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - - framer-motion@12.34.3: - resolution: {integrity: sha512-v81ecyZKYO/DfpTwHivqkxSUBzvceOpoI+wLfgCgoUIKxlFKEXdg0oR9imxwXumT4SFy8vRk9xzJ5l3/Du/55Q==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true - - fs-extra@11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} - engines: {node: '>=14.14'} - - fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} - - 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==} - - gaxios@7.1.3: - resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} - engines: {node: '>=18'} - - gcp-metadata@8.1.2: - resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} - engines: {node: '>=18'} - - generate-function@2.3.1: - resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} - - generic-pool@3.4.2: - resolution: {integrity: sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==} - engines: {node: '>= 4'} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} - engines: {node: '>=18'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - - get-port-please@3.2.0: - resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} - - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} - - giget@2.0.0: - resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} - hasBin: true - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - - glob@11.1.0: - resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} - engines: {node: 20 || >=22} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - - glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} - engines: {node: 18 || 20 || >=22} - - google-logging-utils@1.1.3: - resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} - engines: {node: '>=14'} - - 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==} - - grammex@3.1.12: - resolution: {integrity: sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ==} - - graphmatch@1.1.1: - resolution: {integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - 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'} - - hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - hast-util-from-parse5@8.0.3: - resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} - - hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - - hast-util-raw@9.1.0: - resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} - - hast-util-sanitize@5.0.2: - resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==} - - hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} - - hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - - hast-util-to-parse5@8.0.1: - resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} - - hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - - hastscript@9.0.1: - resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - - hono@4.11.4: - resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==} - engines: {node: '>=16.9.0'} - - html-url-attributes@3.0.1: - resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} - - html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - - http-errors@1.7.3: - resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} - engines: {node: '>= 0.6'} - - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - - http-status-codes@2.3.0: - resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - human-signals@1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} - - import-in-the-middle@1.15.0: - resolution: {integrity: sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==} - - import-in-the-middle@2.0.6: - resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - inline-style-parser@0.2.7: - resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} - - inngest@3.52.3: - resolution: {integrity: sha512-e1sHdjjySXX56m58SMYz+1hRqBKPzxM6w5tPAEs30ocpsK2VZOqyc2aOJ4dQPixilJOphlk+IJx0SjX2gwGtPQ==} - engines: {node: '>=20'} - peerDependencies: - '@sveltejs/kit': '>=1.27.3' - '@vercel/node': '>=2.15.9' - aws-lambda: '>=1.0.7' - express: '>=4.19.2' - fastify: '>=4.21.0' - h3: '>=1.8.1' - hono: '>=4.2.7' - koa: '>=2.14.2' - next: '>=12.0.0' - typescript: '>=5.8.0' - zod: ^3.25.0 || ^4.0.0 - peerDependenciesMeta: - '@sveltejs/kit': - optional: true - '@vercel/node': - optional: true - aws-lambda: - optional: true - express: - optional: true - fastify: - optional: true - h3: - optional: true - hono: - optional: true - koa: - optional: true - next: - optional: true - typescript: - optional: true - - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} - engines: {node: '>= 12'} - - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - - is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-fullwidth-code-point@5.1.0: - resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} - engines: {node: '>=18'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - - 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-property@1.0.2: - resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} - - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-wsl@3.1.1: - resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} - engines: {node: '>=16'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - jackspeak@4.2.3: - resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} - engines: {node: 20 || >=22} - - jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - - jose@5.9.6: - resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} - - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} - - js-base64@3.7.2: - resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} - - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json-schema-to-ts@1.6.4: - resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - kysely@0.28.11: - resolution: {integrity: sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg==} - engines: {node: '>=20.0.0'} - - libphonenumber-js@1.12.37: - resolution: {integrity: sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw==} - - lightningcss-android-arm64@1.31.1: - resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.31.1: - resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.31.1: - resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.31.1: - resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.31.1: - resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.31.1: - resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.31.1: - resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.31.1: - resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.31.1: - resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.31.1: - resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.31.1: - resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.31.1: - resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} - engines: {node: '>= 12.0.0'} - - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - linkifyjs@4.3.2: - resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} - - lint-staged@16.2.7: - resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==} - engines: {node: '>=20.17'} - hasBin: true - - listr2@9.0.5: - resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} - engines: {node: '>=20.0.0'} - - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} - engines: {node: '>=6.11.5'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-update@6.1.0: - resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} - engines: {node: '>=18'} - - long@5.3.2: - resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} - - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@11.2.6: - resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} - engines: {node: 20 || >=22} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - lru.min@1.1.4: - resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} - engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} - - lucide-react@0.575.0: - resolution: {integrity: sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - luxon@3.7.2: - resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} - engines: {node: '>=12'} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magic-string@0.30.8: - resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} - engines: {node: '>=12'} - - markdown-it-task-lists@2.1.1: - resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==} - - markdown-it@14.1.1: - resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} - hasBin: true - - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} - - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} - - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} - - mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - - mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} - - mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - - mdast-util-to-hast@13.2.1: - resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} - - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} - - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - memory-pager@1.5.0: - resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micro@9.3.5-canary.3: - resolution: {integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==} - engines: {node: '>= 8.0.0'} - hasBin: true - - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} - - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} - - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - - 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'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - - minimatch@10.2.2: - resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==} - engines: {node: 18 || 20 || >=22} - - minimatch@3.1.3: - resolution: {integrity: sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==} - - minimatch@9.0.6: - resolution: {integrity: sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - module-details-from-path@1.0.4: - resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} - - mongodb-connection-string-url@7.0.1: - resolution: {integrity: sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ==} - engines: {node: '>=20.19.0'} - - mongodb@7.1.0: - resolution: {integrity: sha512-kMfnKunbolQYwCIyrkxNJFB4Ypy91pYqua5NargS/f8ODNSJxT03ZU3n1JqL4mCzbSih8tvmMEMLpKTT7x5gCg==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@aws-sdk/credential-providers': ^3.806.0 - '@mongodb-js/zstd': ^7.0.0 - gcp-metadata: ^7.0.1 - kerberos: ^7.0.0 - mongodb-client-encryption: '>=7.0.0 <7.1.0' - snappy: ^7.3.2 - socks: ^2.8.6 - peerDependenciesMeta: - '@aws-sdk/credential-providers': - optional: true - '@mongodb-js/zstd': - optional: true - gcp-metadata: - optional: true - kerberos: - optional: true - mongodb-client-encryption: - optional: true - snappy: - optional: true - socks: - optional: true - - motion-dom@12.34.3: - resolution: {integrity: sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==} - - motion-utils@12.29.2: - resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==} - - motion@12.34.3: - resolution: {integrity: sha512-xZIkBGO7v/Uvm+EyaqYd+9IpXu0sZqLywVlGdCFrrMiaO9JI4Kx51mO9KlHSWwll+gZUVY5OJsWgYI5FywJ/tw==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true - - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - ms@2.1.1: - resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mysql2@3.15.3: - resolution: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==} - engines: {node: '>= 8.0'} - - named-placeholders@1.1.6: - resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} - engines: {node: '>=8.0.0'} - - nano-spawn@2.0.0: - resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} - engines: {node: '>=20.17'} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanostores@1.1.0: - resolution: {integrity: sha512-yJBmDJr18xy47dbNVlHcgdPrulSn1nhSE6Ns9vTG+Nx9VPT6iV1MD6aQFp/t52zpf82FhLLTXAXr30NuCnxvwA==} - engines: {node: ^20.0.0 || >=22.0.0} - - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - - next-themes@0.4.6: - resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - - next@16.1.6: - resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==} - engines: {node: '>=20.9.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - - node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@2.6.9: - resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - 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-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-forge@1.3.3: - resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} - engines: {node: '>= 6.13.0'} - - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - - node-rsa@1.1.1: - resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} - - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} - hasBin: true - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nuqs@2.8.8: - resolution: {integrity: sha512-LF5sw9nWpHyPWzMMu9oho3r9C5DvkpmBIg4LQN78sexIzGaeRx8DWr0uy3YiFx5i2QGZN1Qqcb+OAtEVRa2bnA==} - peerDependencies: - '@remix-run/react': '>=2' - '@tanstack/react-router': ^1 - next: '>=14.2.0' - react: '>=18.2.0 || ^19.0.0-0' - react-router: ^5 || ^6 || ^7 - react-router-dom: ^5 || ^6 || ^7 - peerDependenciesMeta: - '@remix-run/react': - optional: true - '@tanstack/react-router': - optional: true - next: - optional: true - react-router: - optional: true - react-router-dom: - optional: true - - nypm@0.6.5: - resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} - engines: {node: '>=18'} - hasBin: true - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - ohm-js@17.5.0: - resolution: {integrity: sha512-l4Sa7026+6jsvYbt0PXKmL+f+ML32fD++IznLgxDhx2t9Cx6NC7zwRqblCujPHGGmkQerHoeBzRutdxaw/S72g==} - engines: {node: '>=0.12.1'} - - once@1.3.3: - resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - - oniguruma-parser@0.12.1: - resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} - - oniguruma-to-es@4.3.4: - resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} - - open@10.2.0: - resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} - engines: {node: '>=18'} - - openapi-fetch@0.14.1: - resolution: {integrity: sha512-l7RarRHxlEZYjMLd/PR0slfMVse2/vvIAGm75/F7J6MlQ8/b9uUQmUF2kCPrQhJqMXSxmYWObVgeYXbFYzZR+A==} - - openapi-typescript-helpers@0.0.15: - resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} - - orderedmap@2.1.1: - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} - - os-paths@4.4.0: - resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} - engines: {node: '>= 6.0'} - - oxc-transform@0.111.0: - resolution: {integrity: sha512-oa5KKSDNLHZGaiqIGAbCWXeN9IJUAz9MElWcQX90epDxdKc9Hrt/BsLj3K4gDqfAYa5dwdH+ZCFJG9hR74fiGg==} - engines: {node: ^20.19.0 || >=22.12.0} - - oxfmt@0.34.0: - resolution: {integrity: sha512-t+zTE4XGpzPTK+Zk9gSwcJcFi4pqjl6PwO/ZxPBJiJQ2XCKMucwjPlHxvPHyVKJtkMSyrDGfQ7Ntg/hUr4OgHQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - oxlint@1.49.0: - resolution: {integrity: sha512-YZffp0gM+63CJoRhHjtjRnwKtAgUnXM6j63YQ++aigji2NVvLGsUlrXo9gJUXZOdcbfShLYtA6RuTu8GZ4lzOQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - oxlint-tsgolint: '>=0.14.1' - peerDependenciesMeta: - oxlint-tsgolint: - optional: true - - p-finally@2.0.1: - resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} - engines: {node: '>=8'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - - parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - - parse-ms@2.1.0: - resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} - engines: {node: '>=6'} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - 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-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} - - path-to-regexp@6.1.0: - resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} - - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} - - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - - perfect-debounce@2.1.0: - resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} - - pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} - - pg-connection-string@2.11.0: - resolution: {integrity: sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-pool@3.11.0: - resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.11.0: - resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.18.0: - resolution: {integrity: sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==} - engines: {node: '>= 16.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - - 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'} - - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - - pip-requirements-js@1.0.2: - resolution: {integrity: sha512-awqoNOSOl4Blu4E4Hzp7jL0g8WKEhCwO+s7C2ibtIW3CAJMwspgoTXd4vnHd21UmhdrsI44Pn8FFSuA8QKrzvg==} - - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - - platform@1.3.6: - resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} - - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-array@3.0.4: - resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} - engines: {node: '>=12'} - - postgres-bytea@1.0.1: - resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - postgres@3.4.7: - resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} - engines: {node: '>=12'} - - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} - engines: {node: '>=14'} - hasBin: true - - pretty-ms@7.0.1: - resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} - engines: {node: '>=10'} - - prisma@7.4.1: - resolution: {integrity: sha512-gDKOXwnPiMdB+uYMhMeN8jj4K7Cu3Q2wB/wUsITOoOk446HtVb8T9BZxFJ1Zop6alc89k6PMNdR2FZCpbXp/jw==} - engines: {node: ^20.19 || ^22.12 || >=24.0} - hasBin: true - peerDependencies: - better-sqlite3: '>=9.0.0' - typescript: '>=5.4.0' - peerDependenciesMeta: - better-sqlite3: - optional: true - typescript: - optional: true - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - promisepipe@3.0.0: - resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - proper-lockfile@4.1.2: - resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - - prosemirror-changeset@2.4.0: - resolution: {integrity: sha512-LvqH2v7Q2SF6yxatuPP2e8vSUKS/L+xAU7dPDC4RMyHMhZoGDfBC74mYuyYF4gLqOEG758wajtyhNnsTkuhvng==} - - prosemirror-collab@1.3.1: - resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} - - prosemirror-commands@1.7.1: - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} - - prosemirror-dropcursor@1.8.2: - resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} - - prosemirror-gapcursor@1.4.0: - resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} - - prosemirror-history@1.5.0: - resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} - - prosemirror-inputrules@1.5.1: - resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} - - prosemirror-keymap@1.2.3: - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - - prosemirror-markdown@1.13.4: - resolution: {integrity: sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==} - - prosemirror-menu@1.3.0: - resolution: {integrity: sha512-TImyPXCHPcDsSka2/lwJ6WjTASr4re/qWq1yoTTuLOqfXucwF6VcRa2LWCkM/EyTD1UO3CUwiH8qURJoWJRxwg==} - - prosemirror-model@1.25.4: - resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} - - prosemirror-schema-basic@1.2.4: - resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} - - prosemirror-schema-list@1.5.1: - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} - - prosemirror-state@1.4.4: - resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} - - prosemirror-tables@1.8.5: - resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} - - prosemirror-trailing-node@3.0.0: - resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} - peerDependencies: - prosemirror-model: ^1.22.1 - prosemirror-state: ^1.4.2 - prosemirror-view: ^1.33.8 - - prosemirror-transform@1.11.0: - resolution: {integrity: sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==} - - prosemirror-view@1.41.6: - resolution: {integrity: sha512-mxpcDG4hNQa/CPtzxjdlir5bJFDlm0/x5nGBbStB2BWX+XOQ9M8ekEG+ojqB5BcVu2Rc80/jssCMZzSstJuSYg==} - - protobufjs@7.5.4: - resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} - engines: {node: '>=12.0.0'} - - protobufjs@8.0.0: - resolution: {integrity: sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==} - engines: {node: '>=12.0.0'} - - proxy-agent@6.4.0: - resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} - engines: {node: '>= 14'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - - qs@6.11.2: - resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} - engines: {node: '>=0.6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - raw-body@2.4.1: - resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} - engines: {node: '>= 0.8'} - - rc9@2.1.2: - resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - - react-dom@19.2.4: - resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} - peerDependencies: - react: ^19.2.4 - - react-markdown@10.1.0: - resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} - peerDependencies: - '@types/react': '>=18' - react: '>=18' - - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react@19.2.4: - resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} - engines: {node: '>=0.10.0'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} - engines: {node: '>= 20.19.0'} - - regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} - - regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - - regex@6.1.0: - resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} - - regexp-to-ast@0.5.0: - resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} - - rehype-raw@7.0.0: - resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} - - rehype-sanitize@6.0.0: - resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} - - rehype-stringify@10.0.1: - resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} - - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} - - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - - remark-rehype@11.1.2: - resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} - - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - - remeda@2.33.4: - resolution: {integrity: sha512-ygHswjlc/opg2VrtiYvUOPLjxjtdKvjGz1/plDhkG66hjNjFr1xmfrs2ClNFo/E6TyUFiwYNh53bKV26oBoMGQ==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - require-in-the-middle@7.5.2: - resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} - engines: {node: '>=8.6.0'} - - require-in-the-middle@8.0.1: - resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} - engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} - - 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.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} - engines: {node: '>= 0.4'} - hasBin: true - - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - rolldown@1.0.0-rc.1: - resolution: {integrity: sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rope-sequence@1.3.4: - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} - - rou3@0.5.1: - resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} - - rou3@0.7.12: - resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} - - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} - engines: {node: '>=18'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - samlify@2.10.2: - resolution: {integrity: sha512-y5s1cHwclqwP8h7K2Wj9SfP1q+1S9+jrs5OAegYTLAiuFi7nDvuKqbiXLmUTvYPMpzHcX94wTY2+D604jgTKvA==} - - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - schema-utils@4.3.3: - resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} - engines: {node: '>= 10.13.0'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - seq-queue@0.0.5: - resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} - - serialize-error-cjs@0.1.4: - resolution: {integrity: sha512-6a6dNqipzbCPlTFgztfNP2oG+IGcflMe/01zSzGrQcxGMKbIjOemBBD85pH92klWaJavAUWxAh9Z0aU28zxW6A==} - deprecated: Rolling release, please update to 0.2.0 - - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - server-only@0.0.1: - resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} - - set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} - - set-cookie-parser@3.0.1: - resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} - - setprototypeof@1.1.1: - resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} - - sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - 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'} - - shiki@3.22.0: - resolution: {integrity: sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==} - - 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@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} - engines: {node: '>=14'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-git-hooks@2.13.1: - resolution: {integrity: sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==} - hasBin: true - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slice-ansi@7.1.2: - resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} - engines: {node: '>=18'} - - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - smol-toml@1.5.2: - resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==} - engines: {node: '>= 18'} - - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - - sparse-bitfield@3.0.3: - resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - sqlstring@2.3.3: - resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} - engines: {node: '>= 0.6'} - - srvx@0.8.9: - resolution: {integrity: sha512-wYc3VLZHRzwYrWJhkEqkhLb31TI0SOkfYZDkUhXdp3NoCnNS0FqajiQszZZjfow/VYEuc6Q5sZh9nM6kPy2NBQ==} - engines: {node: '>=20.16.0'} - hasBin: true - - stacktrace-parser@0.1.11: - resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} - engines: {node: '>=6'} - - stat-mode@0.3.0: - resolution: {integrity: sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==} - - statuses@1.5.0: - resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} - engines: {node: '>= 0.6'} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - - stream-to-array@2.3.0: - resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} - - stream-to-promise@2.2.0: - resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} - - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - - 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-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string-width@8.2.0: - resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} - engines: {node: '>=20'} - - stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} - - strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - - 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-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - stripe@20.4.0: - resolution: {integrity: sha512-F/aN1IQ9vHmlyLNi3DkiIbyzQb6gyBG0uYFd/VrEVQSc9BLtlgknPUx0EvzZdBMRLFuRaPFIFd7Mxwtg7Pbwzw==} - engines: {node: '>=16'} - peerDependencies: - '@types/node': '>=16' - peerDependenciesMeta: - '@types/node': - optional: true - - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} - - style-to-js@1.1.21: - resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} - - style-to-object@1.0.14: - resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} - - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - - supermemory@4.11.1: - resolution: {integrity: sha512-L5I/inWEIjtD+kw/2TAZ7ZsZa3kCYzlXXeNHd09ueFoExvCHLjzTW4SCnN6GjbhE7CZUcwTXA9SttZvihLa8gQ==} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - swr@2.4.0: - resolution: {integrity: sha512-sUlC20T8EOt1pHmDiqueUWMmRRX03W7w5YxovWX7VR2KHEPCTMly85x05vpkP5i6Bu4h44ePSMD9Tc+G2MItFw==} - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - tailwind-merge@3.5.0: - resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} - - tailwindcss@4.2.0: - resolution: {integrity: sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q==} - - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} - - tar@7.5.7: - resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} - engines: {node: '>=18'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - - tar@7.5.9: - resolution: {integrity: sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==} - engines: {node: '>=18'} - - temporal-polyfill@0.2.5: - resolution: {integrity: sha512-ye47xp8Cb0nDguAhrrDS1JT1SzwEV9e26sSsrWzVu+yPZ7LzceEcH0i2gci9jWfOfSCCgM3Qv5nOYShVUUFUXA==} - - temporal-spec@0.2.4: - resolution: {integrity: sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ==} - - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - - terser@5.46.0: - resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} - engines: {node: '>=10'} - hasBin: true - - throttleit@2.1.0: - resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} - engines: {node: '>=18'} - - time-span@4.0.0: - resolution: {integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==} - engines: {node: '>=10'} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - - tinypool@2.1.0: - resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} - engines: {node: ^20.0.0 || >=22.0.0} - - tiptap-markdown@0.9.0: - resolution: {integrity: sha512-dKLQ9iiuGNgrlGVjrNauF/UBzWu4LYOx5pkD0jNkmQt/GOwfCJsBuzZTsf1jZ204ANHOm572mZ9PYvGh1S7tpQ==} - peerDependencies: - '@tiptap/core': ^3.0.1 - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.0: - resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} - engines: {node: '>=0.6'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - - trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - - ts-morph@12.0.0: - resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} - - ts-toolbelt@6.15.5: - resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true - - tw-animate-css@1.4.0: - resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} - - type-fest@0.7.1: - resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} - engines: {node: '>=8'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - uid-promise@1.0.0: - resolution: {integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==} - - ulid@2.4.0: - resolution: {integrity: sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==} - hasBin: true - - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici-types@7.18.2: - resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - undici@6.23.0: - resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} - engines: {node: '>=18.17'} - - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - - unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} - - unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - - unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} - - unist-util-visit@5.1.0: - resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} - - universal-user-agent@7.0.3: - resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - url-join@4.0.1: - resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - valibot@1.2.0: - resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} - peerDependencies: - typescript: '>=5' - peerDependenciesMeta: - typescript: - optional: true - - vercel@50.22.1: - resolution: {integrity: sha512-gtm9yDLbFRISNBeki6VqdZMygygJNEg0zjdh7K9tGkDuVupGFd3KlnEjyjNmxvkkVt8rVxjbh00Ey8S/WcE8LQ==} - engines: {node: '>= 18'} - hasBin: true - - vfile-location@5.0.3: - resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} - - vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} - - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - - vscode-languageserver-textdocument@1.0.12: - resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} - - vscode-languageserver-types@3.17.5: - resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} - - w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - - watchpack@2.5.1: - resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} - engines: {node: '>=10.13.0'} - - web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - - web-vitals@0.2.4: - resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - webpack-sources@3.3.4: - resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} - engines: {node: '>=10.13.0'} - - webpack@5.105.2: - resolution: {integrity: sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - 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'} - - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - wsl-utils@0.1.0: - resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} - engines: {node: '>=18'} - - xdg-app-paths@5.1.0: - resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} - engines: {node: '>=6'} - - xdg-portable@7.3.0: - resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} - engines: {node: '>= 6.0'} - - xml-crypto@6.1.2: - resolution: {integrity: sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w==} - engines: {node: '>=16'} - - xml-escape@1.1.0: - resolution: {integrity: sha512-B/T4sDK8Z6aUh/qNr7mjKAwwncIljFuUP+DO/D5hloYFj+90O88z8Wf7oSucZTHxBAsC1/CTP4rtx/x1Uf72Mg==} - - xml@1.0.1: - resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} - - xpath@0.0.32: - resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==} - engines: {node: '>=0.6.0'} - - xpath@0.0.33: - resolution: {integrity: sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==} - engines: {node: '>=0.6.0'} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} - hasBin: true - - 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'} - - yauzl-clone@1.0.4: - resolution: {integrity: sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==} - engines: {node: '>=6'} - - yauzl-promise@2.1.3: - resolution: {integrity: sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==} - engines: {node: '>=6'} - - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yocto-spinner@0.2.3: - resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==} - engines: {node: '>=18.19'} - - yoctocolors@2.1.2: - resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} - engines: {node: '>=18'} - - zeptomatch@2.1.0: - resolution: {integrity: sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA==} - - zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - -snapshots: - - '@ai-sdk/anthropic@3.0.46(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.15(zod@4.3.6) - zod: 4.3.6 - - '@ai-sdk/gateway@3.0.53(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.15(zod@4.3.6) - '@vercel/oidc': 3.1.0 - zod: 4.3.6 - - '@ai-sdk/provider-utils@4.0.15(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.0.6 - zod: 4.3.6 - - '@ai-sdk/provider@3.0.8': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/react@3.0.99(react@19.2.4)(zod@4.3.6)': - dependencies: - '@ai-sdk/provider-utils': 4.0.15(zod@4.3.6) - ai: 6.0.97(zod@4.3.6) - react: 19.2.4 - swr: 2.4.0(react@19.2.4) - throttleit: 2.1.0 - transitivePeerDependencies: - - zod - - '@alloc/quick-lru@5.2.0': {} - - '@authenio/xml-encryption@2.0.2': - dependencies: - '@xmldom/xmldom': 0.8.11 - escape-html: 1.0.3 - xpath: 0.0.32 - - '@aws-crypto/crc32@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - tslib: 2.8.1 - - '@aws-crypto/crc32c@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - tslib: 2.8.1 - - '@aws-crypto/sha1-browser@5.2.0': - dependencies: - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-locate-window': 3.965.4 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 - - '@aws-crypto/sha256-browser@5.2.0': - dependencies: - '@aws-crypto/sha256-js': 5.2.0 - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-locate-window': 3.965.4 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 - - '@aws-crypto/sha256-js@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - tslib: 2.8.1 - - '@aws-crypto/supports-web-crypto@5.2.0': - dependencies: - tslib: 2.8.1 - - '@aws-crypto/util@5.2.0': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 - - '@aws-sdk/client-s3@3.998.0': - dependencies: - '@aws-crypto/sha1-browser': 5.2.0 - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/credential-provider-node': 3.972.13 - '@aws-sdk/middleware-bucket-endpoint': 3.972.5 - '@aws-sdk/middleware-expect-continue': 3.972.5 - '@aws-sdk/middleware-flexible-checksums': 3.973.0 - '@aws-sdk/middleware-host-header': 3.972.5 - '@aws-sdk/middleware-location-constraint': 3.972.5 - '@aws-sdk/middleware-logger': 3.972.5 - '@aws-sdk/middleware-recursion-detection': 3.972.5 - '@aws-sdk/middleware-sdk-s3': 3.972.14 - '@aws-sdk/middleware-ssec': 3.972.5 - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/region-config-resolver': 3.972.5 - '@aws-sdk/signature-v4-multi-region': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@aws-sdk/util-user-agent-browser': 3.972.5 - '@aws-sdk/util-user-agent-node': 3.972.13 - '@smithy/config-resolver': 4.4.9 - '@smithy/core': 3.23.6 - '@smithy/eventstream-serde-browser': 4.2.10 - '@smithy/eventstream-serde-config-resolver': 4.3.10 - '@smithy/eventstream-serde-node': 4.2.10 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/hash-blob-browser': 4.2.11 - '@smithy/hash-node': 4.2.10 - '@smithy/hash-stream-node': 4.2.10 - '@smithy/invalid-dependency': 4.2.10 - '@smithy/md5-js': 4.2.10 - '@smithy/middleware-content-length': 4.2.10 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-retry': 4.4.37 - '@smithy/middleware-serde': 4.2.11 - '@smithy/middleware-stack': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/node-http-handler': 4.4.12 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-body-length-node': 4.2.2 - '@smithy/util-defaults-mode-browser': 4.3.36 - '@smithy/util-defaults-mode-node': 4.2.39 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - '@smithy/util-waiter': 4.2.10 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.973.14': - dependencies: - '@aws-sdk/types': 3.973.3 - '@aws-sdk/xml-builder': 3.972.7 - '@smithy/core': 3.23.6 - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@aws-sdk/crc64-nvme@3.972.2': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-env@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-http@3.972.14': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/node-http-handler': 4.4.12 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-stream': 4.5.15 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-ini@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/credential-provider-env': 3.972.12 - '@aws-sdk/credential-provider-http': 3.972.14 - '@aws-sdk/credential-provider-login': 3.972.12 - '@aws-sdk/credential-provider-process': 3.972.12 - '@aws-sdk/credential-provider-sso': 3.972.12 - '@aws-sdk/credential-provider-web-identity': 3.972.12 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-login@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-node@3.972.13': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.12 - '@aws-sdk/credential-provider-http': 3.972.14 - '@aws-sdk/credential-provider-ini': 3.972.12 - '@aws-sdk/credential-provider-process': 3.972.12 - '@aws-sdk/credential-provider-sso': 3.972.12 - '@aws-sdk/credential-provider-web-identity': 3.972.12 - '@aws-sdk/types': 3.973.3 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-process@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-sso@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/token-providers': 3.998.0 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-web-identity@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/middleware-bucket-endpoint@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 - tslib: 2.8.1 - - '@aws-sdk/middleware-expect-continue@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-flexible-checksums@3.973.0': - dependencies: - '@aws-crypto/crc32': 5.2.0 - '@aws-crypto/crc32c': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/crc64-nvme': 3.972.2 - '@aws-sdk/types': 3.973.3 - '@smithy/is-array-buffer': 4.2.1 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@aws-sdk/middleware-host-header@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-location-constraint@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-logger@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-recursion-detection@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-sdk-s3@3.972.14': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/core': 3.23.6 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@aws-sdk/middleware-ssec@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/middleware-user-agent@3.972.14': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@smithy/core': 3.23.6 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/nested-clients@3.996.2': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/middleware-host-header': 3.972.5 - '@aws-sdk/middleware-logger': 3.972.5 - '@aws-sdk/middleware-recursion-detection': 3.972.5 - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/region-config-resolver': 3.972.5 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@aws-sdk/util-user-agent-browser': 3.972.5 - '@aws-sdk/util-user-agent-node': 3.972.13 - '@smithy/config-resolver': 4.4.9 - '@smithy/core': 3.23.6 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/hash-node': 4.2.10 - '@smithy/invalid-dependency': 4.2.10 - '@smithy/middleware-content-length': 4.2.10 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-retry': 4.4.37 - '@smithy/middleware-serde': 4.2.11 - '@smithy/middleware-stack': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/node-http-handler': 4.4.12 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-body-length-node': 4.2.2 - '@smithy/util-defaults-mode-browser': 4.3.36 - '@smithy/util-defaults-mode-node': 4.2.39 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/region-config-resolver@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/config-resolver': 4.4.9 - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/s3-request-presigner@3.998.0': - dependencies: - '@aws-sdk/signature-v4-multi-region': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-format-url': 3.972.5 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/signature-v4-multi-region@3.996.2': - dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.14 - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/token-providers@3.998.0': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/types@3.973.3': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/util-arn-parser@3.972.2': - dependencies: - tslib: 2.8.1 - - '@aws-sdk/util-endpoints@3.996.2': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-endpoints': 3.3.1 - tslib: 2.8.1 - - '@aws-sdk/util-format-url@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/querystring-builder': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/util-locate-window@3.965.4': - dependencies: - tslib: 2.8.1 - - '@aws-sdk/util-user-agent-browser@3.972.5': - dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - bowser: 2.14.1 - tslib: 2.8.1 - - '@aws-sdk/util-user-agent-node@3.972.13': - dependencies: - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/types': 3.973.3 - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@aws-sdk/xml-builder@3.972.7': - dependencies: - '@smithy/types': 4.13.0 - fast-xml-parser: 5.3.6 - tslib: 2.8.1 - - '@aws/lambda-invoke-store@0.2.3': {} - - '@babel/code-frame@7.29.0': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.29.0': {} - - '@babel/core@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.27.3': - dependencies: - '@babel/types': 7.29.0 - - '@babel/helper-compilation-targets@7.28.6': - dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.29.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-member-expression-to-functions@7.28.5': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.28.6': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.27.1': - dependencies: - '@babel/types': 7.29.0 - - '@babel/helper-plugin-utils@7.28.6': {} - - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.28.6': - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - - '@babel/parser@7.29.0': - dependencies: - '@babel/types': 7.29.0 - - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - - '@babel/preset-react@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - - '@babel/template@7.28.6': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - - '@babel/traverse@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)': - dependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - '@standard-schema/spec': 1.1.0 - better-call: 1.3.2(zod@4.3.6) - jose: 6.1.3 - kysely: 0.28.11 - nanostores: 1.1.0 - zod: 4.3.6 - - '@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)': - dependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - '@standard-schema/spec': 1.1.0 - better-call: 1.3.2(zod@4.3.6) - jose: 6.1.3 - kysely: 0.28.11 - nanostores: 1.1.0 - zod: 4.3.6 - - '@better-auth/core@1.5.0-beta.20(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.19-beta.1)(better-call@1.1.0-beta.2)(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)': - dependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.19-beta.1 - '@standard-schema/spec': 1.1.0 - better-call: 1.1.0-beta.2 - jose: 6.1.3 - kysely: 0.28.11 - nanostores: 1.1.0 - zod: 4.3.6 - - '@better-auth/drizzle-adapter@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - - '@better-auth/drizzle-adapter@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - - '@better-auth/infra@0.1.8(@better-auth/utils@0.3.1)(better-auth@1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(kysely@0.28.11)(nanostores@1.1.0)(zod@4.3.6)': - dependencies: - '@better-auth/core': 1.5.0-beta.20(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.19-beta.1)(better-call@1.1.0-beta.2)(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/sso': 1.5.0-beta.20(f0f92bebcbcf2bbf6fd94774f08388c0) - '@better-fetch/fetch': 1.1.19-beta.1 - better-auth: 1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - better-call: 1.1.0-beta.2 - jose: 6.1.3 - libphonenumber-js: 1.12.37 - zod: 4.3.6 - transitivePeerDependencies: - - '@better-auth/utils' - - kysely - - nanostores - - '@better-auth/kysely-adapter@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(kysely@0.28.11)': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - kysely: 0.28.11 - - '@better-auth/kysely-adapter@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(kysely@0.28.11)': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - kysely: 0.28.11 - - '@better-auth/memory-adapter@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - - '@better-auth/memory-adapter@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - - '@better-auth/mongo-adapter@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - mongodb: 7.1.0(socks@2.8.7) - - '@better-auth/mongo-adapter@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7))': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - mongodb: 7.1.0(socks@2.8.7) - - '@better-auth/prisma-adapter@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - '@prisma/client': 5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - - '@better-auth/prisma-adapter@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - '@prisma/client': 7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - - '@better-auth/sso@1.5.0-beta.20(f0f92bebcbcf2bbf6fd94774f08388c0)': - dependencies: - '@better-auth/core': 1.5.0-beta.20(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.19-beta.1)(better-call@1.1.0-beta.2)(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - better-auth: 1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - better-call: 1.1.0-beta.2 - fast-xml-parser: 5.4.1 - jose: 6.1.3 - samlify: 2.10.2 - zod: 4.3.6 - - '@better-auth/stripe@1.5.0-beta.18(b897a05a0ee982447836563041d27c5f)': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - better-auth: 1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - better-call: 1.3.2(zod@4.3.6) - defu: 6.1.4 - stripe: 20.4.0(@types/node@25.3.0) - zod: 4.3.6 - - '@better-auth/telemetry@1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))': - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - - '@better-auth/telemetry@1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))': - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - - '@better-auth/utils@0.3.1': {} - - '@better-fetch/fetch@1.1.19-beta.1': {} - - '@better-fetch/fetch@1.1.21': {} - - '@bufbuild/protobuf@2.11.0': {} - - '@bytecodealliance/preview2-shim@0.17.6': {} - - '@chevrotain/cst-dts-gen@10.5.0': - dependencies: - '@chevrotain/gast': 10.5.0 - '@chevrotain/types': 10.5.0 - lodash: 4.17.21 - - '@chevrotain/gast@10.5.0': - dependencies: - '@chevrotain/types': 10.5.0 - lodash: 4.17.21 - - '@chevrotain/types@10.5.0': {} - - '@chevrotain/utils@10.5.0': {} - - '@clack/core@0.5.0': - dependencies: - picocolors: 1.1.1 - sisteransi: 1.0.5 - - '@clack/prompts@0.11.0': - dependencies: - '@clack/core': 0.5.0 - picocolors: 1.1.1 - sisteransi: 1.0.5 - - '@connectrpc/connect-web@2.0.0-rc.3(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.11.0))': - dependencies: - '@bufbuild/protobuf': 2.11.0 - '@connectrpc/connect': 2.0.0-rc.3(@bufbuild/protobuf@2.11.0) - - '@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.11.0)': - dependencies: - '@bufbuild/protobuf': 2.11.0 - - '@edge-runtime/format@2.2.1': {} - - '@edge-runtime/node-utils@2.3.0': {} - - '@edge-runtime/ponyfill@2.4.2': {} - - '@edge-runtime/primitives@4.1.0': {} - - '@edge-runtime/vm@3.2.0': - dependencies: - '@edge-runtime/primitives': 4.1.0 - - '@electric-sql/pglite-socket@0.0.20(@electric-sql/pglite@0.3.15)': - dependencies: - '@electric-sql/pglite': 0.3.15 - - '@electric-sql/pglite-tools@0.2.20(@electric-sql/pglite@0.3.15)': - dependencies: - '@electric-sql/pglite': 0.3.15 - - '@electric-sql/pglite@0.3.15': {} - - '@emnapi/core@1.8.1': - dependencies: - '@emnapi/wasi-threads': 1.1.0 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.8.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.27.0': - optional: true - - '@esbuild/android-arm64@0.27.0': - optional: true - - '@esbuild/android-arm@0.27.0': - optional: true - - '@esbuild/android-x64@0.27.0': - optional: true - - '@esbuild/darwin-arm64@0.27.0': - optional: true - - '@esbuild/darwin-x64@0.27.0': - optional: true - - '@esbuild/freebsd-arm64@0.27.0': - optional: true - - '@esbuild/freebsd-x64@0.27.0': - optional: true - - '@esbuild/linux-arm64@0.27.0': - optional: true - - '@esbuild/linux-arm@0.27.0': - optional: true - - '@esbuild/linux-ia32@0.27.0': - optional: true - - '@esbuild/linux-loong64@0.27.0': - optional: true - - '@esbuild/linux-mips64el@0.27.0': - optional: true - - '@esbuild/linux-ppc64@0.27.0': - optional: true - - '@esbuild/linux-riscv64@0.27.0': - optional: true - - '@esbuild/linux-s390x@0.27.0': - optional: true - - '@esbuild/linux-x64@0.27.0': - optional: true - - '@esbuild/netbsd-arm64@0.27.0': - optional: true - - '@esbuild/netbsd-x64@0.27.0': - optional: true - - '@esbuild/openbsd-arm64@0.27.0': - optional: true - - '@esbuild/openbsd-x64@0.27.0': - optional: true - - '@esbuild/openharmony-arm64@0.27.0': - optional: true - - '@esbuild/sunos-x64@0.27.0': - optional: true - - '@esbuild/win32-arm64@0.27.0': - optional: true - - '@esbuild/win32-ia32@0.27.0': - optional: true - - '@esbuild/win32-x64@0.27.0': - optional: true - - '@fastify/busboy@2.1.1': {} - - '@fastify/otel@0.16.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - minimatch: 10.2.2 - transitivePeerDependencies: - - supports-color - - '@floating-ui/core@1.7.4': - dependencies: - '@floating-ui/utils': 0.2.10 - - '@floating-ui/dom@1.7.5': - dependencies: - '@floating-ui/core': 1.7.4 - '@floating-ui/utils': 0.2.10 - - '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@floating-ui/dom': 1.7.5 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - '@floating-ui/utils@0.2.10': {} - - '@grpc/grpc-js@1.14.3': - dependencies: - '@grpc/proto-loader': 0.8.0 - '@js-sdsl/ordered-map': 4.4.2 - - '@grpc/proto-loader@0.8.0': - dependencies: - lodash.camelcase: 4.3.0 - long: 5.3.2 - protobufjs: 7.5.4 - yargs: 17.7.2 - - '@hono/node-server@1.19.9(hono@4.11.4)': - dependencies: - hono: 4.11.4 - - '@iarna/toml@2.2.5': {} - - '@img/colour@1.0.0': - optional: true - - '@img/sharp-darwin-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.4 - optional: true - - '@img/sharp-darwin-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.2.4': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-riscv64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - optional: true - - '@img/sharp-linux-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.4 - optional: true - - '@img/sharp-linux-arm@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.4 - optional: true - - '@img/sharp-linux-ppc64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.4 - optional: true - - '@img/sharp-linux-riscv64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.2.4 - optional: true - - '@img/sharp-linux-s390x@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.4 - optional: true - - '@img/sharp-linux-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - optional: true - - '@img/sharp-wasm32@0.34.5': - dependencies: - '@emnapi/runtime': 1.8.1 - optional: true - - '@img/sharp-win32-arm64@0.34.5': - optional: true - - '@img/sharp-win32-ia32@0.34.5': - optional: true - - '@img/sharp-win32-x64@0.34.5': - optional: true - - '@inngest/ai@0.1.7': - dependencies: - '@types/node': 22.19.11 - typescript: 5.9.3 - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.1': - dependencies: - '@isaacs/balanced-match': 4.0.1 - - '@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 - - '@isaacs/cliui@9.0.0': {} - - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.3 - - '@jpwilliams/waitgroup@2.1.1': {} - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/source-map@0.3.11': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@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 - - '@js-sdsl/ordered-map@4.4.2': {} - - '@mapbox/node-pre-gyp@2.0.3': - dependencies: - consola: 3.4.2 - detect-libc: 2.1.2 - https-proxy-agent: 7.0.6 - node-fetch: 2.7.0 - nopt: 8.1.0 - semver: 7.7.4 - tar: 7.5.9 - transitivePeerDependencies: - - encoding - - supports-color - - '@mixedbread-ai/sdk@2.2.11': - dependencies: - form-data: 4.0.0 - formdata-node: 6.0.3 - js-base64: 3.7.2 - node-fetch: 2.7.0 - qs: 6.11.2 - url-join: 4.0.1 - transitivePeerDependencies: - - encoding - - '@mongodb-js/saslprep@1.4.6': - dependencies: - sparse-bitfield: 3.0.3 - - '@mrleebo/prisma-ast@0.13.1': - dependencies: - chevrotain: 10.5.0 - lilconfig: 2.1.0 - - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@next/env@16.1.6': {} - - '@next/swc-darwin-arm64@16.1.6': - optional: true - - '@next/swc-darwin-x64@16.1.6': - optional: true - - '@next/swc-linux-arm64-gnu@16.1.6': - optional: true - - '@next/swc-linux-arm64-musl@16.1.6': - optional: true - - '@next/swc-linux-x64-gnu@16.1.6': - optional: true - - '@next/swc-linux-x64-musl@16.1.6': - optional: true - - '@next/swc-win32-arm64-msvc@16.1.6': - optional: true - - '@next/swc-win32-x64-msvc@16.1.6': - optional: true - - '@noble/ciphers@2.1.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.20.1 - - '@octokit/auth-token@6.0.0': {} - - '@octokit/core@7.0.6': - dependencies: - '@octokit/auth-token': 6.0.0 - '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.7 - '@octokit/request-error': 7.1.0 - '@octokit/types': 16.0.0 - before-after-hook: 4.0.0 - universal-user-agent: 7.0.3 - - '@octokit/endpoint@11.0.3': - dependencies: - '@octokit/types': 16.0.0 - universal-user-agent: 7.0.3 - - '@octokit/graphql@9.0.3': - dependencies: - '@octokit/request': 10.0.7 - '@octokit/types': 16.0.0 - universal-user-agent: 7.0.3 - - '@octokit/openapi-types@27.0.0': {} - - '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.6)': - dependencies: - '@octokit/core': 7.0.6 - '@octokit/types': 16.0.0 - - '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.6)': - dependencies: - '@octokit/core': 7.0.6 - - '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.6)': - dependencies: - '@octokit/core': 7.0.6 - '@octokit/types': 16.0.0 - - '@octokit/request-error@7.1.0': - dependencies: - '@octokit/types': 16.0.0 - - '@octokit/request@10.0.7': - dependencies: - '@octokit/endpoint': 11.0.3 - '@octokit/request-error': 7.1.0 - '@octokit/types': 16.0.0 - fast-content-type-parse: 3.0.0 - universal-user-agent: 7.0.3 - - '@octokit/rest@22.0.1': - dependencies: - '@octokit/core': 7.0.6 - '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) - '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.6) - '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) - - '@octokit/types@16.0.0': - dependencies: - '@octokit/openapi-types': 27.0.0 - - '@openrouter/ai-sdk-provider@2.2.3(ai@6.0.97(zod@4.3.6))(zod@4.3.6)': - dependencies: - ai: 6.0.97(zod@4.3.6) - zod: 4.3.6 - - '@opentelemetry/api-logs@0.203.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api-logs@0.207.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api-logs@0.208.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api-logs@0.211.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api-logs@0.212.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api@1.9.0': {} - - '@opentelemetry/auto-instrumentations-node@0.70.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-amqplib': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-aws-lambda': 0.64.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-aws-sdk': 0.67.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-bunyan': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-cassandra-driver': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-connect': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-cucumber': 0.27.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-dataloader': 0.29.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-dns': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-express': 0.60.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fastify': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fs': 0.31.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-generic-pool': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-graphql': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-hapi': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-ioredis': 0.60.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-kafkajs': 0.21.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-knex': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-koa': 0.60.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-lru-memoizer': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-memcached': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongodb': 0.65.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongoose': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql2': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-net': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-openai': 0.10.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-oracledb': 0.37.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pg': 0.64.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pino': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-redis': 0.60.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-restify': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-router': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-runtime-node': 0.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-socket.io': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-tedious': 0.31.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-undici': 0.22.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-winston': 0.56.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resource-detector-alibaba-cloud': 0.33.2(@opentelemetry/api@1.9.0) - '@opentelemetry/resource-detector-aws': 2.12.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resource-detector-azure': 0.20.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resource-detector-container': 0.8.3(@opentelemetry/api@1.9.0) - '@opentelemetry/resource-detector-gcp': 0.47.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-node': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/configuration@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - yaml: 2.8.2 - - '@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/core@2.5.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/exporter-logs-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@grpc/grpc-js': 1.14.3 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-logs-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-logs-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-metrics-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@grpc/grpc-js': 1.14.3 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-metrics-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-metrics-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-prometheus@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/exporter-trace-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@grpc/grpc-js': 1.14.3 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-trace-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-trace-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/exporter-zipkin@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/instrumentation-amqplib@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-amqplib@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-aws-lambda@0.64.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/aws-lambda': 8.10.160 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-aws-sdk@0.67.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-bunyan@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@types/bunyan': 1.8.11 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-cassandra-driver@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-connect@0.54.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/connect': 3.4.38 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-connect@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/connect': 3.4.38 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-cucumber@0.27.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-dataloader@0.28.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-dataloader@0.29.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-dns@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-express@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-express@0.60.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-fastify@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-fs@0.30.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-fs@0.31.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-generic-pool@0.54.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-generic-pool@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-graphql@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-graphql@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-grpc@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-hapi@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-hapi@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-http@0.211.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - forwarded-parse: 2.1.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-http@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - forwarded-parse: 2.1.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-ioredis@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.38.2 - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-ioredis@0.60.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.38.2 - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-kafkajs@0.20.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-kafkajs@0.21.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-knex@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-knex@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-koa@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-koa@0.60.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-lru-memoizer@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-lru-memoizer@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-memcached@0.55.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/memcached': 2.2.10 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongodb@0.64.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongodb@0.65.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongoose@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongoose@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql2@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql2@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/mysql': 2.15.27 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/mysql': 2.15.27 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-nestjs-core@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-net@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-openai@0.10.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-oracledb@0.37.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/oracledb': 6.5.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-pg@0.63.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) - '@types/pg': 8.15.6 - '@types/pg-pool': 2.0.7 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-pg@0.64.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) - '@types/pg': 8.15.6 - '@types/pg-pool': 2.0.7 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-pino@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-redis@0.59.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.38.2 - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-redis@0.60.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.38.2 - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-restify@0.57.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-router@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-runtime-node@0.25.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-socket.io@0.58.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-tedious@0.30.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/tedious': 4.0.14 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-tedious@0.31.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@types/tedious': 4.0.14 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-undici@0.21.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-undici@0.22.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-winston@0.56.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - import-in-the-middle: 1.15.0 - require-in-the-middle: 7.5.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.207.0 - import-in-the-middle: 2.0.6 - require-in-the-middle: 8.0.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.208.0 - import-in-the-middle: 2.0.6 - require-in-the-middle: 8.0.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.211.0 - import-in-the-middle: 2.0.6 - require-in-the-middle: 8.0.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - import-in-the-middle: 2.0.6 - require-in-the-middle: 8.0.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/otlp-exporter-base@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - - '@opentelemetry/otlp-grpc-exporter-base@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@grpc/grpc-js': 1.14.3 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - - '@opentelemetry/otlp-transformer@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - protobufjs: 8.0.0 - - '@opentelemetry/propagator-b3@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/propagator-jaeger@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/redis-common@0.38.2': {} - - '@opentelemetry/resource-detector-alibaba-cloud@0.33.2(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/resource-detector-aws@2.12.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/resource-detector-azure@0.20.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/resource-detector-container@0.8.3(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/resource-detector-gcp@0.47.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - gcp-metadata: 8.1.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/resources@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/sdk-logs@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/sdk-metrics@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/sdk-node@0.212.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/configuration': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-b3': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-node': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@opentelemetry/sdk-trace-node@2.5.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - - '@opentelemetry/semantic-conventions@1.39.0': {} - - '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - - '@oxc-project/types@0.110.0': {} - - '@oxc-transform/binding-android-arm-eabi@0.111.0': - optional: true - - '@oxc-transform/binding-android-arm64@0.111.0': - optional: true - - '@oxc-transform/binding-darwin-arm64@0.111.0': - optional: true - - '@oxc-transform/binding-darwin-x64@0.111.0': - optional: true - - '@oxc-transform/binding-freebsd-x64@0.111.0': - optional: true - - '@oxc-transform/binding-linux-arm-gnueabihf@0.111.0': - optional: true - - '@oxc-transform/binding-linux-arm-musleabihf@0.111.0': - optional: true - - '@oxc-transform/binding-linux-arm64-gnu@0.111.0': - optional: true - - '@oxc-transform/binding-linux-arm64-musl@0.111.0': - optional: true - - '@oxc-transform/binding-linux-ppc64-gnu@0.111.0': - optional: true - - '@oxc-transform/binding-linux-riscv64-gnu@0.111.0': - optional: true - - '@oxc-transform/binding-linux-riscv64-musl@0.111.0': - optional: true - - '@oxc-transform/binding-linux-s390x-gnu@0.111.0': - optional: true - - '@oxc-transform/binding-linux-x64-gnu@0.111.0': - optional: true - - '@oxc-transform/binding-linux-x64-musl@0.111.0': - optional: true - - '@oxc-transform/binding-openharmony-arm64@0.111.0': - optional: true - - '@oxc-transform/binding-wasm32-wasi@0.111.0': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@oxc-transform/binding-win32-arm64-msvc@0.111.0': - optional: true - - '@oxc-transform/binding-win32-ia32-msvc@0.111.0': - optional: true - - '@oxc-transform/binding-win32-x64-msvc@0.111.0': - optional: true - - '@oxfmt/binding-android-arm-eabi@0.34.0': - optional: true - - '@oxfmt/binding-android-arm64@0.34.0': - optional: true - - '@oxfmt/binding-darwin-arm64@0.34.0': - optional: true - - '@oxfmt/binding-darwin-x64@0.34.0': - optional: true - - '@oxfmt/binding-freebsd-x64@0.34.0': - optional: true - - '@oxfmt/binding-linux-arm-gnueabihf@0.34.0': - optional: true - - '@oxfmt/binding-linux-arm-musleabihf@0.34.0': - optional: true - - '@oxfmt/binding-linux-arm64-gnu@0.34.0': - optional: true - - '@oxfmt/binding-linux-arm64-musl@0.34.0': - optional: true - - '@oxfmt/binding-linux-ppc64-gnu@0.34.0': - optional: true - - '@oxfmt/binding-linux-riscv64-gnu@0.34.0': - optional: true - - '@oxfmt/binding-linux-riscv64-musl@0.34.0': - optional: true - - '@oxfmt/binding-linux-s390x-gnu@0.34.0': - optional: true - - '@oxfmt/binding-linux-x64-gnu@0.34.0': - optional: true - - '@oxfmt/binding-linux-x64-musl@0.34.0': - optional: true - - '@oxfmt/binding-openharmony-arm64@0.34.0': - optional: true - - '@oxfmt/binding-win32-arm64-msvc@0.34.0': - optional: true - - '@oxfmt/binding-win32-ia32-msvc@0.34.0': - optional: true - - '@oxfmt/binding-win32-x64-msvc@0.34.0': - optional: true - - '@oxlint/binding-android-arm-eabi@1.49.0': - optional: true - - '@oxlint/binding-android-arm64@1.49.0': - optional: true - - '@oxlint/binding-darwin-arm64@1.49.0': - optional: true - - '@oxlint/binding-darwin-x64@1.49.0': - optional: true - - '@oxlint/binding-freebsd-x64@1.49.0': - optional: true - - '@oxlint/binding-linux-arm-gnueabihf@1.49.0': - optional: true - - '@oxlint/binding-linux-arm-musleabihf@1.49.0': - optional: true - - '@oxlint/binding-linux-arm64-gnu@1.49.0': - optional: true - - '@oxlint/binding-linux-arm64-musl@1.49.0': - optional: true - - '@oxlint/binding-linux-ppc64-gnu@1.49.0': - optional: true - - '@oxlint/binding-linux-riscv64-gnu@1.49.0': - optional: true - - '@oxlint/binding-linux-riscv64-musl@1.49.0': - optional: true - - '@oxlint/binding-linux-s390x-gnu@1.49.0': - optional: true - - '@oxlint/binding-linux-x64-gnu@1.49.0': - optional: true - - '@oxlint/binding-linux-x64-musl@1.49.0': - optional: true - - '@oxlint/binding-openharmony-arm64@1.49.0': - optional: true - - '@oxlint/binding-win32-arm64-msvc@1.49.0': - optional: true - - '@oxlint/binding-win32-ia32-msvc@1.49.0': - optional: true - - '@oxlint/binding-win32-x64-msvc@1.49.0': - optional: true - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@prisma/adapter-pg@7.4.1': - dependencies: - '@prisma/driver-adapter-utils': 7.4.1 - pg: 8.18.0 - postgres-array: 3.0.4 - transitivePeerDependencies: - - pg-native - - '@prisma/client-runtime-utils@7.4.1': {} - - '@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))': - optionalDependencies: - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - - '@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3)': - dependencies: - '@prisma/client-runtime-utils': 7.4.1 - optionalDependencies: - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - typescript: 5.9.3 - - '@prisma/config@7.4.1': - dependencies: - c12: 3.1.0 - deepmerge-ts: 7.1.5 - effect: 3.18.4 - empathic: 2.0.0 - transitivePeerDependencies: - - magicast - - '@prisma/debug@7.2.0': {} - - '@prisma/debug@7.4.1': {} - - '@prisma/dev@0.20.0(typescript@5.9.3)': - dependencies: - '@electric-sql/pglite': 0.3.15 - '@electric-sql/pglite-socket': 0.0.20(@electric-sql/pglite@0.3.15) - '@electric-sql/pglite-tools': 0.2.20(@electric-sql/pglite@0.3.15) - '@hono/node-server': 1.19.9(hono@4.11.4) - '@mrleebo/prisma-ast': 0.13.1 - '@prisma/get-platform': 7.2.0 - '@prisma/query-plan-executor': 7.2.0 - foreground-child: 3.3.1 - get-port-please: 3.2.0 - hono: 4.11.4 - http-status-codes: 2.3.0 - pathe: 2.0.3 - proper-lockfile: 4.1.2 - remeda: 2.33.4 - std-env: 3.10.0 - valibot: 1.2.0(typescript@5.9.3) - zeptomatch: 2.1.0 - transitivePeerDependencies: - - typescript - - '@prisma/driver-adapter-utils@7.4.1': - dependencies: - '@prisma/debug': 7.4.1 - - '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': {} - - '@prisma/engines@7.4.1': - dependencies: - '@prisma/debug': 7.4.1 - '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 - '@prisma/fetch-engine': 7.4.1 - '@prisma/get-platform': 7.4.1 - - '@prisma/fetch-engine@7.4.1': - dependencies: - '@prisma/debug': 7.4.1 - '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 - '@prisma/get-platform': 7.4.1 - - '@prisma/get-platform@7.2.0': - dependencies: - '@prisma/debug': 7.2.0 - - '@prisma/get-platform@7.4.1': - dependencies: - '@prisma/debug': 7.4.1 - - '@prisma/instrumentation@7.2.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@prisma/query-plan-executor@7.2.0': {} - - '@prisma/studio-core@0.13.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@types/react': 19.2.14 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} - - '@protobufjs/fetch@1.1.0': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} - - '@protobufjs/utf8@1.1.0': {} - - '@radix-ui/primitive@1.1.3': {} - - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-avatar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-context': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-context@1.1.3(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/rect': 1.1.1 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - use-sync-external-store: 1.6.0(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/rect': 1.1.1 - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-visually-hidden@1.2.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/rect@1.1.1': {} - - '@remirror/core-constants@3.0.0': {} - - '@renovatebot/pep440@4.2.1': {} - - '@rolldown/binding-android-arm64@1.0.0-rc.1': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-rc.1': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-rc.1': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-rc.1': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.1': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.1': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.1': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.1': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.1': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.1': - optional: true - - '@rolldown/pluginutils@1.0.0-rc.1': {} - - '@rollup/plugin-commonjs@28.0.1(rollup@4.59.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.3) - is-reference: 1.2.1 - magic-string: 0.30.21 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.59.0 - - '@rollup/pluginutils@5.3.0(rollup@4.59.0)': - dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.59.0 - - '@rollup/rollup-android-arm-eabi@4.59.0': - optional: true - - '@rollup/rollup-android-arm64@4.59.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.59.0': - optional: true - - '@rollup/rollup-darwin-x64@4.59.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.59.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.59.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.59.0': - optional: true - - '@rollup/rollup-openbsd-x64@4.59.0': - optional: true - - '@rollup/rollup-openharmony-arm64@4.59.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.59.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.59.0': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.59.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.59.0': - optional: true - - '@sentry-internal/browser-utils@10.40.0': - dependencies: - '@sentry/core': 10.40.0 - - '@sentry-internal/feedback@10.40.0': - dependencies: - '@sentry/core': 10.40.0 - - '@sentry-internal/replay-canvas@10.40.0': - dependencies: - '@sentry-internal/replay': 10.40.0 - '@sentry/core': 10.40.0 - - '@sentry-internal/replay@10.40.0': - dependencies: - '@sentry-internal/browser-utils': 10.40.0 - '@sentry/core': 10.40.0 - - '@sentry/babel-plugin-component-annotate@5.1.0': {} - - '@sentry/browser@10.40.0': - dependencies: - '@sentry-internal/browser-utils': 10.40.0 - '@sentry-internal/feedback': 10.40.0 - '@sentry-internal/replay': 10.40.0 - '@sentry-internal/replay-canvas': 10.40.0 - '@sentry/core': 10.40.0 - - '@sentry/bundler-plugin-core@5.1.0': - dependencies: - '@babel/core': 7.29.0 - '@sentry/babel-plugin-component-annotate': 5.1.0 - '@sentry/cli': 2.58.5 - dotenv: 16.6.1 - find-up: 5.0.0 - glob: 13.0.6 - magic-string: 0.30.8 - transitivePeerDependencies: - - encoding - - supports-color - - '@sentry/cli-darwin@2.58.5': - optional: true - - '@sentry/cli-linux-arm64@2.58.5': - optional: true - - '@sentry/cli-linux-arm@2.58.5': - optional: true - - '@sentry/cli-linux-i686@2.58.5': - optional: true - - '@sentry/cli-linux-x64@2.58.5': - optional: true - - '@sentry/cli-win32-arm64@2.58.5': - optional: true - - '@sentry/cli-win32-i686@2.58.5': - optional: true - - '@sentry/cli-win32-x64@2.58.5': - optional: true - - '@sentry/cli@2.58.5': - dependencies: - https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 - progress: 2.0.3 - proxy-from-env: 1.1.0 - which: 2.0.2 - optionalDependencies: - '@sentry/cli-darwin': 2.58.5 - '@sentry/cli-linux-arm': 2.58.5 - '@sentry/cli-linux-arm64': 2.58.5 - '@sentry/cli-linux-i686': 2.58.5 - '@sentry/cli-linux-x64': 2.58.5 - '@sentry/cli-win32-arm64': 2.58.5 - '@sentry/cli-win32-i686': 2.58.5 - '@sentry/cli-win32-x64': 2.58.5 - transitivePeerDependencies: - - encoding - - supports-color - - '@sentry/core@10.40.0': {} - - '@sentry/nextjs@10.40.0(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(webpack@5.105.2)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.39.0 - '@rollup/plugin-commonjs': 28.0.1(rollup@4.59.0) - '@sentry-internal/browser-utils': 10.40.0 - '@sentry/bundler-plugin-core': 5.1.0 - '@sentry/core': 10.40.0 - '@sentry/node': 10.40.0 - '@sentry/opentelemetry': 10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) - '@sentry/react': 10.40.0(react@19.2.4) - '@sentry/vercel-edge': 10.40.0 - '@sentry/webpack-plugin': 5.1.0(webpack@5.105.2) - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - rollup: 4.59.0 - stacktrace-parser: 0.1.11 - transitivePeerDependencies: - - '@opentelemetry/context-async-hooks' - - '@opentelemetry/core' - - '@opentelemetry/sdk-trace-base' - - encoding - - react - - supports-color - - webpack - - '@sentry/node-core@10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)': - dependencies: - '@sentry/core': 10.40.0 - '@sentry/opentelemetry': 10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) - import-in-the-middle: 2.0.6 - optionalDependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - - '@sentry/node@10.40.0': - dependencies: - '@fastify/otel': 0.16.0(@opentelemetry/api@1.9.0) - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-amqplib': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-connect': 0.54.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-dataloader': 0.28.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-express': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fs': 0.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-generic-pool': 0.54.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-graphql': 0.58.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-hapi': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-http': 0.211.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-ioredis': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-kafkajs': 0.20.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-knex': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-koa': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-lru-memoizer': 0.55.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongodb': 0.64.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongoose': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql2': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pg': 0.63.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-redis': 0.59.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-tedious': 0.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-undici': 0.21.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@prisma/instrumentation': 7.2.0(@opentelemetry/api@1.9.0) - '@sentry/core': 10.40.0 - '@sentry/node-core': 10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) - '@sentry/opentelemetry': 10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0) - import-in-the-middle: 2.0.6 - transitivePeerDependencies: - - supports-color - - '@sentry/opentelemetry@10.40.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@sentry/core': 10.40.0 - - '@sentry/react@10.40.0(react@19.2.4)': - dependencies: - '@sentry/browser': 10.40.0 - '@sentry/core': 10.40.0 - react: 19.2.4 - - '@sentry/vercel-edge@10.40.0': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@sentry/core': 10.40.0 - - '@sentry/webpack-plugin@5.1.0(webpack@5.105.2)': - dependencies: - '@sentry/bundler-plugin-core': 5.1.0 - uuid: 9.0.1 - webpack: 5.105.2 - transitivePeerDependencies: - - encoding - - supports-color - - '@shikijs/core@3.22.0': - dependencies: - '@shikijs/types': 3.22.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - - '@shikijs/engine-javascript@3.22.0': - dependencies: - '@shikijs/types': 3.22.0 - '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.4 - - '@shikijs/engine-oniguruma@3.22.0': - dependencies: - '@shikijs/types': 3.22.0 - '@shikijs/vscode-textmate': 10.0.2 - - '@shikijs/langs@3.22.0': - dependencies: - '@shikijs/types': 3.22.0 - - '@shikijs/themes@3.22.0': - dependencies: - '@shikijs/types': 3.22.0 - - '@shikijs/types@3.22.0': - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - '@shikijs/vscode-textmate@10.0.2': {} - - '@sinclair/typebox@0.25.24': {} - - '@smithy/abort-controller@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/chunked-blob-reader-native@4.2.2': - dependencies: - '@smithy/util-base64': 4.3.1 - tslib: 2.8.1 - - '@smithy/chunked-blob-reader@5.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/config-resolver@4.4.9': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - tslib: 2.8.1 - - '@smithy/core@3.23.6': - dependencies: - '@smithy/middleware-serde': 4.2.11 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - '@smithy/uuid': 1.1.1 - tslib: 2.8.1 - - '@smithy/credential-provider-imds@4.2.10': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - tslib: 2.8.1 - - '@smithy/eventstream-codec@4.2.10': - dependencies: - '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.13.0 - '@smithy/util-hex-encoding': 4.2.1 - tslib: 2.8.1 - - '@smithy/eventstream-serde-browser@4.2.10': - dependencies: - '@smithy/eventstream-serde-universal': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/eventstream-serde-config-resolver@4.3.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/eventstream-serde-node@4.2.10': - dependencies: - '@smithy/eventstream-serde-universal': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/eventstream-serde-universal@4.2.10': - dependencies: - '@smithy/eventstream-codec': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/fetch-http-handler@5.3.11': - dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/querystring-builder': 4.2.10 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - tslib: 2.8.1 - - '@smithy/hash-blob-browser@4.2.11': - dependencies: - '@smithy/chunked-blob-reader': 5.2.1 - '@smithy/chunked-blob-reader-native': 4.2.2 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/hash-node@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/hash-stream-node@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/invalid-dependency@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/is-array-buffer@2.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/is-array-buffer@4.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/md5-js@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/middleware-content-length@4.2.10': - dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/middleware-endpoint@4.4.20': - dependencies: - '@smithy/core': 3.23.6 - '@smithy/middleware-serde': 4.2.11 - '@smithy/node-config-provider': 4.3.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-middleware': 4.2.10 - tslib: 2.8.1 - - '@smithy/middleware-retry@4.4.37': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/service-error-classification': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/uuid': 1.1.1 - tslib: 2.8.1 - - '@smithy/middleware-serde@4.2.11': - dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/middleware-stack@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/node-config-provider@4.3.10': - dependencies: - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/node-http-handler@4.4.12': - dependencies: - '@smithy/abort-controller': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/querystring-builder': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/property-provider@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/protocol-http@5.3.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/querystring-builder@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-uri-escape': 4.2.1 - tslib: 2.8.1 - - '@smithy/querystring-parser@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/service-error-classification@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - - '@smithy/shared-ini-file-loader@4.4.5': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/signature-v4@5.3.10': - dependencies: - '@smithy/is-array-buffer': 4.2.1 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-hex-encoding': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-uri-escape': 4.2.1 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/smithy-client@4.12.0': - dependencies: - '@smithy/core': 3.23.6 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-stack': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-stream': 4.5.15 - tslib: 2.8.1 - - '@smithy/types@4.13.0': - dependencies: - tslib: 2.8.1 - - '@smithy/url-parser@4.2.10': - dependencies: - '@smithy/querystring-parser': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-base64@4.3.1': - dependencies: - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/util-body-length-browser@4.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/util-body-length-node@4.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/util-buffer-from@2.2.0': - dependencies: - '@smithy/is-array-buffer': 2.2.0 - tslib: 2.8.1 - - '@smithy/util-buffer-from@4.2.1': - dependencies: - '@smithy/is-array-buffer': 4.2.1 - tslib: 2.8.1 - - '@smithy/util-config-provider@4.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/util-defaults-mode-browser@4.3.36': - dependencies: - '@smithy/property-provider': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-defaults-mode-node@4.2.39': - dependencies: - '@smithy/config-resolver': 4.4.9 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-endpoints@3.3.1': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-hex-encoding@4.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/util-middleware@4.2.10': - dependencies: - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-retry@4.2.10': - dependencies: - '@smithy/service-error-classification': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/util-stream@4.5.15': - dependencies: - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/node-http-handler': 4.4.12 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-hex-encoding': 4.2.1 - '@smithy/util-utf8': 4.2.1 - tslib: 2.8.1 - - '@smithy/util-uri-escape@4.2.1': - dependencies: - tslib: 2.8.1 - - '@smithy/util-utf8@2.3.0': - dependencies: - '@smithy/util-buffer-from': 2.2.0 - tslib: 2.8.1 - - '@smithy/util-utf8@4.2.1': - dependencies: - '@smithy/util-buffer-from': 4.2.1 - tslib: 2.8.1 - - '@smithy/util-waiter@4.2.10': - dependencies: - '@smithy/abort-controller': 4.2.10 - '@smithy/types': 4.13.0 - tslib: 2.8.1 - - '@smithy/uuid@1.1.1': - dependencies: - tslib: 2.8.1 - - '@standard-schema/spec@1.0.0': {} - - '@standard-schema/spec@1.1.0': {} - - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 - - '@tailwindcss/node@4.2.0': - dependencies: - '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.19.0 - jiti: 2.6.1 - lightningcss: 1.31.1 - magic-string: 0.30.21 - source-map-js: 1.2.1 - tailwindcss: 4.2.0 - - '@tailwindcss/oxide-android-arm64@4.2.0': - optional: true - - '@tailwindcss/oxide-darwin-arm64@4.2.0': - optional: true - - '@tailwindcss/oxide-darwin-x64@4.2.0': - optional: true - - '@tailwindcss/oxide-freebsd-x64@4.2.0': - optional: true - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0': - optional: true - - '@tailwindcss/oxide-linux-arm64-gnu@4.2.0': - optional: true - - '@tailwindcss/oxide-linux-arm64-musl@4.2.0': - optional: true - - '@tailwindcss/oxide-linux-x64-gnu@4.2.0': - optional: true - - '@tailwindcss/oxide-linux-x64-musl@4.2.0': - optional: true - - '@tailwindcss/oxide-wasm32-wasi@4.2.0': - optional: true - - '@tailwindcss/oxide-win32-arm64-msvc@4.2.0': - optional: true - - '@tailwindcss/oxide-win32-x64-msvc@4.2.0': - optional: true - - '@tailwindcss/oxide@4.2.0': - optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.2.0 - '@tailwindcss/oxide-darwin-arm64': 4.2.0 - '@tailwindcss/oxide-darwin-x64': 4.2.0 - '@tailwindcss/oxide-freebsd-x64': 4.2.0 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.0 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.0 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.0 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.0 - '@tailwindcss/oxide-linux-x64-musl': 4.2.0 - '@tailwindcss/oxide-wasm32-wasi': 4.2.0 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.0 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.0 - - '@tailwindcss/postcss@4.2.0': - dependencies: - '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.2.0 - '@tailwindcss/oxide': 4.2.0 - postcss: 8.5.6 - tailwindcss: 4.2.0 - - '@tanstack/hotkeys@0.3.0': - dependencies: - '@tanstack/store': 0.9.1 - - '@tanstack/query-core@5.90.20': {} - - '@tanstack/react-hotkeys@0.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@tanstack/hotkeys': 0.3.0 - '@tanstack/react-store': 0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - '@tanstack/react-query@5.90.21(react@19.2.4)': - dependencies: - '@tanstack/query-core': 5.90.20 - react: 19.2.4 - - '@tanstack/react-store@0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@tanstack/store': 0.9.1 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - use-sync-external-store: 1.6.0(react@19.2.4) - - '@tanstack/store@0.9.1': {} - - '@tiptap/core@3.20.0(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/pm': 3.20.0 - - '@tiptap/extension-blockquote@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-bold@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-bubble-menu@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@floating-ui/dom': 1.7.5 - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - optional: true - - '@tiptap/extension-bullet-list@3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extension-list': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-code-block@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tiptap/extension-code@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-document@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-dropcursor@3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extensions': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-floating-menu@3.20.0(@floating-ui/dom@1.7.5)(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@floating-ui/dom': 1.7.5 - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - optional: true - - '@tiptap/extension-gapcursor@3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extensions': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-hard-break@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-heading@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-horizontal-rule@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tiptap/extension-italic@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-link@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - linkifyjs: 4.3.2 - - '@tiptap/extension-list-item@3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extension-list': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-list-keymap@3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extension-list': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tiptap/extension-mention@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)(@tiptap/suggestion@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - '@tiptap/suggestion': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-ordered-list@3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extension-list': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-paragraph@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-placeholder@3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/extensions': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - - '@tiptap/extension-strike@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-text@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extension-underline@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - - '@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tiptap/pm@3.20.0': - dependencies: - prosemirror-changeset: 2.4.0 - prosemirror-collab: 1.3.1 - prosemirror-commands: 1.7.1 - prosemirror-dropcursor: 1.8.2 - prosemirror-gapcursor: 1.4.0 - prosemirror-history: 1.5.0 - prosemirror-inputrules: 1.5.1 - prosemirror-keymap: 1.2.3 - prosemirror-markdown: 1.13.4 - prosemirror-menu: 1.3.0 - prosemirror-model: 1.25.4 - prosemirror-schema-basic: 1.2.4 - prosemirror-schema-list: 1.5.1 - prosemirror-state: 1.4.4 - prosemirror-tables: 1.8.5 - prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6) - prosemirror-transform: 1.11.0 - prosemirror-view: 1.41.6 - - '@tiptap/react@3.20.0(@floating-ui/dom@1.7.5)(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@types/use-sync-external-store': 0.0.6 - fast-equals: 5.4.0 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - use-sync-external-store: 1.6.0(react@19.2.4) - optionalDependencies: - '@tiptap/extension-bubble-menu': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-floating-menu': 3.20.0(@floating-ui/dom@1.7.5)(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - transitivePeerDependencies: - - '@floating-ui/dom' - - '@tiptap/starter-kit@3.20.0': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/extension-blockquote': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-bold': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-bullet-list': 3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-code': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-code-block': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-document': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-dropcursor': 3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-gapcursor': 3.20.0(@tiptap/extensions@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-hard-break': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-heading': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-horizontal-rule': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-italic': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-link': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-list': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/extension-list-item': 3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-list-keymap': 3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-ordered-list': 3.20.0(@tiptap/extension-list@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)) - '@tiptap/extension-paragraph': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-strike': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-text': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extension-underline': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)) - '@tiptap/extensions': 3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tiptap/suggestion@3.20.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0))(@tiptap/pm@3.20.0)': - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@tiptap/pm': 3.20.0 - - '@tootallnate/once@2.0.0': {} - - '@tootallnate/quickjs-emscripten@0.23.0': {} - - '@traceloop/ai-semantic-conventions@0.20.0': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@traceloop/instrumentation-anthropic@0.20.0': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 - '@traceloop/ai-semantic-conventions': 0.20.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@ts-morph/common@0.11.1': - dependencies: - fast-glob: 3.3.3 - minimatch: 3.1.3 - mkdirp: 1.0.4 - path-browserify: 1.0.1 - - '@tybys/wasm-util@0.10.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/aws-lambda@8.10.160': {} - - '@types/bunyan@1.8.11': - dependencies: - '@types/node': 25.3.0 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 25.3.0 - - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 - - '@types/eslint-scope@3.7.7': - dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 - - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - - '@types/estree-jsx@1.0.5': - dependencies: - '@types/estree': 1.0.8 - - '@types/estree@1.0.8': {} - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/json-schema@7.0.15': {} - - '@types/linkify-it@3.0.5': {} - - '@types/linkify-it@5.0.0': {} - - '@types/markdown-it@13.0.9': - dependencies: - '@types/linkify-it': 3.0.5 - '@types/mdurl': 1.0.5 - - '@types/markdown-it@14.1.2': - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - - '@types/mdast@4.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/mdurl@1.0.5': {} - - '@types/mdurl@2.0.0': {} - - '@types/memcached@2.2.10': - dependencies: - '@types/node': 25.3.0 - - '@types/ms@2.1.0': {} - - '@types/mysql@2.15.27': - dependencies: - '@types/node': 25.3.0 - - '@types/node@20.11.0': - dependencies: - undici-types: 5.26.5 - - '@types/node@22.19.11': - dependencies: - undici-types: 6.21.0 - - '@types/node@25.3.0': - dependencies: - undici-types: 7.18.2 - - '@types/oracledb@6.5.2': - dependencies: - '@types/node': 25.3.0 - - '@types/pg-pool@2.0.7': - dependencies: - '@types/pg': 8.16.0 - - '@types/pg@8.15.6': - dependencies: - '@types/node': 25.3.0 - pg-protocol: 1.11.0 - pg-types: 2.2.0 - - '@types/pg@8.16.0': - dependencies: - '@types/node': 25.3.0 - pg-protocol: 1.11.0 - pg-types: 2.2.0 - - '@types/react-dom@19.2.3(@types/react@19.2.14)': - dependencies: - '@types/react': 19.2.14 - - '@types/react@19.2.14': - dependencies: - csstype: 3.2.3 - - '@types/tedious@4.0.14': - dependencies: - '@types/node': 25.3.0 - - '@types/unist@2.0.11': {} - - '@types/unist@3.0.3': {} - - '@types/use-sync-external-store@0.0.6': {} - - '@types/webidl-conversions@7.0.3': {} - - '@types/whatwg-url@13.0.0': - dependencies: - '@types/webidl-conversions': 7.0.3 - - '@ungap/structured-clone@1.3.0': {} - - '@upstash/redis@1.36.2': - dependencies: - uncrypto: 0.1.3 - - '@vercel/analytics@1.6.1(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)': - optionalDependencies: - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - - '@vercel/backends@0.0.36(rollup@4.59.0)(typescript@5.9.3)': - dependencies: - '@vercel/build-utils': 13.4.3 - '@vercel/nft': 1.3.0(rollup@4.59.0) - execa: 3.2.0 - fs-extra: 11.1.0 - oxc-transform: 0.111.0 - path-to-regexp: 8.3.0 - resolve.exports: 2.0.3 - rolldown: 1.0.0-rc.1 - srvx: 0.8.9 - tsx: 4.21.0 - typescript: 5.9.3 - zod: 3.22.4 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/blob@2.3.0': - dependencies: - async-retry: 1.3.3 - is-buffer: 2.0.5 - is-node-process: 1.2.0 - throttleit: 2.1.0 - undici: 6.23.0 - - '@vercel/build-utils@13.4.3': - dependencies: - '@vercel/python-analysis': 0.6.0 - - '@vercel/cervel@0.0.23(rollup@4.59.0)(typescript@5.9.3)': - dependencies: - '@vercel/backends': 0.0.36(rollup@4.59.0)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/detect-agent@1.1.0': {} - - '@vercel/elysia@0.1.39(rollup@4.59.0)': - dependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/error-utils@2.0.3': {} - - '@vercel/express@0.1.48(rollup@4.59.0)(typescript@5.9.3)': - dependencies: - '@vercel/cervel': 0.0.23(rollup@4.59.0)(typescript@5.9.3) - '@vercel/nft': 1.1.1(rollup@4.59.0) - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - fs-extra: 11.1.0 - path-to-regexp: 8.3.0 - ts-morph: 12.0.0 - zod: 3.22.4 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - typescript - - '@vercel/fastify@0.1.42(rollup@4.59.0)': - dependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/fun@1.3.0': - dependencies: - '@tootallnate/once': 2.0.0 - async-listen: 1.2.0 - debug: 4.3.4 - generic-pool: 3.4.2 - micro: 9.3.5-canary.3 - ms: 2.1.1 - node-fetch: 2.6.7 - path-to-regexp: 8.2.0 - promisepipe: 3.0.0 - semver: 7.5.4 - stat-mode: 0.3.0 - stream-to-promise: 2.2.0 - tar: 7.5.7 - tinyexec: 0.3.2 - tree-kill: 1.2.2 - uid-promise: 1.0.0 - xdg-app-paths: 5.1.0 - yauzl-promise: 2.1.3 - transitivePeerDependencies: - - encoding - - supports-color - - '@vercel/functions@3.4.2(@aws-sdk/credential-provider-web-identity@3.972.12)': - dependencies: - '@vercel/oidc': 3.2.0 - optionalDependencies: - '@aws-sdk/credential-provider-web-identity': 3.972.12 - - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': - dependencies: - web-vitals: 0.2.4 - - '@vercel/gatsby-plugin-vercel-builder@2.0.138': - dependencies: - '@sinclair/typebox': 0.25.24 - '@vercel/build-utils': 13.4.3 - esbuild: 0.27.0 - etag: 1.8.1 - fs-extra: 11.1.0 - - '@vercel/go@3.4.1': {} - - '@vercel/h3@0.1.48(rollup@4.59.0)': - dependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/hono@0.2.42(rollup@4.59.0)': - dependencies: - '@vercel/nft': 1.1.1(rollup@4.59.0) - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - fs-extra: 11.1.0 - path-to-regexp: 8.3.0 - ts-morph: 12.0.0 - zod: 3.22.4 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/hydrogen@1.3.5': - dependencies: - '@vercel/static-config': 3.1.2 - ts-morph: 12.0.0 - - '@vercel/koa@0.1.22(rollup@4.59.0)': - dependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nestjs@0.2.43(rollup@4.59.0)': - dependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/next@4.15.31(rollup@4.59.0)': - dependencies: - '@vercel/nft': 1.1.1(rollup@4.59.0) - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nft@1.1.1(rollup@4.59.0)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.3 - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - acorn: 8.16.0 - acorn-import-attributes: 1.9.5(acorn@8.16.0) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 13.0.6 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.4 - picomatch: 4.0.3 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nft@1.3.0(rollup@4.59.0)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.3 - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - acorn: 8.16.0 - acorn-import-attributes: 1.9.5(acorn@8.16.0) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 13.0.6 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.4 - picomatch: 4.0.3 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/node@5.6.6(rollup@4.59.0)': - dependencies: - '@edge-runtime/node-utils': 2.3.0 - '@edge-runtime/primitives': 4.1.0 - '@edge-runtime/vm': 3.2.0 - '@types/node': 20.11.0 - '@vercel/build-utils': 13.4.3 - '@vercel/error-utils': 2.0.3 - '@vercel/nft': 1.1.1(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - async-listen: 3.0.0 - cjs-module-lexer: 1.2.3 - edge-runtime: 2.5.9 - es-module-lexer: 1.4.1 - esbuild: 0.27.0 - etag: 1.8.1 - mime-types: 2.1.35 - node-fetch: 2.6.9 - path-to-regexp: 6.1.0 - path-to-regexp-updated: path-to-regexp@6.3.0 - ts-morph: 12.0.0 - tsx: 4.21.0 - typescript: 5.9.3 - undici: 5.28.4 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/oidc@3.1.0': {} - - '@vercel/oidc@3.2.0': {} - - '@vercel/python-analysis@0.6.0': - dependencies: - '@bytecodealliance/preview2-shim': 0.17.6 - '@renovatebot/pep440': 4.2.1 - fs-extra: 11.1.1 - js-yaml: 4.1.1 - minimatch: 10.1.1 - pip-requirements-js: 1.0.2 - smol-toml: 1.5.2 - zod: 3.22.4 - - '@vercel/python@6.15.1': - dependencies: - '@vercel/python-analysis': 0.6.0 - - '@vercel/redwood@2.4.9(rollup@4.59.0)': - dependencies: - '@vercel/nft': 1.1.1(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - semver: 6.3.1 - ts-morph: 12.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/remix-builder@5.5.10(rollup@4.59.0)': - dependencies: - '@vercel/error-utils': 2.0.3 - '@vercel/nft': 1.1.1(rollup@4.59.0) - '@vercel/static-config': 3.1.2 - path-to-regexp: 6.1.0 - path-to-regexp-updated: path-to-regexp@6.3.0 - ts-morph: 12.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/ruby@2.3.1': {} - - '@vercel/rust@1.0.5': - dependencies: - '@iarna/toml': 2.2.5 - execa: 5.1.1 - - '@vercel/static-build@2.8.40': - dependencies: - '@vercel/gatsby-plugin-vercel-analytics': 1.0.11 - '@vercel/gatsby-plugin-vercel-builder': 2.0.138 - '@vercel/static-config': 3.1.2 - ts-morph: 12.0.0 - - '@vercel/static-config@3.1.2': - dependencies: - ajv: 8.6.3 - json-schema-to-ts: 1.6.4 - ts-morph: 12.0.0 - - '@webassemblyjs/ast@1.14.1': - dependencies: - '@webassemblyjs/helper-numbers': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - - '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - - '@webassemblyjs/helper-api-error@1.13.2': {} - - '@webassemblyjs/helper-buffer@1.14.1': {} - - '@webassemblyjs/helper-numbers@1.13.2': - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.13.2 - '@webassemblyjs/helper-api-error': 1.13.2 - '@xtuc/long': 4.2.2 - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - - '@webassemblyjs/helper-wasm-section@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/wasm-gen': 1.14.1 - - '@webassemblyjs/ieee754@1.13.2': - dependencies: - '@xtuc/ieee754': 1.2.0 - - '@webassemblyjs/leb128@1.13.2': - dependencies: - '@xtuc/long': 4.2.2 - - '@webassemblyjs/utf8@1.13.2': {} - - '@webassemblyjs/wasm-edit@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/helper-wasm-section': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-opt': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wast-printer': 1.14.1 - - '@webassemblyjs/wasm-gen@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wasm-opt@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - - '@webassemblyjs/wasm-parser@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-api-error': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wast-printer@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@xtuc/long': 4.2.2 - - '@xmldom/is-dom-node@1.0.1': {} - - '@xmldom/xmldom@0.8.11': {} - - '@xtuc/ieee754@1.2.0': {} - - '@xtuc/long@4.2.2': {} - - abbrev@3.0.1: {} - - acorn-import-attributes@1.9.5(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn-import-phases@1.0.4(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn@8.16.0: {} - - agent-base@6.0.2: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - agent-base@7.1.4: {} - - ai@6.0.97(zod@4.3.6): - dependencies: - '@ai-sdk/gateway': 3.0.53(zod@4.3.6) - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.15(zod@4.3.6) - '@opentelemetry/api': 1.9.0 - zod: 4.3.6 - - ajv-formats@2.1.1(ajv@8.18.0): - optionalDependencies: - ajv: 8.18.0 - - ajv-keywords@5.1.0(ajv@8.18.0): - dependencies: - ajv: 8.18.0 - fast-deep-equal: 3.1.3 - - ajv@8.18.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ajv@8.6.3: - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - - ansi-escapes@7.3.0: - dependencies: - environment: 1.1.0 - - ansi-regex@4.1.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.2.2: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.3: {} - - any-promise@1.3.0: {} - - arg@4.1.0: {} - - argparse@2.0.1: {} - - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - ast-types@0.13.4: - dependencies: - tslib: 2.8.1 - - async-listen@1.2.0: {} - - async-listen@3.0.0: {} - - async-listen@3.0.1: {} - - async-retry@1.3.3: - dependencies: - retry: 0.13.1 - - async-sema@3.1.1: {} - - asynckit@0.4.0: {} - - auth@1.5.0-beta.18(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(nanostores@1.1.0)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@babel/core': 7.29.0 - '@babel/preset-react': 7.28.5(@babel/core@7.29.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/telemetry': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) - '@better-auth/utils': 0.3.1 - '@clack/prompts': 0.11.0 - '@mrleebo/prisma-ast': 0.13.1 - '@prisma/client': 5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - '@types/pg': 8.16.0 - better-auth: 1.5.0-beta.16(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - c12: 3.3.3 - chalk: 5.6.2 - commander: 12.1.0 - dotenv: 17.3.1 - drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - open: 10.2.0 - pg: 8.18.0 - prettier: 3.8.1 - prompts: 2.4.2 - semver: 7.7.4 - yocto-spinner: 0.2.3 - zod: 4.3.6 - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@better-fetch/fetch' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@lynx-js/react' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@sveltejs/kit' - - '@tanstack/react-start' - - '@tanstack/solid-start' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/sql.js' - - '@vercel/postgres' - - '@xata.io/client' - - better-call - - better-sqlite3 - - bun-types - - drizzle-kit - - expo-sqlite - - gel - - jose - - knex - - kysely - - magicast - - mongodb - - mysql2 - - nanostores - - next - - pg-native - - postgres - - prisma - - react - - react-dom - - solid-js - - sql.js - - sqlite3 - - supports-color - - svelte - - vitest - - vue - - aws-ssl-profiles@1.1.2: {} - - bail@2.0.2: {} - - balanced-match@1.0.2: {} - - balanced-match@4.0.3: {} - - baseline-browser-mapping@2.10.0: {} - - basic-ftp@5.1.0: {} - - before-after-hook@4.0.0: {} - - better-all@0.0.7: {} - - better-auth@1.5.0-beta.16(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@better-auth/core': 1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/drizzle-adapter': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))) - '@better-auth/kysely-adapter': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(kysely@0.28.11) - '@better-auth/memory-adapter': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) - '@better-auth/prisma-adapter': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - '@better-auth/telemetry': 1.5.0-beta.16(@better-auth/core@1.5.0-beta.16(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - '@noble/ciphers': 2.1.1 - '@noble/hashes': 2.0.1 - better-call: 1.3.2(zod@4.3.6) - defu: 6.1.4 - jose: 6.1.3 - kysely: 0.28.11 - nanostores: 1.1.0 - zod: 4.3.6 - optionalDependencies: - '@prisma/client': 5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - mongodb: 7.1.0(socks@2.8.7) - mysql2: 3.15.3 - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - pg: 8.18.0 - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - better-auth@1.5.0-beta.18(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(mongodb@7.1.0(socks@2.8.7))(mysql2@3.15.3)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.18.0)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@better-auth/core': 1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) - '@better-auth/drizzle-adapter': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))) - '@better-auth/kysely-adapter': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(kysely@0.28.11) - '@better-auth/memory-adapter': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) - '@better-auth/prisma-adapter': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(@better-auth/utils@0.3.1)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - '@better-auth/telemetry': 1.5.0-beta.18(@better-auth/core@1.5.0-beta.18(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - '@noble/ciphers': 2.1.1 - '@noble/hashes': 2.0.1 - better-call: 1.3.2(zod@4.3.6) - defu: 6.1.4 - jose: 6.1.3 - kysely: 0.28.11 - nanostores: 1.1.0 - zod: 4.3.6 - optionalDependencies: - '@prisma/client': 7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) - drizzle-orm: 0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) - mongodb: 7.1.0(socks@2.8.7) - mysql2: 3.15.3 - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - pg: 8.18.0 - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - better-call@1.1.0-beta.2: - dependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - rou3: 0.5.1 - set-cookie-parser: 2.7.2 - - better-call@1.3.2(zod@4.3.6): - dependencies: - '@better-auth/utils': 0.3.1 - '@better-fetch/fetch': 1.1.21 - rou3: 0.7.12 - set-cookie-parser: 3.0.1 - optionalDependencies: - zod: 4.3.6 - - bignumber.js@9.3.1: {} - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - bowser@2.14.1: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@5.0.2: - dependencies: - balanced-match: 4.0.3 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.28.1: - dependencies: - baseline-browser-mapping: 2.10.0 - caniuse-lite: 1.0.30001770 - electron-to-chromium: 1.5.302 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) - - bson@7.2.0: {} - - buffer-crc32@0.2.13: {} - - buffer-from@1.1.2: {} - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.1.0 - - bytes@3.1.0: {} - - c12@3.1.0: - dependencies: - chokidar: 4.0.3 - confbox: 0.2.4 - defu: 6.1.4 - dotenv: 16.6.1 - exsolve: 1.0.8 - giget: 2.0.0 - jiti: 2.6.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.3.0 - rc9: 2.1.2 - - c12@3.3.3: - dependencies: - chokidar: 5.0.0 - confbox: 0.2.4 - defu: 6.1.4 - dotenv: 17.3.1 - exsolve: 1.0.8 - giget: 2.0.0 - jiti: 2.6.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.0 - rc9: 2.1.2 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001770: {} - - canonicalize@1.0.8: {} - - ccount@2.0.1: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.6.2: {} - - character-entities-html4@2.1.0: {} - - character-entities-legacy@3.0.0: {} - - character-entities@2.0.2: {} - - character-reference-invalid@2.0.1: {} - - chevrotain@10.5.0: - dependencies: - '@chevrotain/cst-dts-gen': 10.5.0 - '@chevrotain/gast': 10.5.0 - '@chevrotain/types': 10.5.0 - '@chevrotain/utils': 10.5.0 - lodash: 4.17.21 - regexp-to-ast: 0.5.0 - - chokidar@4.0.0: - dependencies: - readdirp: 4.1.2 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - chokidar@5.0.0: - dependencies: - readdirp: 5.0.0 - - chownr@3.0.0: {} - - chrome-trace-event@1.0.4: {} - - citty@0.1.6: - dependencies: - consola: 3.4.2 - - citty@0.2.1: {} - - cjs-module-lexer@1.2.3: {} - - cjs-module-lexer@1.4.3: {} - - cjs-module-lexer@2.2.0: {} - - class-variance-authority@0.7.1: - dependencies: - clsx: 2.1.1 - - cli-cursor@5.0.0: - dependencies: - restore-cursor: 5.1.0 - - cli-truncate@5.1.1: - dependencies: - slice-ansi: 7.1.2 - string-width: 8.2.0 - - client-only@0.0.1: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clsx@2.1.1: {} - - cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - - code-block-writer@10.1.1: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - colorette@2.0.20: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - comma-separated-tokens@2.0.3: {} - - commander@12.1.0: {} - - commander@14.0.3: {} - - commander@2.20.3: {} - - commondir@1.0.1: {} - - compare-versions@6.1.1: {} - - concat-map@0.0.1: {} - - confbox@0.2.4: {} - - consola@3.4.2: {} - - content-type@1.0.4: {} - - convert-hrtime@3.0.0: {} - - convert-source-map@2.0.0: {} - - cookie-es@2.0.0: {} - - crelt@1.0.6: {} - - cross-fetch@4.1.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - csstype@3.2.3: {} - - data-uri-to-buffer@4.0.1: {} - - data-uri-to-buffer@6.0.2: {} - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decode-named-character-reference@1.3.0: - dependencies: - character-entities: 2.0.2 - - deepmerge-ts@7.1.5: {} - - default-browser-id@5.0.1: {} - - default-browser@5.5.0: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.1 - - define-lazy-prop@3.0.0: {} - - defu@6.1.4: {} - - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - - delayed-stream@1.0.0: {} - - denque@2.1.0: {} - - depd@1.1.2: {} - - dequal@2.0.3: {} - - destr@2.0.5: {} - - detect-libc@2.1.2: {} - - detect-node-es@1.1.0: {} - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - dockerfile-ast@0.7.1: - dependencies: - vscode-languageserver-textdocument: 1.0.12 - vscode-languageserver-types: 3.17.5 - - dotenv@16.6.1: {} - - dotenv@17.3.1: {} - - drizzle-orm@0.41.0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.16.0)(kysely@0.28.11)(mysql2@3.15.3)(pg@8.18.0)(postgres@3.4.7)(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)): - optionalDependencies: - '@electric-sql/pglite': 0.3.15 - '@opentelemetry/api': 1.9.0 - '@prisma/client': 7.4.1(prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) - '@types/pg': 8.16.0 - kysely: 0.28.11 - mysql2: 3.15.3 - pg: 8.18.0 - postgres: 3.4.7 - prisma: 7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - e2b@2.12.1: - dependencies: - '@bufbuild/protobuf': 2.11.0 - '@connectrpc/connect': 2.0.0-rc.3(@bufbuild/protobuf@2.11.0) - '@connectrpc/connect-web': 2.0.0-rc.3(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.11.0)) - chalk: 5.6.2 - compare-versions: 6.1.1 - dockerfile-ast: 0.7.1 - glob: 11.1.0 - openapi-fetch: 0.14.1 - platform: 1.3.6 - tar: 7.5.9 - - eastasianwidth@0.2.0: {} - - edge-runtime@2.5.9: - dependencies: - '@edge-runtime/format': 2.2.1 - '@edge-runtime/ponyfill': 2.4.2 - '@edge-runtime/vm': 3.2.0 - async-listen: 3.0.1 - mri: 1.2.0 - picocolors: 1.0.0 - pretty-ms: 7.0.1 - signal-exit: 4.0.2 - time-span: 4.0.0 - - effect@3.18.4: - dependencies: - '@standard-schema/spec': 1.1.0 - fast-check: 3.23.2 - - electron-to-chromium@1.5.302: {} - - emoji-regex@10.6.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - empathic@2.0.0: {} - - end-of-stream@1.1.0: - dependencies: - once: 1.3.3 - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - enhanced-resolve@5.19.0: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - - entities@4.5.0: {} - - entities@6.0.1: {} - - environment@1.1.0: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.4.1: {} - - es-module-lexer@2.0.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 - - esbuild@0.27.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.0 - '@esbuild/android-arm': 0.27.0 - '@esbuild/android-arm64': 0.27.0 - '@esbuild/android-x64': 0.27.0 - '@esbuild/darwin-arm64': 0.27.0 - '@esbuild/darwin-x64': 0.27.0 - '@esbuild/freebsd-arm64': 0.27.0 - '@esbuild/freebsd-x64': 0.27.0 - '@esbuild/linux-arm': 0.27.0 - '@esbuild/linux-arm64': 0.27.0 - '@esbuild/linux-ia32': 0.27.0 - '@esbuild/linux-loong64': 0.27.0 - '@esbuild/linux-mips64el': 0.27.0 - '@esbuild/linux-ppc64': 0.27.0 - '@esbuild/linux-riscv64': 0.27.0 - '@esbuild/linux-s390x': 0.27.0 - '@esbuild/linux-x64': 0.27.0 - '@esbuild/netbsd-arm64': 0.27.0 - '@esbuild/netbsd-x64': 0.27.0 - '@esbuild/openbsd-arm64': 0.27.0 - '@esbuild/openbsd-x64': 0.27.0 - '@esbuild/openharmony-arm64': 0.27.0 - '@esbuild/sunos-x64': 0.27.0 - '@esbuild/win32-arm64': 0.27.0 - '@esbuild/win32-ia32': 0.27.0 - '@esbuild/win32-x64': 0.27.0 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@4.0.0: {} - - escape-string-regexp@5.0.0: {} - - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - esprima@4.0.1: {} - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - estree-util-is-identifier-name@3.0.0: {} - - estree-walker@2.0.2: {} - - esutils@2.0.3: {} - - etag@1.8.1: {} - - eventemitter3@5.0.4: {} - - events-intercept@2.0.0: {} - - events@3.3.0: {} - - eventsource-parser@3.0.6: {} - - execa@3.2.0: - dependencies: - cross-spawn: 7.0.6 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - p-finally: 2.0.1 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exsolve@1.0.8: {} - - extend@3.0.2: {} - - fast-check@3.23.2: - dependencies: - pure-rand: 6.1.0 - - fast-content-type-parse@3.0.0: {} - - fast-deep-equal@3.1.3: {} - - fast-equals@5.4.0: {} - - 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-uri@3.1.0: {} - - fast-xml-builder@1.0.0: {} - - fast-xml-parser@5.3.6: - dependencies: - strnum: 2.1.2 - - fast-xml-parser@5.4.1: - dependencies: - fast-xml-builder: 1.0.0 - strnum: 2.1.2 - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - - file-uri-to-path@1.0.0: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - form-data@4.0.5: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - formdata-node@6.0.3: {} - - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - - forwarded-parse@2.1.2: {} - - foxact@0.2.52(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - client-only: 0.0.1 - server-only: 0.0.1 - optionalDependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - framer-motion@12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - motion-dom: 12.34.3 - motion-utils: 12.29.2 - tslib: 2.8.1 - optionalDependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - fs-extra@11.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - - fs-extra@11.1.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - gaxios@7.1.3: - dependencies: - extend: 3.0.2 - https-proxy-agent: 7.0.6 - node-fetch: 3.3.2 - rimraf: 5.0.10 - transitivePeerDependencies: - - supports-color - - gcp-metadata@8.1.2: - dependencies: - gaxios: 7.1.3 - google-logging-utils: 1.1.3 - json-bigint: 1.0.0 - transitivePeerDependencies: - - supports-color - - generate-function@2.3.1: - dependencies: - is-property: 1.0.2 - - generic-pool@3.4.2: {} - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-east-asian-width@1.5.0: {} - - 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-nonce@1.0.1: {} - - get-port-please@3.2.0: {} - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@5.2.0: - dependencies: - pump: 3.0.3 - - get-stream@6.0.1: {} - - get-tsconfig@4.13.6: - dependencies: - resolve-pkg-maps: 1.0.0 - - get-uri@6.0.5: - dependencies: - basic-ftp: 5.1.0 - data-uri-to-buffer: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - giget@2.0.0: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - defu: 6.1.4 - node-fetch-native: 1.6.7 - nypm: 0.6.5 - pathe: 2.0.3 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@10.5.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.6 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - glob@11.1.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 4.2.3 - minimatch: 10.2.2 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.2 - - glob@13.0.6: - dependencies: - minimatch: 10.2.2 - minipass: 7.1.3 - path-scurry: 2.0.2 - - google-logging-utils@1.1.3: {} - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - grammex@3.1.12: {} - - graphmatch@1.1.1: {} - - has-flag@4.0.0: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hash.js@1.1.7: - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hast-util-from-parse5@8.0.3: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - devlop: 1.1.0 - hastscript: 9.0.1 - property-information: 7.1.0 - vfile: 6.0.3 - vfile-location: 5.0.3 - web-namespaces: 2.0.1 - - hast-util-parse-selector@4.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-raw@9.1.0: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.0 - hast-util-from-parse5: 8.0.3 - hast-util-to-parse5: 8.0.1 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.1 - parse5: 7.3.0 - unist-util-position: 5.0.0 - unist-util-visit: 5.1.0 - vfile: 6.0.3 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-sanitize@5.0.2: - dependencies: - '@types/hast': 3.0.4 - '@ungap/structured-clone': 1.3.0 - unist-util-position: 5.0.0 - - hast-util-to-html@9.0.5: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-whitespace: 3.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.4 - zwitch: 2.0.4 - - hast-util-to-jsx-runtime@2.3.6: - dependencies: - '@types/estree': 1.0.8 - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.1 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - style-to-js: 1.1.21 - unist-util-position: 5.0.0 - vfile-message: 4.0.3 - transitivePeerDependencies: - - supports-color - - hast-util-to-parse5@8.0.1: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-whitespace@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hastscript@9.0.1: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - - hono@4.11.4: {} - - html-url-attributes@3.0.1: {} - - html-void-elements@3.0.0: {} - - http-errors@1.7.3: - dependencies: - depd: 1.1.2 - inherits: 2.0.4 - setprototypeof: 1.1.1 - statuses: 1.5.0 - toidentifier: 1.0.0 - - http-proxy-agent@7.0.2: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - http-status-codes@2.3.0: {} - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - human-signals@1.1.1: {} - - human-signals@2.1.0: {} - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.7.2: - dependencies: - safer-buffer: 2.1.2 - - import-in-the-middle@1.15.0: - dependencies: - acorn: 8.16.0 - acorn-import-attributes: 1.9.5(acorn@8.16.0) - cjs-module-lexer: 1.4.3 - module-details-from-path: 1.0.4 - - import-in-the-middle@2.0.6: - dependencies: - acorn: 8.16.0 - acorn-import-attributes: 1.9.5(acorn@8.16.0) - cjs-module-lexer: 2.2.0 - module-details-from-path: 1.0.4 - - inherits@2.0.4: {} - - inline-style-parser@0.2.7: {} - - inngest@3.52.3(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@vercel/node@5.6.6(rollup@4.59.0))(hono@4.11.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(zod@4.3.6): - dependencies: - '@bufbuild/protobuf': 2.11.0 - '@inngest/ai': 0.1.7 - '@jpwilliams/waitgroup': 2.1.1 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/auto-instrumentations-node': 0.70.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0)) - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@standard-schema/spec': 1.1.0 - '@traceloop/instrumentation-anthropic': 0.20.0 - '@types/debug': 4.1.12 - '@types/ms': 2.1.0 - canonicalize: 1.0.8 - chalk: 4.1.2 - cross-fetch: 4.1.0 - debug: 4.4.3 - hash.js: 1.1.7 - json-stringify-safe: 5.0.1 - ms: 2.1.3 - serialize-error-cjs: 0.1.4 - strip-ansi: 5.2.0 - temporal-polyfill: 0.2.5 - ulid: 2.4.0 - zod: 4.3.6 - optionalDependencies: - '@vercel/node': 5.6.6(rollup@4.59.0) - hono: 4.11.4 - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - typescript: 5.9.3 - transitivePeerDependencies: - - '@opentelemetry/core' - - encoding - - supports-color - - ip-address@10.1.0: {} - - is-alphabetical@2.0.1: {} - - is-alphanumerical@2.0.1: - dependencies: - is-alphabetical: 2.0.1 - is-decimal: 2.0.1 - - is-buffer@2.0.5: {} - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-decimal@2.0.1: {} - - is-docker@3.0.0: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-fullwidth-code-point@5.1.0: - dependencies: - get-east-asian-width: 1.5.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-hexadecimal@2.0.1: {} - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-node-process@1.2.0: {} - - is-number@7.0.0: {} - - is-plain-obj@4.1.0: {} - - is-property@1.0.2: {} - - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.8 - - is-stream@2.0.1: {} - - is-wsl@3.1.1: - dependencies: - is-inside-container: 1.0.0 - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jackspeak@4.2.3: - dependencies: - '@isaacs/cliui': 9.0.0 - - jest-worker@27.5.1: - dependencies: - '@types/node': 25.3.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jiti@2.6.1: {} - - jose@5.9.6: {} - - jose@6.1.3: {} - - js-base64@3.7.2: {} - - js-tokens@4.0.0: {} - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-bigint@1.0.0: - dependencies: - bignumber.js: 9.3.1 - - json-parse-even-better-errors@2.3.1: {} - - json-schema-to-ts@1.6.4: - dependencies: - '@types/json-schema': 7.0.15 - ts-toolbelt: 6.15.5 - - json-schema-traverse@1.0.0: {} - - json-schema@0.4.0: {} - - json-stringify-safe@5.0.1: {} - - json5@2.2.3: {} - - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - kleur@3.0.3: {} - - kysely@0.28.11: {} - - libphonenumber-js@1.12.37: {} - - lightningcss-android-arm64@1.31.1: - optional: true - - lightningcss-darwin-arm64@1.31.1: - optional: true - - lightningcss-darwin-x64@1.31.1: - optional: true - - lightningcss-freebsd-x64@1.31.1: - optional: true - - lightningcss-linux-arm-gnueabihf@1.31.1: - optional: true - - lightningcss-linux-arm64-gnu@1.31.1: - optional: true - - lightningcss-linux-arm64-musl@1.31.1: - optional: true - - lightningcss-linux-x64-gnu@1.31.1: - optional: true - - lightningcss-linux-x64-musl@1.31.1: - optional: true - - lightningcss-win32-arm64-msvc@1.31.1: - optional: true - - lightningcss-win32-x64-msvc@1.31.1: - optional: true - - lightningcss@1.31.1: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.31.1 - lightningcss-darwin-arm64: 1.31.1 - lightningcss-darwin-x64: 1.31.1 - lightningcss-freebsd-x64: 1.31.1 - lightningcss-linux-arm-gnueabihf: 1.31.1 - lightningcss-linux-arm64-gnu: 1.31.1 - lightningcss-linux-arm64-musl: 1.31.1 - lightningcss-linux-x64-gnu: 1.31.1 - lightningcss-linux-x64-musl: 1.31.1 - lightningcss-win32-arm64-msvc: 1.31.1 - lightningcss-win32-x64-msvc: 1.31.1 - - lilconfig@2.1.0: {} - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - linkifyjs@4.3.2: {} - - lint-staged@16.2.7: - dependencies: - commander: 14.0.3 - listr2: 9.0.5 - micromatch: 4.0.8 - nano-spawn: 2.0.0 - pidtree: 0.6.0 - string-argv: 0.3.2 - yaml: 2.8.2 - - listr2@9.0.5: - dependencies: - cli-truncate: 5.1.1 - colorette: 2.0.20 - eventemitter3: 5.0.4 - log-update: 6.1.0 - rfdc: 1.4.1 - wrap-ansi: 9.0.2 - - loader-runner@4.3.1: {} - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.camelcase@4.3.0: {} - - lodash@4.17.21: {} - - log-update@6.1.0: - dependencies: - ansi-escapes: 7.3.0 - cli-cursor: 5.0.0 - slice-ansi: 7.1.2 - strip-ansi: 7.1.2 - wrap-ansi: 9.0.2 - - long@5.3.2: {} - - longest-streak@3.1.0: {} - - lru-cache@10.4.3: {} - - lru-cache@11.2.6: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lru-cache@7.18.3: {} - - lru.min@1.1.4: {} - - lucide-react@0.575.0(react@19.2.4): - dependencies: - react: 19.2.4 - - luxon@3.7.2: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magic-string@0.30.8: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - markdown-it-task-lists@2.1.1: {} - - markdown-it@14.1.1: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - markdown-table@3.0.4: {} - - math-intrinsics@1.1.0: {} - - mdast-util-find-and-replace@3.0.2: - dependencies: - '@types/mdast': 4.0.4 - escape-string-regexp: 5.0.0 - unist-util-is: 6.0.1 - unist-util-visit-parents: 6.0.2 - - mdast-util-from-markdown@2.0.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - decode-named-character-reference: 1.3.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-gfm-autolink-literal@2.0.1: - dependencies: - '@types/mdast': 4.0.4 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.2 - micromark-util-character: 2.1.1 - - mdast-util-gfm-footnote@2.1.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - micromark-util-normalize-identifier: 2.0.1 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-strikethrough@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-table@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-task-list-item@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm@3.1.0: - dependencies: - mdast-util-from-markdown: 2.0.2 - mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0 - mdast-util-gfm-strikethrough: 2.0.0 - mdast-util-gfm-table: 2.0.0 - mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-expression@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-jsx@3.2.0: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - parse-entities: 4.0.2 - stringify-entities: 4.0.4 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.3 - transitivePeerDependencies: - - supports-color - - mdast-util-mdxjs-esm@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-phrasing@4.1.0: - dependencies: - '@types/mdast': 4.0.4 - unist-util-is: 6.0.1 - - mdast-util-to-hast@13.2.1: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.1 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.1.0 - vfile: 6.0.3 - - mdast-util-to-markdown@2.1.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - longest-streak: 3.1.0 - mdast-util-phrasing: 4.1.0 - mdast-util-to-string: 4.0.0 - micromark-util-classify-character: 2.0.1 - micromark-util-decode-string: 2.0.1 - unist-util-visit: 5.1.0 - zwitch: 2.0.4 - - mdast-util-to-string@4.0.0: - dependencies: - '@types/mdast': 4.0.4 - - mdurl@2.0.0: {} - - memory-pager@1.5.0: {} - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micro@9.3.5-canary.3: - dependencies: - arg: 4.1.0 - content-type: 1.0.4 - raw-body: 2.4.1 - - micromark-core-commonmark@2.0.3: - dependencies: - decode-named-character-reference: 1.3.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-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-footnote@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-strikethrough@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-table@2.1.1: - dependencies: - devlop: 1.1.0 - 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-extension-gfm-tagfilter@2.0.0: - dependencies: - micromark-util-types: 2.0.2 - - micromark-extension-gfm-task-list-item@2.1.0: - dependencies: - devlop: 1.1.0 - 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-extension-gfm@3.0.0: - dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 - micromark-util-combine-extensions: 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.3.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.3.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 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@2.1.0: {} - - mimic-function@5.0.1: {} - - minimalistic-assert@1.0.1: {} - - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.1 - - minimatch@10.2.2: - dependencies: - brace-expansion: 5.0.2 - - minimatch@3.1.3: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.6: - dependencies: - brace-expansion: 5.0.2 - - minipass@7.1.3: {} - - minizlib@3.1.0: - dependencies: - minipass: 7.1.3 - - mkdirp@1.0.4: {} - - module-details-from-path@1.0.4: {} - - mongodb-connection-string-url@7.0.1: - dependencies: - '@types/whatwg-url': 13.0.0 - whatwg-url: 14.2.0 - - mongodb@7.1.0(socks@2.8.7): - dependencies: - '@mongodb-js/saslprep': 1.4.6 - bson: 7.2.0 - mongodb-connection-string-url: 7.0.1 - optionalDependencies: - socks: 2.8.7 - - motion-dom@12.34.3: - dependencies: - motion-utils: 12.29.2 - - motion-utils@12.29.2: {} - - motion@12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - framer-motion: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - tslib: 2.8.1 - optionalDependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - mri@1.2.0: {} - - ms@2.1.1: {} - - ms@2.1.2: {} - - ms@2.1.3: {} - - mysql2@3.15.3: - dependencies: - aws-ssl-profiles: 1.1.2 - denque: 2.1.0 - generate-function: 2.3.1 - iconv-lite: 0.7.2 - long: 5.3.2 - lru.min: 1.1.4 - named-placeholders: 1.1.6 - seq-queue: 0.0.5 - sqlstring: 2.3.3 - - named-placeholders@1.1.6: - dependencies: - lru.min: 1.1.4 - - nano-spawn@2.0.0: {} - - nanoid@3.3.11: {} - - nanostores@1.1.0: {} - - neo-async@2.6.2: {} - - netmask@2.0.2: {} - - next-themes@0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@next/env': 16.1.6 - '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.0 - caniuse-lite: 1.0.30001770 - postcss: 8.4.31 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4) - optionalDependencies: - '@next/swc-darwin-arm64': 16.1.6 - '@next/swc-darwin-x64': 16.1.6 - '@next/swc-linux-arm64-gnu': 16.1.6 - '@next/swc-linux-arm64-musl': 16.1.6 - '@next/swc-linux-x64-gnu': 16.1.6 - '@next/swc-linux-x64-musl': 16.1.6 - '@next/swc-win32-arm64-msvc': 16.1.6 - '@next/swc-win32-x64-msvc': 16.1.6 - '@opentelemetry/api': 1.9.0 - sharp: 0.34.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - node-domexception@1.0.0: {} - - node-fetch-native@1.6.7: {} - - node-fetch@2.6.7: - dependencies: - whatwg-url: 5.0.0 - - node-fetch@2.6.9: - dependencies: - whatwg-url: 5.0.0 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-forge@1.3.3: {} - - node-gyp-build@4.8.4: {} - - node-releases@2.0.27: {} - - node-rsa@1.1.1: - dependencies: - asn1: 0.2.6 - - nopt@8.1.0: - dependencies: - abbrev: 3.0.1 - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nuqs@2.8.8(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4): - dependencies: - '@standard-schema/spec': 1.0.0 - react: 19.2.4 - optionalDependencies: - next: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - - nypm@0.6.5: - dependencies: - citty: 0.2.1 - pathe: 2.0.3 - tinyexec: 1.0.2 - - object-inspect@1.13.4: {} - - ohash@2.0.11: {} - - ohm-js@17.5.0: {} - - once@1.3.3: - dependencies: - wrappy: 1.0.2 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - - oniguruma-parser@0.12.1: {} - - oniguruma-to-es@4.3.4: - dependencies: - oniguruma-parser: 0.12.1 - regex: 6.1.0 - regex-recursion: 6.0.2 - - open@10.2.0: - dependencies: - default-browser: 5.5.0 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - wsl-utils: 0.1.0 - - openapi-fetch@0.14.1: - dependencies: - openapi-typescript-helpers: 0.0.15 - - openapi-typescript-helpers@0.0.15: {} - - orderedmap@2.1.1: {} - - os-paths@4.4.0: {} - - oxc-transform@0.111.0: - optionalDependencies: - '@oxc-transform/binding-android-arm-eabi': 0.111.0 - '@oxc-transform/binding-android-arm64': 0.111.0 - '@oxc-transform/binding-darwin-arm64': 0.111.0 - '@oxc-transform/binding-darwin-x64': 0.111.0 - '@oxc-transform/binding-freebsd-x64': 0.111.0 - '@oxc-transform/binding-linux-arm-gnueabihf': 0.111.0 - '@oxc-transform/binding-linux-arm-musleabihf': 0.111.0 - '@oxc-transform/binding-linux-arm64-gnu': 0.111.0 - '@oxc-transform/binding-linux-arm64-musl': 0.111.0 - '@oxc-transform/binding-linux-ppc64-gnu': 0.111.0 - '@oxc-transform/binding-linux-riscv64-gnu': 0.111.0 - '@oxc-transform/binding-linux-riscv64-musl': 0.111.0 - '@oxc-transform/binding-linux-s390x-gnu': 0.111.0 - '@oxc-transform/binding-linux-x64-gnu': 0.111.0 - '@oxc-transform/binding-linux-x64-musl': 0.111.0 - '@oxc-transform/binding-openharmony-arm64': 0.111.0 - '@oxc-transform/binding-wasm32-wasi': 0.111.0 - '@oxc-transform/binding-win32-arm64-msvc': 0.111.0 - '@oxc-transform/binding-win32-ia32-msvc': 0.111.0 - '@oxc-transform/binding-win32-x64-msvc': 0.111.0 - - oxfmt@0.34.0: - dependencies: - tinypool: 2.1.0 - optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.34.0 - '@oxfmt/binding-android-arm64': 0.34.0 - '@oxfmt/binding-darwin-arm64': 0.34.0 - '@oxfmt/binding-darwin-x64': 0.34.0 - '@oxfmt/binding-freebsd-x64': 0.34.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.34.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.34.0 - '@oxfmt/binding-linux-arm64-gnu': 0.34.0 - '@oxfmt/binding-linux-arm64-musl': 0.34.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.34.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.34.0 - '@oxfmt/binding-linux-riscv64-musl': 0.34.0 - '@oxfmt/binding-linux-s390x-gnu': 0.34.0 - '@oxfmt/binding-linux-x64-gnu': 0.34.0 - '@oxfmt/binding-linux-x64-musl': 0.34.0 - '@oxfmt/binding-openharmony-arm64': 0.34.0 - '@oxfmt/binding-win32-arm64-msvc': 0.34.0 - '@oxfmt/binding-win32-ia32-msvc': 0.34.0 - '@oxfmt/binding-win32-x64-msvc': 0.34.0 - - oxlint@1.49.0: - optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.49.0 - '@oxlint/binding-android-arm64': 1.49.0 - '@oxlint/binding-darwin-arm64': 1.49.0 - '@oxlint/binding-darwin-x64': 1.49.0 - '@oxlint/binding-freebsd-x64': 1.49.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.49.0 - '@oxlint/binding-linux-arm-musleabihf': 1.49.0 - '@oxlint/binding-linux-arm64-gnu': 1.49.0 - '@oxlint/binding-linux-arm64-musl': 1.49.0 - '@oxlint/binding-linux-ppc64-gnu': 1.49.0 - '@oxlint/binding-linux-riscv64-gnu': 1.49.0 - '@oxlint/binding-linux-riscv64-musl': 1.49.0 - '@oxlint/binding-linux-s390x-gnu': 1.49.0 - '@oxlint/binding-linux-x64-gnu': 1.49.0 - '@oxlint/binding-linux-x64-musl': 1.49.0 - '@oxlint/binding-openharmony-arm64': 1.49.0 - '@oxlint/binding-win32-arm64-msvc': 1.49.0 - '@oxlint/binding-win32-ia32-msvc': 1.49.0 - '@oxlint/binding-win32-x64-msvc': 1.49.0 - - p-finally@2.0.1: {} - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - pac-proxy-agent@7.2.0: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.4 - debug: 4.4.3 - get-uri: 6.0.5 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - - package-json-from-dist@1.0.1: {} - - pako@1.0.11: {} - - parse-entities@4.0.2: - dependencies: - '@types/unist': 2.0.11 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.3.0 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - is-hexadecimal: 2.0.1 - - parse-ms@2.1.0: {} - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - path-browserify@1.0.1: {} - - 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.3 - - path-scurry@2.0.2: - dependencies: - lru-cache: 11.2.6 - minipass: 7.1.3 - - path-to-regexp@6.1.0: {} - - path-to-regexp@6.3.0: {} - - path-to-regexp@8.2.0: {} - - path-to-regexp@8.3.0: {} - - pathe@2.0.3: {} - - pend@1.2.0: {} - - perfect-debounce@1.0.0: {} - - perfect-debounce@2.1.0: {} - - pg-cloudflare@1.3.0: - optional: true - - pg-connection-string@2.11.0: {} - - pg-int8@1.0.1: {} - - pg-pool@3.11.0(pg@8.18.0): - dependencies: - pg: 8.18.0 - - pg-protocol@1.11.0: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.1 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg@8.18.0: - dependencies: - pg-connection-string: 2.11.0 - pg-pool: 3.11.0(pg@8.18.0) - pg-protocol: 1.11.0 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.3.0 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.0.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pidtree@0.6.0: {} - - pip-requirements-js@1.0.2: - dependencies: - ohm-js: 17.5.0 - - pkg-types@2.3.0: - dependencies: - confbox: 0.2.4 - exsolve: 1.0.8 - pathe: 2.0.3 - - platform@1.3.6: {} - - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postgres-array@2.0.0: {} - - postgres-array@3.0.4: {} - - postgres-bytea@1.0.1: {} - - postgres-date@1.0.7: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - postgres@3.4.7: {} - - prettier@3.8.1: {} - - pretty-ms@7.0.1: - dependencies: - parse-ms: 2.1.0 - - prisma@7.4.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): - dependencies: - '@prisma/config': 7.4.1 - '@prisma/dev': 0.20.0(typescript@5.9.3) - '@prisma/engines': 7.4.1 - '@prisma/studio-core': 0.13.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - mysql2: 3.15.3 - postgres: 3.4.7 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/react' - - magicast - - react - - react-dom - - progress@2.0.3: {} - - promisepipe@3.0.0: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - proper-lockfile@4.1.2: - dependencies: - graceful-fs: 4.2.11 - retry: 0.12.0 - signal-exit: 3.0.7 - - property-information@7.1.0: {} - - prosemirror-changeset@2.4.0: - dependencies: - prosemirror-transform: 1.11.0 - - prosemirror-collab@1.3.1: - dependencies: - prosemirror-state: 1.4.4 - - prosemirror-commands@1.7.1: - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - - prosemirror-dropcursor@1.8.2: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - prosemirror-view: 1.41.6 - - prosemirror-gapcursor@1.4.0: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.6 - - prosemirror-history@1.5.0: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - prosemirror-view: 1.41.6 - rope-sequence: 1.3.4 - - prosemirror-inputrules@1.5.1: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - - prosemirror-keymap@1.2.3: - dependencies: - prosemirror-state: 1.4.4 - w3c-keyname: 2.2.8 - - prosemirror-markdown@1.13.4: - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.1 - prosemirror-model: 1.25.4 - - prosemirror-menu@1.3.0: - dependencies: - crelt: 1.0.6 - prosemirror-commands: 1.7.1 - prosemirror-history: 1.5.0 - prosemirror-state: 1.4.4 - - prosemirror-model@1.25.4: - dependencies: - orderedmap: 2.1.1 - - prosemirror-schema-basic@1.2.4: - dependencies: - prosemirror-model: 1.25.4 - - prosemirror-schema-list@1.5.1: - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - - prosemirror-state@1.4.4: - dependencies: - prosemirror-model: 1.25.4 - prosemirror-transform: 1.11.0 - prosemirror-view: 1.41.6 - - prosemirror-tables@1.8.5: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - prosemirror-view: 1.41.6 - - prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6): - dependencies: - '@remirror/core-constants': 3.0.0 - escape-string-regexp: 4.0.0 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.6 - - prosemirror-transform@1.11.0: - dependencies: - prosemirror-model: 1.25.4 - - prosemirror-view@1.41.6: - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.11.0 - - protobufjs@7.5.4: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 25.3.0 - long: 5.3.2 - - protobufjs@8.0.0: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 25.3.0 - long: 5.3.2 - - proxy-agent@6.4.0: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - proxy-from-env@1.1.0: {} - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - punycode.js@2.3.1: {} - - punycode@2.3.1: {} - - pure-rand@6.1.0: {} - - qs@6.11.2: - dependencies: - side-channel: 1.1.0 - - queue-microtask@1.2.3: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - raw-body@2.4.1: - dependencies: - bytes: 3.1.0 - http-errors: 1.7.3 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - rc9@2.1.2: - dependencies: - defu: 6.1.4 - destr: 2.0.5 - - react-dom@19.2.4(react@19.2.4): - dependencies: - react: 19.2.4 - scheduler: 0.27.0 - - react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4): - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/react': 19.2.14 - devlop: 1.1.0 - hast-util-to-jsx-runtime: 2.3.6 - html-url-attributes: 3.0.1 - mdast-util-to-hast: 13.2.1 - react: 19.2.4 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - unified: 11.0.5 - unist-util-visit: 5.1.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.4) - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4) - use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - - react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - get-nonce: 1.0.1 - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - react@19.2.4: {} - - readdirp@4.1.2: {} - - readdirp@5.0.0: {} - - regex-recursion@6.0.2: - dependencies: - regex-utilities: 2.3.0 - - regex-utilities@2.3.0: {} - - regex@6.1.0: - dependencies: - regex-utilities: 2.3.0 - - regexp-to-ast@0.5.0: {} - - rehype-raw@7.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-raw: 9.1.0 - vfile: 6.0.3 - - rehype-sanitize@6.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-sanitize: 5.0.2 - - rehype-stringify@10.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - unified: 11.0.5 - - remark-gfm@4.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0 - micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-parse@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - micromark-util-types: 2.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-rehype@11.1.2: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - mdast-util-to-hast: 13.2.1 - unified: 11.0.5 - vfile: 6.0.3 - - remark-stringify@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-to-markdown: 2.1.2 - unified: 11.0.5 - - remeda@2.33.4: {} - - require-directory@2.1.1: {} - - require-from-string@2.0.2: {} - - require-in-the-middle@7.5.2: - dependencies: - debug: 4.4.3 - module-details-from-path: 1.0.4 - resolve: 1.22.11 - transitivePeerDependencies: - - supports-color - - require-in-the-middle@8.0.1: - dependencies: - debug: 4.4.3 - module-details-from-path: 1.0.4 - transitivePeerDependencies: - - supports-color - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve.exports@2.0.3: {} - - resolve@1.22.11: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - - retry@0.12.0: {} - - retry@0.13.1: {} - - reusify@1.1.0: {} - - rfdc@1.4.1: {} - - rimraf@5.0.10: - dependencies: - glob: 10.5.0 - - rolldown@1.0.0-rc.1: - dependencies: - '@oxc-project/types': 0.110.0 - '@rolldown/pluginutils': 1.0.0-rc.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.1 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.1 - '@rolldown/binding-darwin-x64': 1.0.0-rc.1 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.1 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.1 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.1 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.1 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.1 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.1 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.1 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.1 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.1 - - rollup@4.59.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 - fsevents: 2.3.3 - - rope-sequence@1.3.4: {} - - rou3@0.5.1: {} - - rou3@0.7.12: {} - - run-applescript@7.1.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - samlify@2.10.2: - dependencies: - '@authenio/xml-encryption': 2.0.2 - '@xmldom/xmldom': 0.8.11 - camelcase: 6.3.0 - node-forge: 1.3.3 - node-rsa: 1.1.1 - pako: 1.0.11 - uuid: 8.3.2 - xml: 1.0.1 - xml-crypto: 6.1.2 - xml-escape: 1.1.0 - xpath: 0.0.32 - - scheduler@0.27.0: {} - - schema-utils@4.3.3: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.18.0 - ajv-formats: 2.1.1(ajv@8.18.0) - ajv-keywords: 5.1.0(ajv@8.18.0) - - semver@6.3.1: {} - - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - - semver@7.7.4: {} - - seq-queue@0.0.5: {} - - serialize-error-cjs@0.1.4: {} - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - server-only@0.0.1: {} - - set-cookie-parser@2.7.2: {} - - set-cookie-parser@3.0.1: {} - - setprototypeof@1.1.1: {} - - sharp@0.34.5: - dependencies: - '@img/colour': 1.0.0 - detect-libc: 2.1.2 - semver: 7.7.4 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.5 - '@img/sharp-darwin-x64': 0.34.5 - '@img/sharp-libvips-darwin-arm64': 1.2.4 - '@img/sharp-libvips-darwin-x64': 1.2.4 - '@img/sharp-libvips-linux-arm': 1.2.4 - '@img/sharp-libvips-linux-arm64': 1.2.4 - '@img/sharp-libvips-linux-ppc64': 1.2.4 - '@img/sharp-libvips-linux-riscv64': 1.2.4 - '@img/sharp-libvips-linux-s390x': 1.2.4 - '@img/sharp-libvips-linux-x64': 1.2.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - '@img/sharp-linux-arm': 0.34.5 - '@img/sharp-linux-arm64': 0.34.5 - '@img/sharp-linux-ppc64': 0.34.5 - '@img/sharp-linux-riscv64': 0.34.5 - '@img/sharp-linux-s390x': 0.34.5 - '@img/sharp-linux-x64': 0.34.5 - '@img/sharp-linuxmusl-arm64': 0.34.5 - '@img/sharp-linuxmusl-x64': 0.34.5 - '@img/sharp-wasm32': 0.34.5 - '@img/sharp-win32-arm64': 0.34.5 - '@img/sharp-win32-ia32': 0.34.5 - '@img/sharp-win32-x64': 0.34.5 - optional: true - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - shiki@3.22.0: - dependencies: - '@shikijs/core': 3.22.0 - '@shikijs/engine-javascript': 3.22.0 - '@shikijs/engine-oniguruma': 3.22.0 - '@shikijs/langs': 3.22.0 - '@shikijs/themes': 3.22.0 - '@shikijs/types': 3.22.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - 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@3.0.7: {} - - signal-exit@4.0.2: {} - - signal-exit@4.1.0: {} - - simple-git-hooks@2.13.1: {} - - sisteransi@1.0.5: {} - - slice-ansi@7.1.2: - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 - - smart-buffer@4.2.0: {} - - smol-toml@1.5.2: {} - - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.1.0 - smart-buffer: 4.2.0 - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - space-separated-tokens@2.0.2: {} - - sparse-bitfield@3.0.3: - dependencies: - memory-pager: 1.5.0 - - split2@4.2.0: {} - - sqlstring@2.3.3: {} - - srvx@0.8.9: - dependencies: - cookie-es: 2.0.0 - - stacktrace-parser@0.1.11: - dependencies: - type-fest: 0.7.1 - - stat-mode@0.3.0: {} - - statuses@1.5.0: {} - - std-env@3.10.0: {} - - stream-to-array@2.3.0: - dependencies: - any-promise: 1.3.0 - - stream-to-promise@2.2.0: - dependencies: - any-promise: 1.3.0 - end-of-stream: 1.1.0 - stream-to-array: 2.3.0 - - string-argv@0.3.2: {} - - 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-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.5.0 - strip-ansi: 7.1.2 - - string-width@8.2.0: - dependencies: - get-east-asian-width: 1.5.0 - strip-ansi: 7.1.2 - - stringify-entities@4.0.4: - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - - strip-ansi@5.2.0: - dependencies: - ansi-regex: 4.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-final-newline@2.0.0: {} - - stripe@20.4.0(@types/node@25.3.0): - optionalDependencies: - '@types/node': 25.3.0 - - strnum@2.1.2: {} - - style-to-js@1.1.21: - dependencies: - style-to-object: 1.0.14 - - style-to-object@1.0.14: - dependencies: - inline-style-parser: 0.2.7 - - styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.4): - dependencies: - client-only: 0.0.1 - react: 19.2.4 - optionalDependencies: - '@babel/core': 7.29.0 - - supermemory@4.11.1: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - swr@2.4.0(react@19.2.4): - dependencies: - dequal: 2.0.3 - react: 19.2.4 - use-sync-external-store: 1.6.0(react@19.2.4) - - tailwind-merge@3.5.0: {} - - tailwindcss@4.2.0: {} - - tapable@2.3.0: {} - - tar@7.5.7: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - - tar@7.5.9: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - - temporal-polyfill@0.2.5: - dependencies: - temporal-spec: 0.2.4 - - temporal-spec@0.2.4: {} - - terser-webpack-plugin@5.3.16(webpack@5.105.2): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.46.0 - webpack: 5.105.2 - - terser@5.46.0: - dependencies: - '@jridgewell/source-map': 0.3.11 - acorn: 8.16.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - throttleit@2.1.0: {} - - time-span@4.0.0: - dependencies: - convert-hrtime: 3.0.0 - - tinyexec@0.3.2: {} - - tinyexec@1.0.2: {} - - tinypool@2.1.0: {} - - tiptap-markdown@0.9.0(@tiptap/core@3.20.0(@tiptap/pm@3.20.0)): - dependencies: - '@tiptap/core': 3.20.0(@tiptap/pm@3.20.0) - '@types/markdown-it': 13.0.9 - markdown-it: 14.1.1 - markdown-it-task-lists: 2.1.1 - prosemirror-markdown: 1.13.4 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toidentifier@1.0.0: {} - - tr46@0.0.3: {} - - tr46@5.1.1: - dependencies: - punycode: 2.3.1 - - tree-kill@1.2.2: {} - - trim-lines@3.0.1: {} - - trough@2.2.0: {} - - ts-morph@12.0.0: - dependencies: - '@ts-morph/common': 0.11.1 - code-block-writer: 10.1.1 - - ts-toolbelt@6.15.5: {} - - tslib@2.8.1: {} - - tsx@4.21.0: - dependencies: - esbuild: 0.27.0 - get-tsconfig: 4.13.6 - optionalDependencies: - fsevents: 2.3.3 - - tw-animate-css@1.4.0: {} - - type-fest@0.7.1: {} - - typescript@5.9.3: {} - - uc.micro@2.1.0: {} - - uid-promise@1.0.0: {} - - ulid@2.4.0: {} - - uncrypto@0.1.3: {} - - undici-types@5.26.5: {} - - undici-types@6.21.0: {} - - undici-types@7.18.2: {} - - undici@5.28.4: - dependencies: - '@fastify/busboy': 2.1.1 - - undici@6.23.0: {} - - unified@11.0.5: - dependencies: - '@types/unist': 3.0.3 - bail: 2.0.2 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.1.0 - trough: 2.2.0 - vfile: 6.0.3 - - unist-util-is@6.0.1: - dependencies: - '@types/unist': 3.0.3 - - unist-util-position@5.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-stringify-position@4.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-visit-parents@6.0.2: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.1 - - unist-util-visit@5.1.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.1 - unist-util-visit-parents: 6.0.2 - - universal-user-agent@7.0.3: {} - - universalify@2.0.1: {} - - unpipe@1.0.0: {} - - update-browserslist-db@1.2.3(browserslist@4.28.1): - dependencies: - browserslist: 4.28.1 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - url-join@4.0.1: {} - - use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - detect-node-es: 1.1.0 - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - use-sync-external-store@1.6.0(react@19.2.4): - dependencies: - react: 19.2.4 - - uuid@8.3.2: {} - - uuid@9.0.1: {} - - valibot@1.2.0(typescript@5.9.3): - optionalDependencies: - typescript: 5.9.3 - - vercel@50.22.1(rollup@4.59.0)(typescript@5.9.3): - dependencies: - '@vercel/backends': 0.0.36(rollup@4.59.0)(typescript@5.9.3) - '@vercel/blob': 2.3.0 - '@vercel/build-utils': 13.4.3 - '@vercel/detect-agent': 1.1.0 - '@vercel/elysia': 0.1.39(rollup@4.59.0) - '@vercel/express': 0.1.48(rollup@4.59.0)(typescript@5.9.3) - '@vercel/fastify': 0.1.42(rollup@4.59.0) - '@vercel/fun': 1.3.0 - '@vercel/go': 3.4.1 - '@vercel/h3': 0.1.48(rollup@4.59.0) - '@vercel/hono': 0.2.42(rollup@4.59.0) - '@vercel/hydrogen': 1.3.5 - '@vercel/koa': 0.1.22(rollup@4.59.0) - '@vercel/nestjs': 0.2.43(rollup@4.59.0) - '@vercel/next': 4.15.31(rollup@4.59.0) - '@vercel/node': 5.6.6(rollup@4.59.0) - '@vercel/python': 6.15.1 - '@vercel/redwood': 2.4.9(rollup@4.59.0) - '@vercel/remix-builder': 5.5.10(rollup@4.59.0) - '@vercel/ruby': 2.3.1 - '@vercel/rust': 1.0.5 - '@vercel/static-build': 2.8.40 - chokidar: 4.0.0 - esbuild: 0.27.0 - form-data: 4.0.5 - jose: 5.9.6 - luxon: 3.7.2 - proxy-agent: 6.4.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - typescript - - vfile-location@5.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile: 6.0.3 - - vfile-message@4.0.3: - dependencies: - '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 - - vfile@6.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile-message: 4.0.3 - - vscode-languageserver-textdocument@1.0.12: {} - - vscode-languageserver-types@3.17.5: {} - - w3c-keyname@2.2.8: {} - - watchpack@2.5.1: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - - web-namespaces@2.0.1: {} - - web-streams-polyfill@3.3.3: {} - - web-vitals@0.2.4: {} - - webidl-conversions@3.0.1: {} - - webidl-conversions@7.0.0: {} - - webpack-sources@3.3.4: {} - - webpack@5.105.2: - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.16.0 - acorn-import-phases: 1.0.4(acorn@8.16.0) - browserslist: 4.28.1 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.19.0 - es-module-lexer: 2.0.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(webpack@5.105.2) - watchpack: 2.5.1 - webpack-sources: 3.3.4 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - whatwg-url@14.2.0: - dependencies: - tr46: 5.1.1 - webidl-conversions: 7.0.0 - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - 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 - - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.1.2 - - wrappy@1.0.2: {} - - wsl-utils@0.1.0: - dependencies: - is-wsl: 3.1.1 - - xdg-app-paths@5.1.0: - dependencies: - xdg-portable: 7.3.0 - - xdg-portable@7.3.0: - dependencies: - os-paths: 4.4.0 - - xml-crypto@6.1.2: - dependencies: - '@xmldom/is-dom-node': 1.0.1 - '@xmldom/xmldom': 0.8.11 - xpath: 0.0.33 - - xml-escape@1.1.0: {} - - xml@1.0.1: {} - - xpath@0.0.32: {} - - xpath@0.0.33: {} - - xtend@4.0.2: {} - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yallist@4.0.0: {} - - yallist@5.0.0: {} - - yaml@2.8.2: {} - - 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 - - yauzl-clone@1.0.4: - dependencies: - events-intercept: 2.0.0 - - yauzl-promise@2.1.3: - dependencies: - yauzl: 2.10.0 - yauzl-clone: 1.0.4 - - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - yocto-queue@0.1.0: {} - - yocto-spinner@0.2.3: - dependencies: - yoctocolors: 2.1.2 - - yoctocolors@2.1.2: {} - - zeptomatch@2.1.0: - dependencies: - grammex: 3.1.12 - graphmatch: 1.1.1 - - zod@3.22.4: {} - - zod@4.3.6: {} - - zwitch@2.0.4: {} From 950705703d1ce3030b171bb37a282ab7d06dd9de Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Mon, 16 Mar 2026 08:23:36 -0700 Subject: [PATCH 03/10] fix: git-setup --- packages/cli/src/commands/create-repo.ts | 37 +++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/commands/create-repo.ts b/packages/cli/src/commands/create-repo.ts index 0812adf9..b71f2e1b 100644 --- a/packages/cli/src/commands/create-repo.ts +++ b/packages/cli/src/commands/create-repo.ts @@ -243,16 +243,45 @@ export const createRepoCommand = new Command("create") const defaultBranch = repo.data.defaultBranch || "main"; if (shouldInit) { - execSync(`git init -b "${defaultBranch}"`, { cwd: path }); + try { + execSync(`git init -b "${defaultBranch}"`, { cwd: path }); + } catch (error) { + log.error(`Failed to initialize Git repository: ${error}`); + process.exit(1); + } gitCLIDetails.push(pc.dim("✓ Initialized Git repository")); } else { gitCLIDetails.push(pc.dim("→ Using existing Git repository")); } if (repo.data.remoteURL) { - execSync(`cd ${path} && git remote add better-hub ${repo.data.remoteURL}`, { - cwd: path, - }); + try { + execSync( + `cd ${path} && git remote add better-hub ${repo.data.remoteURL}`, + { + cwd: path, + }, + ); + } catch (error) { + log.error(`Failed to add remote repository: ${error}`); + process.exit(1); + } + try { + execSync(`git config remote.pushDefault better-hub`, { + cwd: path, + }); + } catch (error) { + log.error(`Failed to set remote.pushDefault: ${error}`); + process.exit(1); + } + try { + execSync(`git config push.autoSetupRemote true`, { + cwd: path, + }); + } catch (error) { + log.error(`Failed to set push.autoSetupRemote: ${error}`); + process.exit(1); + } gitCLIDetails.push(pc.dim("✓ Registered remote repository")); } else { gitCLIDetails.push( From a8f7fa97e6214d533db3aec9baf15e1f4c847625 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Mon, 16 Mar 2026 09:22:34 -0700 Subject: [PATCH 04/10] fix: make real commits --- packages/cli/src/commands/commit.ts | 237 ++++++++++++++++++++++------ 1 file changed, 185 insertions(+), 52 deletions(-) diff --git a/packages/cli/src/commands/commit.ts b/packages/cli/src/commands/commit.ts index 90ae1015..fabb31d3 100644 --- a/packages/cli/src/commands/commit.ts +++ b/packages/cli/src/commands/commit.ts @@ -4,7 +4,6 @@ import { requireAuth } from "../lib/client.js"; import { cancel, confirm, - intro, isCancel, log, multiselect, @@ -17,6 +16,86 @@ import { } from "@clack/prompts"; import { betterHubIntro } from "../lib/intro.js"; import { sleep } from "../lib/utils.js"; +import { execSync, execFileSync, spawn } from "child_process"; + +let _repoRoot: string | undefined; +function repoRoot(): string { + if (!_repoRoot) { + _repoRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim(); + } + return _repoRoot; +} + +function git(cmd: string): string { + return execSync(`git ${cmd}`, { encoding: "utf-8", cwd: repoRoot() }).trim(); +} + +type FileStatus = "modified" | "added" | "deleted" | "renamed"; + +interface ChangedFile { + raw: string; + status: FileStatus; + diff: { additions: number; deletions: number } | null; +} + +function getChangedFiles(): ChangedFile[] { + const porcelain = execSync("git status --porcelain", { + encoding: "utf-8", + cwd: repoRoot(), + }).trimEnd(); + if (!porcelain) return []; + + const numstat = new Map(); + for (const cmd of ["diff --numstat", "diff --cached --numstat"]) { + try { + const output = git(cmd); + if (!output) continue; + for (const line of output.split("\n").filter(Boolean)) { + const [add, del, ...rest] = line.split("\t"); + const file = rest.join("\t"); + const additions = parseInt(add!) || 0; + const deletions = parseInt(del!) || 0; + const existing = numstat.get(file); + if (existing) { + existing.additions += additions; + existing.deletions += deletions; + } else { + numstat.set(file, { additions, deletions }); + } + } + } catch {} + } + + const files: ChangedFile[] = []; + for (const line of porcelain.split("\n").filter(Boolean)) { + const xy = line.slice(0, 2); + const rest = line.slice(3); + + let status: FileStatus; + if (xy.includes("?")) status = "added"; + else if (xy.includes("A")) status = "added"; + else if (xy.includes("D")) status = "deleted"; + else if (xy.includes("R")) status = "renamed"; + else status = "modified"; + + const filePath = rest.includes(" -> ") ? rest.split(" -> ")[1]! : rest; + files.push({ + raw: filePath, + status, + diff: numstat.get(filePath) ?? null, + }); + } + + return files; +} + +function getCurrentBranch(): string { + try { + return git("branch --show-current"); + } catch { + return git("rev-parse --short HEAD"); + } +} export const commitCommand = new Command("commit") .alias("push") @@ -30,31 +109,16 @@ export const commitCommand = new Command("commit") .action(async (opts: { message?: string | boolean; all?: boolean; push?: boolean }) => { requireAuth(); betterHubIntro("Commit & Push"); - const fakeFiles: { - raw: string; - status: "modified" | "added" | "deleted" | "renamed"; - diff: { additions: number; deletions: number } | null; - }[] = [ - { - raw: "src/lib/auth.ts", - status: "modified", - diff: { additions: 10, deletions: 5 }, - }, - { - raw: "src/components/navbar.tsx", - status: "modified", - diff: { additions: 10, deletions: 5 }, - }, - { raw: "src/app/settings/page.tsx", status: "added", diff: null }, - { - raw: "src/utils/format.ts", - status: "modified", - diff: { additions: 10, deletions: 5 }, - }, - { raw: "tests/auth.test.ts", status: "deleted", diff: null }, - ]; - - const maxLen = Math.max(...fakeFiles.map((f) => f.raw.length)); + + const changedFiles = getChangedFiles(); + if (changedFiles.length === 0) { + log.warn("No changes to commit."); + outro(pc.dim("Nothing to do.")); + return; + } + + const branch = getCurrentBranch(); + const maxLen = Math.max(...changedFiles.map((f) => f.raw.length)); const statusColor = (s: string) => { if (s === "added") return pc.green(s); @@ -62,10 +126,7 @@ export const commitCommand = new Command("commit") return pc.yellowBright(s); }; - const formatPath = ( - raw: string, - status: "modified" | "added" | "deleted" | "renamed", - ) => { + const formatPath = (raw: string, status: FileStatus) => { const sep = raw.lastIndexOf("/"); const dir = raw.slice(0, sep + 1); const file = raw.slice(sep + 1); @@ -95,14 +156,14 @@ export const commitCommand = new Command("commit") }; log.info( - `${pc.dim("On branch")} ${pc.cyan("feat/custom-storage")} ${pc.dim("· 5 changed files")}`, + `${pc.dim("On branch")} ${pc.cyan(branch)} ${pc.dim(`· ${changedFiles.length} changed file(s)`)}`, ); const staged = opts.all ? (() => { log.step("Staging all changed files:"); const logs: string[] = []; - for (const f of fakeFiles) { + for (const f of changedFiles) { const padding = " ".repeat( maxLen - f.raw.length + 2, ); @@ -116,11 +177,11 @@ export const commitCommand = new Command("commit") ); } log.message(logs.join("\n")); - return fakeFiles.map((f) => f.raw); + return changedFiles.map((f) => f.raw); })() : await multiselect({ message: "Select files to stage:", - options: fakeFiles.map((f) => { + options: changedFiles.map((f) => { const padding = " ".repeat( maxLen - f.raw.length + 2, ); @@ -133,7 +194,7 @@ export const commitCommand = new Command("commit") value: f.raw, }; }), - initialValues: fakeFiles.map((x) => x.raw), + initialValues: changedFiles.map((x) => x.raw), }); if (isCancel(staged)) { @@ -184,12 +245,31 @@ export const commitCommand = new Command("commit") shouldPush = answer; } - const shortHash = Math.random().toString(16).slice(2, 9); + const selectedFiles = staged as string[]; + try { + execFileSync("git", ["add", "--", ...selectedFiles], { cwd: repoRoot() }); + } catch (e) { + log.error(`Failed to stage files: ${(e as Error).message}`); + process.exit(1); + } + + try { + execFileSync("git", ["commit", "-m", commitMsg], { cwd: repoRoot() }); + } catch (e) { + log.error(`Commit failed: ${(e as Error).message}`); + process.exit(1); + } + + const shortHash = git("rev-parse --short HEAD"); + let diffSummary: string; + try { + diffSummary = git('show --shortstat --format=""'); + } catch { + diffSummary = `${selectedFiles.length} file(s) changed`; + } log.success(`Committed ${pc.bold(shortHash)} ${pc.dim("→")} ${pc.cyan(commitMsg)}`); - log.message( - `${pc.dim(`${(staged as string[]).length} file(s) changed, 47 insertions(+), 12 deletions(-)`)}`, - ); + log.message(pc.dim(diffSummary)); if (!shouldPush) { outro(pc.green("Done!")); @@ -197,19 +277,72 @@ export const commitCommand = new Command("commit") } const p = progress({ max: 100 }); - p.start(`Pushing to ${pc.cyan("origin/feat/custom-storage")}`); - await sleep(800); - p.advance(15, "Enumerating objects..."); - await sleep(600); - p.advance(30, "Counting objects..."); - await sleep(700); - p.advance(50, "Compressing objects..."); - await sleep(800); - p.advance(70, "Writing objects..."); - await sleep(900); - p.advance(90, "Resolving deltas..."); - await sleep(600); - p.stop(`${pc.green("✓")} Pushed to ${pc.cyan("origin/feat/custom-storage")}`); + p.start(`Pushing to ${pc.cyan(`better-hub/${branch}`)}`); + + try { + await new Promise((resolve, reject) => { + const child = spawn( + "git", + ["push", "-u", "better-hub", "HEAD", "--progress"], + { + cwd: repoRoot(), + }, + ); + let stderr = ""; + + const STAGES: [RegExp, number, string][] = [ + [/enumerating objects/i, 10, "Enumerating objects..."], + [/counting objects/i, 25, "Counting objects..."], + [/compressing objects/i, 45, "Compressing objects..."], + [/writing objects/i, 65, "Writing objects..."], + [/resolving deltas/i, 85, "Resolving deltas..."], + [/remote:/i, 92, "Remote processing..."], + ]; + let reached = 0; + + const advance = (chunk: string) => { + for (const [pattern, pct, label] of STAGES) { + if (pct > reached && pattern.test(chunk)) { + reached = pct; + p.advance(pct, label); + } + } + }; + + child.stderr.on("data", (data: Buffer) => { + const text = data.toString(); + stderr += text; + advance(text); + }); + + child.stdout.on("data", (data: Buffer) => { + advance(data.toString()); + }); + + child.on("close", (code) => { + if (code === 0) { + p.advance(100, "Done"); + resolve(); + } else { + reject( + new Error( + stderr || + `git push exited with code ${code}`, + ), + ); + } + }); + + child.on("error", reject); + }); + + p.stop(`${pc.green("✓")} Pushed to ${pc.cyan(`better-hub/${branch}`)}`); + } catch (e) { + p.stop(`${pc.red("✗")} Push failed`); + log.error((e as Error).message); + process.exit(1); + } + log.info(`${pc.bold("Running Actions")} ${pc.dim("— watching CI run...")}`); await streamCIResults(); From f6d935df9ddaf222f76004ec49f5f6c26213b8ca Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Tue, 17 Mar 2026 17:41:54 -0700 Subject: [PATCH 05/10] add: status, clone & config commands --- bun.lock | 15 +- packages/cli/package.json | 3 +- packages/cli/src/commands/cd.ts | 68 +- packages/cli/src/commands/clone.ts | 401 ++++++++++++ packages/cli/src/commands/commit.ts | 37 +- packages/cli/src/commands/config.ts | 251 +++++++ packages/cli/src/commands/delete.ts | 21 +- packages/cli/src/commands/status.ts | 727 +++++++++++++++++++++ packages/cli/src/index.ts | 6 + packages/cli/src/lib/preferences.ts | 53 ++ packages/cli/src/lib/repo-registry.ts | 27 +- packages/storage/src/adapter.ts | 12 +- packages/storage/src/client.ts | 1 + packages/storage/src/lib/parse-slug.ts | 22 + packages/storage/src/plugin.ts | 8 +- packages/storage/src/routes/clone-repo.ts | 77 +++ packages/storage/src/routes/create-repo.ts | 13 +- packages/storage/src/zod-schema.ts | 4 + 18 files changed, 1709 insertions(+), 37 deletions(-) create mode 100644 packages/cli/src/commands/clone.ts create mode 100644 packages/cli/src/commands/config.ts create mode 100644 packages/cli/src/commands/status.ts create mode 100644 packages/cli/src/lib/preferences.ts create mode 100644 packages/storage/src/routes/clone-repo.ts diff --git a/bun.lock b/bun.lock index 04653a9f..20408be6 100644 --- a/bun.lock +++ b/bun.lock @@ -111,6 +111,7 @@ "fzf": "^0.5.2", "open": "^11.0.0", "picocolors": "^1.1.1", + "terminal-link": "^5.0.0", }, "devDependencies": { "@types/node": "^25.3.0", @@ -2004,7 +2005,7 @@ "graphmatch": ["graphmatch@1.1.1", "", {}, "sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg=="], - "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-flag": ["has-flag@5.0.1", "", {}, "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA=="], "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], @@ -2780,7 +2781,9 @@ "supermemory": ["supermemory@4.15.0", "", {}, "sha512-FNBBOEi1HMvbBecXC6gn84nGy7ZEdFW5kLv7VlWirHDPEM08omBBBHQ7H2cwBIGWUenBMDaao3kPKe9W6Ki+UQ=="], - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + + "supports-hyperlinks": ["supports-hyperlinks@4.4.0", "", { "dependencies": { "has-flag": "^5.0.1", "supports-color": "^10.2.2" } }, "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], @@ -2798,6 +2801,8 @@ "temporal-spec": ["temporal-spec@0.2.4", "", {}, "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ=="], + "terminal-link": ["terminal-link@5.0.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "supports-hyperlinks": "^4.1.0" } }, "sha512-qFAy10MTMwjzjU8U16YS4YoZD+NQLHzLssFMNqgravjbvIPNiqkGFR4yjhJfmY9R5OFU7+yHxc6y+uGHkKwLRA=="], + "terser": ["terser@5.46.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="], "terser-webpack-plugin": ["terser-webpack-plugin@5.3.16", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q=="], @@ -3748,6 +3753,10 @@ "gaxios/node-fetch/data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + "inngest/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "log-update/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -3786,6 +3795,8 @@ "@vercel/fun/semver/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "inngest/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 8dd87d24..c6fec319 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -26,7 +26,8 @@ "commander": "^13.1.0", "fzf": "^0.5.2", "open": "^11.0.0", - "picocolors": "^1.1.1" + "picocolors": "^1.1.1", + "terminal-link": "^5.0.0" }, "devDependencies": { "@types/node": "^25.3.0" diff --git a/packages/cli/src/commands/cd.ts b/packages/cli/src/commands/cd.ts index 01ab2655..365044a7 100644 --- a/packages/cli/src/commands/cd.ts +++ b/packages/cli/src/commands/cd.ts @@ -2,7 +2,12 @@ import { spawn } from "node:child_process"; import { Command } from "commander"; import pc from "picocolors"; import { select, isCancel, cancel, outro, log } from "@clack/prompts"; -import { fuzzyFindRepos, getRepoPath, listRegisteredRepos } from "../lib/repo-registry.js"; +import { + fuzzyFindRepos, + getRepoEntries, + listRegisteredRepos, + pruneStaleRepos, +} from "../lib/repo-registry.js"; import { betterHubIntro } from "../lib/intro.js"; export const cdCommand = new Command("cd") @@ -10,6 +15,14 @@ export const cdCommand = new Command("cd") .argument("[slug]", "Repository slug (org/name)") .action(async (slug?: string) => { betterHubIntro("Change Directory"); + + const pruned = pruneStaleRepos(); + if (pruned.length > 0) { + log.warn( + `Removed ${pruned.length} stale ${pruned.length === 1 ? "repo" : "repos"} (path no longer exists): ${pruned.map((r) => pc.dim(r.slug)).join(", ")}`, + ); + } + if (!slug) { const repos = listRegisteredRepos(); if (!repos.length) { @@ -24,7 +37,7 @@ export const cdCommand = new Command("cd") const segments = r.slug.split("/"); return { label: `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))} ${pc.dim(r.path)}`, - value: r.slug, + value: { slug: r.slug, path: r.path } as const, }; }), }); @@ -34,10 +47,41 @@ export const cdCommand = new Command("cd") process.exit(0); } - slug = selected; + const segments = selected.slug.split("/"); + outro( + pc.green(`${pc.bold("Directory changed to")}`) + + " " + + `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))}`, + ); + + spawn(process.env["SHELL"]!, { + stdio: "inherit", + cwd: selected.path, + }); + return; } - let repoPath = getRepoPath(slug); + let repoPath: string | null = null; + + const exactEntries = getRepoEntries(slug); + if (exactEntries.length === 1) { + repoPath = exactEntries[0]!.path; + } else if (exactEntries.length > 1) { + const selected = await select({ + message: `Multiple clones of "${slug}":`, + options: exactEntries.map((e) => ({ + label: `${pc.cyan(e.slug)} ${pc.dim(e.path)}`, + value: e.path, + })), + }); + + if (isCancel(selected)) { + cancel("Operation cancelled."); + process.exit(0); + } + + repoPath = selected; + } if (!repoPath) { const matches = fuzzyFindRepos(slug); @@ -62,13 +106,10 @@ export const cdCommand = new Command("cd") } else { const selected = await select({ message: `Multiple repos match "${slug}":`, - options: matches.map((m) => { - const segments = m.entry.slug.split("/"); - return { - label: `${pc.cyan(segments[0]! + "/")}${pc.cyan(pc.bold(segments[1]!))} ${pc.dim(m.entry.path)}`, - value: m.entry.slug, - }; - }), + options: matches.map((m) => ({ + label: `${pc.cyan(m.entry.slug)} ${pc.dim(m.entry.path)}`, + value: m.entry.path, + })), }); if (isCancel(selected)) { @@ -76,8 +117,9 @@ export const cdCommand = new Command("cd") process.exit(0); } - slug = selected; - repoPath = getRepoPath(slug)!; + repoPath = selected; + const match = matches.find((m) => m.entry.path === selected); + if (match) slug = match.entry.slug; } } diff --git a/packages/cli/src/commands/clone.ts b/packages/cli/src/commands/clone.ts new file mode 100644 index 00000000..1360feac --- /dev/null +++ b/packages/cli/src/commands/clone.ts @@ -0,0 +1,401 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import { requireAuth } from "../lib/client.js"; +import { getAuthClient } from "../lib/auth-client.js"; +import { + cancel, + confirm, + isCancel, + log, + outro, + progress, + select, + spinner, + text, +} from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { registerRepo } from "../lib/repo-registry.js"; +import { getBaseUrl } from "../lib/config.js"; +import { spawn, execSync } from "node:child_process"; +import { resolve, isAbsolute, basename } from "node:path"; +import { existsSync, mkdirSync, readdirSync } from "node:fs"; + +function repoSegment(slug: string): string { + const parts = slug.split("/"); + return parts[1] ?? parts[0]!; +} + +function isDirEmpty(path: string): boolean { + try { + return readdirSync(path).length === 0; + } catch { + return false; + } +} + +async function promptDir(cwd: string, segment: string): Promise { + const customPath = await text({ + message: `Directory path ${pc.dim("(relative or absolute)")}:`, + placeholder: `./${segment}`, + validate(value) { + if (!value?.trim()) return "Path is required"; + const resolved = isAbsolute(value) ? resolve(value) : resolve(cwd, value); + if (existsSync(resolved) && !isDirEmpty(resolved)) { + return `Directory is not empty: ${resolved}`; + } + }, + }); + + if (isCancel(customPath)) { + cancel("Operation cancelled."); + process.exit(0); + } + + return isAbsolute(customPath) ? resolve(customPath) : resolve(cwd, customPath); +} + +export const cloneCommand = new Command("clone") + .description("Clone a Better Hub repository") + .argument("[slug]", "Repository slug (owner/repo)") + .option("-d, --dir ", "Target directory") + .action(async (slug?: string, opts?: { dir?: string }) => { + requireAuth(); + const authClient = getAuthClient(); + const session = await authClient.getSession(); + + if (session.error) { + outro(pc.red(`Failed to get session: ${session.error.message}`)); + process.exit(1); + } + if (!session.data) { + outro(pc.red("Not logged in. Run `better-hub auth login` first.")); + process.exit(1); + } + + betterHubIntro("Clone"); + + const s = spinner({}); + s.start("Fetching repositories..."); + + const repos = await authClient.storage.listRepo(); + if (repos.error) { + s.stop(`${pc.bold("Failed to fetch repositories")} ${pc.red("✗")}`); + outro(pc.red(repos.error.message)); + process.exit(1); + } + if (!repos.data?.length) { + s.stop(`${pc.bold("No repositories found")} ${pc.red("✗")}`); + outro(pc.dim("Create one with `bh create`.")); + process.exit(0); + } + + s.stop( + `${pc.bold(`${repos.data.length} ${repos.data.length === 1 ? "repository" : "repositories"}`)} ${pc.green("✓")}`, + ); + + let repo: (typeof repos.data)[number] | undefined; + + if (slug) { + repo = repos.data.find( + (r) => r.slug === slug || r.slug.endsWith(`/${slug}`), + ); + if (!repo) { + log.error(`Repository ${pc.bold(slug)} not found.`); + log.message( + pc.dim("Available repositories:\n") + + repos.data + .map((r) => ` ${pc.cyan(r.slug)}`) + .join("\n"), + ); + process.exit(1); + } + } else { + const maxName = Math.max(...repos.data.map((r) => r.name.length)); + const selected = await select({ + message: "Select a repository to clone:", + options: repos.data.map((r) => { + const visibility = + r.visibility === "private" + ? pc.yellow("private") + : pc.green("public"); + return { + label: `${pc.bold(r.name.padEnd(maxName))} ${pc.dim(r.slug)} ${visibility}`, + value: r.slug, + }; + }), + }); + + if (isCancel(selected)) { + cancel("Operation cancelled."); + process.exit(0); + } + + repo = repos.data.find((r) => r.slug === selected)!; + } + + slug = repo.slug; + const segment = repoSegment(slug); + + // ── Fetch clone URL ────────────────────────────── + const cloneSpinner = spinner({}); + cloneSpinner.start(`Resolving remote for ${pc.cyan(slug)}...`); + + const cloneInfo = await authClient.storage.cloneRepo({ + slug: slug as `${string}/${string}`, + }); + if (cloneInfo.error) { + cloneSpinner.stop(`${pc.bold("Failed to resolve remote")} ${pc.red("✗")}`); + log.error( + cloneInfo.error.message ?? + "Could not get clone URL for this repository.", + ); + process.exit(1); + } + + const { remoteURL, defaultBranch } = cloneInfo.data; + cloneSpinner.stop(`${pc.bold("Remote resolved")} ${pc.green("✓")}`); + + // ── Target directory ───────────────────────────── + let targetDir: string; + const cwd = process.cwd(); + const cwdEmpty = isDirEmpty(cwd); + + if (opts?.dir) { + const resolved = isAbsolute(opts.dir) + ? resolve(opts.dir) + : resolve(cwd, opts.dir); + if (existsSync(resolved) && !isDirEmpty(resolved)) { + log.error( + `Directory ${pc.bold(basename(resolved))} is not empty at ${pc.dim(resolved)}`, + ); + process.exit(1); + } + targetDir = resolved; + } else if (cwdEmpty) { + const cloneHere = await confirm({ + message: `Current directory is empty. Clone into ${pc.cyan(`.`)} ${pc.dim(`(${cwd})`)}?`, + initialValue: true, + }); + + if (isCancel(cloneHere)) { + cancel("Operation cancelled."); + process.exit(0); + } + + if (cloneHere) { + targetDir = cwd; + } else { + targetDir = await promptDir(cwd, segment); + } + } else { + const defaultDir = resolve(cwd, segment); + const useDefault = await confirm({ + message: `Clone into ${pc.cyan(`./${segment}`)}?`, + initialValue: true, + }); + + if (isCancel(useDefault)) { + cancel("Operation cancelled."); + process.exit(0); + } + + if (useDefault) { + targetDir = defaultDir; + } else { + targetDir = await promptDir(cwd, segment); + } + } + + if (existsSync(targetDir) && !isDirEmpty(targetDir)) { + log.error( + `Directory ${pc.bold(basename(targetDir))} is not empty at ${pc.dim(targetDir)}`, + ); + process.exit(1); + } + + if (!existsSync(targetDir)) { + const parentDir = resolve(targetDir, ".."); + if (!existsSync(parentDir)) { + mkdirSync(parentDir, { recursive: true }); + } + } + + // ── Clone ──────────────────────────────────────── + const baseUrl = getBaseUrl(); + + log.info( + `${pc.dim("Cloning")} ${pc.cyan(slug)} ${pc.dim("→")} ${pc.white(targetDir)}`, + ); + + const p = progress({ max: 100 }); + p.start(`Cloning ${pc.cyan(slug)}`); + + try { + await new Promise((resolve, reject) => { + const child = spawn( + "git", + ["clone", "--progress", remoteURL, targetDir], + { stdio: ["ignore", "pipe", "pipe"] }, + ); + + let stderr = ""; + + const STAGES: [RegExp, number, string][] = [ + [/cloning into/i, 5, "Initializing..."], + [/enumerating objects/i, 10, "Enumerating objects..."], + [/counting objects/i, 25, "Counting objects..."], + [/compressing objects/i, 40, "Compressing objects..."], + [/receiving objects/i, 55, "Receiving objects..."], + [/resolving deltas/i, 75, "Resolving deltas..."], + [/checking out files/i, 90, "Checking out files..."], + ]; + let reached = 0; + + const advance = (chunk: string) => { + for (const [pattern, pct, label] of STAGES) { + if (pct > reached && pattern.test(chunk)) { + reached = pct; + p.advance(pct, label); + } + } + + const pctMatch = chunk.match(/(\d+)%/); + if (pctMatch) { + const parsed = parseInt(pctMatch[1]!); + const scaled = Math.min( + 95, + reached + + Math.floor( + ((parsed / 100) * + (100 - reached)) / + 5, + ), + ); + if (scaled > reached) { + reached = scaled; + p.advance(reached); + } + } + }; + + child.stderr.on("data", (data: Buffer) => { + const text = data.toString(); + stderr += text; + advance(text); + }); + + child.stdout.on("data", (data: Buffer) => { + advance(data.toString()); + }); + + child.on("close", (code) => { + if (code === 0) { + p.advance(100, "Done"); + resolve(); + } else { + reject( + new Error( + stderr.trim() || + `git clone exited with code ${code}`, + ), + ); + } + }); + + child.on("error", reject); + }); + + p.stop(`${pc.green("✓")} Cloned ${pc.cyan(slug)}`); + } catch (e) { + p.stop(`${pc.red("✗")} Clone failed`); + log.error((e as Error).message); + process.exit(1); + } + + // ── Set up Better Hub ──────────────────────────── + log.info(`${pc.bold("Setting up Better Hub")}`); + const setupDetails: string[] = []; + + try { + const existingRemotes = execSync("git remote", { + cwd: targetDir, + encoding: "utf-8", + }).trim(); + + if (!existingRemotes.includes("better-hub")) { + execSync(`git remote add better-hub ${remoteURL}`, { + cwd: targetDir, + }); + setupDetails.push(pc.dim("✓ Added better-hub remote")); + } else { + execSync(`git remote set-url better-hub ${remoteURL}`, { + cwd: targetDir, + }); + setupDetails.push(pc.dim("✓ Updated better-hub remote URL")); + } + } catch (error) { + setupDetails.push( + pc.yellow( + `⚠ Could not configure remote: ${(error as Error).message}`, + ), + ); + } + + try { + execSync("git config remote.pushDefault better-hub", { + cwd: targetDir, + }); + setupDetails.push(pc.dim("✓ Set remote.pushDefault to better-hub")); + } catch { + setupDetails.push(pc.yellow("⚠ Could not set remote.pushDefault")); + } + + try { + execSync("git config push.autoSetupRemote true", { + cwd: targetDir, + }); + setupDetails.push(pc.dim("✓ Enabled push.autoSetupRemote")); + } catch { + setupDetails.push(pc.yellow("⚠ Could not set push.autoSetupRemote")); + } + + log.message(setupDetails.join("\n")); + + registerRepo(slug, targetDir); + setupDetails.push(pc.dim("✓ Registered in local repo registry")); + + // ── Summary ────────────────────────────────────── + log.info( + [ + `${pc.bold(pc.white(repo.name))}`, + repo.description ? `${pc.gray(repo.description)}` : null, + "", + `${pc.dim("→")} ${pc.yellow(` ${slug}`)}`, + `${pc.dim("→")} ${pc.magenta(`⎇ ${defaultBranch}`)}`, + `${pc.dim("→")} ${pc.cyan(pc.underline(`${baseUrl}/${slug}`))}`, + `${pc.dim("→")} ${pc.white(targetDir)}`, + ] + .filter((x) => !(x !== "" && !x)) + .join("\n"), + ); + + const commands: [string, string][] = [ + [`cd ${targetDir}`, "Navigate to the repository"], + ["bh status", "View working tree status"], + ["bh push", "Stage, commit & push your changes"], + [`bh cd ${segment}`, "Quick-navigate to this repo later"], + ]; + + const maxCmd = Math.max(...commands.map(([cmd]) => cmd.length)); + log.info(`${pc.bold("Next steps")}`); + log.message( + commands + .map( + ([cmd, desc]) => + `${pc.dim("$")} ${pc.cyan(cmd.padEnd(maxCmd))} ${pc.dim(desc)}`, + ) + .join("\n"), + ); + + outro(pc.green("Repository cloned successfully!")); + }); diff --git a/packages/cli/src/commands/commit.ts b/packages/cli/src/commands/commit.ts index fabb31d3..0cd345ba 100644 --- a/packages/cli/src/commands/commit.ts +++ b/packages/cli/src/commands/commit.ts @@ -119,6 +119,13 @@ export const commitCommand = new Command("commit") const branch = getCurrentBranch(); const maxLen = Math.max(...changedFiles.map((f) => f.raw.length)); + const maxStatusLen = Math.max(...changedFiles.map((f) => f.status.length)); + const maxAddLen = Math.max( + ...changedFiles.map((f) => (f.diff ? `+${f.diff.additions}`.length : 0)), + ); + const maxDelLen = Math.max( + ...changedFiles.map((f) => (f.diff ? `-${f.diff.deletions}`.length : 0)), + ); const statusColor = (s: string) => { if (s === "added") return pc.green(s); @@ -167,13 +174,24 @@ export const commitCommand = new Command("commit") const padding = " ".repeat( maxLen - f.raw.length + 2, ); + const statusPad = " ".repeat( + maxStatusLen - f.status.length, + ); let diff = ""; if (f.diff) { - diff = ` ${pc.dim(pc.green(`+${f.diff.additions}`) + " " + `${pc.red(`-${f.diff.deletions}`)}`)}`; + const addStr = + `+${f.diff.additions}`.padStart( + maxAddLen, + ); + const delStr = + `-${f.diff.deletions}`.padStart( + maxDelLen, + ); + diff = ` ${pc.dim(pc.green(addStr) + " " + pc.red(delStr))}`; } logs.push( - ` ${formatPath(f.raw, f.status)}${padding}${pc.dim(`${statusColor(f.status)}${diff}`)}`, + ` ${formatPath(f.raw, f.status)}${padding}${pc.dim(statusColor(f.status))}${statusPad} ${diff}`, ); } log.message(logs.join("\n")); @@ -185,12 +203,23 @@ export const commitCommand = new Command("commit") const padding = " ".repeat( maxLen - f.raw.length + 2, ); + const statusPad = " ".repeat( + maxStatusLen - f.status.length, + ); let diff = ""; if (f.diff) { - diff = ` ${pc.dim(pc.green(`+${f.diff.additions}`) + " " + `${pc.red(`-${f.diff.deletions}`)}`)}`; + const addStr = + `+${f.diff.additions}`.padStart( + maxAddLen, + ); + const delStr = + `-${f.diff.deletions}`.padStart( + maxDelLen, + ); + diff = ` ${pc.dim(pc.green(addStr) + " " + pc.red(delStr))}`; } return { - label: `${formatPath(f.raw, f.status)}${padding}${pc.dim(`${statusColor(f.status)}${diff}`)}`, + label: `${formatPath(f.raw, f.status)}${padding} ${pc.dim(statusColor(f.status))}${statusPad} ${diff}`, value: f.raw, }; }), diff --git a/packages/cli/src/commands/config.ts b/packages/cli/src/commands/config.ts new file mode 100644 index 00000000..d5851d1d --- /dev/null +++ b/packages/cli/src/commands/config.ts @@ -0,0 +1,251 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import open from "open"; +import { cancel, confirm, isCancel, log, outro, select } from "@clack/prompts"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { betterHubIntro } from "../lib/intro.js"; +import { + type Preferences, + getPreferences, + preferenceDefaults, + resetPreferences, + setPreference, +} from "../lib/preferences.js"; + +interface PreferenceEntry { + key: keyof Preferences; + label: string; + description: string; + type: "boolean"; +} + +const PREFERENCE_ENTRIES: PreferenceEntry[] = [ + { + key: "showRecentCommits", + label: "Show recent commits", + description: "Display the last 3 commits in bh status output", + type: "boolean", + }, +]; + +function findEntry(key: string): PreferenceEntry | undefined { + return PREFERENCE_ENTRIES.find( + (e) => e.key === key || e.key.toLowerCase() === key.toLowerCase(), + ); +} + +function parseBooleanValue(raw: string): boolean | null { + const v = raw.toLowerCase(); + if (["true", "on", "1", "yes"].includes(v)) return true; + if (["false", "off", "0", "no"].includes(v)) return false; + return null; +} + +function formatValue(value: unknown, type: "boolean"): string { + if (type === "boolean") { + return value ? pc.green("on") : pc.red("off"); + } + return String(value); +} + +function printAllPreferences() { + const prefs = getPreferences(); + const defaults = preferenceDefaults(); + const maxKey = Math.max(...PREFERENCE_ENTRIES.map((e) => e.key.length)); + + console.log(); + for (const entry of PREFERENCE_ENTRIES) { + const val = prefs[entry.key]; + const isDefault = val === defaults[entry.key]; + const pad = " ".repeat(maxKey - entry.key.length + 2); + console.log( + ` ${pc.bold(entry.key)}${pad}${formatValue(val, entry.type)}${isDefault ? pc.dim(" (default)") : ""} ${pc.dim(entry.description)}`, + ); + } + console.log(); +} + +function preferencesMenu(prefs: Preferences) { + const options = PREFERENCE_ENTRIES.map((entry) => ({ + value: entry.key as string, + label: `${entry.label} ${pc.dim("·")} ${formatValue(prefs[entry.key], entry.type)}`, + hint: entry.description, + })); + + options.push( + { + value: "_reset", + label: pc.yellow("Reset all to defaults"), + hint: "Restore factory settings", + }, + { + value: "_done", + label: pc.dim("Done"), + hint: "Exit settings", + }, + ); + + return options; +} + +function availableKeysHelp(): string { + const maxKey = Math.max(...PREFERENCE_ENTRIES.map((e) => e.key.length)); + const lines = PREFERENCE_ENTRIES.map((e) => { + const pad = " ".repeat(maxKey - e.key.length + 2); + const typeTag = e.type === "boolean" ? pc.yellow("boolean") : pc.yellow("string"); + return ` ${pc.cyan(e.key)}${pad}${typeTag} ${pc.dim(e.description)}`; + }); + return `\n${pc.bold("Available keys:")}\n${lines.join("\n")}\n\n${pc.bold("Commands:")}\n ${pc.cyan("explore")} ${pc.dim("Open the config directory (~/.better-hub) in your file explorer")}\n`; +} + +export const configCommand = new Command("config") + .alias("settings") + .description("Configure Better Hub CLI preferences") + .argument("[key]", "Preference key to get or set") + .argument("[value]", "Value to set (booleans: true/false/on/off)") + .option("-l, --list", "List all preferences and their current values") + .addHelpText("after", availableKeysHelp()) + .action(async (key?: string, value?: string, opts?: { list?: boolean }) => { + if (key === "explore") { + const configDir = join(homedir(), ".better-hub"); + console.log(); + console.log(` ${pc.dim("Opening")} ${pc.cyan(configDir)}`); + console.log(); + await open(configDir); + return; + } + + if (opts?.list) { + printAllPreferences(); + return; + } + + if (key && value !== undefined) { + const entry = findEntry(key); + if (!entry) { + console.log(); + console.log(` ${pc.red("✗")} Unknown preference ${pc.bold(key)}`); + console.log( + ` ${pc.dim("Available keys:")} ${PREFERENCE_ENTRIES.map((e) => pc.cyan(e.key)).join(", ")}`, + ); + console.log(); + process.exit(1); + } + + if (entry.type === "boolean") { + const parsed = parseBooleanValue(value); + if (parsed === null) { + console.log(); + console.log( + ` ${pc.red("✗")} Invalid boolean value ${pc.bold(value)}`, + ); + console.log( + ` ${pc.dim("Use:")} true, false, on, off, 1, 0, yes, no`, + ); + console.log(); + process.exit(1); + } + setPreference(entry.key, parsed); + console.log(); + console.log( + ` ${pc.green("✓")} ${pc.bold(entry.key)} set to ${formatValue(parsed, "boolean")}`, + ); + console.log(); + } + return; + } + + if (key) { + const entry = findEntry(key); + if (!entry) { + console.log(); + console.log(` ${pc.red("✗")} Unknown preference ${pc.bold(key)}`); + console.log( + ` ${pc.dim("Available keys:")} ${PREFERENCE_ENTRIES.map((e) => pc.cyan(e.key)).join(", ")}`, + ); + console.log(); + process.exit(1); + } + + const prefs = getPreferences(); + const defaults = preferenceDefaults(); + const val = prefs[entry.key]; + const isDefault = val === defaults[entry.key]; + console.log(); + console.log( + ` ${pc.bold(entry.key)} ${formatValue(val, entry.type)}${isDefault ? pc.dim(" (default)") : ""}`, + ); + console.log(` ${pc.dim(entry.description)}`); + console.log(); + return; + } + + betterHubIntro("Settings"); + + let prefs = getPreferences(); + + while (true) { + const choice = await select({ + message: "Configure a setting", + options: preferencesMenu(prefs), + }); + + if (isCancel(choice)) { + cancel("Settings closed."); + return; + } + + if (choice === "_done") { + break; + } + + if (choice === "_reset") { + const sure = await confirm({ + message: "Reset all preferences to defaults?", + initialValue: false, + }); + + if (isCancel(sure)) { + cancel("Settings closed."); + return; + } + + if (sure) { + resetPreferences(); + prefs = getPreferences(); + log.success("All preferences reset to defaults."); + } + continue; + } + + const entry = PREFERENCE_ENTRIES.find((e) => e.key === choice); + if (!entry) continue; + + if (entry.type === "boolean") { + const current = prefs[entry.key] as boolean; + const result = await confirm({ + message: entry.label, + active: "on", + inactive: "off", + initialValue: current, + }); + + if (isCancel(result)) { + cancel("Settings closed."); + return; + } + + setPreference(entry.key, result); + prefs = getPreferences(); + + const defaults = preferenceDefaults(); + const isDefault = prefs[entry.key] === defaults[entry.key]; + log.success( + `${pc.bold(entry.label)} set to ${formatValue(result, "boolean")}${isDefault ? pc.dim(" (default)") : ""}`, + ); + } + } + + outro(pc.dim("Settings saved.")); + }); diff --git a/packages/cli/src/commands/delete.ts b/packages/cli/src/commands/delete.ts index 8b84e66d..1dc22be3 100644 --- a/packages/cli/src/commands/delete.ts +++ b/packages/cli/src/commands/delete.ts @@ -3,7 +3,7 @@ import { requireAuth } from "../lib/client.js"; import { getAuthClient } from "../lib/auth-client.js"; import { cancel, confirm, isCancel, log, outro, select, spinner } from "@clack/prompts"; import { betterHubIntro } from "../lib/intro.js"; -import { getRepoPath, syncRegistry, unregisterRepo } from "../lib/repo-registry.js"; +import { getRepoEntries, syncRegistry, unregisterRepo } from "../lib/repo-registry.js"; import fs from "node:fs/promises"; import { existsSync } from "node:fs"; import { Command } from "commander"; @@ -111,24 +111,31 @@ export const deleteRepoCommand = new Command("delete") process.exit(1); } - const localPath = getRepoPath(targetRepo.slug); + const localEntries = getRepoEntries(targetRepo.slug).filter((e) => + existsSync(e.path), + ); unregisterRepo(targetRepo.slug); s.stop(`${pc.bold("Repository deleted")} ${pc.green("✓")}`); - if (localPath && existsSync(localPath)) { + for (const entry of localEntries) { const deleteLocal = await confirm({ - message: `Delete local files at ${pc.dim(localPath)}?`, + message: `Delete local files at ${pc.dim(entry.path)}?`, initialValue: false, active: pc.red("Yes"), inactive: pc.green("No"), }); - if (!isCancel(deleteLocal) && deleteLocal) { + if (isCancel(deleteLocal)) { + cancel("Skipped remaining local cleanup."); + break; + } + + if (deleteLocal) { const ds = spinner({}); ds.start("Removing local files..."); try { - await fs.rm(localPath, { recursive: true, force: true }); + await fs.rm(entry.path, { recursive: true, force: true }); ds.stop( `${pc.bold("Local files removed")} ${pc.green("✓")}`, ); @@ -137,7 +144,7 @@ export const deleteRepoCommand = new Command("delete") `${pc.bold("Failed to remove local files")} ${pc.red("✗")}`, ); log.error( - `Could not delete ${pc.dim(localPath)}: ${err instanceof Error ? err.message : String(err)}`, + `Could not delete ${pc.dim(entry.path)}: ${err instanceof Error ? err.message : String(err)}`, ); } } diff --git a/packages/cli/src/commands/status.ts b/packages/cli/src/commands/status.ts new file mode 100644 index 00000000..470ee8a0 --- /dev/null +++ b/packages/cli/src/commands/status.ts @@ -0,0 +1,727 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import terminalLink from "terminal-link"; +import { log, outro } from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { getBaseUrl } from "../lib/config.js"; +import { getPreference } from "../lib/preferences.js"; +import { execFileSync } from "child_process"; + +let _repoRoot: string | undefined; +function repoRoot(): string { + if (!_repoRoot) { + _repoRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], { + encoding: "utf-8", + }).trim(); + } + return _repoRoot; +} + +function git(...args: string[]): string { + return execFileSync("git", args, { + encoding: "utf-8", + cwd: repoRoot(), + stdio: "pipe", + }).trim(); +} + +function gitSafe(...args: string[]): string | null { + try { + return git(...args); + } catch { + return null; + } +} + +let _repoSlug: string | null | undefined; +function getRepoSlug(): string | null { + if (_repoSlug !== undefined) return _repoSlug; + let url: string | null = null; + try { + url = + gitSafe("remote", "get-url", "origin") ?? + gitSafe("remote", "get-url", "better-hub"); + } catch (error) { + if (!String(error).includes("No such remote")) { + log.error(`Failed to get remote URL: ${error}`); + } + } + if (!url) return (_repoSlug = null); + const match = url.match(/[/:]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/); + return (_repoSlug = match ? `${match[1]}/${match[2]}` : null); +} + +function commitUrl(hash: string): string | null { + const slug = getRepoSlug(); + return slug ? `${getBaseUrl()}/${slug}/commit/${hash}` : null; +} + +function authorUrl(author: string): string | null { + const slug = getRepoSlug(); + return slug ? `${getBaseUrl()}/${author.replace(/\s+/g, "")}` : null; +} + +function branchUrl(branch: string): string | null { + const slug = getRepoSlug(); + return slug ? `${getBaseUrl()}/${slug}/tree/${branch}` : null; +} + +function link(text: string, url: string | null): string { + if (!url) return text; + return terminalLink(text, url, { fallback: () => text }); +} + +// ─── Symbols ──────────────────────────────────────────────── +const SYM = { + staged: pc.green("●"), + modified: pc.yellow("●"), + untracked: pc.blue("?"), + deleted: pc.red("✗"), + renamed: pc.magenta("→"), + conflict: pc.red("⚡"), + added: pc.green("+"), + branch: pc.cyan("⎇"), + ahead: pc.green("↑"), + behind: pc.red("↓"), + commit: pc.dim("○"), + clean: pc.green("✓"), + dirty: pc.yellow("!"), + bar: { filled: "█", half: "▓", empty: "░" }, +} as const; + +// ─── Types ────────────────────────────────────────────────── +type FileCategory = "staged" | "unstaged" | "untracked" | "conflicted"; +type FileStatus = + | "modified" + | "added" + | "deleted" + | "renamed" + | "copied" + | "untracked" + | "conflicted"; + +interface StatusFile { + path: string; + origPath: string | undefined; + status: FileStatus; + category: FileCategory; + additions: number; + deletions: number; +} + +interface BranchInfo { + name: string; + upstream: string | null; + ahead: number; + behind: number; + detached: boolean; +} + +// ─── Git Parsing ──────────────────────────────────────────── + +function parseBranch(): BranchInfo { + const detachedHead = gitSafe("symbolic-ref", "--short", "HEAD") === null; + const name = detachedHead + ? git("rev-parse", "--short", "HEAD") + : git("branch", "--show-current"); + + let upstream: string | null = null; + let ahead = 0; + let behind = 0; + + if (!detachedHead) { + upstream = gitSafe("config", `branch.${name}.remote`); + if (upstream) { + const trackingBranch = gitSafe( + "rev-parse", + "--abbrev-ref", + `${name}@{upstream}`, + ); + if (trackingBranch) { + upstream = trackingBranch; + const counts = gitSafe( + "rev-list", + "--left-right", + "--count", + `${name}...${trackingBranch}`, + ); + if (counts) { + const [a, b] = counts.split(/\s+/); + ahead = parseInt(a!) || 0; + behind = parseInt(b!) || 0; + } + } + } + } + + return { name, upstream, ahead, behind, detached: detachedHead }; +} + +function parseStatusFiles(): StatusFile[] { + const porcelain = gitSafe("status", "--porcelain=v2"); + if (!porcelain) return []; + + const stagedNumstat = new Map(); + const unstagedNumstat = new Map(); + + for (const [map, args] of [ + [stagedNumstat, ["diff", "--cached", "--numstat"]], + [unstagedNumstat, ["diff", "--numstat"]], + ] as const) { + const output = gitSafe(...args); + if (!output) continue; + for (const line of output.split("\n").filter(Boolean)) { + const [add, del, ...rest] = line.split("\t"); + const file = rest.join("\t"); + map.set(file, { + additions: parseInt(add!) || 0, + deletions: parseInt(del!) || 0, + }); + } + } + + const files: StatusFile[] = []; + + for (const line of porcelain.split("\n").filter(Boolean)) { + if (line.startsWith("#")) continue; + + if (line.startsWith("?")) { + const path = line.slice(2); + files.push({ + path, + origPath: undefined, + status: "untracked", + category: "untracked", + additions: 0, + deletions: 0, + }); + continue; + } + + if (line.startsWith("u")) { + // Unmerged: u

+ const fields = line.split(" "); + const path = fields.slice(10).join(" "); + files.push({ + path, + origPath: undefined, + status: "conflicted", + category: "conflicted", + additions: 0, + deletions: 0, + }); + continue; + } + + if (line.startsWith("1")) { + // Ordinary entry: 1 + const fields = line.split(" "); + const xy = fields[1]!; + const stagedCode = xy[0]!; + const unstagedCode = xy[1]!; + const path = fields.slice(8).join(" "); + + if (stagedCode !== ".") { + const stat = stagedNumstat.get(path) ?? { + additions: 0, + deletions: 0, + }; + files.push({ + path, + origPath: undefined, + status: codeToStatus(stagedCode), + category: "staged", + ...stat, + }); + } + if (unstagedCode !== ".") { + const stat = unstagedNumstat.get(path) ?? { + additions: 0, + deletions: 0, + }; + files.push({ + path, + origPath: undefined, + status: codeToStatus(unstagedCode), + category: "unstaged", + ...stat, + }); + } + } + + if (line.startsWith("2")) { + // Rename/copy: 2 \t\t + const tabParts = line.split("\t"); + const headerFields = tabParts[0]!.split(" "); + const xy = headerFields[1]!; + const stagedCode = xy[0]!; + const unstagedCode = xy[1]!; + const path = tabParts[1]!; + const origPath = tabParts[2]; + + if (stagedCode !== ".") { + const stat = stagedNumstat.get(path) ?? { + additions: 0, + deletions: 0, + }; + files.push({ + path, + origPath, + status: codeToStatus(stagedCode), + category: "staged", + ...stat, + }); + } + if (unstagedCode !== ".") { + const stat = unstagedNumstat.get(path) ?? { + additions: 0, + deletions: 0, + }; + files.push({ + path, + origPath, + status: codeToStatus(unstagedCode), + category: "unstaged", + ...stat, + }); + } + } + } + + return files; +} + +function codeToStatus(code: string): FileStatus { + switch (code) { + case "M": + return "modified"; + case "A": + return "added"; + case "D": + return "deleted"; + case "R": + return "renamed"; + case "C": + return "copied"; + default: + return "modified"; + } +} + +function relativeTime(epochSec: number): string { + const delta = Math.floor(Date.now() / 1000) - epochSec; + if (delta < 60) return "just now"; + + const minutes = Math.floor(delta / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + const weeks = Math.floor(days / 7); + const months = Math.floor(days / 30); + const years = Math.floor(days / 365); + + if (years > 0) return `${years}y ago`; + if (months > 0) return `${months}mo ago`; + if (weeks > 0) return `${weeks}w ago`; + if (days > 0) { + const remH = hours - days * 24; + return remH > 0 ? `${days}d ${remH}h ago` : `${days}d ago`; + } + if (hours > 0) { + const remM = minutes - hours * 60; + return remM > 0 ? `${hours}h ${remM}m ago` : `${hours}h ago`; + } + return `${minutes}m ago`; +} + +interface CommitInfo { + hash: string; + author: string; + message: string; + relTime: string; +} + +function getRecentCommits(count = 3): CommitInfo[] { + const output = gitSafe("log", "--format=%h\t%an\t%s\t%at", "--no-decorate", `-${count}`); + if (!output) return []; + return output + .split("\n") + .filter(Boolean) + .map((line) => { + const [hash, author, message, epoch] = line.split("\t"); + return { + hash: hash!, + author: author!, + message: message!, + relTime: relativeTime(parseInt(epoch!)), + }; + }); +} + +function getLastCommitTime(): string | null { + const epoch = gitSafe("log", "-1", "--format=%at"); + if (!epoch) return null; + return relativeTime(parseInt(epoch)); +} + +// ─── Display Helpers ──────────────────────────────────────── + +function diffBar(additions: number, deletions: number, width = 8): string { + const total = additions + deletions; + if (total === 0) return pc.dim("░".repeat(width)); + + const addWidth = Math.round((additions / total) * width); + const delWidth = width - addWidth; + + return pc.green("█".repeat(addWidth)) + pc.red("█".repeat(delWidth)); +} + +function diffNumbers(additions: number, deletions: number, addWidth = 0, delWidth = 0): string { + if (additions > 0 && deletions > 0) { + return `${pc.green(String(additions).padStart(addWidth))} ${pc.dim("│")} ${pc.red(String(deletions).padEnd(delWidth))}`; + } + if (additions > 0) return pc.green(String(additions).padStart(addWidth)); + if (deletions > 0) return pc.red(String(deletions).padEnd(delWidth)); + return pc.dim("0"); +} + +function statusSymbol(file: StatusFile): string { + if (file.category === "untracked") return SYM.untracked; + if (file.category === "conflicted") return SYM.conflict; + if (file.category === "staged") { + switch (file.status) { + case "deleted": + return SYM.deleted; + case "renamed": + return SYM.renamed; + case "added": + return SYM.added; + default: + return SYM.staged; + } + } + switch (file.status) { + case "deleted": + return SYM.deleted; + default: + return SYM.modified; + } +} + +function formatFilePath(raw: string, status: FileStatus): string { + const sep = raw.lastIndexOf("/"); + const dir = sep >= 0 ? raw.slice(0, sep + 1) : ""; + const file = sep >= 0 ? raw.slice(sep + 1) : raw; + + const coloredFile = (() => { + switch (status) { + case "added": + case "untracked": + return pc.green(file); + case "deleted": + return pc.strikethrough(pc.red(file)); + case "renamed": + case "copied": + return pc.magenta(file); + case "conflicted": + return pc.red(pc.bold(file)); + default: + return pc.yellow(file); + } + })(); + + return `${pc.dim(dir)}${coloredFile}`; +} + +function statusLabel(status: FileStatus): string { + switch (status) { + case "modified": + return pc.yellow("modified"); + case "added": + return pc.green("new file"); + case "deleted": + return pc.red("deleted "); + case "renamed": + return pc.magenta("renamed "); + case "copied": + return pc.magenta("copied "); + case "untracked": + return pc.blue("untracked"); + case "conflicted": + return pc.red(pc.bold("conflict")); + default: + return pc.dim("unknown "); + } +} + +interface ColumnWidths { + path: number; + add: number; + del: number; + diff: number; +} + +function diffNumVisibleWidth(f: StatusFile, addW: number, delW: number): number { + if (f.additions > 0 && f.deletions > 0) return addW + 3 + delW; // "N / N" + if (f.additions > 0) return addW; + if (f.deletions > 0) return delW; + return 0; +} + +function computeColumnWidths(files: StatusFile[]): ColumnWidths { + const add = Math.max(...files.map((f) => String(f.additions).length)); + const del = Math.max(...files.map((f) => String(f.deletions).length)); + const diff = Math.max( + 0, + ...files + .filter((f) => f.additions > 0 || f.deletions > 0) + .map((f) => diffNumVisibleWidth(f, add, del)), + ); + return { + path: Math.max(...files.map((f) => f.path.length)), + add, + del, + diff, + }; +} + +function renderFileList(files: StatusFile[], cols: ColumnWidths): string { + if (files.length === 0) return ""; + + const { path: maxPathLen, add: maxAddLen, del: maxDelLen } = cols; + + return files + .map((f) => { + const sym = statusSymbol(f); + const path = formatFilePath(f.path, f.status); + const pathPad = " ".repeat(Math.max(0, maxPathLen - f.path.length + 2)); + const label = statusLabel(f.status); + const hasDiff = f.additions > 0 || f.deletions > 0; + + let line = ` ${sym} ${path}${pathPad}${label}`; + + const visibleW = diffNumVisibleWidth(f, maxAddLen, maxDelLen); + if (hasDiff) { + const nums = diffNumbers( + f.additions, + f.deletions, + maxAddLen, + maxDelLen, + ); + const numPad = " ".repeat(Math.max(0, cols.diff - visibleW)); + const bar = diffBar(f.additions, f.deletions, 6); + line += ` ${nums}${numPad} ${bar}`; + } else { + line += " ".repeat(cols.diff + 4 + 6); + } + + if (f.origPath) { + line += ` ${pc.dim(`← ${f.origPath}`)}`; + } + + return line; + }) + .join("\n"); +} + +function sectionHeader( + icon: string, + title: string, + count: number, + color: (s: string) => string, +): string { + const badge = color(`${count}`); + return `${icon} ${pc.bold(title)} ${badge}`; +} + +function stripAnsi(str: string): number { + return str.replace(/\x1B\[[0-9;]*m/g, "").length; +} + +function box(content: string, title: string): string { + const lines = content.split("\n"); + const innerWidth = Math.max(...lines.map((l) => stripAnsi(l)), stripAnsi(title) + 2) + 4; + const pad = (line: string) => { + const visible = stripAnsi(line); + return ` ${line}${" ".repeat(Math.max(0, innerWidth - visible - 2))}`; + }; + const empty = " ".repeat(innerWidth); + const bar = pc.dim("│"); + const titleLen = stripAnsi(title); + const leftDash = Math.floor((innerWidth - titleLen) / 2); + const rightDash = innerWidth - titleLen - leftDash; + const top = `${pc.dim("╭")}${pc.dim("─".repeat(leftDash))} ${title} ${pc.dim("─".repeat(rightDash))}${pc.dim("╮")}`; + const bottom = `${pc.dim("╰")}${pc.dim("─".repeat(innerWidth + 2))}${pc.dim("╯")}`; + const body = lines.map((l) => `${bar} ${pad(l)} ${bar}`).join("\n"); + return `${top}\n${bar} ${empty} ${bar}\n${body}\n${bar} ${empty} ${bar}\n${bottom}`; +} + +// ─── Command ──────────────────────────────────────────────── + +export const statusCommand = new Command("status") + .alias("s") + .alias("st") + .description("Show a beautiful overview of your working tree") + .option("-s, --short", "Show compact output") + .action(async (opts: { short?: boolean }) => { + try { + repoRoot(); + } catch { + log.error("Not inside a git repository."); + process.exit(1); + } + + betterHubIntro("Status"); + + const showCommits = getPreference("showRecentCommits"); + const branch = parseBranch(); + const files = parseStatusFiles(); + const lastCommitTime = getLastCommitTime(); + const recentCommits = showCommits ? getRecentCommits(3) : []; + + // ── Branch ──────────────────────────────────── + const branchDisplay = branch.detached + ? `${pc.red("⊘")} ${pc.bold("Detached HEAD")} at ${pc.cyan(branch.name)}` + : `${SYM.branch} ${pc.bold(pc.cyan(branch.name))}`; + + let trackingInfo = ""; + if (branch.upstream) { + trackingInfo = pc.gray( + ` → ${link(branch.upstream, branchUrl(branch.upstream))}`, + ); + const parts: string[] = []; + if (branch.ahead > 0) parts.push(`${SYM.ahead}${branch.ahead}`); + if (branch.behind > 0) parts.push(`${SYM.behind}${branch.behind}`); + if (parts.length > 0) trackingInfo += ` ${parts.join(pc.dim(" · "))}`; + if (branch.ahead === 0 && branch.behind === 0) + trackingInfo += ` ${pc.green("✓ up to date")}`; + } else if (!branch.detached) { + trackingInfo = pc.dim(" (no upstream)"); + } + + log.info(`${branchDisplay}${trackingInfo}`); + + if (files.length === 0) { + log.success(`${SYM.clean} Working tree clean — nothing to commit`); + if (recentCommits.length > 0 && !opts.short) { + log.step(`${pc.dim("Recent commits:")}`); + const maxAuthor = Math.max( + ...recentCommits.map((c) => c.author.length), + ); + const maxMsg = Math.max( + ...recentCommits.map((c) => c.message.length), + ); + const maxTime = Math.max( + ...recentCommits.map((c) => c.relTime.length), + ); + log.message( + recentCommits + .map((c) => { + const url = commitUrl(c.hash); + const authorText = link( + pc.cyan(c.author), + authorUrl(c.author), + ); + const msgText = link( + pc.white(c.message), + url, + ); + const hashText = link(pc.dim(c.hash), url); + return ` ${SYM.commit} ${authorText}${" ".repeat(maxAuthor - c.author.length)} ${msgText}${" ".repeat(maxMsg - c.message.length)} ${pc.dim(c.relTime)}${" ".repeat(maxTime - c.relTime.length)} ${hashText}`; + }) + .join("\n"), + ); + } + outro(pc.dim(lastCommitTime ? `Last commit ${lastCommitTime}` : "")); + return; + } + + // ── File Sections ──────────────────────────── + const staged = files.filter((f) => f.category === "staged"); + const unstaged = files.filter((f) => f.category === "unstaged"); + const untracked = files.filter((f) => f.category === "untracked"); + const conflicted = files.filter((f) => f.category === "conflicted"); + + const totalAdd = files.reduce((s, f) => s + f.additions, 0); + const totalDel = files.reduce((s, f) => s + f.deletions, 0); + const cols = computeColumnWidths(files); + + // ── Build box content ───────────────────────── + const sections: string[] = []; + + if (conflicted.length > 0) { + sections.push( + sectionHeader( + SYM.conflict, + "Merge Conflicts", + conflicted.length, + pc.red, + ), + ); + sections.push(renderFileList(conflicted, cols)); + } + + if (staged.length > 0) { + sections.push( + `${sectionHeader(pc.green("◆"), "Staged", staged.length, pc.green)}\n${renderFileList(staged, cols)}`, + ); + } + + if (unstaged.length > 0) { + sections.push( + `${sectionHeader( + pc.yellow("◆"), + "Modified", + unstaged.length, + pc.yellow, + )}\n${renderFileList(unstaged, cols)}`, + ); + } + + if (untracked.length > 0) { + sections.push( + `${sectionHeader(pc.blue("◆"), "Untracked", untracked.length, pc.blue)}\n${renderFileList(untracked, cols)}`, + ); + } + + const summaryParts: string[] = []; + if (staged.length > 0) summaryParts.push(pc.green(`${staged.length} staged`)); + if (unstaged.length > 0) + summaryParts.push(pc.yellow(`${unstaged.length} modified`)); + if (untracked.length > 0) + summaryParts.push(pc.blue(`${untracked.length} untracked`)); + if (conflicted.length > 0) + summaryParts.push(pc.red(`${conflicted.length} conflicted`)); + + const diffSummary = + totalAdd > 0 || totalDel > 0 + ? ` ${pc.dim("·")} ${pc.green(`+${totalAdd.toLocaleString()}`)} ${pc.red(`-${totalDel.toLocaleString()}`)}` + : ""; + + const title = `${pc.bold(`${files.length}`)} ${pc.gray("changes")} ${pc.dim("·")} ${summaryParts.join(pc.dim(" · "))}${diffSummary}`; + + log.message(box(sections.join("\n\n"), title)); + + // ── Recent Commits ─────────────────────────── + if (!opts.short && recentCommits.length > 0) { + log.info(pc.gray("Recent commits:")); + const maxAuthor = Math.max(...recentCommits.map((c) => c.author.length)); + const maxMsg = Math.max(...recentCommits.map((c) => c.message.length)); + const maxTime = Math.max(...recentCommits.map((c) => c.relTime.length)); + log.message( + recentCommits + .map((c) => { + const url = commitUrl(c.hash); + const authorText = link( + pc.cyan(c.author), + authorUrl(c.author), + ); + const msgText = link(pc.white(c.message), url); + const hashText = link(pc.dim(c.hash), url); + return ` ${SYM.commit} ${authorText}${" ".repeat(maxAuthor - c.author.length)} ${msgText}${" ".repeat(maxMsg - c.message.length)} ${pc.dim(c.relTime)}${" ".repeat(maxTime - c.relTime.length)} ${hashText}`; + }) + .join("\n"), + ); + } + + outro(pc.dim(lastCommitTime ? `${"Last commit"} ${lastCommitTime}` : "")); + }); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 41d112a4..2e91db43 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -2,10 +2,13 @@ import { Command } from "commander"; import { authCommand } from "./commands/auth.js"; import { cdCommand } from "./commands/cd.js"; +import { cloneCommand } from "./commands/clone.js"; import { commitCommand } from "./commands/commit.js"; import { createRepoCommand } from "./commands/create-repo.js"; import { deleteRepoCommand } from "./commands/delete.js"; import { listRepoCommand } from "./commands/list-repo.js"; +import { configCommand } from "./commands/config.js"; +import { statusCommand } from "./commands/status.js"; const program = new Command() .name("better-hub") @@ -14,9 +17,12 @@ const program = new Command() program.addCommand(authCommand); program.addCommand(cdCommand); +program.addCommand(cloneCommand); +program.addCommand(configCommand); program.addCommand(createRepoCommand); program.addCommand(commitCommand); program.addCommand(deleteRepoCommand); program.addCommand(listRepoCommand); +program.addCommand(statusCommand); program.parse(); diff --git a/packages/cli/src/lib/preferences.ts b/packages/cli/src/lib/preferences.ts new file mode 100644 index 00000000..607daeb7 --- /dev/null +++ b/packages/cli/src/lib/preferences.ts @@ -0,0 +1,53 @@ +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; + +export interface Preferences { + showRecentCommits: boolean; +} + +const DEFAULTS: Preferences = { + showRecentCommits: true, +}; + +const PREFS_DIR = join(homedir(), ".better-hub"); +const PREFS_FILE = join(PREFS_DIR, "preferences.json"); + +function ensurePrefsDir() { + if (!existsSync(PREFS_DIR)) { + mkdirSync(PREFS_DIR, { recursive: true }); + } +} + +export function getPreferences(): Preferences { + ensurePrefsDir(); + if (!existsSync(PREFS_FILE)) { + return { ...DEFAULTS }; + } + try { + const raw = readFileSync(PREFS_FILE, "utf-8"); + return { ...DEFAULTS, ...JSON.parse(raw) }; + } catch { + return { ...DEFAULTS }; + } +} + +export function getPreference(key: K): Preferences[K] { + return getPreferences()[key]; +} + +export function setPreference(key: K, value: Preferences[K]): void { + const prefs = getPreferences(); + prefs[key] = value; + ensurePrefsDir(); + writeFileSync(PREFS_FILE, JSON.stringify(prefs, null, 2) + "\n"); +} + +export function resetPreferences(): void { + ensurePrefsDir(); + writeFileSync(PREFS_FILE, JSON.stringify(DEFAULTS, null, 2) + "\n"); +} + +export function preferenceDefaults(): Readonly { + return DEFAULTS; +} diff --git a/packages/cli/src/lib/repo-registry.ts b/packages/cli/src/lib/repo-registry.ts index b2ac66c0..8ea066bf 100644 --- a/packages/cli/src/lib/repo-registry.ts +++ b/packages/cli/src/lib/repo-registry.ts @@ -42,7 +42,7 @@ function writeRegistry(registry: RepoRegistry) { export function registerRepo(slug: string, path: string): RepoEntry { const registry = readRegistry(); - const existing = registry.repos.findIndex((r) => r.slug === slug); + const existing = registry.repos.findIndex((r) => r.slug === slug && r.path === path); const entry: RepoEntry = { slug, @@ -60,10 +60,12 @@ export function registerRepo(slug: string, path: string): RepoEntry { return entry; } -export function unregisterRepo(slug: string): boolean { +export function unregisterRepo(slug: string, path?: string): boolean { const registry = readRegistry(); const before = registry.repos.length; - registry.repos = registry.repos.filter((r) => r.slug !== slug); + registry.repos = registry.repos.filter( + (r) => !(r.slug === slug && (path == null || r.path === path)), + ); if (registry.repos.length === before) return false; writeRegistry(registry); return true; @@ -74,10 +76,29 @@ export function getRepoPath(slug: string): string | null { return registry.repos.find((r) => r.slug === slug)?.path ?? null; } +export function getRepoEntries(slug: string): RepoEntry[] { + const registry = readRegistry(); + return registry.repos.filter((r) => r.slug === slug); +} + export function listRegisteredRepos(): RepoEntry[] { return readRegistry().repos; } +/** + * Removes registry entries whose paths no longer exist on disk. + * Returns the pruned entries so callers can inform the user. + */ +export function pruneStaleRepos(): RepoEntry[] { + const registry = readRegistry(); + const stale = registry.repos.filter((r) => !existsSync(r.path)); + if (stale.length > 0) { + registry.repos = registry.repos.filter((r) => existsSync(r.path)); + writeRegistry(registry); + } + return stale; +} + /** * Removes local registry entries whose slugs aren't in the given set of * server-known slugs. Returns the number of pruned entries. diff --git a/packages/storage/src/adapter.ts b/packages/storage/src/adapter.ts index 7577c86a..6f2dcb15 100644 --- a/packages/storage/src/adapter.ts +++ b/packages/storage/src/adapter.ts @@ -1,4 +1,4 @@ -import type { GenericEndpointContext, User } from "better-auth"; +import { APIError, type GenericEndpointContext, type User } from "better-auth"; import { storage } from "."; import type { RepositoryMember, @@ -41,7 +41,7 @@ export const storageAdapter = (ctx: GenericEndpointContext) => { }); if (checkExisting) { - return ctx.error("BAD_REQUEST", { + throw new APIError("BAD_REQUEST", { message: "Repository already exists", code: "REPOSITORY_ALREADY_EXISTS", }); @@ -79,6 +79,14 @@ export const storageAdapter = (ctx: GenericEndpointContext) => { }); return !!checkExisting; }, + findRepoBySlug: async (slug: `${string}/${string}`) => { + const adapter = ctx.context.adapter; + const repo = await adapter.findOne({ + model: "repository", + where: [{ field: "slug", value: slug }], + }); + return repo; + }, deleteRepo: async (id: string) => { const adapter = ctx.context.adapter; await adapter.delete({ diff --git a/packages/storage/src/client.ts b/packages/storage/src/client.ts index ace6e2d5..acdede03 100644 --- a/packages/storage/src/client.ts +++ b/packages/storage/src/client.ts @@ -6,6 +6,7 @@ export const storageClient = () => { id: "storage-client", $InferServerPlugin: {} as ReturnType, pathMethods: { + "/storage/clone-repo": "POST", "/storage/delete-repo": "POST", }, } satisfies BetterAuthClientPlugin; diff --git a/packages/storage/src/lib/parse-slug.ts b/packages/storage/src/lib/parse-slug.ts index 5f6e246a..5f590128 100644 --- a/packages/storage/src/lib/parse-slug.ts +++ b/packages/storage/src/lib/parse-slug.ts @@ -1,6 +1,7 @@ import type { AuthContext } from "better-auth"; import type { Organization } from "better-auth/plugins"; import type { Repository } from "../db-schema"; +import { slugSchema } from "../zod-schema"; export const parseSlugInit = (ctx: AuthContext) => @@ -50,3 +51,24 @@ export const parseSlugInit = } return [result.organization, result.repository] as any; }; + +/** + * Returns a boolean indicating if the slug is valid in terms of syntax + * Example: + * ```ts + * if (ctx.body.newSlug) { + * const isValidSlug = validateSlugSyntax(ctx.body.newSlug); + * if (!isValidSlug) { + * throw ctx.error("BAD_REQUEST", { + * message: "Invalid slug syntax", + * code: "INVALID_SLUG_SYNTAX", + * }); + * } + * } + * ``` + * @param slug + * @returns + */ +export const isValidSlugSyntax = (slug: string | `${string}/${string}`) => { + return slugSchema.safeParse(slug).success; +}; diff --git a/packages/storage/src/plugin.ts b/packages/storage/src/plugin.ts index 08208e47..c92839f9 100644 --- a/packages/storage/src/plugin.ts +++ b/packages/storage/src/plugin.ts @@ -1,6 +1,7 @@ import type { BetterAuthPlugin } from "better-auth"; import { storageSchema } from "./db-schema"; import { parseSlugInit } from "./lib/parse-slug"; +import { cloneRepo } from "./routes/clone-repo"; import { createRepo } from "./routes/create-repo"; import { listRepo } from "./routes/list-repo"; import { deleteRepo } from "./routes/delete-repo"; @@ -17,6 +18,11 @@ export const storagePlugin = () => { }, }; }, - endpoints: { createRepo: createRepo, listRepo: listRepo, deleteRepo: deleteRepo }, + endpoints: { + cloneRepo: cloneRepo, + createRepo: createRepo, + listRepo: listRepo, + deleteRepo: deleteRepo, + }, } satisfies BetterAuthPlugin; }; diff --git a/packages/storage/src/routes/clone-repo.ts b/packages/storage/src/routes/clone-repo.ts new file mode 100644 index 00000000..9f6b16ff --- /dev/null +++ b/packages/storage/src/routes/clone-repo.ts @@ -0,0 +1,77 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import { storageAdapter } from "../adapter"; +import * as z from "zod/v4"; +import { slugSchema } from "../zod-schema"; +import { storageMiddleware } from "../lib/middleware"; +import { createRepo } from "./create-repo"; +import type { Visibility } from "../db-schema"; +import { isValidSlugSyntax } from "../lib/parse-slug"; + +const body = z.object({ + slug: slugSchema, + newSlug: slugSchema.optional(), + newName: z.string().optional(), + newVisibility: z.enum(["public", "private"]).optional(), + newDescription: z.string().optional(), +}); + +export const cloneRepo = createAuthEndpoint( + "/storage/clone-repo", + { + method: "POST", + use: [sessionMiddleware, storageMiddleware], + body, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const repo = await adapter.findRepoBySlug(ctx.body.slug); + + if (!repo) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + // if for some reason the existing repo that is trying to be clone has an invalid slug: + if (!isValidSlugSyntax(repo.slug)) { + throw ctx.error("UNPROCESSABLE_ENTITY", { + message: "Upstream repository slug is invalid", + code: "INVALID_UPSTREAM_REPOSITORY_SLUG", + }); + } + + const data = { + name: repo.name, + slug: (repo.slug + `-clone`) as `${string}/${string}`, + visibility: repo.visibility as Visibility, + description: repo.description ?? undefined, + }; + + if (ctx.body.newName) { + data.name = ctx.body.newName; + } + if (ctx.body.newSlug) { + if (!isValidSlugSyntax(ctx.body.newSlug)) { + throw ctx.error("BAD_REQUEST", { + message: "Invalid slug syntax", + code: "INVALID_SLUG_SYNTAX", + }); + } + data.slug = ctx.body.newSlug as `${string}/${string}`; + } + if (ctx.body.newVisibility) { + data.visibility = ctx.body.newVisibility as Visibility; + } + if (ctx.body.newDescription) { + data.description = ctx.body.newDescription; + } + + const result = await createRepo({ + body: data, + headers: ctx.headers, + }); + + return result; + }, +); diff --git a/packages/storage/src/routes/create-repo.ts b/packages/storage/src/routes/create-repo.ts index 658c6a3e..5d104672 100644 --- a/packages/storage/src/routes/create-repo.ts +++ b/packages/storage/src/routes/create-repo.ts @@ -1,15 +1,20 @@ import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; import { storageAdapter } from "../adapter"; import * as z from "zod/v4"; -import { slugSchema } from "../zod-schema"; +import { + repositoryDescriptionSchema, + repositoryNameSchema, + repositoryVisibilitySchema, + slugSchema, +} from "../zod-schema"; import { storageMiddleware } from "../lib/middleware"; import { storage } from ".."; const body = z.object({ - name: z.string().min(1), + name: repositoryNameSchema, slug: slugSchema, - description: z.string().optional(), - visibility: z.enum(["public", "private"]), + description: repositoryDescriptionSchema, + visibility: repositoryVisibilitySchema, }); export const createRepo = createAuthEndpoint( diff --git a/packages/storage/src/zod-schema.ts b/packages/storage/src/zod-schema.ts index 3e5df4e4..29a254c5 100644 --- a/packages/storage/src/zod-schema.ts +++ b/packages/storage/src/zod-schema.ts @@ -5,4 +5,8 @@ const slugSegmentSchema = z .min(1) .max(100) .regex(/^[a-z0-9-_]+$/); + export const slugSchema = z.templateLiteral([slugSegmentSchema, "/", slugSegmentSchema]); +export const repositoryNameSchema = z.string().min(1).max(100); +export const repositoryDescriptionSchema = z.string().max(1000).optional(); +export const repositoryVisibilitySchema = z.enum(["public", "private"]); From 54dd9f1d2c9aa4835f9ca5a1374d6d757cbf18da Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Fri, 20 Mar 2026 17:31:42 +1000 Subject: [PATCH 06/10] feat: log command to CLI --- packages/cli/src/commands/log.ts | 695 +++++++++++++++++++++++++++++++ packages/cli/src/index.ts | 2 + 2 files changed, 697 insertions(+) create mode 100644 packages/cli/src/commands/log.ts diff --git a/packages/cli/src/commands/log.ts b/packages/cli/src/commands/log.ts new file mode 100644 index 00000000..c8ba382e --- /dev/null +++ b/packages/cli/src/commands/log.ts @@ -0,0 +1,695 @@ +import { Command } from "commander"; +import pc from "picocolors"; +import terminalLink from "terminal-link"; +import { log, outro } from "@clack/prompts"; +import { betterHubIntro } from "../lib/intro.js"; +import { getBaseUrl } from "../lib/config.js"; +import { execFileSync } from "child_process"; + +// ─── Git Helpers ───────────────────────────────────────────── + +let _repoRoot: string | undefined; +function repoRoot(): string { + if (!_repoRoot) { + _repoRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], { + encoding: "utf-8", + }).trim(); + } + return _repoRoot; +} + +function git(...args: string[]): string { + return execFileSync("git", args, { + encoding: "utf-8", + cwd: repoRoot(), + stdio: "pipe", + maxBuffer: 10 * 1024 * 1024, + }).trim(); +} + +function gitSafe(...args: string[]): string | null { + try { + return git(...args); + } catch { + return null; + } +} + +// ─── Repo / URL Helpers ────────────────────────────────────── + +let _repoSlug: string | null | undefined; +function getRepoSlug(): string | null { + if (_repoSlug !== undefined) return _repoSlug; + const url = + gitSafe("remote", "get-url", "origin") ?? + gitSafe("remote", "get-url", "better-hub"); + if (!url) return (_repoSlug = null); + const match = url.match(/[/:]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/); + return (_repoSlug = match ? `${match[1]}/${match[2]}` : null); +} + +function commitUrl(hash: string): string | null { + const slug = getRepoSlug(); + return slug ? `${getBaseUrl()}/${slug}/commit/${hash}` : null; +} + +function authorUrl(name: string): string | null { + const slug = getRepoSlug(); + return slug ? `${getBaseUrl()}/${name.replace(/\s+/g, "")}` : null; +} + +/** Terminal hyperlink — same pattern as `status.ts` */ +function link(text: string, url: string | null): string { + if (!url) return text; + return terminalLink(text, url, { fallback: () => text }); +} + +// ─── Constants ─────────────────────────────────────────────── + +const SEP = "\x01"; +const FORMAT = `${SEP}%h${SEP}%H${SEP}%an${SEP}%at${SEP}%s${SEP}%d${SEP}%p`; + +/** Cap layout width on very wide terminals so the graph + columns don’t span the full screen. */ +const MAX_LOG_LAYOUT_WIDTH = 200; + +const LANE_COLORS = [pc.cyan, pc.magenta, pc.green, pc.yellow, pc.blue, pc.red] as const; + +// ─── Types ─────────────────────────────────────────────────── + +interface CommitLine { + type: "commit"; + graph: string; + hash: string; + fullHash: string; + author: string; + timestamp: number; + subject: string; + refs: string; + parentHashes: string[]; + lane: number; +} + +interface GraphOnlyLine { + type: "graph"; + graph: string; +} + +type LogLine = CommitLine | GraphOnlyLine; + +// ─── Parsing ───────────────────────────────────────────────── + +function parseLogOutput(raw: string): LogLine[] { + const lines: LogLine[] = []; + + for (const line of raw.split("\n")) { + if (!line && lines.length === 0) continue; + + const sepIdx = line.indexOf(SEP); + if (sepIdx >= 0) { + const graphPart = line.slice(0, sepIdx); + const parts = line.slice(sepIdx + 1).split(SEP); + const lane = graphPart.indexOf("*"); + + lines.push({ + type: "commit", + graph: graphPart, + hash: parts[0] ?? "", + fullHash: parts[1] ?? "", + author: parts[2] ?? "", + timestamp: parseInt(parts[3] ?? "0"), + subject: parts[4] ?? "", + refs: (parts[5] ?? "").trim(), + parentHashes: (parts[6] ?? "").trim().split(" ").filter(Boolean), + lane: lane >= 0 ? lane : 0, + }); + } else { + if (line.trim() || lines.length > 0) { + lines.push({ type: "graph", graph: line }); + } + } + } + + return lines; +} + +// ─── Graph Beautification ──────────────────────────────────── + +function laneColor(lane: number): (s: string) => string { + return LANE_COLORS[lane % LANE_COLORS.length]!; +} + +function beautifyGraph(raw: string, isHead: boolean, isMerge: boolean): string { + let result = ""; + + for (let i = 0; i < raw.length; i++) { + const ch = raw[i]!; + + if (ch === " ") { + result += " "; + continue; + } + + const lane = Math.round(i / 2); + const color = laneColor(lane); + + switch (ch) { + case "*": + if (isHead) { + result += color(pc.bold("◉")); + } else if (isMerge) { + result += color("◆"); + } else { + result += color("●"); + } + break; + case "|": + result += color("│"); + break; + case "-": + result += color("─"); + break; + case "_": + result += color("─"); + break; + case ".": + result += color("·"); + break; + case "/": + result += color("╱"); + break; + case "\\": + result += color("╲"); + break; + default: + result += color(ch); + } + } + + return result; +} + +// ─── Time ──────────────────────────────────────────────────── + +function relativeTime(epochSec: number): string { + const delta = Math.floor(Date.now() / 1000) - epochSec; + if (delta < 60) return "just now"; + + const minutes = Math.floor(delta / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + const weeks = Math.floor(days / 7); + const months = Math.floor(days / 30); + const years = Math.floor(days / 365); + + if (years > 0) return `${years}y ago`; + if (months > 0) return `${months}mo ago`; + if (weeks > 0) return `${weeks}w ago`; + if (days > 0) return `${days}d ago`; + if (hours > 0) return `${hours}h ago`; + return `${minutes}m ago`; +} + +// ─── Decorations ───────────────────────────────────────────── + +function renderRefs(raw: string): string { + if (!raw) return ""; + + const inner = raw.replace(/^\s*\(/, "").replace(/\)\s*$/, ""); + if (!inner) return ""; + + const parts = inner.split(",").map((s) => s.trim()); + const rendered = parts.map((part) => { + if (part.startsWith("HEAD -> ")) { + const branch = part.slice(8); + return `${pc.bold(pc.red("HEAD"))} ${pc.dim("→")} ${pc.bold(pc.green(branch))}`; + } + if (part === "HEAD") { + return pc.bold(pc.red("HEAD")); + } + if (part.startsWith("tag: ")) { + return pc.bold(pc.yellow(`⚑ ${part.slice(5)}`)); + } + if (part.startsWith("origin/")) { + return pc.red(part); + } + return pc.bold(pc.green(part)); + }); + + return ` ${pc.dim("‹")}${rendered.join(pc.dim(", "))}${pc.dim("›")}`; +} + +// ─── Stats ─────────────────────────────────────────────────── + +interface DiffStat { + files: number; + additions: number; + deletions: number; +} + +function getCommitStat(hash: string): DiffStat | null { + const raw = gitSafe("show", "--stat", "--format=", hash); + if (!raw) return null; + + const lines = raw.split("\n").filter(Boolean); + const summary = lines[lines.length - 1]; + if (!summary) return null; + + const filesMatch = summary.match(/(\d+) files? changed/); + const addMatch = summary.match(/(\d+) insertions?/); + const delMatch = summary.match(/(\d+) deletions?/); + + return { + files: parseInt(filesMatch?.[1] ?? "0"), + additions: parseInt(addMatch?.[1] ?? "0"), + deletions: parseInt(delMatch?.[1] ?? "0"), + }; +} + +// ─── Subject Formatting ────────────────────────────────────── + +const COMMIT_TYPE_COLORS: Record string> = { + feat: pc.green, + fix: pc.red, + refactor: pc.blue, + chore: pc.yellow, + docs: pc.cyan, + style: pc.magenta, + test: pc.yellow, + perf: pc.yellow, + ci: pc.dim, + build: pc.dim, + revert: pc.red, + add: pc.green, +}; + +function formatSubject(raw: string, bold: boolean): string { + const match = raw.match(/^(\w+)(\(.+?\))?(!)?:\s*(.*)$/); + if (match) { + const [, type, scope, bang, rest] = match; + const colorFn = COMMIT_TYPE_COLORS[type!.toLowerCase()] ?? pc.white; + const typeStr = colorFn(pc.bold(type!)); + const scopeStr = scope ? pc.dim(scope) : ""; + const bangStr = bang ? pc.red(pc.bold("!")) : ""; + const restStr = bold ? pc.bold(pc.white(rest!)) : pc.white(rest!); + return `${typeStr}${scopeStr}${bangStr}${pc.dim(":")} ${restStr}`; + } + + if (raw.startsWith("Merge ")) { + return `${pc.dim("Merge")} ${pc.white(raw.slice(6))}`; + } + + return bold ? pc.bold(pc.white(raw)) : pc.white(raw); +} + +// ─── Rendering ─────────────────────────────────────────────── + +const CLACK_PREFIX_W = 3; // clack's `│ ` prefix on each line + +function visibleLength(str: string): number { + return str.replace(/\x1B\]8;[^\x07]*\x07/g, "").replace(/\x1B\[[0-9;]*m/g, "").length; +} + +function skipEscape(str: string, i: number): number { + if (str[i] !== "\x1B") return i; + + if (str[i + 1] === "[") { + // CSI sequence — skip to 'm' + let j = i + 2; + while (j < str.length && str[j] !== "m") j++; + return j + 1; + } + + if (str[i + 1] === "]") { + // OSC sequence — skip to BEL (\x07) or ST (\x1B\\) + let j = i + 2; + while (j < str.length) { + if (str[j] === "\x07") return j + 1; + if (str[j] === "\x1B" && str[j + 1] === "\\") return j + 2; + j++; + } + return j; + } + + return i + 1; +} + +function truncateLine(str: string, maxVisible: number): string { + if (maxVisible <= 0) return ""; + const currentLen = visibleLength(str); + if (currentLen <= maxVisible) return str; + + const target = maxVisible - 1; + let visible = 0; + let i = 0; + + while (i < str.length && visible < target) { + if (str[i] === "\x1B") { + i = skipEscape(str, i); + } else if (str[i] === "\x07") { + i++; + } else { + visible++; + i++; + } + } + + return str.slice(0, i) + "\x1B[0m…"; +} + +function padRight(str: string, width: number): string { + const visible = visibleLength(str); + return visible >= width ? str : str + " ".repeat(width - visible); +} + +function continuationGraphFor(commitGraph: string): string { + return commitGraph.replace(/\*/g, "|"); +} + +function renderFullGraph(lines: LogLine[], opts: { stat?: boolean; termWidth: number }): string { + const commits = lines.filter((l): l is CommitLine => l.type === "commit"); + if (commits.length === 0) return pc.dim(" No commits found."); + + const currentHead = gitSafe("rev-parse", "HEAD"); + + const maxGraphLen = Math.max(...lines.map((l) => l.graph.length), 0); + const maxAuthorLen = Math.min(Math.max(...commits.map((c) => c.author.length), 0), 16); + const maxTimeLen = Math.max(...commits.map((c) => relativeTime(c.timestamp).length), 0); + + // Git abbreviates %h to more characters in large repos (often 7, sometimes 9+). + const HASH_W = Math.max(7, ...commits.map((c) => c.hash.length)); + const rightColW = maxAuthorLen + 2 + maxTimeLen; + const contentW = opts.termWidth - CLACK_PREFIX_W; + const subjectColW = contentW - maxGraphLen - 1 - HASH_W - 2 - rightColW - 2; + + const statCache = new Map(); + let maxStatTotal = 0; + if (opts.stat) { + for (const c of commits) { + const stat = getCommitStat(c.hash); + statCache.set(c.hash, stat); + if (stat) { + maxStatTotal = Math.max( + maxStatTotal, + stat.additions + stat.deletions, + ); + } + } + } + + const output: string[] = []; + + for (const line of lines) { + if (line.type === "graph") { + if (!line.graph.trim() && output.length === 0) continue; + output.push(beautifyGraph(line.graph, false, false)); + continue; + } + + const isHead = line.fullHash === currentHead; + const isMerge = line.parentHashes.length > 1; + + const graph = beautifyGraph(line.graph, isHead, isMerge); + const graphPad = " ".repeat(Math.max(0, maxGraphLen - line.graph.length)); + + const hashColored = link( + pc.dim(pc.yellowBright(line.hash)), + commitUrl(line.fullHash), + ); + + const authorTrunc = + line.author.length > maxAuthorLen + ? line.author.slice(0, maxAuthorLen - 1) + "…" + : line.author; + const authorColored = padRight( + link(pc.cyan(authorTrunc), authorUrl(line.author)), + maxAuthorLen, + ); + + const time = relativeTime(line.timestamp); + const timeColored = pc.dim(time.padStart(maxTimeLen)); + + const refs = renderRefs(line.refs); + const refsVisLen = visibleLength(refs); + + const refsOverflow = refsVisLen > 0 && subjectColW - refsVisLen < 30; + + let subject = line.subject; + if (refsOverflow) { + if (subject.length > subjectColW) { + subject = subject.slice(0, subjectColW - 1) + "…"; + } + } else { + const availSubject = Math.max(10, subjectColW - refsVisLen); + if (subject.length > availSubject) { + subject = subject.slice(0, availSubject - 1) + "…"; + } + } + + const subjectColored = link( + formatSubject(subject, isHead), + commitUrl(line.fullHash), + ); + + if (refsOverflow) { + const paddedSubject = padRight(subjectColored, subjectColW); + output.push( + `${graph}${graphPad} ${hashColored} ${paddedSubject} ${authorColored} ${timeColored}`, + ); + + const contGraph = continuationGraphFor(line.graph); + const contBeautified = beautifyGraph(contGraph, false, false); + const contPad = " ".repeat(Math.max(0, maxGraphLen - contGraph.length)); + const refsLinePrefix = `${contBeautified}${contPad} ${" ".repeat(HASH_W)} `; + const refsAvail = contentW - maxGraphLen - 1 - HASH_W - 2; + const refsTruncated = + visibleLength(refs.trimStart()) > refsAvail + ? truncateLine(refs.trimStart(), refsAvail) + : refs.trimStart(); + output.push(`${refsLinePrefix}${refsTruncated}`); + } else { + const subjectAndRefs = `${subjectColored}${refs}`; + const paddedSubject = padRight(subjectAndRefs, subjectColW); + output.push( + `${graph}${graphPad} ${hashColored} ${paddedSubject} ${authorColored} ${timeColored}`, + ); + } + + if (opts.stat) { + const stat = statCache.get(line.hash); + if (stat && (stat.additions > 0 || stat.deletions > 0)) { + const contGraph = continuationGraphFor(line.graph); + const contBeautified = beautifyGraph(contGraph, false, false); + const contPad = " ".repeat( + Math.max(0, maxGraphLen - contGraph.length), + ); + output.push( + `${contBeautified}${contPad} ${" ".repeat(HASH_W)} ${renderStatBar(stat, Math.min(20, subjectColW), maxStatTotal)}`, + ); + } + } + } + + return output.map((l) => truncateLine(l, contentW)).join("\n"); +} + +function renderStatBar(stat: DiffStat, maxBarWidth: number, maxTotal: number): string { + const total = stat.additions + stat.deletions; + const barWidth = Math.max(1, Math.round((total / Math.max(maxTotal, 1)) * maxBarWidth)); + const addW = Math.max( + stat.additions > 0 ? 1 : 0, + Math.round((stat.additions / Math.max(total, 1)) * barWidth), + ); + const delW = Math.max(stat.deletions > 0 ? 1 : 0, barWidth - addW); + + const bar = pc.green("▓".repeat(addW)) + pc.red("▓".repeat(delW)); + const nums: string[] = []; + if (stat.additions > 0) nums.push(pc.green(`+${stat.additions}`)); + if (stat.deletions > 0) nums.push(pc.red(`-${stat.deletions}`)); + return `${pc.dim(`${stat.files}f`)} ${nums.join(" ")} ${bar}`; +} + +function renderOneline(lines: LogLine[], opts: { termWidth: number }): string { + const commits = lines.filter((l): l is CommitLine => l.type === "commit"); + if (commits.length === 0) return pc.dim(" No commits found."); + + const currentHead = gitSafe("rev-parse", "HEAD"); + const contentW = opts.termWidth - CLACK_PREFIX_W; + const hashW = Math.max(7, ...commits.map((c) => c.hash.length)); + + const maxGraphLen = Math.max(...lines.map((l) => l.graph.length), 0); + + const output: string[] = []; + + for (const line of lines) { + if (line.type === "graph") { + if (!line.graph.trim() && output.length === 0) continue; + output.push(beautifyGraph(line.graph, false, false)); + continue; + } + + const isHead = line.fullHash === currentHead; + const isMerge = line.parentHashes.length > 1; + + const graph = beautifyGraph(line.graph, isHead, isMerge); + const graphPad = " ".repeat(Math.max(0, maxGraphLen - line.graph.length)); + + const hashColored = link(pc.yellow(line.hash), commitUrl(line.fullHash)); + + const refs = renderRefs(line.refs); + const refsVisLen = visibleLength(refs); + + const available = contentW - maxGraphLen - 1 - hashW - 2 - refsVisLen; + let subject = line.subject; + if (subject.length > available && available > 10) { + subject = subject.slice(0, available - 1) + "…"; + } + + const subjectColored = link( + formatSubject(subject, isHead), + commitUrl(line.fullHash), + ); + + output.push(`${graph}${graphPad} ${hashColored} ${subjectColored}${refs}`); + } + + return output.map((l) => truncateLine(l, contentW)).join("\n"); +} + +// ─── Branch Header ─────────────────────────────────────────── + +function renderBranchHeader(showAll: boolean): string { + const head = gitSafe("symbolic-ref", "--short", "HEAD"); + const detached = head === null; + const name = detached ? (gitSafe("rev-parse", "--short", "HEAD") ?? "???") : head; + + const icon = detached ? pc.red("⊘") : pc.cyan("⎇"); + const branchName = detached + ? `${pc.red("detached")} at ${pc.cyan(name)}` + : pc.bold(pc.cyan(name)); + + const scope = showAll ? pc.dim(" (all branches)") : ""; + + return `${icon} ${branchName}${scope}`; +} + +// ─── Summary Footer ────────────────────────────────────────── + +function renderSummary(commits: CommitLine[]): string { + if (commits.length === 0) return ""; + + const authors = new Set(commits.map((c) => c.author)); + const merges = commits.filter((c) => c.parentHashes.length > 1).length; + const oldest = Math.min(...commits.map((c) => c.timestamp)); + const newest = Math.max(...commits.map((c) => c.timestamp)); + + const parts: string[] = []; + parts.push(pc.bold(`${commits.length}`) + pc.gray(" commits")); + parts.push( + pc.bold(`${authors.size}`) + pc.gray(authors.size === 1 ? " author" : " authors"), + ); + if (merges > 0) { + parts.push(pc.bold(`${merges}`) + pc.gray(merges === 1 ? " merge" : " merges")); + } + + if (oldest !== newest) { + parts.push( + pc.gray(`${relativeTime(newest)} ${pc.dim("→")} ${relativeTime(oldest)}`), + ); + } + + return parts.join(pc.dim(" · ")); +} + +// ─── Command ───────────────────────────────────────────────── + +export const logCommand = new Command("log") + .alias("l") + .alias("lg") + .description("Show a beautiful commit graph log") + .option("-n, --count ", "Number of commits to show", "20") + .option("-a, --all", "Show all branches") + .option("--oneline", "Compact one-line output") + .option("--stat", "Show file change stats per commit") + .option("--no-graph", "Disable graph rendering") + .option("--author ", "Filter commits by author") + .option("--since ", "Show commits after date") + .option("--until ", "Show commits before date") + .option("--grep ", "Filter commits by message pattern") + .option("--reverse", "Show commits in reverse order") + .argument("[path...]", "Limit to commits touching these paths") + .action( + async ( + paths: string[], + opts: { + count: string; + all?: boolean; + oneline?: boolean; + stat?: boolean; + graph?: boolean; + author?: string; + since?: string; + until?: string; + grep?: string; + reverse?: boolean; + }, + ) => { + try { + repoRoot(); + } catch { + log.error("Not inside a git repository."); + process.exit(1); + } + + betterHubIntro("Log"); + + log.info(renderBranchHeader(opts.all ?? false)); + + const args: string[] = ["log", `-${opts.count}`, `--format=${FORMAT}`]; + + if (opts.graph !== false) { + args.push("--graph"); + } + if (opts.all) args.push("--all"); + if (opts.author) args.push(`--author=${opts.author}`); + if (opts.since) args.push(`--since=${opts.since}`); + if (opts.until) args.push(`--until=${opts.until}`); + if (opts.grep) args.push(`--grep=${opts.grep}`); + if (opts.reverse) args.push("--reverse"); + + if (paths.length > 0) { + args.push("--"); + args.push(...paths); + } + + const raw = gitSafe(...args); + if (!raw) { + log.warn("No commits found."); + outro(pc.dim("Try adjusting your filters.")); + return; + } + + const parsed = parseLogOutput(raw); + const commits = parsed.filter((l): l is CommitLine => l.type === "commit"); + + const envCols = process.env["COLUMNS"] + ? parseInt(process.env["COLUMNS"]) + : 0; + const rawWidth = process.stdout.columns ?? (envCols || 100); + const termWidth = Math.min(rawWidth, MAX_LOG_LAYOUT_WIDTH); + + if (opts.oneline) { + log.message(renderOneline(parsed, { termWidth })); + } else { + log.message( + renderFullGraph(parsed, { + stat: opts.stat ?? false, + termWidth, + }), + ); + } + + // Summary footer + log.message(""); + outro(renderSummary(commits)); + }, + ); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 2e91db43..a9d45dce 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -8,6 +8,7 @@ import { createRepoCommand } from "./commands/create-repo.js"; import { deleteRepoCommand } from "./commands/delete.js"; import { listRepoCommand } from "./commands/list-repo.js"; import { configCommand } from "./commands/config.js"; +import { logCommand } from "./commands/log.js"; import { statusCommand } from "./commands/status.js"; const program = new Command() @@ -23,6 +24,7 @@ program.addCommand(createRepoCommand); program.addCommand(commitCommand); program.addCommand(deleteRepoCommand); program.addCommand(listRepoCommand); +program.addCommand(logCommand); program.addCommand(statusCommand); program.parse(); From e9f16d11b0e37fe24568239caa3844d7b4c1bd88 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Sat, 21 Mar 2026 16:21:11 +1000 Subject: [PATCH 07/10] update: log cmd for more styles --- packages/cli/src/commands/log.ts | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/log.ts b/packages/cli/src/commands/log.ts index c8ba382e..fb8b5877 100644 --- a/packages/cli/src/commands/log.ts +++ b/packages/cli/src/commands/log.ts @@ -280,6 +280,7 @@ const COMMIT_TYPE_COLORS: Record string> = { build: pc.dim, revert: pc.red, add: pc.green, + update: pc.cyan, }; function formatSubject(raw: string, bold: boolean): string { @@ -295,7 +296,29 @@ function formatSubject(raw: string, bold: boolean): string { } if (raw.startsWith("Merge ")) { - return `${pc.dim("Merge")} ${pc.white(raw.slice(6))}`; + return `${pc.magentaBright("Merge")} ${pc.white(raw.slice(6))}`; + } else if (raw.toLowerCase().startsWith("update ")) { + return `${pc.cyan("Update")} ${pc.white(raw.slice(7))}`; + } else if (raw.toLowerCase().startsWith("delete ")) { + return `${pc.red("Delete")} ${pc.white(raw.slice(7))}`; + } else if (raw.toLowerCase().startsWith("remove ")) { + return `${pc.red("Remove")} ${pc.white(raw.slice(7))}`; + } else if (raw.toLowerCase().startsWith("revert ")) { + return `${pc.redBright("revert")} ${pc.white(raw.slice(7))}`; + } else if (raw.toLowerCase().startsWith("add ")) { + return `${pc.green("Add")} ${pc.white(raw.slice(4))}`; + } else if (raw.toLowerCase().startsWith("added ")) { + return `${pc.green("Added")} ${pc.white(raw.slice(6))}`; + } else if (raw.toLowerCase().startsWith("fix ")) { + return `${pc.red("Fix")} ${pc.white(raw.slice(4))}`; + } else if (raw.toLowerCase().startsWith("refactor ")) { + return `${pc.blue("Refactor")} ${pc.white(raw.slice(9))}`; + } else if (raw.toLowerCase().startsWith("chore ")) { + return `${pc.yellow("Chore")} ${pc.white(raw.slice(6))}`; + } else if (raw.toLowerCase().startsWith("create ")) { + return `${pc.green("Create")} ${pc.white(raw.slice(7))}`; + } else if (raw.toLowerCase().startsWith("init")) { + return `${pc.cyan(raw.split(" ")[0])}${pc.white(raw.slice(4))}`; } return bold ? pc.bold(pc.white(raw)) : pc.white(raw); @@ -689,7 +712,6 @@ export const logCommand = new Command("log") } // Summary footer - log.message(""); outro(renderSummary(commits)); }, ); From 5abc1f2e8836a5fa23a5660f4f5f97075daaf717 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Sat, 21 Mar 2026 23:31:25 +1000 Subject: [PATCH 08/10] add: better-hub UI for our storage --- agent-docs/architecture/project-structure.md | 8 + agent-docs/frontend/routing.md | 51 +++--- agent-docs/infrastructure/environment.md | 104 +++++------ apps/web/.env.example | 8 + apps/web/next.config.ts | 1 + apps/web/package.json | 4 +- .../(app)/s/[owner]/[repo]/actions/page.tsx | 5 + .../(app)/s/[owner]/[repo]/activity/page.tsx | 5 + .../[repo]/blob/[ref]/[...path]/page.tsx | 63 +++++++ .../app/(app)/s/[owner]/[repo]/code/page.tsx | 165 ++++++++++++++++++ .../(app)/s/[owner]/[repo]/commits/page.tsx | 5 + .../(app)/s/[owner]/[repo]/insights/page.tsx | 5 + .../(app)/s/[owner]/[repo]/issues/page.tsx | 5 + .../src/app/(app)/s/[owner]/[repo]/layout.tsx | 107 ++++++++++++ .../src/app/(app)/s/[owner]/[repo]/page.tsx | 20 +++ .../(app)/s/[owner]/[repo]/prompts/page.tsx | 5 + .../app/(app)/s/[owner]/[repo]/pulls/page.tsx | 5 + .../(app)/s/[owner]/[repo]/releases/page.tsx | 5 + .../(app)/s/[owner]/[repo]/security/page.tsx | 5 + .../(app)/s/[owner]/[repo]/settings/page.tsx | 5 + .../app/(app)/s/[owner]/[repo]/tags/page.tsx | 5 + .../[repo]/tree/[ref]/[[...path]]/page.tsx | 58 ++++++ apps/web/src/app/device/page.tsx | 18 +- .../components/layout/nav-aware-content.tsx | 2 +- .../src/components/repo/branch-selector.tsx | 8 +- .../src/components/repo/breadcrumb-nav.tsx | 18 +- .../components/repo/code-content-wrapper.tsx | 22 ++- apps/web/src/components/repo/code-toolbar.tsx | 53 +++--- .../components/repo/code-viewer-client.tsx | 2 +- .../components/repo/file-explorer-tree.tsx | 83 ++++++--- apps/web/src/components/repo/file-list.tsx | 10 +- .../src/components/repo/repo-breadcrumb.tsx | 25 ++- .../components/repo/repo-layout-wrapper.tsx | 4 + apps/web/src/components/repo/repo-nav.tsx | 36 ++-- .../repo/storage-repo-empty-state.tsx | 28 +++ .../components/repo/storage-repo-sidebar.tsx | 78 +++++++++ .../repo/storage-repo-tab-placeholder.tsx | 10 ++ apps/web/src/lib/auth-client.ts | 1 - apps/web/src/lib/storage-file-tree.ts | 23 +++ apps/web/src/lib/storage-git.ts | 105 +++++++++++ apps/web/src/proxy.ts | 1 + bun.lock | 26 +-- packages/storage/package.json | 1 - packages/storage/src/adapter.ts | 20 ++- packages/storage/src/git-storage.ts | 11 ++ packages/storage/src/index.ts | 6 - packages/storage/src/lib/storage-tree.ts | 164 +++++++++++++++++ packages/storage/src/plugin.ts | 6 + packages/storage/src/routes/create-repo.ts | 4 +- packages/storage/src/routes/delete-repo.ts | 4 +- packages/storage/src/routes/repo-file.ts | 43 +++++ packages/storage/src/routes/repo-git-meta.ts | 59 +++++++ .../storage/src/routes/repo-list-directory.ts | 47 +++++ packages/storage/tsdown.config.ts | 8 +- 54 files changed, 1362 insertions(+), 208 deletions(-) create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/actions/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/activity/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/blob/[ref]/[...path]/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/code/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/insights/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/issues/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/prompts/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/pulls/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/releases/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/security/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/settings/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/tags/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/tree/[ref]/[[...path]]/page.tsx create mode 100644 apps/web/src/components/repo/storage-repo-empty-state.tsx create mode 100644 apps/web/src/components/repo/storage-repo-sidebar.tsx create mode 100644 apps/web/src/components/repo/storage-repo-tab-placeholder.tsx create mode 100644 apps/web/src/lib/storage-file-tree.ts create mode 100644 apps/web/src/lib/storage-git.ts create mode 100644 packages/storage/src/git-storage.ts delete mode 100644 packages/storage/src/index.ts create mode 100644 packages/storage/src/lib/storage-tree.ts create mode 100644 packages/storage/src/routes/repo-file.ts create mode 100644 packages/storage/src/routes/repo-git-meta.ts create mode 100644 packages/storage/src/routes/repo-list-directory.ts diff --git a/agent-docs/architecture/project-structure.md b/agent-docs/architecture/project-structure.md index 738c7841..58a5e42f 100644 --- a/agent-docs/architecture/project-structure.md +++ b/agent-docs/architecture/project-structure.md @@ -54,6 +54,14 @@ The `(app)` route group wraps all authenticated pages with a shared layout that ├── layout.tsx # Auth gate, navbar, Ghost chat, theme provider ├── dashboard/page.tsx # User dashboard (activity feed, repos) ├── repos/page.tsx # Repository listing +├── s/[owner]/[repo]/ # Better Hub git storage (Pierre) — same chrome as GitHub repos +│ ├── layout.tsx # RepoLayoutWrapper, RepoNav (shared tabs), CodeContentWrapper, StorageRepoSidebar +│ ├── page.tsx # Overview placeholder (`/s/:owner/:repo`) +│ ├── code/page.tsx # Code tab (matches GitHub code page; FileList + README) +│ ├── tree/[ref]/[[...path]]/# Directory listing +│ ├── blob/[ref]/[...path]/ # File viewer +│ └── commits, pulls, issues, prompts, actions, releases, tags, security, activity, insights, settings/ +│ # Tab placeholders (empty) ├── repos/[owner]/[repo]/ # Repository detail (has its own layout) │ ├── layout.tsx # Repo sidebar, nav tabs, file tree, branch selector │ ├── page.tsx # Repo overview (README, file list) diff --git a/agent-docs/frontend/routing.md b/agent-docs/frontend/routing.md index cc25bfb0..b093c2a5 100644 --- a/agent-docs/frontend/routing.md +++ b/agent-docs/frontend/routing.md @@ -15,12 +15,12 @@ There are two layers of URL rewriting, both achieving the same goal: The middleware handles specific GitHub URL patterns that require transformation beyond simple path prefixing: -| GitHub URL | Better Hub Internal Route | -|---|---| -| `/:owner/:repo` | `/repos/:owner/:repo` | -| `/:owner/:repo/pull/:number` | `/repos/:owner/:repo/pulls/:number` | -| `/:owner/:repo/commit/:sha` | `/repos/:owner/:repo/commits/:sha` | -| `/:owner/:repo/actions/runs/:runId` | `/repos/:owner/:repo/actions/:runId` | +| GitHub URL | Better Hub Internal Route | +| ----------------------------------- | ------------------------------------------- | +| `/:owner/:repo` | `/repos/:owner/:repo` | +| `/:owner/:repo/pull/:number` | `/repos/:owner/:repo/pulls/:number` | +| `/:owner/:repo/commit/:sha` | `/repos/:owner/:repo/commits/:sha` | +| `/:owner/:repo/actions/runs/:runId` | `/repos/:owner/:repo/actions/:runId` | | `/:owner/:repo/compare/base...head` | `/repos/:owner/:repo/pulls/new?base=&head=` | The middleware uses `NextResponse.rewrite()` for transparent rewrites (URL stays the same in the browser) and `NextResponse.redirect()` for the compare URL (which changes the URL). @@ -44,10 +44,12 @@ rewrites: { Both layers maintain a list of first-segment routes that should NOT be rewritten: **Middleware (`APP_ROUTES`)**: -`dashboard`, `repos`, `issues`, `prs`, `stars`, `settings`, `search`, `trending`, `notifications`, `orgs`, `users`, `api`, `debug`, `_next` +`dashboard`, `s`, `repos`, `issues`, `prs`, `stars`, `settings`, `search`, `trending`, `notifications`, `orgs`, `users`, `api`, `debug`, `_next` + +The `s` segment is reserved for **git storage** repositories (Better Hub–hosted repos) at `/s/:owner/:repo/...`, not GitHub-style `/:owner/:repo` rewrites. **Next.js Config (`KNOWN_ROUTES`)**: -`api`, `dashboard`, `debug`, `extension`, `issues`, `notifications`, `orgs`, `prompt`, `repos`, `search`, `stars`, `trending`, `users`, `_next` +`api`, `dashboard`, `debug`, `extension`, `issues`, `notifications`, `orgs`, `prompt`, `repos`, `s`, `search`, `stars`, `trending`, `users`, `_next` If the first URL segment matches a known route, the URL is passed through unmodified. Otherwise, it's assumed to be an `/:owner/:repo` pattern and gets rewritten. @@ -81,31 +83,32 @@ The App Router uses route groups for layout organization: Key dynamic route segments: -| Segment | Purpose | -|---|---| -| `[owner]` | GitHub user or organization login | -| `[repo]` | Repository name | -| `[number]` | Issue or PR number | -| `[sha]` | Commit SHA | -| `[...path]` | File or directory path (catch-all) | -| `[runId]` | CI/CD workflow run ID | -| `[jobId]` | CI/CD job ID | -| `[tag]` | Release tag | -| `[ghsaId]` | GitHub Security Advisory ID | -| `[username]` | GitHub username | -| `[org]` | Organization name | -| `[id]` | Generic ID (prompt requests) | -| `[...sub]` | Sub-pages (catch-all for PR tabs, new PR sub-views) | +| Segment | Purpose | +| ------------ | --------------------------------------------------- | +| `[owner]` | GitHub user or organization login | +| `[repo]` | Repository name | +| `[number]` | Issue or PR number | +| `[sha]` | Commit SHA | +| `[...path]` | File or directory path (catch-all) | +| `[runId]` | CI/CD workflow run ID | +| `[jobId]` | CI/CD job ID | +| `[tag]` | Release tag | +| `[ghsaId]` | GitHub Security Advisory ID | +| `[username]` | GitHub username | +| `[org]` | Organization name | +| `[id]` | Generic ID (prompt requests) | +| `[...sub]` | Sub-pages (catch-all for PR tabs, new PR sub-views) | ## Middleware Matcher ```typescript export const config = { - matcher: ["/((?!api|_next/static|_next/image|favicon\\.ico|[^/]+\\.[^/]+$).*)"], + matcher: ["/((?!api|_next/static|_next/image|favicon\\.ico|[^/]+\\.[^/]+$).*)"], }; ``` The middleware runs on all paths except: + - `/api/*` (API routes handle their own auth) - `/_next/static/*` and `/_next/image/*` (static assets) - `/favicon.ico` and other root-level files with extensions diff --git a/agent-docs/infrastructure/environment.md b/agent-docs/infrastructure/environment.md index 0d7b9441..4ca2e0a3 100644 --- a/agent-docs/infrastructure/environment.md +++ b/agent-docs/infrastructure/environment.md @@ -6,96 +6,96 @@ All environment variables are defined in `apps/web/.env`. See `apps/web/.env.exa ### Authentication -| Variable | Description | -|---|---| -| `GITHUB_CLIENT_ID` | GitHub OAuth App client ID | -| `GITHUB_CLIENT_SECRET` | GitHub OAuth App client secret | -| `BETTER_AUTH_SECRET` | 32-char random string for session encryption. Generate with `openssl rand -hex 16` | -| `BETTER_AUTH_URL` | Base URL of the app (e.g., `http://localhost:3000`) | -| `NEXT_PUBLIC_APP_URL` | Public-facing app URL (same as above for local dev) | +| Variable | Description | +| ---------------------- | ---------------------------------------------------------------------------------- | +| `GITHUB_CLIENT_ID` | GitHub OAuth App client ID | +| `GITHUB_CLIENT_SECRET` | GitHub OAuth App client secret | +| `BETTER_AUTH_SECRET` | 32-char random string for session encryption. Generate with `openssl rand -hex 16` | +| `BETTER_AUTH_URL` | Base URL of the app (e.g., `http://localhost:3000`) | +| `NEXT_PUBLIC_APP_URL` | Public-facing app URL (same as above for local dev) | ### Database -| Variable | Description | -|---|---| +| Variable | Description | +| -------------- | ----------------------------------------------------------------------------------------------------------------- | | `DATABASE_URL` | PostgreSQL connection string. Docker Compose default: `postgresql://postgres:postgres@localhost:54320/better_hub` | ### Redis -| Variable | Description | -|---|---| -| `UPSTASH_REDIS_REST_URL` | Upstash Redis REST API URL. Docker Compose default: `http://localhost:8079` | -| `UPSTASH_REDIS_REST_TOKEN` | Upstash Redis REST API token. Docker Compose default: `local_token` | +| Variable | Description | +| -------------------------- | --------------------------------------------------------------------------- | +| `UPSTASH_REDIS_REST_URL` | Upstash Redis REST API URL. Docker Compose default: `http://localhost:8079` | +| `UPSTASH_REDIS_REST_TOKEN` | Upstash Redis REST API token. Docker Compose default: `local_token` | ## AI (Required for AI Features) -| Variable | Description | Default | -|---|---|---| -| `OPEN_ROUTER_API_KEY` | OpenRouter API key for Ghost AI | (none) | -| `GHOST_MODEL` | Default Ghost model ID | `moonshotai/kimi-k2.5` | -| `GHOST_MERGE_MODEL` | Model for merge conflict resolution | `google/gemini-2.5-pro-preview` | -| `ANTHROPIC_API_KEY` | Anthropic API key for specific tasks | (none) | -| `OPENAPI_KEY` | OpenAI API key (optional, for specific tasks) | (none) | +| Variable | Description | Default | +| --------------------- | --------------------------------------------- | ------------------------------- | +| `OPEN_ROUTER_API_KEY` | OpenRouter API key for Ghost AI | (none) | +| `GHOST_MODEL` | Default Ghost model ID | `moonshotai/kimi-k2.5` | +| `GHOST_MERGE_MODEL` | Model for merge conflict resolution | `google/gemini-2.5-pro-preview` | +| `ANTHROPIC_API_KEY` | Anthropic API key for specific tasks | (none) | +| `OPENAPI_KEY` | OpenAI API key (optional, for specific tasks) | (none) | ## Billing (Optional) -| Variable | Description | -|---|---| -| `STRIPE_SECRET_KEY` | Stripe API key. If unset, all billing features are disabled. | -| `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret | -| `STRIPE_BASE_PRICE_ID` | Stripe Price ID for the base subscription plan | -| `STRIPE_METERED_PRICE_ID` | Stripe Price ID for metered usage | +| Variable | Description | +| ------------------------- | ------------------------------------------------------------ | +| `STRIPE_SECRET_KEY` | Stripe API key. If unset, all billing features are disabled. | +| `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret | +| `STRIPE_BASE_PRICE_ID` | Stripe Price ID for the base subscription plan | +| `STRIPE_METERED_PRICE_ID` | Stripe Price ID for metered usage | ## Code Execution (Optional) -| Variable | Description | -|---|---| -| `E2B_API_KEY` | E2B API key for sandboxed code execution | +| Variable | Description | +| -------------- | --------------------------------------------------------- | +| `E2B_API_KEY` | E2B API key for sandboxed code execution | | `E2B_TEMPLATE` | Custom E2B template ID (falls back to default base image) | ## Background Jobs (Optional) -| Variable | Description | -|---|---| -| `INNGEST_EVENT_KEY` | Inngest event key for background job processing | -| `INNGEST_SIGNING_KEY` | Inngest webhook signing key | +| Variable | Description | +| --------------------- | ----------------------------------------------- | +| `INNGEST_EVENT_KEY` | Inngest event key for background job processing | +| `INNGEST_SIGNING_KEY` | Inngest webhook signing key | ## Search and Memory (Optional) -| Variable | Description | -|---|---| -| `MIXEDBREAD_API_KEY` | Mixedbread API key for embeddings and reranking | -| `SUPER_MEMORY_API_KEY` | SuperMemory API key for AI conversation memory | +| Variable | Description | +| ---------------------- | ----------------------------------------------- | +| `MIXEDBREAD_API_KEY` | Mixedbread API key for embeddings and reranking | +| `SUPER_MEMORY_API_KEY` | SuperMemory API key for AI conversation memory | ## Git Storage (Optional) -| Variable | Description | -|---|---| -| `GIT_STORAGE_PRIVATE_KEY` | Private key for `@pierre/storage` Git storage client | +| Variable | Description | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `GIT_STORAGE_PRIVATE_KEY` | PKCS8 private key for Pierre (`@pierre/storage`) JWT signing, used inside the **`@better-hub/storage`** Better Auth plugin. Required to create repos and to back **`/s/:owner/:repo`** browsing; the web app calls storage through **`auth.api`** (plugin routes), not by importing Pierre directly. Optional override: `GIT_STORAGE_NAME` (defaults to `better-hub`). | ## Integrations (Optional) -| Variable | Description | -|---|---| -| `SLACK_CLIENT_ID` | Slack app client ID for notifications | -| `SLACK_CLIENT_SECRET` | Slack app client secret | -| `VERCEL_OIDC_TOKEN` | Vercel OIDC token for deployment auth | +| Variable | Description | +| --------------------- | ------------------------------------- | +| `SLACK_CLIENT_ID` | Slack app client ID for notifications | +| `SLACK_CLIENT_SECRET` | Slack app client secret | +| `VERCEL_OIDC_TOKEN` | Vercel OIDC token for deployment auth | ## Error Tracking (Optional) -| Variable | Description | -|---|---| -| `SENTRY_DSN` | Sentry Data Source Name | +| Variable | Description | +| ------------------- | ---------------------------------------- | +| `SENTRY_DSN` | Sentry Data Source Name | | `SENTRY_AUTH_TOKEN` | Sentry auth token for source map uploads | ## Docker Compose Variables The Docker Compose file uses these with defaults: -| Variable | Default | Purpose | -|---|---|---| -| `POSTGRES_PASSWORD` | `postgres` | PostgreSQL password | -| `SRH_TOKEN` | `local_token` | Redis REST proxy token | +| Variable | Default | Purpose | +| ------------------- | ------------- | ---------------------- | +| `POSTGRES_PASSWORD` | `postgres` | PostgreSQL password | +| `SRH_TOKEN` | `local_token` | Redis REST proxy token | ## Minimal Local Setup diff --git a/apps/web/.env.example b/apps/web/.env.example index ef5b241e..7ca9496a 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -78,6 +78,14 @@ ANTHROPIC_API_KEY=your_anthropic_api_key # SuperMemory for AI conversation memory # SUPER_MEMORY_API_KEY=your_super_memory_api_key +# ────────────────────────────────────────────── +# Git storage — Better Hub hosted repos /s/... (optional) +# ────────────────────────────────────────────── +# Same key as packages/storage; required for create-repo and /s code browser +# GIT_STORAGE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" +# Optional; defaults to better-hub (Pierre storage client name). +# GIT_STORAGE_NAME="better-hub" + # ────────────────────────────────────────────── # Integrations (optional) # ────────────────────────────────────────────── diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index 4c17e89c..35509de3 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -8,6 +8,7 @@ import type { NextConfig } from "next"; const KNOWN_ROUTES = [ "api", "dashboard", + "s", "debug", "extension", "issues", diff --git a/apps/web/package.json b/apps/web/package.json index 1d475e14..6c0605b9 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -18,12 +18,12 @@ "@aws-sdk/client-s3": "^3.998.0", "@aws-sdk/s3-request-presigner": "^3.998.0", "@better-auth/infra": "0.1.9-beta.1", - "@better-auth/stripe": "1.5.1", + "@better-auth/stripe": "1.5.5", "@better-auth/utils": "^0.3.1", + "@better-hub/storage": "workspace:*", "@mixedbread-ai/sdk": "^2.2.11", "@octokit/rest": "^22.0.1", "@openrouter/ai-sdk-provider": "^2.2.3", - "@pierre/storage": "^1.3.2", "@prisma/adapter-pg": "^7.4.1", "@prisma/client": "^7.4.1", "@radix-ui/react-avatar": "^1.1.11", diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/actions/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/actions/page.tsx new file mode 100644 index 00000000..06007ac3 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/actions/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageActionsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/activity/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/activity/page.tsx new file mode 100644 index 00000000..1f77e4d5 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/activity/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageActivityPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/blob/[ref]/[...path]/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/blob/[ref]/[...path]/page.tsx new file mode 100644 index 00000000..daf5f887 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/blob/[ref]/[...path]/page.tsx @@ -0,0 +1,63 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { CodeViewer } from "@/components/repo/code-viewer"; +import { + StorageRepoNoBranchesState, + StorageRepoRefNotFoundState, +} from "@/components/repo/storage-repo-empty-state"; +import { getServerSession } from "@/lib/auth"; +import { getMemberStorageRepository, getStorageFileText } from "@/lib/storage-git"; + +export const runtime = "nodejs"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string; ref: string; path: string[] }>; +}): Promise { + const { owner, repo, path } = await params; + const basename = path[path.length - 1] ?? "file"; + return { title: `${basename} · ${owner}/${repo}` }; +} + +export default async function StorageRepoBlobPage({ + params, +}: { + params: Promise<{ owner: string; repo: string; ref: string; path: string[] }>; +}) { + const { owner, repo, ref, path } = await params; + if (!path?.length) notFound(); + + const session = await getServerSession(); + if (!session?.user) notFound(); + + const record = await getMemberStorageRepository(owner, repo, session.user.id); + if (!record) notFound(); + + const filePath = path.join("/"); + const filename = path[path.length - 1] ?? filePath; + + const file = await getStorageFileText(owner, repo, filePath, ref); + if (file === null) notFound(); + if (file.kind === "file_not_found") notFound(); + + if (file.kind === "file") { + return ( + + ); + } + + if (file.kind === "no_branches") { + return ; + } + + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/code/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/code/page.tsx new file mode 100644 index 00000000..b92cf77e --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/code/page.tsx @@ -0,0 +1,165 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { BranchSelector } from "@/components/repo/branch-selector"; +import { CodeToolbar } from "@/components/repo/code-toolbar"; +import { FileList } from "@/components/repo/file-list"; +import { + StorageRepoNoBranchesState, + StorageRepoRefNotFoundState, +} from "@/components/repo/storage-repo-empty-state"; +import { MarkdownRenderer } from "@/components/shared/markdown-renderer"; +import { TrackView } from "@/components/shared/track-view"; +import { getServerSession } from "@/lib/auth"; +import { + getMemberStorageRepository, + getStorageFileText, + getStorageGitMeta, + listStorageDirectory, +} from "@/lib/storage-git"; + +export const runtime = "nodejs"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string }>; +}): Promise { + const { owner, repo } = await params; + return { title: `Code · ${owner}/${repo}` }; +} + +export default async function StorageRepoCodePage({ + params, +}: { + params: Promise<{ owner: string; repo: string }>; +}) { + const { owner, repo } = await params; + const session = await getServerSession(); + if (!session?.user) notFound(); + + const record = await getMemberStorageRepository(owner, repo, session.user.id); + if (!record) notFound(); + + const repoBasePath = `/s/${owner}/${repo}`; + + const [listed, gitMeta] = await Promise.all([ + listStorageDirectory(owner, repo, { pathPrefix: "" }), + getStorageGitMeta(owner, repo), + ]); + + if (listed === null || !gitMeta) notFound(); + + const branches = gitMeta.branches; + const tags: { name: string }[] = []; + const defaultBranch = gitMeta.defaultBranch; + + const toolbar = ( +
+ +
+ ({ name: b.name }))} + defaultBranch={defaultBranch} + showCloneControls={false} + /> +
+
+ ); + + if (!listed.ok) { + return ( +
+ + {toolbar} + {listed.reason === "no_branches" ? ( + + ) : ( + + )} +
+ ); + } + + const items = listed.items; + const hasReadme = items.some( + (i) => + i.type === "file" && + typeof i.name === "string" && + i.name.toLowerCase().startsWith("readme"), + ); + + let readme: { content: string } | null = null; + if (hasReadme) { + const readmeItem = items.find( + (i) => i.type === "file" && i.name.toLowerCase().startsWith("readme"), + ); + if (readmeItem) { + const file = await getStorageFileText( + owner, + repo, + readmeItem.path, + listed.resolvedRef, + ); + if (file?.kind === "file") readme = { content: file.content }; + } + } + + return ( +
+ + {toolbar} + + {readme && ( +
+
+ + README.md + +
+
+ +
+
+ )} +
+ ); +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx new file mode 100644 index 00000000..5f798bda --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageCommitsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/insights/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/insights/page.tsx new file mode 100644 index 00000000..34c3e669 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/insights/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageInsightsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/issues/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/issues/page.tsx new file mode 100644 index 00000000..256e6b94 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/issues/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageIssuesPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx new file mode 100644 index 00000000..07e5decb --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx @@ -0,0 +1,107 @@ +import { cookies } from "next/headers"; +import { notFound } from "next/navigation"; +import { RepoLayoutWrapper } from "@/components/repo/repo-layout-wrapper"; +import { RepoNav } from "@/components/repo/repo-nav"; +import { CodeContentWrapper } from "@/components/repo/code-content-wrapper"; +import { StorageRepoSidebar } from "@/components/repo/storage-repo-sidebar"; +import { getServerSession } from "@/lib/auth"; +import { getMemberStorageRepository, getStorageGitMeta } from "@/lib/storage-git"; +import { buildStorageFileTree } from "@/lib/storage-file-tree"; +import { + REPO_SIDEBAR_COOKIE, + type RepoSidebarState, +} from "@/components/repo/repo-sidebar-constants"; +import type { FileTreeNode } from "@/lib/file-tree"; + +export const runtime = "nodejs"; + +export default async function StorageRepoLayout({ + children, + params, +}: { + children: React.ReactNode; + params: Promise<{ owner: string; repo: string }>; +}) { + const { owner, repo: repoName } = await params; + const session = await getServerSession(); + if (!session?.user) notFound(); + + const [record, gitMeta] = await Promise.all([ + getMemberStorageRepository(owner, repoName, session.user.id), + getStorageGitMeta(owner, repoName), + ]); + if (!record) notFound(); + if (!gitMeta) notFound(); + + const initialBranches = gitMeta.branches; + + let tree: FileTreeNode[] | null = null; + if (gitMeta.branches.length > 0 && gitMeta.files) { + tree = buildStorageFileTree(gitMeta.files); + } + + const cookieStore = await cookies(); + const sidebarCookie = cookieStore.get(REPO_SIDEBAR_COOKIE); + let sidebarState: RepoSidebarState | null = null; + if (sidebarCookie?.value) { + try { + sidebarState = JSON.parse(sidebarCookie.value); + } catch {} + } + + const repoBasePath = `/s/${owner}/${repoName}`; + const visibility = record.visibility === "private" ? "private" : "public"; + + return ( +
+ + } + > +
+ +
+ + {children} + +
+
+ ); +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/page.tsx new file mode 100644 index 00000000..f359fa17 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/page.tsx @@ -0,0 +1,20 @@ +import type { Metadata } from "next"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string }>; +}): Promise { + const { owner, repo } = await params; + return { title: `${owner}/${repo}` }; +} + +export default async function StorageRepoOverviewPage() { + return ( +
+

+ Overview — coming soon. +

+
+ ); +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/prompts/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/prompts/page.tsx new file mode 100644 index 00000000..78cbc7a8 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/prompts/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StoragePromptsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/pulls/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/pulls/page.tsx new file mode 100644 index 00000000..97bc3459 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/pulls/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StoragePullsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/releases/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/releases/page.tsx new file mode 100644 index 00000000..6dfaffb6 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/releases/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageReleasesPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/security/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/security/page.tsx new file mode 100644 index 00000000..fb1cf4e7 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/security/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageSecurityPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/settings/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/settings/page.tsx new file mode 100644 index 00000000..d9ab70d5 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/settings/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageSettingsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/tags/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/tags/page.tsx new file mode 100644 index 00000000..53d04461 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/tags/page.tsx @@ -0,0 +1,5 @@ +import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; + +export default function StorageTagsPage() { + return ; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/tree/[ref]/[[...path]]/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/tree/[ref]/[[...path]]/page.tsx new file mode 100644 index 00000000..59b3e555 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/tree/[ref]/[[...path]]/page.tsx @@ -0,0 +1,58 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { FileList } from "@/components/repo/file-list"; +import { + StorageRepoNoBranchesState, + StorageRepoRefNotFoundState, +} from "@/components/repo/storage-repo-empty-state"; +import { getServerSession } from "@/lib/auth"; +import { getMemberStorageRepository, listStorageDirectory } from "@/lib/storage-git"; + +export const runtime = "nodejs"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string; ref: string; path?: string[] }>; +}): Promise { + const { owner, repo, ref } = await params; + return { title: `Tree · ${owner}/${repo} @ ${ref}` }; +} + +export default async function StorageRepoTreePage({ + params, +}: { + params: Promise<{ owner: string; repo: string; ref: string; path?: string[] }>; +}) { + const { owner, repo, ref, path: pathSegs } = await params; + const session = await getServerSession(); + if (!session?.user) notFound(); + + const record = await getMemberStorageRepository(owner, repo, session.user.id); + if (!record) notFound(); + + const pathPrefix = pathSegs?.length ? pathSegs.join("/") : ""; + const listed = await listStorageDirectory(owner, repo, { + ref, + pathPrefix, + }); + if (listed === null) notFound(); + + if (!listed.ok) { + return listed.reason === "no_branches" ? ( + + ) : ( + + ); + } + + return ( + + ); +} diff --git a/apps/web/src/app/device/page.tsx b/apps/web/src/app/device/page.tsx index 86419c4b..2bc53489 100644 --- a/apps/web/src/app/device/page.tsx +++ b/apps/web/src/app/device/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect, useCallback, useRef } from "react"; +import { useState, useEffect, useCallback, useRef, Suspense } from "react"; import { useSearchParams } from "next/navigation"; import { authClient, useSession } from "@/lib/auth-client"; import { LoadingSpinner } from "@/components/shared/icons/loading-spinner"; @@ -12,7 +12,7 @@ type Phase = "enter-code" | "approve" | "success" | "denied" | "error"; const LOGO_SVG_PATH = "M25.3906 16.25C25.3908 14.8872 24.9992 13.5531 24.2627 12.4066C23.5261 11.26 22.4755 10.3494 21.236 9.78298C19.9965 9.21661 18.6203 9.01841 17.2714 9.21199C15.9224 9.40557 14.6576 9.98277 13.6274 10.8749C12.5972 11.7669 11.8451 12.9363 11.4606 14.2437C11.0762 15.5512 11.0756 16.9415 11.459 18.2492C11.8424 19.557 12.5935 20.727 13.623 21.6199C14.6524 22.5128 15.9169 23.091 17.2656 23.2857V41.7142C15.4867 41.971 13.871 42.8921 12.7438 44.2921C11.6165 45.6921 11.0614 47.467 11.1901 49.2598C11.3189 51.0526 12.1218 52.7301 13.4375 53.9547C14.7532 55.1793 16.4839 55.8601 18.2813 55.8601C20.0787 55.8601 21.8093 55.1793 23.125 53.9547C24.4407 52.7301 25.2437 51.0526 25.3724 49.2598C25.5011 47.467 24.946 45.6921 23.8188 44.2921C22.6915 42.8921 21.0758 41.971 19.2969 41.7142V23.2857C20.9888 23.0415 22.5361 22.1959 23.6552 20.9037C24.7744 19.6116 25.3905 17.9594 25.3906 16.25ZM13.2031 16.25C13.2031 15.2456 13.501 14.2638 14.059 13.4287C14.6169 12.5936 15.41 11.9428 16.3379 11.5584C17.2659 11.1741 18.2869 11.0735 19.272 11.2694C20.257 11.4654 21.1619 11.949 21.872 12.6592C22.5822 13.3694 23.0659 14.2742 23.2618 15.2593C23.4578 16.2444 23.3572 17.2654 22.9728 18.1933C22.5885 19.1212 21.9376 19.9143 21.1025 20.4723C20.2674 21.0303 19.2856 21.3281 18.2813 21.3281C16.9345 21.3281 15.6428 20.7931 14.6905 19.8408C13.7382 18.8884 13.2031 17.5968 13.2031 16.25ZM23.3594 48.75C23.3594 49.7543 23.0616 50.7362 22.5036 51.5712C21.9456 52.4063 21.1525 53.0572 20.2246 53.4416C19.2967 53.8259 18.2756 53.9265 17.2906 53.7305C16.3055 53.5346 15.4007 53.051 14.6905 52.3408C13.9803 51.6306 13.4967 50.7257 13.3007 49.7407C13.1048 48.7556 13.2053 47.7346 13.5897 46.8067C13.974 45.8788 14.6249 45.0857 15.46 44.5277C16.2951 43.9697 17.2769 43.6719 18.2813 43.6719C18.9481 43.6719 19.6085 43.8032 20.2246 44.0584C20.8407 44.3136 21.4005 44.6877 21.872 45.1592C22.3436 45.6308 22.7176 46.1906 22.9728 46.8067C23.228 47.4228 23.3594 48.0831 23.3594 48.75ZM51.7969 41.7142V28.0896C51.7985 27.4222 51.6678 26.761 51.4124 26.1444C51.157 25.5277 50.782 24.9678 50.309 24.4969L39.0152 13.2031H48.75C49.0194 13.2031 49.2777 13.0961 49.4682 12.9056C49.6586 12.7152 49.7656 12.4568 49.7656 12.1875C49.7656 11.9181 49.6586 11.6598 49.4682 11.4693C49.2777 11.2789 49.0194 11.1719 48.75 11.1719H36.5625C36.2932 11.1719 36.0348 11.2789 35.8444 11.4693C35.6539 11.6598 35.5469 11.9181 35.5469 12.1875V24.375C35.5469 24.6443 35.6539 24.9027 35.8444 25.0931C36.0348 25.2836 36.2932 25.3906 36.5625 25.3906C36.8319 25.3906 37.0902 25.2836 37.2807 25.0931C37.4711 24.9027 37.5781 24.6443 37.5781 24.375V14.6402L48.8744 25.934C49.1573 26.2171 49.3816 26.5533 49.5345 26.9231C49.6874 27.293 49.766 27.6894 49.7656 28.0896V41.7142C47.9867 41.971 46.371 42.8921 45.2438 44.2921C44.1165 45.6921 43.5614 47.467 43.6901 49.2598C43.8189 51.0526 44.6219 52.7301 45.9375 53.9547C47.2532 55.1793 48.9839 55.8601 50.7813 55.8601C52.5787 55.8601 54.3093 55.1793 55.625 53.9547C56.9407 52.7301 57.7437 51.0526 57.8724 49.2598C58.0011 47.467 57.446 45.6921 56.3187 44.2921C55.1915 42.8921 53.5758 41.971 51.7969 41.7142ZM50.7813 53.8281C49.7769 53.8281 48.7951 53.5303 47.96 52.9723C47.1249 52.4143 46.474 51.6212 46.0897 50.6933C45.7053 49.7654 45.6048 48.7444 45.8007 47.7593C45.9967 46.7742 46.4803 45.8694 47.1905 45.1592C47.9007 44.449 48.8055 43.9654 49.7906 43.7694C50.7756 43.5735 51.7967 43.6741 52.7246 44.0584C53.6525 44.4428 54.4456 45.0936 55.0036 45.9287C55.5616 46.7638 55.8594 47.7456 55.8594 48.75C55.8594 50.0968 55.3244 51.3884 54.372 52.3408C53.4197 53.2931 52.1281 53.8281 50.7813 53.8281Z"; -export default function DeviceAuthorizationPage() { +function DeviceAuthorizationInner() { const searchParams = useSearchParams(); const { data: session, isPending: sessionLoading } = useSession(); @@ -322,6 +322,20 @@ export default function DeviceAuthorizationPage() { ); } +export default function DeviceAuthorizationPage() { + return ( + + + + } + > + + + ); +} + function Shell({ children }: { children: React.ReactNode }) { return (
- {children} +
{children}
); } diff --git a/apps/web/src/components/repo/branch-selector.tsx b/apps/web/src/components/repo/branch-selector.tsx index b1b75562..3a7339a2 100644 --- a/apps/web/src/components/repo/branch-selector.tsx +++ b/apps/web/src/components/repo/branch-selector.tsx @@ -8,6 +8,8 @@ import { cn } from "@/lib/utils"; interface BranchSelectorProps { owner: string; repo: string; + /** Defaults to `/${owner}/${repo}` */ + repoBasePath?: string; currentRef: string; branches: { name: string }[]; tags: { name: string }[]; @@ -19,6 +21,7 @@ interface BranchSelectorProps { export function BranchSelector({ owner, repo, + repoBasePath, currentRef, branches, tags, @@ -26,6 +29,7 @@ export function BranchSelector({ pathType = "tree", defaultBranch, }: BranchSelectorProps) { + const base = repoBasePath ?? `/${owner}/${repo}`; const [open, setOpen] = useState(false); const [search, setSearch] = useState(""); const [tab, setTab] = useState<"branches" | "tags">("branches"); @@ -52,9 +56,9 @@ export function BranchSelector({ setSearch(""); const pathSuffix = currentPath ? `/${currentPath}` : ""; if (currentPath) { - router.push(`/${owner}/${repo}/${pathType}/${ref}${pathSuffix}`); + router.push(`${base}/${pathType}/${ref}${pathSuffix}`); } else { - router.push(`/${owner}/${repo}/tree/${ref}`); + router.push(`${base}/tree/${ref}`); } } diff --git a/apps/web/src/components/repo/breadcrumb-nav.tsx b/apps/web/src/components/repo/breadcrumb-nav.tsx index eb1fdde5..db07f34c 100644 --- a/apps/web/src/components/repo/breadcrumb-nav.tsx +++ b/apps/web/src/components/repo/breadcrumb-nav.tsx @@ -4,22 +4,32 @@ import { encodeFilePath } from "@/lib/github-utils"; interface BreadcrumbNavProps { owner: string; repo: string; + /** Defaults to `/${owner}/${repo}` */ + repoBasePath?: string; currentRef: string; path: string; isFile?: boolean; } -export function BreadcrumbNav({ owner, repo, currentRef, path, isFile }: BreadcrumbNavProps) { +export function BreadcrumbNav({ + owner, + repo, + repoBasePath, + currentRef, + path, + isFile, +}: BreadcrumbNavProps) { if (!path) return null; + const base = repoBasePath ?? `/${owner}/${repo}`; const segments = path.split("/").filter(Boolean); const crumbs = segments.map((segment, i) => { const partialPath = segments.slice(0, i + 1).join("/"); const isLast = i === segments.length - 1; const href = isLast && isFile - ? `/${owner}/${repo}/blob/${currentRef}/${encodeFilePath(partialPath)}` - : `/${owner}/${repo}/tree/${currentRef}/${encodeFilePath(partialPath)}`; + ? `${base}/blob/${currentRef}/${encodeFilePath(partialPath)}` + : `${base}/tree/${currentRef}/${encodeFilePath(partialPath)}`; return { label: segment, href, isLast }; }); @@ -27,7 +37,7 @@ export function BreadcrumbNav({ owner, repo, currentRef, path, isFile }: Breadcr return (

@@ -321,6 +334,7 @@ export function CodeContentWrapper({ )} diff --git a/apps/web/src/components/repo/code-toolbar.tsx b/apps/web/src/components/repo/code-toolbar.tsx index 5ed7a104..a1001bc1 100644 --- a/apps/web/src/components/repo/code-toolbar.tsx +++ b/apps/web/src/components/repo/code-toolbar.tsx @@ -25,9 +25,13 @@ interface EnrichedBranch { interface CodeToolbarProps { owner: string; repo: string; + /** Defaults to `/${owner}/${repo}` — used for GitHub clone/ZIP URLs. */ + repoBasePath?: string; currentRef: string; branches: EnrichedBranch[]; defaultBranch: string; + /** @default true — set false for hosted storage (no GitHub clone UI). */ + showCloneControls?: boolean; onDeleteBranch?: ( owner: string, repo: string, @@ -38,9 +42,11 @@ interface CodeToolbarProps { export function CodeToolbar({ owner, repo, + repoBasePath, currentRef, branches, defaultBranch, + showCloneControls = true, onDeleteBranch, }: CodeToolbarProps) { const [showClone, setShowClone] = useState(false); @@ -52,6 +58,7 @@ export function CodeToolbar({ const [isPending, startTransition] = useTransition(); const [cloneProtocol, setCloneProtocol] = useState<"https" | "ssh">("https"); + const isGithubPath = !repoBasePath || repoBasePath === `/${owner}/${repo}`; const cloneUrl = cloneProtocol === "https" ? `https://github.com/${owner}/${repo}.git` @@ -272,32 +279,34 @@ export function CodeToolbar({ )} -
-
- - - - ZIP - + {showCloneControls && isGithubPath && ( +
+
+ + + + ZIP + +
-
+ )}
{/* Clone dropdown */} - {showClone && ( + {showCloneControls && isGithubPath && showClone && ( <>
>(new Set()); const searchIndex = useMemo(() => buildSearchIndex(tree), [tree]); + const pathRef = useMemo( + () => refAndSubpathFromCodePath(pathname, base, defaultBranch).ref, + [pathname, base, defaultBranch], + ); + const currentPath = useMemo(() => { - const base = `/${owner}/${repo}`; - const blobPrefix = `${base}/blob/${defaultBranch}/`; - const treePrefix = `${base}/tree/${defaultBranch}/`; - if (pathname.startsWith(blobPrefix)) - return decodeURIComponent(pathname.slice(blobPrefix.length)); - if (pathname.startsWith(treePrefix)) - return decodeURIComponent(pathname.slice(treePrefix.length)); - return null; - }, [pathname, owner, repo, defaultBranch]); + return refAndSubpathFromCodePath(pathname, base, defaultBranch).filePath; + }, [pathname, base, defaultBranch]); useEffect(() => { if (!currentPath) return; @@ -264,9 +294,8 @@ export function FileExplorerTree({ tree, owner, repo, defaultBranch }: FileExplo
{tree.map((node) => ( @@ -274,9 +303,8 @@ export function FileExplorerTree({ tree, owner, repo, defaultBranch }: FileExplo key={node.path} node={node} depth={0} - owner={owner} - repo={repo} - defaultBranch={defaultBranch} + repoBasePath={base} + defaultBranch={pathRef} currentPath={currentPath} expandedPaths={expandedPaths} onToggle={toggleExpand} @@ -292,8 +320,7 @@ export function FileExplorerTree({ tree, owner, repo, defaultBranch }: FileExplo interface TreeNodeProps { node: FileTreeNode; depth: number; - owner: string; - repo: string; + repoBasePath: string; defaultBranch: string; currentPath: string | null; expandedPaths: Set; @@ -303,8 +330,7 @@ interface TreeNodeProps { const TreeNode = memo(function TreeNode({ node, depth, - owner, - repo, + repoBasePath, defaultBranch, currentPath, expandedPaths, @@ -360,8 +386,7 @@ const TreeNode = memo(function TreeNode({ key={child.path} node={child} depth={depth + 1} - owner={owner} - repo={repo} + repoBasePath={repoBasePath} defaultBranch={defaultBranch} currentPath={currentPath} expandedPaths={expandedPaths} @@ -376,7 +401,7 @@ const TreeNode = memo(function TreeNode({ return ( { if (a.type === "dir" && b.type !== "dir") return -1; if (a.type !== "dir" && b.type === "dir") return 1; @@ -33,13 +35,15 @@ export function FileList({ items, owner, repo, currentRef }: FileListProps) { ); } + const pathPrefix = linkBase === "storage" ? `/s/${owner}/${repo}` : `/${owner}/${repo}`; + return (
{sorted.map((item) => { const href = item.type === "dir" - ? `/${owner}/${repo}/tree/${currentRef}/${encodeFilePath(item.path)}` - : `/${owner}/${repo}/blob/${currentRef}/${encodeFilePath(item.path)}`; + ? `${pathPrefix}/tree/${currentRef}/${encodeFilePath(item.path)}` + : `${pathPrefix}/blob/${currentRef}/${encodeFilePath(item.path)}`; return ( (null); @@ -42,7 +45,7 @@ export function RepoBreadcrumb({ const fetchedRef = useRef(false); const inputRef = useRef(null); - const isOrg = ownerType === "Organization"; + const isOrg = ownerType === "Organization" && !repoBasePath; const fetchOrgRepos = useCallback(async () => { if (fetchedRef.current) return; @@ -97,12 +100,18 @@ export function RepoBreadcrumb({ className="rounded-sm border border-border" /> )} - - {owner} - + {repoBasePath ? ( + + {owner} + + ) : ( + + {owner} + + )} / {isOrg ? ( @@ -215,7 +224,7 @@ export function RepoBreadcrumb({ ) : ( {repoName} diff --git a/apps/web/src/components/repo/repo-layout-wrapper.tsx b/apps/web/src/components/repo/repo-layout-wrapper.tsx index d8422380..17c2c453 100644 --- a/apps/web/src/components/repo/repo-layout-wrapper.tsx +++ b/apps/web/src/components/repo/repo-layout-wrapper.tsx @@ -15,6 +15,8 @@ interface RepoLayoutWrapperProps { repo: string; ownerType: string; ownerAvatarUrl?: string; + /** Passed to collapsed breadcrumb (storage: `/s/owner/repo`). */ + repoBasePath?: string; initialCollapsed?: boolean; initialWidth?: number; } @@ -34,6 +36,7 @@ export function RepoLayoutWrapper({ initialWidth = DEFAULT_WIDTH, ownerType, ownerAvatarUrl, + repoBasePath, }: RepoLayoutWrapperProps) { const pathname = usePathname(); const isPrPage = pathname.includes("/pulls/"); @@ -247,6 +250,7 @@ export function RepoLayoutWrapper({ repoName={repo} ownerType={ownerType} ownerAvatarUrl={ownerAvatarUrl} + repoBasePath={repoBasePath} />
, navbarSlot, diff --git a/apps/web/src/components/repo/repo-nav.tsx b/apps/web/src/components/repo/repo-nav.tsx index 12f3c0bc..356146fe 100644 --- a/apps/web/src/components/repo/repo-nav.tsx +++ b/apps/web/src/components/repo/repo-nav.tsx @@ -11,6 +11,10 @@ import { useNavVisibility } from "@/components/shared/nav-visibility-provider"; interface RepoNavProps { owner: string; repo: string; + /** URL prefix for this repo, e.g. `/owner/repo` (GitHub) or `/s/owner/repo` (storage). */ + basePath?: string; + /** When false, skip live PR/issue count adjustments (storage repos). @default true */ + subscribeToRepoMutations?: boolean; openIssuesCount?: number; openPrsCount?: number; activeRunsCount?: number; @@ -24,6 +28,8 @@ interface RepoNavProps { export function RepoNav({ owner, repo, + basePath, + subscribeToRepoMutations = true, openIssuesCount, openPrsCount, activeRunsCount, @@ -34,7 +40,7 @@ export function RepoNav({ showPeopleTab, }: RepoNavProps) { const pathname = usePathname(); - const base = `/${owner}/${repo}`; + const base = basePath ?? `/${owner}/${repo}`; const containerRef = useRef(null); const [indicator, setIndicator] = useState({ left: 0, width: 0 }); const [hasAnimated, setHasAnimated] = useState(false); @@ -45,20 +51,22 @@ export function RepoNav({ }, [openPrsCount, openIssuesCount, promptRequestsCount]); useMutationSubscription( - [ - "pr:merged", - "pr:closed", - "pr:reopened", - "issue:closed", - "issue:reopened", - "issue:created", - "prompt:created", - "prompt:accepted", - "prompt:closed", - "prompt:reopened", - ], + subscribeToRepoMutations + ? [ + "pr:merged", + "pr:closed", + "pr:reopened", + "issue:closed", + "issue:reopened", + "issue:created", + "prompt:created", + "prompt:accepted", + "prompt:closed", + "prompt:reopened", + ] + : [], (event: MutationEvent) => { - if (!isRepoEvent(event, owner, repo)) return; + if (!subscribeToRepoMutations || !isRepoEvent(event, owner, repo)) return; setCountAdjustments((prev) => { switch (event.type) { case "pr:merged": diff --git a/apps/web/src/components/repo/storage-repo-empty-state.tsx b/apps/web/src/components/repo/storage-repo-empty-state.tsx new file mode 100644 index 00000000..dfa3c7d4 --- /dev/null +++ b/apps/web/src/components/repo/storage-repo-empty-state.tsx @@ -0,0 +1,28 @@ +export function StorageRepoNoBranchesState({ defaultBranch }: { defaultBranch: string }) { + return ( +
+

+ This repository has no branches yet. +

+

+ There is no{" "} + {defaultBranch} (or any) + branch until you push an initial commit. +

+
+ ); +} + +export function StorageRepoRefNotFoundState({ ref }: { ref: string }) { + return ( +
+

+ Branch or ref not found. +

+

+ {ref} does not exist in + this repository. +

+
+ ); +} diff --git a/apps/web/src/components/repo/storage-repo-sidebar.tsx b/apps/web/src/components/repo/storage-repo-sidebar.tsx new file mode 100644 index 00000000..96a3de5e --- /dev/null +++ b/apps/web/src/components/repo/storage-repo-sidebar.tsx @@ -0,0 +1,78 @@ +import Link from "next/link"; +import { HardDrive } from "lucide-react"; +import { RepoBreadcrumb } from "@/components/repo/repo-breadcrumb"; +import { RepoBadge } from "@/components/repo/repo-badge"; + +export function StorageRepoSidebar({ + owner, + repoName, + description, + visibility, + defaultBranch, + repoBasePath, +}: { + owner: string; + repoName: string; + description: string | null; + visibility: "public" | "private"; + defaultBranch: string; + repoBasePath: string; +}) { + const badges = [ + { type: visibility === "private" ? ("private" as const) : ("public" as const) }, + ]; + + return ( + + ); +} diff --git a/apps/web/src/components/repo/storage-repo-tab-placeholder.tsx b/apps/web/src/components/repo/storage-repo-tab-placeholder.tsx new file mode 100644 index 00000000..eac6bea0 --- /dev/null +++ b/apps/web/src/components/repo/storage-repo-tab-placeholder.tsx @@ -0,0 +1,10 @@ +export function StorageRepoTabPlaceholder({ label }: { label: string }) { + return ( +
+

{label}

+

+ Not available for git storage yet. +

+
+ ); +} diff --git a/apps/web/src/lib/auth-client.ts b/apps/web/src/lib/auth-client.ts index 2ad5f02d..e48e0a68 100644 --- a/apps/web/src/lib/auth-client.ts +++ b/apps/web/src/lib/auth-client.ts @@ -10,7 +10,6 @@ export const authClient = createAuthClient({ inferAdditionalFields(), dashClient(), sentinelClient(), - //@ts-expect-error - better-auth type issues stripeClient({ subscription: true }), deviceAuthorizationClient(), storageClient(), diff --git a/apps/web/src/lib/storage-file-tree.ts b/apps/web/src/lib/storage-file-tree.ts new file mode 100644 index 00000000..d4dd9174 --- /dev/null +++ b/apps/web/src/lib/storage-file-tree.ts @@ -0,0 +1,23 @@ +import { buildFileTree, type FileTreeNode } from "@/lib/file-tree"; + +/** + * Build explorer tree from Pierre flat file paths (all blobs; dirs inferred). + */ +export function buildStorageFileTree(files: Array<{ path: string; size: number }>): FileTreeNode[] { + const seenDir = new Set(); + const items: Array<{ path: string; type: string; size?: number }> = []; + + for (const f of files) { + const parts = f.path.split("/").filter(Boolean); + for (let i = 1; i < parts.length; i++) { + const dirPath = parts.slice(0, i).join("/"); + if (!seenDir.has(dirPath)) { + seenDir.add(dirPath); + items.push({ path: dirPath, type: "tree" }); + } + } + items.push({ path: f.path, type: "blob", size: f.size }); + } + + return buildFileTree(items); +} diff --git a/apps/web/src/lib/storage-git.ts b/apps/web/src/lib/storage-git.ts new file mode 100644 index 00000000..f0c9a25a --- /dev/null +++ b/apps/web/src/lib/storage-git.ts @@ -0,0 +1,105 @@ +import { headers } from "next/headers"; +import { isAPIError } from "better-auth/api"; +import { auth } from "./auth"; +import { prisma } from "@/lib/db"; + +export type StorageListItem = { + name: string; + path: string; + type: "file" | "dir"; + size?: number; +}; + +export type ListStorageDirectoryResult = + | { ok: false; reason: "no_branches"; defaultBranch: string } + | { ok: false; reason: "ref_not_found"; ref: string; defaultBranch: string } + | { + ok: true; + items: StorageListItem[]; + resolvedRef: string; + defaultBranch: string; + }; + +export type StorageBlobResult = + | { kind: "no_branches"; defaultBranch: string } + | { kind: "ref_not_found"; ref: string } + | { kind: "file_not_found" } + | { kind: "file"; content: string; size: number }; + +export type StorageGitMeta = { + defaultBranch: string; + branches: { name: string }[]; + files: Array<{ path: string; size: number }> | null; +}; + +export async function getMemberStorageRepository(owner: string, repo: string, userId: string) { + const slug = `${owner}/${repo}`; + return prisma.repository.findFirst({ + where: { + slug, + repositorymembers: { some: { userId } }, + }, + }); +} + +function storageSlug(owner: string, repo: string): `${string}/${string}` { + return `${owner}/${repo}`; +} + +export async function getStorageGitMeta( + owner: string, + repo: string, +): Promise { + const slug = storageSlug(owner, repo); + const h = await headers(); + try { + return await auth.api.repoGitMeta({ + query: { slug }, + headers: h, + }); + } catch (e) { + if (isAPIError(e) && e.statusCode === 404) return null; + throw e; + } +} + +export async function listStorageDirectory( + owner: string, + repo: string, + options: { ref?: string; pathPrefix: string }, +): Promise { + const slug = storageSlug(owner, repo); + const h = await headers(); + try { + return await auth.api.repoListDirectory({ + query: { + slug, + ref: options.ref, + pathPrefix: options.pathPrefix, + }, + headers: h, + }); + } catch (e) { + if (isAPIError(e) && e.statusCode === 404) return null; + throw e; + } +} + +export async function getStorageFileText( + owner: string, + repo: string, + path: string, + ref: string, +): Promise { + const slug = storageSlug(owner, repo); + const h = await headers(); + try { + return await auth.api.repoFile({ + query: { slug, ref, path }, + headers: h, + }); + } catch (e) { + if (isAPIError(e) && e.statusCode === 404) return null; + throw e; + } +} diff --git a/apps/web/src/proxy.ts b/apps/web/src/proxy.ts index 213819c0..c13c192e 100644 --- a/apps/web/src/proxy.ts +++ b/apps/web/src/proxy.ts @@ -5,6 +5,7 @@ const publicPaths = ["/", "/api/auth", "/api/inngest"]; const APP_ROUTES = new Set([ "dashboard", + "s", "repos", "issues", "prs", diff --git a/bun.lock b/bun.lock index 20408be6..fe322404 100644 --- a/bun.lock +++ b/bun.lock @@ -22,12 +22,12 @@ "@aws-sdk/client-s3": "^3.998.0", "@aws-sdk/s3-request-presigner": "^3.998.0", "@better-auth/infra": "0.1.9-beta.1", - "@better-auth/stripe": "1.5.1", + "@better-auth/stripe": "1.5.5", "@better-auth/utils": "^0.3.1", + "@better-hub/storage": "workspace:*", "@mixedbread-ai/sdk": "^2.2.11", "@octokit/rest": "^22.0.1", "@openrouter/ai-sdk-provider": "^2.2.3", - "@pierre/storage": "^1.3.2", "@prisma/adapter-pg": "^7.4.1", "@prisma/client": "^7.4.1", "@radix-ui/react-avatar": "^1.1.11", @@ -317,7 +317,7 @@ "@better-auth/sso": ["@better-auth/sso@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "fast-xml-parser": "^5.4.1", "jose": "^6.1.3", "samlify": "^2.10.2", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/core": "1.5.1", "better-auth": "1.5.1", "better-call": "1.3.2" } }, "sha512-c6xO8+eaKZ7kUCrazpbjSZGIUxDrjmdB+WIXFWeWi5kXCbWe2nl39j1kCwkiudFs0nmPKjtFGGNGNbJoleXiag=="], - "@better-auth/stripe": ["@better-auth/stripe@1.5.1", "", { "dependencies": { "defu": "^6.1.4", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/core": "1.5.1", "better-auth": "1.5.1", "better-call": "1.3.2", "stripe": "^18 || ^19 || ^20" } }, "sha512-YOOJ5pxtJ7EB7qf0TRegAUqI1AFL9SiONJiLqAwqBOpRquKbiOnypEOenNCuRBeK8NktURdcbQoT0rIeD7nVkQ=="], + "@better-auth/stripe": ["@better-auth/stripe@1.5.5", "", { "dependencies": { "defu": "^6.1.4", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/core": "1.5.5", "better-auth": "1.5.5", "better-call": "1.3.2", "stripe": "^18 || ^19 || ^20" } }, "sha512-cAqEsIurtuNnaXXDqykJwP3p4U2f6c7Ff4twzD0eWqo0hpBsT/EZPEcCGrYrxRAoozjmilANAffaef3Dm5Oj3g=="], "@better-auth/telemetry": ["@better-auth/telemetry@1.5.5", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.5" } }, "sha512-1+lklxArn4IMHuU503RcPdXrSG2tlXt4jnGG3omolmspQ7tktg/Y9XO/yAkYDurtvMn1xJ8X1Ov01Ji/r5s9BQ=="], @@ -2839,7 +2839,7 @@ "ts-toolbelt": ["ts-toolbelt@6.15.5", "", {}, "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A=="], - "tsdown": ["tsdown@0.21.2", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.4", "empathic": "^2.0.0", "hookable": "^6.0.1", "import-without-cache": "^0.2.5", "obug": "^2.1.1", "picomatch": "^4.0.3", "rolldown": "1.0.0-rc.9", "rolldown-plugin-dts": "^0.22.5", "semver": "^7.7.4", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0", "unrun": "^0.2.32" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.2", "@tsdown/exe": "0.21.2", "@vitejs/devtools": "*", "publint": "^0.3.0", "typescript": "^5.0.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "typescript", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-pP8eAcd1XAWjl5gjosuJs0BAuVoheUe3V8VDHx31QK7YOgXjcCMsBSyFWO3CMh/CSUkjRUzR96JtGH3WJFTExQ=="], + "tsdown": ["tsdown@0.21.4", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.4", "empathic": "^2.0.0", "hookable": "^6.1.0", "import-without-cache": "^0.2.5", "obug": "^2.1.1", "picomatch": "^4.0.3", "rolldown": "1.0.0-rc.9", "rolldown-plugin-dts": "^0.22.5", "semver": "^7.7.4", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0", "unrun": "^0.2.32" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.4", "@tsdown/exe": "0.21.4", "@vitejs/devtools": "*", "publint": "^0.3.0", "typescript": "^5.0.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "typescript", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-Q/kBi8SXkr4X6JI/NAZKZY1UuiEcbuXtIskL4tZCsgpDiEPM/2W6lC+OonNA31S+V3KsWedFvbFDBs23hvt+Aw=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -3031,10 +3031,6 @@ "@better-auth/sso/better-auth": ["better-auth@1.5.1", "", { "dependencies": { "@better-auth/core": "1.5.1", "@better-auth/drizzle-adapter": "1.5.1", "@better-auth/kysely-adapter": "1.5.1", "@better-auth/memory-adapter": "1.5.1", "@better-auth/mongo-adapter": "1.5.1", "@better-auth/prisma-adapter": "1.5.1", "@better-auth/telemetry": "1.5.1", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-Hnr4Ar49WpC0wyHFKYA86eQL5HhN5sNhtNquHrsH0T0r/IDqxDxAfW1VdSnTaXv4zc2WCXCQ8b1+InAopR2hAw=="], - "@better-auth/stripe/@better-auth/core": ["@better-auth/core@1.5.1", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@cloudflare/workers-types": ">=4", "better-call": "1.3.2", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types"] }, "sha512-lHDoChK6FFy3+oawt/tl9S08LuYNnbT1o3HKxleFrRtQIyIdUKu38X8AUJ8ueB6sE+ju5YhxBqoCFhdb6Aa67A=="], - - "@better-auth/stripe/better-auth": ["better-auth@1.5.1", "", { "dependencies": { "@better-auth/core": "1.5.1", "@better-auth/drizzle-adapter": "1.5.1", "@better-auth/kysely-adapter": "1.5.1", "@better-auth/memory-adapter": "1.5.1", "@better-auth/mongo-adapter": "1.5.1", "@better-auth/prisma-adapter": "1.5.1", "@better-auth/telemetry": "1.5.1", "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.1.1", "@noble/hashes": "^2.0.1", "better-call": "1.3.2", "defu": "^6.1.4", "jose": "^6.1.3", "kysely": "^0.28.11", "nanostores": "^1.1.1", "zod": "^4.3.6" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.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", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "@tanstack/solid-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-Hnr4Ar49WpC0wyHFKYA86eQL5HhN5sNhtNquHrsH0T0r/IDqxDxAfW1VdSnTaXv4zc2WCXCQ8b1+InAopR2hAw=="], - "@fastify/otel/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA=="], "@grpc/proto-loader/protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], @@ -3501,6 +3497,8 @@ "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "tsdown/tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + "vercel/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], "webpack/es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], @@ -3541,18 +3539,6 @@ "@better-auth/sso/better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.1" } }, "sha512-bHn9sdmf1bWUiC75J8FIF3rAEnL5ICihY5IBoXKVwxemaB3jSXL/sG9OpmadapPXlC8BY2OuATxdg39qbg+JlA=="], - "@better-auth/stripe/better-auth/@better-auth/drizzle-adapter": ["@better-auth/drizzle-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "drizzle-orm": ">=0.41.0" } }, "sha512-0KKIpDTi1IWXVHL//H8w0S8oQ9KjdlE5YgN9mMloMbU1uyxZ0shhUiT8mC9025vwkZ7OXLywI2hFeGJ+mcdRBQ=="], - - "@better-auth/stripe/better-auth/@better-auth/kysely-adapter": ["@better-auth/kysely-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "kysely": "^0.27.0 || ^0.28.0" } }, "sha512-OuhmNKjxpHlSw214kww4/tGfLHjtyC/HzN6Q/HulUeRF5QyCCHqj0y44ba6WGj3hcGsvPUkdUk4SayKXCrUCFw=="], - - "@better-auth/stripe/better-auth/@better-auth/memory-adapter": ["@better-auth/memory-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0" } }, "sha512-FSacaykLJXEizbnShF2FWZtWk5j0f87iq5Esjfd/7XHcF9nZeXn9Ju8jItDKeOWbEasOdfErEBqWSn30hmueRQ=="], - - "@better-auth/stripe/better-auth/@better-auth/mongo-adapter": ["@better-auth/mongo-adapter@1.5.1", "", { "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "mongodb": "^6.0.0 || ^7.0.0" } }, "sha512-BrbVuH1cqjs86Z6ae8OFEbvNLNxibddU4hDApVNtJcz7a/BaUPUdIM1Ep7HFhDozK7DrODXWZGLFXk+yV2pt3g=="], - - "@better-auth/stripe/better-auth/@better-auth/prisma-adapter": ["@better-auth/prisma-adapter@1.5.1", "", { "dependencies": { "@prisma/client": "^7.4.1" }, "peerDependencies": { "@better-auth/core": "1.5.1", "@better-auth/utils": "^0.3.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-24kBkBVaQbLnGe3/V/H+nX0hYaI+wNZFJhMnK16GQV7g6LyQw7UOcsd1xPDKtC61JCDmXEEEqXfnyuw5QITMVw=="], - - "@better-auth/stripe/better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.5.1", "", { "dependencies": { "@better-auth/utils": "0.3.1", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.5.1" } }, "sha512-bHn9sdmf1bWUiC75J8FIF3rAEnL5ICihY5IBoXKVwxemaB3jSXL/sG9OpmadapPXlC8BY2OuATxdg39qbg+JlA=="], - "@fastify/otel/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="], "@inngest/ai/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], diff --git a/packages/storage/package.json b/packages/storage/package.json index af324bce..5c1bb094 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -13,7 +13,6 @@ ], "type": "module", "exports": { - ".": "./dist/index.mjs", "./adapter": "./dist/adapter.mjs", "./client": "./dist/client.mjs", "./db-schema": "./dist/db-schema.mjs", diff --git a/packages/storage/src/adapter.ts b/packages/storage/src/adapter.ts index 6f2dcb15..142addcb 100644 --- a/packages/storage/src/adapter.ts +++ b/packages/storage/src/adapter.ts @@ -1,5 +1,5 @@ import { APIError, type GenericEndpointContext, type User } from "better-auth"; -import { storage } from "."; +import { gitStorage } from "./git-storage"; import type { RepositoryMember, Repository, @@ -18,7 +18,7 @@ export const storageAdapter = (ctx: GenericEndpointContext) => { description?: string | undefined; }) => { const adapter = ctx.context.adapter; - const repo = await storage.createRepo(); + const repo = await gitStorage.createRepo(); const repositoryData: RepositoryInput = { name: options.name, @@ -87,6 +87,22 @@ export const storageAdapter = (ctx: GenericEndpointContext) => { }); return repo; }, + findRepoBySlugForUser: async (slug: `${string}/${string}`, userId: string) => { + const adapter = ctx.context.adapter; + const repo = await adapter.findOne({ + model: "repository", + where: [{ field: "slug", value: slug }], + }); + if (!repo) return null; + const member = await adapter.findOne({ + model: "repositoryMember", + where: [ + { field: "userId", value: userId }, + { field: "repositoryId", value: repo.id }, + ], + }); + return member ? repo : null; + }, deleteRepo: async (id: string) => { const adapter = ctx.context.adapter; await adapter.delete({ diff --git a/packages/storage/src/git-storage.ts b/packages/storage/src/git-storage.ts new file mode 100644 index 00000000..b8f26655 --- /dev/null +++ b/packages/storage/src/git-storage.ts @@ -0,0 +1,11 @@ +import { GitStorage } from "@pierre/storage"; + +const name = process.env["GIT_STORAGE_NAME"] ?? "better-hub"; +const key = process.env["GIT_STORAGE_PRIVATE_KEY"]; + +if (!key) { + throw new Error("Missing GIT_STORAGE_PRIVATE_KEY environment variable"); +} + +/** Package-private Pierre client — not re-exported from the package root. */ +export const gitStorage = new GitStorage({ name, key }); diff --git a/packages/storage/src/index.ts b/packages/storage/src/index.ts deleted file mode 100644 index af12eeb6..00000000 --- a/packages/storage/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GitStorage } from "@pierre/storage"; - -export const storage = new GitStorage({ - name: "better-hub", - key: process.env["GIT_STORAGE_PRIVATE_KEY"]!, -}); diff --git a/packages/storage/src/lib/storage-tree.ts b/packages/storage/src/lib/storage-tree.ts new file mode 100644 index 00000000..3732f090 --- /dev/null +++ b/packages/storage/src/lib/storage-tree.ts @@ -0,0 +1,164 @@ +import { ApiError } from "@pierre/storage"; + +export type StorageListItem = { + name: string; + path: string; + type: "file" | "dir"; + size?: number; +}; + +/** + * Flat file list from Pierre → immediate children of `dirPrefix` ("" = repo root). + */ +export function immediateChildrenFromPaths( + files: Array<{ path: string; size: number }>, + dirPrefix: string, +): StorageListItem[] { + const norm = dirPrefix.replace(/^\/+|\/+$/g, ""); + const p = norm ? `${norm}/` : ""; + const map = new Map(); + + for (const f of files) { + if (!f.path.startsWith(p)) continue; + const rest = f.path.slice(p.length); + if (!rest) continue; + const slash = rest.indexOf("/"); + const name = slash === -1 ? rest : rest.slice(0, slash); + const isDir = slash !== -1; + if (isDir) { + map.set(name, { + name, + path: norm ? `${norm}/${name}` : name, + type: "dir", + }); + } else { + map.set(name, { + name, + path: f.path, + type: "file", + size: f.size, + }); + } + } + + return [...map.values()].sort((a, b) => { + if (a.type === "dir" && b.type !== "dir") return -1; + if (a.type !== "dir" && b.type === "dir") return 1; + return a.name.localeCompare(b.name); + }); +} + +export function branchListIncludesRef( + branches: Array<{ name: string; headSha: string }>, + ref: string, +): boolean { + return branches.some((b) => b.name === ref || b.headSha === ref); +} + +export type ListStorageDirectoryResult = + | { ok: false; reason: "no_branches"; defaultBranch: string } + | { ok: false; reason: "ref_not_found"; ref: string; defaultBranch: string } + | { + ok: true; + items: StorageListItem[]; + resolvedRef: string; + defaultBranch: string; + }; + +type RemoteForList = { + defaultBranch: string; + listBranches: () => Promise<{ branches: Array<{ name: string; headSha: string }> }>; + listFilesWithMetadata: (args: { + ref: string; + }) => Promise<{ files: Array<{ path: string; size: number }>; ref: string }>; +}; + +export async function listStorageDirectoryFromRemote( + remote: RemoteForList, + options: { ref?: string; pathPrefix: string }, +): Promise { + const { branches } = await remote.listBranches(); + if (branches.length === 0) { + return { + ok: false, + reason: "no_branches", + defaultBranch: remote.defaultBranch, + }; + } + + const ref = options.ref ?? remote.defaultBranch; + if (!branchListIncludesRef(branches, ref)) { + return { + ok: false, + reason: "ref_not_found", + ref, + defaultBranch: remote.defaultBranch, + }; + } + + try { + const meta = await remote.listFilesWithMetadata({ ref }); + return { + ok: true, + items: immediateChildrenFromPaths(meta.files, options.pathPrefix), + resolvedRef: meta.ref, + defaultBranch: remote.defaultBranch, + }; + } catch (e) { + if (e instanceof ApiError && e.status === 404) { + return { + ok: false, + reason: "ref_not_found", + ref, + defaultBranch: remote.defaultBranch, + }; + } + throw e; + } +} + +export type StorageBlobResult = + | { kind: "no_branches"; defaultBranch: string } + | { kind: "ref_not_found"; ref: string } + | { kind: "file_not_found" } + | { kind: "file"; content: string; size: number }; + +type RemoteForFile = { + defaultBranch: string; + listBranches: () => Promise<{ branches: Array<{ name: string; headSha: string }> }>; + getFileStream: (args: { path: string; ref: string }) => Promise; +}; + +export async function getStorageFileTextFromRemote( + remote: RemoteForFile, + path: string, + ref: string, +): Promise { + const { branches } = await remote.listBranches(); + if (branches.length === 0) { + return { kind: "no_branches", defaultBranch: remote.defaultBranch }; + } + + if (!branchListIncludesRef(branches, ref)) { + return { kind: "ref_not_found", ref }; + } + + const res = await remote.getFileStream({ path, ref }); + if (!res.ok) { + if (res.status === 404) return { kind: "file_not_found" }; + throw new Error(`Pierre getFileStream failed: ${res.status}`); + } + + const content = await res.text(); + const cl = res.headers.get("content-length"); + const size = + cl !== null && cl !== "" + ? Number.parseInt(cl, 10) + : Buffer.byteLength(content, "utf8"); + + return { + kind: "file", + content, + size: Number.isFinite(size) ? size : content.length, + }; +} diff --git a/packages/storage/src/plugin.ts b/packages/storage/src/plugin.ts index c92839f9..b693bb43 100644 --- a/packages/storage/src/plugin.ts +++ b/packages/storage/src/plugin.ts @@ -5,6 +5,9 @@ import { cloneRepo } from "./routes/clone-repo"; import { createRepo } from "./routes/create-repo"; import { listRepo } from "./routes/list-repo"; import { deleteRepo } from "./routes/delete-repo"; +import { repoFile } from "./routes/repo-file"; +import { repoGitMeta } from "./routes/repo-git-meta"; +import { repoListDirectory } from "./routes/repo-list-directory"; export const storagePlugin = () => { return { @@ -23,6 +26,9 @@ export const storagePlugin = () => { createRepo: createRepo, listRepo: listRepo, deleteRepo: deleteRepo, + repoFile: repoFile, + repoGitMeta: repoGitMeta, + repoListDirectory: repoListDirectory, }, } satisfies BetterAuthPlugin; }; diff --git a/packages/storage/src/routes/create-repo.ts b/packages/storage/src/routes/create-repo.ts index 5d104672..ec83bfe2 100644 --- a/packages/storage/src/routes/create-repo.ts +++ b/packages/storage/src/routes/create-repo.ts @@ -8,7 +8,7 @@ import { slugSchema, } from "../zod-schema"; import { storageMiddleware } from "../lib/middleware"; -import { storage } from ".."; +import { gitStorage } from "../git-storage"; const body = z.object({ name: repositoryNameSchema, @@ -46,7 +46,7 @@ export const createRepo = createAuthEndpoint( const result = await adapter.createRepo(data); if ("repository" in result) { - const repository = await storage.createRepo({ + const repository = await gitStorage.createRepo({ id: result.repository.id, }); const remoteURL = await repository.getRemoteURL({ diff --git a/packages/storage/src/routes/delete-repo.ts b/packages/storage/src/routes/delete-repo.ts index 0d926901..60563e12 100644 --- a/packages/storage/src/routes/delete-repo.ts +++ b/packages/storage/src/routes/delete-repo.ts @@ -1,6 +1,6 @@ import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; import { storageMiddleware } from "../lib/middleware"; -import { storage } from ".."; +import { gitStorage } from "../git-storage"; import * as z from "zod/v4"; import { storageAdapter } from "../adapter"; @@ -31,7 +31,7 @@ export const deleteRepo = createAuthEndpoint( } await adapter.deleteRepo(ctx.body.id); try { - await storage.deleteRepo({ + await gitStorage.deleteRepo({ id: ctx.body.id, }); } catch { diff --git a/packages/storage/src/routes/repo-file.ts b/packages/storage/src/routes/repo-file.ts new file mode 100644 index 00000000..a17520e7 --- /dev/null +++ b/packages/storage/src/routes/repo-file.ts @@ -0,0 +1,43 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import * as z from "zod/v4"; +import { slugSchema } from "../zod-schema"; +import { storageMiddleware } from "../lib/middleware"; +import { storageAdapter } from "../adapter"; +import { gitStorage } from "../git-storage"; +import { getStorageFileTextFromRemote } from "../lib/storage-tree"; + +const query = z.object({ + slug: slugSchema, + ref: z.string(), + path: z.string(), +}); + +export const repoFile = createAuthEndpoint( + "/storage/repo/file", + { + method: "GET", + use: [sessionMiddleware, storageMiddleware], + query, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const { slug, ref, path } = ctx.query; + const repo = await adapter.findRepoBySlugForUser(slug, ctx.context.session.user.id); + if (!repo) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + const remote = await gitStorage.findOne({ id: repo.id }); + if (!remote) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + return getStorageFileTextFromRemote(remote, path, ref); + }, +); diff --git a/packages/storage/src/routes/repo-git-meta.ts b/packages/storage/src/routes/repo-git-meta.ts new file mode 100644 index 00000000..194c3f1b --- /dev/null +++ b/packages/storage/src/routes/repo-git-meta.ts @@ -0,0 +1,59 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import * as z from "zod/v4"; +import { slugSchema } from "../zod-schema"; +import { storageMiddleware } from "../lib/middleware"; +import { storageAdapter } from "../adapter"; +import { gitStorage } from "../git-storage"; + +const query = z.object({ + slug: slugSchema, +}); + +export const repoGitMeta = createAuthEndpoint( + "/storage/repo/git-meta", + { + method: "GET", + use: [sessionMiddleware, storageMiddleware], + query, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const { slug } = ctx.query; + const repo = await adapter.findRepoBySlugForUser(slug, ctx.context.session.user.id); + if (!repo) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + const remote = await gitStorage.findOne({ id: repo.id }); + if (!remote) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + const { branches } = await remote.listBranches(); + const branchRows = branches.map((b) => ({ name: b.name })); + + let files: Array<{ path: string; size: number }> | null = null; + if (branches.length > 0) { + try { + const meta = await remote.listFilesWithMetadata({ + ref: remote.defaultBranch, + }); + files = meta.files; + } catch { + files = null; + } + } + + return { + defaultBranch: remote.defaultBranch, + branches: branchRows, + files, + }; + }, +); diff --git a/packages/storage/src/routes/repo-list-directory.ts b/packages/storage/src/routes/repo-list-directory.ts new file mode 100644 index 00000000..e7ee2c0c --- /dev/null +++ b/packages/storage/src/routes/repo-list-directory.ts @@ -0,0 +1,47 @@ +import { createAuthEndpoint, sessionMiddleware } from "better-auth/api"; +import * as z from "zod/v4"; +import { slugSchema } from "../zod-schema"; +import { storageMiddleware } from "../lib/middleware"; +import { storageAdapter } from "../adapter"; +import { gitStorage } from "../git-storage"; +import { listStorageDirectoryFromRemote } from "../lib/storage-tree"; + +const query = z.object({ + slug: slugSchema, + ref: z.string().optional(), + pathPrefix: z.string().optional(), +}); + +export const repoListDirectory = createAuthEndpoint( + "/storage/repo/list-directory", + { + method: "GET", + use: [sessionMiddleware, storageMiddleware], + query, + }, + async (ctx) => { + const adapter = storageAdapter(ctx); + const { slug, ref, pathPrefix } = ctx.query; + const repo = await adapter.findRepoBySlugForUser(slug, ctx.context.session.user.id); + if (!repo) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + const remote = await gitStorage.findOne({ id: repo.id }); + if (!remote) { + throw ctx.error("NOT_FOUND", { + message: "Repository not found or you don't have access", + code: "REPOSITORY_NOT_FOUND", + }); + } + + const opts: { ref?: string; pathPrefix: string } = { + pathPrefix: pathPrefix ?? "", + }; + if (ref !== undefined) opts.ref = ref; + return listStorageDirectoryFromRemote(remote, opts); + }, +); diff --git a/packages/storage/tsdown.config.ts b/packages/storage/tsdown.config.ts index fe5b41d3..3ea92e12 100644 --- a/packages/storage/tsdown.config.ts +++ b/packages/storage/tsdown.config.ts @@ -1,13 +1,7 @@ import { defineConfig } from "tsdown"; export default defineConfig({ - entry: [ - "src/index.ts", - "src/client.ts", - "src/plugin.ts", - "src/adapter.ts", - "src/db-schema.ts", - ], + entry: ["src/client.ts", "src/plugin.ts", "src/adapter.ts", "src/db-schema.ts"], format: "esm", dts: true, clean: true, From a227c962960391c1ea1e93aa4d13b5788861f69a Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Mon, 23 Mar 2026 14:21:21 +1000 Subject: [PATCH 09/10] add: commits UI --- .cursor/debug.log | 2 + agent-docs/frontend/components.md | 71 +++-- .../repos/[owner]/[repo]/commits/actions.ts | 1 + .../s/[owner]/[repo]/commits/[sha]/page.tsx | 62 ++++ .../(app)/s/[owner]/[repo]/commits/actions.ts | 75 +++++ .../(app)/s/[owner]/[repo]/commits/page.tsx | 66 ++++- .../src/app/(app)/s/[owner]/[repo]/layout.tsx | 32 ++- .../web/src/components/repo/commit-detail.tsx | 15 +- apps/web/src/components/repo/commits-list.tsx | 269 ++++++++++++++---- .../components/repo/repo-sidebar-identity.tsx | 58 ++++ apps/web/src/components/repo/repo-sidebar.tsx | 43 +-- .../components/repo/storage-repo-sidebar.tsx | 42 +-- .../lib/auth-hooks/backfill-github-login.ts | 1 - apps/web/src/lib/github-utils.ts | 16 ++ apps/web/src/lib/storage-git.ts | 69 +++++ packages/storage/src/client.ts | 5 + .../src/lib/map-storage-commit-detail.ts | 99 +++++++ .../storage/src/lib/storage-commit-walk.ts | 44 +++ packages/storage/src/plugin.ts | 4 + .../storage/src/routes/repo-commit-detail.ts | 79 +++++ packages/storage/src/routes/repo-commits.ts | 73 +++++ 21 files changed, 971 insertions(+), 155 deletions(-) create mode 100644 .cursor/debug.log create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/commits/[sha]/page.tsx create mode 100644 apps/web/src/app/(app)/s/[owner]/[repo]/commits/actions.ts create mode 100644 apps/web/src/components/repo/repo-sidebar-identity.tsx create mode 100644 packages/storage/src/lib/map-storage-commit-detail.ts create mode 100644 packages/storage/src/lib/storage-commit-walk.ts create mode 100644 packages/storage/src/routes/repo-commit-detail.ts create mode 100644 packages/storage/src/routes/repo-commits.ts diff --git a/.cursor/debug.log b/.cursor/debug.log new file mode 100644 index 00000000..414e2bd6 --- /dev/null +++ b/.cursor/debug.log @@ -0,0 +1,2 @@ +{"location":"map-storage-commit-detail.ts:buildCommitDetailPayload","message":"pierre first file raw prefix","data":{"path":"test.ts","state":"deleted","rawLen":134,"rawPrefix":"diff --git a/test.ts b/test.ts\ndeleted file mode 100644\nindex 54b82a0..0000000\n--- a/test.ts\n+++ /dev/null\n@@ -1 +0,0 @@\n-const a = 1;"},"timestamp":1774205454126,"hypothesisId":"H1-H4"} +{"location":"map-storage-commit-detail.ts:buildCommitDetailPayload","message":"pierre first file raw prefix","data":{"path":"test.ts","state":"deleted","rawLen":134,"rawPrefix":"diff --git a/test.ts b/test.ts\ndeleted file mode 100644\nindex 54b82a0..0000000\n--- a/test.ts\n+++ /dev/null\n@@ -1 +0,0 @@\n-const a = 1;"},"timestamp":1774205459285,"hypothesisId":"H1-H4"} diff --git a/agent-docs/frontend/components.md b/agent-docs/frontend/components.md index a2fb6a2d..b5b5598b 100644 --- a/agent-docs/frontend/components.md +++ b/agent-docs/frontend/components.md @@ -5,21 +5,26 @@ Components live in `apps/web/src/components/` and are organized by feature domai ## Directory Structure ### `layout/` -- App Shell (3 files) + - `navbar.tsx` -- Top navigation bar with user menu, notifications, command palette trigger - `nav-aware-content.tsx` -- Content wrapper that adjusts for navbar visibility - `notification-sheet.tsx` -- Slide-out notification panel -### `repo/` -- Repository Views (38 files) +### `repo/` -- Repository Views (39 files) The largest component group, covering all repository UI: **Layout** + - `repo-layout-wrapper.tsx` -- Outer wrapper managing sidebar + content split - `repo-sidebar.tsx` -- Left sidebar: description, stats, topics, license, links, contributors, languages +- `repo-sidebar-identity.tsx` -- Shared repo header (breadcrumb, owner avatar image, description, badges) used by `repo-sidebar.tsx` and `storage-repo-sidebar.tsx` +- `storage-repo-sidebar.tsx` -- Git storage (`/s/...`) sidebar; same identity block as GitHub repos, plus storage-specific info - `repo-nav.tsx` -- Tab navigation (Code, Issues, PRs, Actions, Discussions, etc.) - `code-content-wrapper.tsx` -- Wraps code views with file tree and branch selector **Code Browsing** + - `code-viewer.tsx` / `code-viewer-client.tsx` -- File content display with syntax highlighting - `file-list.tsx` -- Directory listing (table of files) - `file-explorer-tree.tsx` -- Sidebar file tree @@ -28,6 +33,7 @@ The largest component group, covering all repository UI: - `document-outline.tsx` -- Markdown heading outline **Repository Info** + - `repo-overview.tsx` -- Main repo page (README + file list) - `repo-badge.tsx` -- Repo visibility badge (public/private) - `repo-breadcrumb.tsx` / `breadcrumb-nav.tsx` -- Path breadcrumbs @@ -36,11 +42,13 @@ The largest component group, covering all repository UI: - `insights-view.tsx` -- Repository insights **Branch/Tag Management** + - `branch-selector.tsx` -- Branch/tag dropdown - `sidebar-branch-switcher.tsx` -- Sidebar branch switcher - `tags-list.tsx` -- Tags listing page **Releases and Commits** + - `releases-list.tsx` -- Releases listing - `release-detail.tsx` -- Individual release view - `commits-list.tsx` -- Commit history @@ -48,11 +56,13 @@ The largest component group, covering all repository UI: - `latest-commit-section.tsx` -- Latest commit display in code view **Sidebar Sections** + - `sidebar-contributors.tsx` -- Top contributors with avatars - `sidebar-languages.tsx` -- Language breakdown bar - `sidebar-used-by.tsx` -- "Used by" section **Actions** + - `star-button.tsx` -- Star/unstar repo - `fork-button.tsx` -- Fork repo - `fork-sync-button.tsx` -- Sync fork with upstream @@ -62,6 +72,7 @@ The largest component group, covering all repository UI: - `readme-toolbar.tsx` -- README view toolbar **Utilities** + - `repo-revalidator.tsx` -- Triggers background data revalidation ### `pr/` -- Pull Request UI (30 files) @@ -69,12 +80,15 @@ The largest component group, covering all repository UI: See [features/pr-reviews.md](../features/pr-reviews.md) for detailed documentation. ### `issue/` -- Issue Detail + Components for viewing and interacting with individual issues. ### `issues/` -- Issue Listing + Components for the issues list view with filtering and sorting. ### `prs/` -- PR Listing + Components for the pull requests list view. ### `shared/` -- Cross-Cutting Components (32 files) @@ -82,6 +96,7 @@ Components for the pull requests list view. Reusable components used across multiple features: **AI** + - `ai-chat.tsx` -- Chat interface component - `global-chat-panel.tsx` -- Ghost AI slide-out panel - `global-chat-provider.tsx` -- Chat state context provider @@ -89,6 +104,7 @@ Reusable components used across multiple features: - `chat-page-activator.tsx` -- Sets chat context based on current page **Markdown** + - `markdown-renderer.tsx` -- Server-side markdown rendering - `client-markdown.tsx` -- Client-side markdown rendering - `markdown-editor.tsx` -- TipTap-based markdown editor @@ -97,14 +113,17 @@ Reusable components used across multiple features: - `github-emoji.tsx` -- GitHub emoji rendering **Code** + - `highlighted-code-block.tsx` -- Syntax-highlighted code block - `reactive-code-blocks.tsx` -- Interactive code blocks with copy buttons **Comments** + - `comment.tsx` -- Individual comment component - `comment-thread.tsx` -- Threaded comment display **GitHub UI** + - `github-avatar.tsx` -- GitHub user avatar with fallback - `github-link-interceptor.tsx` -- Rewrites github.com links to Better Hub - `user-tooltip.tsx` -- User info tooltip on hover @@ -113,16 +132,19 @@ Reusable components used across multiple features: - `reaction-display.tsx` -- Emoji reaction display and picker **Navigation** + - `navigation-progress.tsx` -- Top loading bar - `nav-visibility-provider.tsx` -- Navbar visibility context **Actions** + - `refresh-button.tsx` -- Force refresh button - `copy-link-button.tsx` -- Copy URL to clipboard - `pin-button.tsx` -- Pin item button - `track-view.tsx` -- View tracking component **Utilities** + - `list-controls.tsx` -- List filtering/sorting controls - `mention-suggestion.tsx` -- @mention autocomplete - `mutation-event-provider.tsx` -- Mutation event bus context @@ -150,37 +172,40 @@ Low-level UI components, mostly wrapping Radix UI: ### Other Feature Directories -| Directory | Purpose | -|---|---| -| `dashboard/` | Dashboard page widgets | -| `search/` | Search UI and results | -| `settings/` | User settings panels | -| `settings/tabs/` | Individual settings tab content | -| `actions/` | CI/CD workflow views | -| `discussion/` | Discussion UI | -| `notifications/` | Notification list and items | -| `onboarding/` | First-run onboarding overlay | -| `orgs/` | Organization views | -| `people/` | People/contributors views | -| `security/` | Security advisory views | -| `trending/` | Trending repos view | -| `users/` | User profile views | -| `users/activity-timeline/` | Activity timeline components | -| `repos/` | Repository listing views | -| `prompt-request/` | Prompt request UI | -| `extension/` | Browser extension promo | -| `providers/` | React context providers | -| `pwa/` | PWA support | -| `theme/` | Theme provider and selector | +| Directory | Purpose | +| -------------------------- | ------------------------------- | +| `dashboard/` | Dashboard page widgets | +| `search/` | Search UI and results | +| `settings/` | User settings panels | +| `settings/tabs/` | Individual settings tab content | +| `actions/` | CI/CD workflow views | +| `discussion/` | Discussion UI | +| `notifications/` | Notification list and items | +| `onboarding/` | First-run onboarding overlay | +| `orgs/` | Organization views | +| `people/` | People/contributors views | +| `security/` | Security advisory views | +| `trending/` | Trending repos view | +| `users/` | User profile views | +| `users/activity-timeline/` | Activity timeline components | +| `repos/` | Repository listing views | +| `prompt-request/` | Prompt request UI | +| `extension/` | Browser extension promo | +| `providers/` | React context providers | +| `pwa/` | PWA support | +| `theme/` | Theme provider and selector | ## Component Patterns ### Server vs Client Components + - **Server components** (default): Used for data fetching, database access, rendering with session context. No `"use client"` directive. - **Client components**: Used for interactivity (event handlers, state, effects). Marked with `"use client"` at the top. ### Data Passing + Server components fetch data and pass it as props to client components. The `use-server-initial-data.ts` hook pattern hydrates server-fetched data into client state without refetching. ### Optimistic Updates + The `use-mutation.ts` hook provides optimistic update support. `MutationEventProvider` and `use-mutation-subscription.ts` enable cross-component communication after mutations. diff --git a/apps/web/src/app/(app)/repos/[owner]/[repo]/commits/actions.ts b/apps/web/src/app/(app)/repos/[owner]/[repo]/commits/actions.ts index 5f799c70..8c5d4330 100644 --- a/apps/web/src/app/(app)/repos/[owner]/[repo]/commits/actions.ts +++ b/apps/web/src/app/(app)/repos/[owner]/[repo]/commits/actions.ts @@ -104,6 +104,7 @@ export async function fetchCommitDetail( owner: string, repo: string, sha: string, + _branch?: string, ): Promise<{ commit: CommitDetailData | null; highlightData: Record>; diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/commits/[sha]/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/[sha]/page.tsx new file mode 100644 index 00000000..5c44823b --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/[sha]/page.tsx @@ -0,0 +1,62 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { CommitDetail } from "@/components/repo/commit-detail"; +import { getServerSession } from "@/lib/auth"; +import { getMemberStorageRepository } from "@/lib/storage-git"; +import { fetchStorageCommitDetail } from "../actions"; + +export const runtime = "nodejs"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string; sha: string }>; +}): Promise { + const { owner, repo, sha } = await params; + const shortSha = sha.slice(0, 7); + return { title: `Commit ${shortSha} · ${owner}/${repo}` }; +} + +export default async function StorageCommitDetailPage({ + params, + searchParams, +}: { + params: Promise<{ owner: string; repo: string; sha: string }>; + searchParams: Promise<{ branch?: string }>; +}) { + const { owner, repo: repoName, sha } = await params; + const { branch } = await searchParams; + + const session = await getServerSession(); + if (!session?.user) notFound(); + + const record = await getMemberStorageRepository(owner, repoName, session.user.id); + if (!record) notFound(); + + const { commit, highlightData } = await fetchStorageCommitDetail( + owner, + repoName, + sha, + branch, + ); + + if (!commit) { + return ( +
+

+ Commit not found +

+
+ ); + } + + return ( + + ); +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/commits/actions.ts b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/actions.ts new file mode 100644 index 00000000..9eb7b774 --- /dev/null +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/actions.ts @@ -0,0 +1,75 @@ +"use server"; + +import { listStorageCommits, getStorageCommitDetailPayload } from "@/lib/storage-git"; +import { highlightDiffLines, type SyntaxToken } from "@/lib/shiki"; +import type { CommitDetailData } from "@/app/(app)/repos/[owner]/[repo]/commits/actions"; +import type { StorageCommitListRow } from "@/lib/storage-git"; + +export async function fetchStorageCommitsByDate( + owner: string, + repo: string, + _since?: string, + _until?: string, + branch?: string, +): Promise<{ commits: StorageCommitListRow[]; nextCursor: string | null; hasMore: boolean }> { + return ( + (await listStorageCommits(owner, repo, { branch, limit: 30 })) ?? { + commits: [], + nextCursor: null, + hasMore: false, + } + ); +} + +export async function fetchStorageCommitsNext( + owner: string, + repo: string, + branch: string, + cursor: string, + _since?: string, + _until?: string, +): Promise<{ commits: StorageCommitListRow[]; nextCursor: string | null; hasMore: boolean }> { + return ( + (await listStorageCommits(owner, repo, { branch, cursor, limit: 30 })) ?? { + commits: [], + nextCursor: null, + hasMore: false, + } + ); +} + +export async function fetchStorageCommitDetail( + owner: string, + repo: string, + sha: string, + branch?: string, +): Promise<{ + commit: CommitDetailData | null; + highlightData: Record>; +}> { + const commit = await getStorageCommitDetailPayload(owner, repo, sha, branch); + if (!commit) { + return { commit: null, highlightData: {} }; + } + + const highlightData: Record> = {}; + if (commit.files && commit.files.length > 0) { + await Promise.all( + commit.files.map(async (file: { filename: string; patch?: string }) => { + if (file.patch) { + try { + highlightData[file.filename] = + await highlightDiffLines( + file.patch, + file.filename, + ); + } catch { + // silent + } + } + }), + ); + } + + return { commit, highlightData }; +} diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx index 5f798bda..e075049b 100644 --- a/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/commits/page.tsx @@ -1,5 +1,65 @@ -import { StorageRepoTabPlaceholder } from "@/components/repo/storage-repo-tab-placeholder"; +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { CommitsList } from "@/components/repo/commits-list"; +import type { Commit } from "@/components/repo/commits-list"; +import { getServerSession } from "@/lib/auth"; +import { + getMemberStorageRepository, + getStorageGitMeta, + listStorageCommits, +} from "@/lib/storage-git"; +import { + fetchStorageCommitDetail, + fetchStorageCommitsByDate, + fetchStorageCommitsNext, +} from "./actions"; -export default function StorageCommitsPage() { - return ; +export const runtime = "nodejs"; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ owner: string; repo: string }>; +}): Promise { + const { owner, repo } = await params; + return { title: `Commits · ${owner}/${repo}` }; +} + +export default async function StorageCommitsPage({ + params, +}: { + params: Promise<{ owner: string; repo: string }>; +}) { + const { owner, repo: repoName } = await params; + const session = await getServerSession(); + if (!session?.user) notFound(); + + const record = await getMemberStorageRepository(owner, repoName, session.user.id); + if (!record) notFound(); + + const [gitMeta, data] = await Promise.all([ + getStorageGitMeta(owner, repoName), + listStorageCommits(owner, repoName, { limit: 30 }), + ]); + if (!gitMeta) notFound(); + if (!data) notFound(); + + return ( + + ); } diff --git a/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx b/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx index 07e5decb..c0750293 100644 --- a/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx +++ b/apps/web/src/app/(app)/s/[owner]/[repo]/layout.tsx @@ -5,6 +5,7 @@ import { RepoNav } from "@/components/repo/repo-nav"; import { CodeContentWrapper } from "@/components/repo/code-content-wrapper"; import { StorageRepoSidebar } from "@/components/repo/storage-repo-sidebar"; import { getServerSession } from "@/lib/auth"; +import { getUser } from "@/lib/github"; import { getMemberStorageRepository, getStorageGitMeta } from "@/lib/storage-git"; import { buildStorageFileTree } from "@/lib/storage-file-tree"; import { @@ -26,13 +27,37 @@ export default async function StorageRepoLayout({ const session = await getServerSession(); if (!session?.user) notFound(); - const [record, gitMeta] = await Promise.all([ + const [record, gitMeta, ownerProfile] = await Promise.all([ getMemberStorageRepository(owner, repoName, session.user.id), getStorageGitMeta(owner, repoName), + getUser(owner), ]); if (!record) notFound(); if (!gitMeta) notFound(); + const gh = session.githubUser; + const ghLogin = gh && typeof gh.login === "string" ? gh.login : null; + const avatarFromMatchingSession = + gh && + typeof gh.avatar_url === "string" && + ghLogin?.toLowerCase() === owner.toLowerCase() + ? gh.avatar_url + : undefined; + + let ownerAvatarUrl = + (typeof ownerProfile?.avatar_url === "string" + ? ownerProfile.avatar_url + : undefined) ?? avatarFromMatchingSession; + + if (!ownerAvatarUrl && typeof session.user.image === "string") { + ownerAvatarUrl = session.user.image; + } + if (!ownerAvatarUrl) { + ownerAvatarUrl = `https://github.com/identicons/${encodeURIComponent(owner)}.png`; + } + + const ownerType = ownerProfile?.type === "Organization" ? "Organization" : "User"; + const initialBranches = gitMeta.branches; let tree: FileTreeNode[] | null = null; @@ -57,7 +82,8 @@ export default async function StorageRepoLayout({ >; } @@ -109,7 +111,14 @@ const DEFAULT_SIDEBAR_WIDTH = 300; const MIN_SIDEBAR_WIDTH = 140; const MAX_SIDEBAR_WIDTH = 1000; -export function CommitDetail({ owner, repo, commit, highlightData }: CommitDetailProps) { +export function CommitDetail({ + owner, + repo, + repoBasePath, + commit, + highlightData, +}: CommitDetailProps) { + const base = repoBasePath ?? `/${owner}/${repo}`; const [activeIndex, setActiveIndex] = useState(0); const [wordWrap, setWordWrap] = useState(true); const [sidebarWidth, setSidebarWidth] = useState(DEFAULT_SIDEBAR_WIDTH); @@ -173,7 +182,7 @@ export function CommitDetail({ owner, repo, commit, highlightData }: CommitDetai }; const copyLink = () => { - const url = `${window.location.origin}/${owner}/${repo}/commits/${commit.sha}`; + const url = `${window.location.origin}${base}/commits/${commit.sha}`; navigator.clipboard.writeText(url); setCopiedLink(true); setTimeout(() => setCopiedLink(false), 2000); @@ -326,7 +335,7 @@ export function CommitDetail({ owner, repo, commit, highlightData }: CommitDetai {commit.parents.map((p) => ( {p.sha.slice(0, 7)} diff --git a/apps/web/src/components/repo/commits-list.tsx b/apps/web/src/components/repo/commits-list.tsx index f78ca2e4..e7d893fa 100644 --- a/apps/web/src/components/repo/commits-list.tsx +++ b/apps/web/src/components/repo/commits-list.tsx @@ -18,9 +18,9 @@ import { cn } from "@/lib/utils"; import { TimeAgo } from "@/components/ui/time-ago"; import { ResizeHandle } from "@/components/ui/resize-handle"; import { - fetchCommitsByDate, - fetchCommitsPage, - fetchCommitDetail, + fetchCommitsByDate as defaultFetchCommitsByDate, + fetchCommitsPage as defaultFetchCommitsPage, + fetchCommitDetail as defaultFetchCommitDetail, type CommitDetailData, } from "@/app/(app)/repos/[owner]/[repo]/commits/actions"; import { useMutationSubscription } from "@/hooks/use-mutation-subscription"; @@ -38,7 +38,7 @@ const MIN_SHEET_WIDTH = 400; const MAX_SHEET_WIDTH_RATIO = 0.9; // Types -type Commit = { +export type Commit = { sha: string; commit: { message: string; @@ -57,12 +57,47 @@ type Commit = { html_url: string; }; +export type CommitsListCursorPagination = { + initialNextCursor: string | null; + initialHasMore: boolean; + fetchByBranch: ( + owner: string, + repo: string, + branch: string, + since?: string, + until?: string, + ) => Promise<{ commits: Commit[]; nextCursor: string | null; hasMore: boolean }>; + fetchMore: ( + owner: string, + repo: string, + branch: string, + cursor: string, + since?: string, + until?: string, + ) => Promise<{ commits: Commit[]; nextCursor: string | null; hasMore: boolean }>; + fetchCommitDetail: ( + owner: string, + repo: string, + sha: string, + branch?: string, + ) => Promise<{ + commit: CommitDetailData | null; + highlightData: Record>; + }>; +}; + interface CommitsListProps { owner: string; repo: string; commits: Commit[]; defaultBranch: string; branches: { name: string }[]; + /** e.g. `/s/owner/repo` for Code.Storage repos */ + repoBasePath?: string; + /** Cursor-based pagination (Pierre); omit for GitHub page-based pagination */ + cursorPagination?: CommitsListCursorPagination; + /** Hide date inputs when the backend does not support since/until */ + enableDateFilter?: boolean; } // Utility functions @@ -233,6 +268,7 @@ function CommitsToolbar({ since, until, hasDateFilter, + showDateFilters, onBranchChange, onSearchChange, onSinceChange, @@ -246,6 +282,7 @@ function CommitsToolbar({ since: string; until: string; hasDateFilter: boolean; + showDateFilters: boolean; onBranchChange: (branch: string) => void; onSearchChange: (search: string) => void; onSinceChange: (since: string) => void; @@ -283,28 +320,32 @@ function CommitsToolbar({
- onSinceChange(e.target.value)} - title="Since date" - className="h-9 rounded-md border border-border bg-background px-3 font-mono text-xs text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" - /> - onUntilChange(e.target.value)} - title="Until date" - className="h-9 rounded-md border border-border bg-background px-3 font-mono text-xs text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" - /> - {hasDateFilter && ( - + {showDateFilters && ( + <> + onSinceChange(e.target.value)} + title="Since date" + className="h-9 rounded-md border border-border bg-background px-3 font-mono text-xs text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" + /> + onUntilChange(e.target.value)} + title="Until date" + className="h-9 rounded-md border border-border bg-background px-3 font-mono text-xs text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" + /> + {hasDateFilter && ( + + )} + )}
); @@ -314,6 +355,7 @@ function CommitRow({ commit, owner, repo, + repoLinkBase, isFirst, isExpanded, copiedSha, @@ -325,6 +367,7 @@ function CommitRow({ commit: Commit; owner: string; repo: string; + repoLinkBase: string; isFirst: boolean; isExpanded: boolean; copiedSha: string | null; @@ -380,7 +423,7 @@ function CommitRow({
{isMobile === undefined || isMobile ? ( {firstLine} @@ -477,6 +520,7 @@ function CommitDateGroup({ commits, owner, repo, + repoLinkBase, expandedShas, copiedSha, isMobile, @@ -488,6 +532,7 @@ function CommitDateGroup({ commits: Commit[]; owner: string; repo: string; + repoLinkBase: string; expandedShas: Set; copiedSha: string | null; isMobile: boolean | undefined; @@ -507,6 +552,7 @@ function CommitDateGroup({ commit={commit} owner={owner} repo={repo} + repoLinkBase={repoLinkBase} isFirst={i === 0} isExpanded={expandedShas.has(commit.sha)} copiedSha={copiedSha} @@ -526,6 +572,7 @@ function CommitDetailSheet({ onOpenChange, owner, repo, + repoBasePath, selectedCommitSha, commitDetail, highlightData, @@ -540,6 +587,7 @@ function CommitDetailSheet({ onOpenChange: (open: boolean) => void; owner: string; repo: string; + repoBasePath: string; selectedCommitSha: string | null; commitDetail: CommitDetailData | null; highlightData: Record>; @@ -574,7 +622,7 @@ function CommitDetailSheet({
{selectedCommitSha && ( @@ -600,6 +648,7 @@ function CommitDetailSheet({ @@ -619,7 +668,21 @@ function CommitDetailSheet({ const PER_PAGE = 30; // Main component -export function CommitsList({ owner, repo, commits, defaultBranch, branches }: CommitsListProps) { +export function CommitsList({ + owner, + repo, + commits, + defaultBranch, + branches, + repoBasePath: repoBasePathProp, + cursorPagination, + enableDateFilter = true, +}: CommitsListProps) { + const repoLinkBase = repoBasePathProp ?? `/${owner}/${repo}`; + const initialCommitsRef = useRef(commits); + const initialNextCursorRef = useRef(cursorPagination?.initialNextCursor ?? null); + const initialHasMoreRef = useRef(cursorPagination?.initialHasMore ?? false); + // Filter state const [search, setSearch] = useState(""); const [since, setSince] = useState(""); @@ -628,9 +691,14 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C const [displayedCommits, setDisplayedCommits] = useState(commits); const [isPending, startTransition] = useTransition(); - // Infinite scroll state + // Infinite scroll state (GitHub: page; storage: cursor) const [page, setPage] = useState(1); - const [hasMore, setHasMore] = useState(commits.length >= PER_PAGE); + const [nextCursor, setNextCursor] = useState( + cursorPagination?.initialNextCursor ?? null, + ); + const [hasMore, setHasMore] = useState( + cursorPagination ? cursorPagination.initialHasMore : commits.length >= PER_PAGE, + ); const [isLoadingMore, setIsLoadingMore] = useState(false); const loadMoreRef = useRef(null); @@ -663,27 +731,57 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C } }, []); - // Infinite scroll: load next page + // Infinite scroll: load next page (GitHub) or next cursor page (storage) const loadMore = useCallback(async () => { if (isLoadingMore || !hasMore) return; setIsLoadingMore(true); - const nextPage = page + 1; - const result = await fetchCommitsPage( - owner, - repo, - nextPage, - currentBranch, - since || undefined, - until || undefined, - ); - const newCommits = result as Commit[]; - if (newCommits.length < PER_PAGE) { - setHasMore(false); + if (cursorPagination) { + if (!nextCursor) { + setHasMore(false); + setIsLoadingMore(false); + return; + } + const result = await cursorPagination.fetchMore( + owner, + repo, + currentBranch, + nextCursor, + since || undefined, + until || undefined, + ); + setDisplayedCommits((prev) => [...prev, ...result.commits]); + setNextCursor(result.nextCursor); + setHasMore(result.hasMore); + } else { + const nextPage = page + 1; + const result = await defaultFetchCommitsPage( + owner, + repo, + nextPage, + currentBranch, + since || undefined, + until || undefined, + ); + const newCommits = result as Commit[]; + if (newCommits.length < PER_PAGE) { + setHasMore(false); + } + setDisplayedCommits((prev) => [...prev, ...newCommits]); + setPage(nextPage); } - setDisplayedCommits((prev) => [...prev, ...newCommits]); - setPage(nextPage); setIsLoadingMore(false); - }, [isLoadingMore, hasMore, page, owner, repo, currentBranch, since, until]); + }, [ + isLoadingMore, + hasMore, + page, + owner, + repo, + currentBranch, + since, + until, + cursorPagination, + nextCursor, + ]); // IntersectionObserver for infinite scroll useEffect(() => { @@ -734,7 +832,27 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C const fetchCommits = useCallback( (branch: string, newSince?: string, newUntil?: string) => { startTransition(async () => { - const result = await fetchCommitsByDate( + if (cursorPagination) { + const result = await cursorPagination.fetchByBranch( + owner, + repo, + branch, + newSince + ? new Date(newSince).toISOString() + : undefined, + newUntil + ? new Date( + newUntil + "T23:59:59", + ).toISOString() + : undefined, + ); + setDisplayedCommits(result.commits); + setNextCursor(result.nextCursor); + setHasMore(result.hasMore); + setPage(1); + return; + } + const result = await defaultFetchCommitsByDate( owner, repo, newSince ? new Date(newSince).toISOString() : undefined, @@ -749,7 +867,7 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C setHasMore(data.length >= PER_PAGE); }); }, - [owner, repo], + [owner, repo, cursorPagination], ); // Subscribe to mutations @@ -771,55 +889,77 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C (branch: string) => { setCurrentBranch(branch); if (branch === defaultBranch && !since && !until) { - setDisplayedCommits(commits); + setDisplayedCommits(initialCommitsRef.current); setPage(1); - setHasMore(commits.length >= PER_PAGE); + if (cursorPagination) { + setNextCursor(initialNextCursorRef.current); + setHasMore(initialHasMoreRef.current); + } else { + setHasMore(initialCommitsRef.current.length >= PER_PAGE); + } } else { fetchCommits(branch, since, until); } }, - [defaultBranch, since, until, commits, fetchCommits], + [defaultBranch, since, until, fetchCommits, cursorPagination], ); const handleSinceChange = useCallback( (newSince: string) => { setSince(newSince); if (!newSince && !until && currentBranch === defaultBranch) { - setDisplayedCommits(commits); + setDisplayedCommits(initialCommitsRef.current); setPage(1); - setHasMore(commits.length >= PER_PAGE); + if (cursorPagination) { + setNextCursor(initialNextCursorRef.current); + setHasMore(initialHasMoreRef.current); + } else { + setHasMore(initialCommitsRef.current.length >= PER_PAGE); + } } else { fetchCommits(currentBranch, newSince, until); } }, - [until, currentBranch, defaultBranch, commits, fetchCommits], + [until, currentBranch, defaultBranch, fetchCommits, cursorPagination], ); const handleUntilChange = useCallback( (newUntil: string) => { setUntil(newUntil); if (!since && !newUntil && currentBranch === defaultBranch) { - setDisplayedCommits(commits); + setDisplayedCommits(initialCommitsRef.current); setPage(1); - setHasMore(commits.length >= PER_PAGE); + if (cursorPagination) { + setNextCursor(initialNextCursorRef.current); + setHasMore(initialHasMoreRef.current); + } else { + setHasMore(initialCommitsRef.current.length >= PER_PAGE); + } } else { fetchCommits(currentBranch, since, newUntil); } }, - [since, currentBranch, defaultBranch, commits, fetchCommits], + [since, currentBranch, defaultBranch, fetchCommits, cursorPagination], ); const clearDates = useCallback(() => { setSince(""); setUntil(""); if (currentBranch === defaultBranch) { - setDisplayedCommits(commits); + setDisplayedCommits(initialCommitsRef.current); setPage(1); - setHasMore(commits.length >= PER_PAGE); + if (cursorPagination) { + setNextCursor(initialNextCursorRef.current); + setHasMore(initialHasMoreRef.current); + } else { + setHasMore(initialCommitsRef.current.length >= PER_PAGE); + } } else { fetchCommits(currentBranch); } - }, [currentBranch, defaultBranch, commits, fetchCommits]); + }, [currentBranch, defaultBranch, fetchCommits, cursorPagination]); + + const fetchDetailFn = cursorPagination?.fetchCommitDetail ?? defaultFetchCommitDetail; const handleCommitClick = useCallback( async (sha: string) => { @@ -829,12 +969,12 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C setCommitDetail(null); setHighlightData({}); - const result = await fetchCommitDetail(owner, repo, sha); + const result = await fetchDetailFn(owner, repo, sha, currentBranch); setCommitDetail(result.commit); setHighlightData(result.highlightData); setIsLoadingDetail(false); }, - [owner, repo], + [owner, repo, currentBranch, fetchDetailFn], ); const copySha = useCallback((sha: string) => { @@ -871,6 +1011,7 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C since={since} until={until} hasDateFilter={hasDateFilter} + showDateFilters={enableDateFilter} onBranchChange={handleBranchChange} onSearchChange={setSearch} onSinceChange={handleSinceChange} @@ -897,6 +1038,7 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C commits={dateCommits} owner={owner} repo={repo} + repoLinkBase={repoLinkBase} expandedShas={expandedShas} copiedSha={copiedSha} isMobile={isMobile} @@ -923,6 +1065,7 @@ export function CommitsList({ owner, repo, commits, defaultBranch, branches }: C onOpenChange={setSheetOpen} owner={owner} repo={repo} + repoBasePath={repoLinkBase} selectedCommitSha={selectedCommitSha} commitDetail={commitDetail} highlightData={highlightData} diff --git a/apps/web/src/components/repo/repo-sidebar-identity.tsx b/apps/web/src/components/repo/repo-sidebar-identity.tsx new file mode 100644 index 00000000..f89d455e --- /dev/null +++ b/apps/web/src/components/repo/repo-sidebar-identity.tsx @@ -0,0 +1,58 @@ +import Image from "next/image"; +import { RepoBreadcrumb } from "@/components/repo/repo-breadcrumb"; +import { RepoBadge, type RepoBadgeProps } from "@/components/repo/repo-badge"; + +export function RepoSidebarIdentity({ + owner, + repoName, + ownerType, + ownerAvatarUrl, + description, + badges, + repoBasePath, + children, +}: { + owner: string; + repoName: string; + ownerType: string; + ownerAvatarUrl: string; + description: string | null; + badges: Array>; + repoBasePath?: string; + children?: React.ReactNode; +}) { + return ( +
+ + + {description ? ( +

+ {description} +

+ ) : null} +
+ {badges.map((b, i) => ( + + ))} +
+ {children} +
+ ); +} diff --git a/apps/web/src/components/repo/repo-sidebar.tsx b/apps/web/src/components/repo/repo-sidebar.tsx index 59627d47..7e0cf234 100644 --- a/apps/web/src/components/repo/repo-sidebar.tsx +++ b/apps/web/src/components/repo/repo-sidebar.tsx @@ -1,4 +1,3 @@ -import Image from "next/image"; import Link from "next/link"; import { GitFork, Eye, Scale, HardDrive, LinkIcon } from "lucide-react"; import { formatNumber } from "@/lib/utils"; @@ -13,7 +12,7 @@ import { SidebarLanguages } from "@/components/repo/sidebar-languages"; import { SidebarContributors } from "@/components/repo/sidebar-contributors"; import { LatestCommitSection } from "@/components/repo/latest-commit-section"; -import { RepoBreadcrumb } from "@/components/repo/repo-breadcrumb"; +import { RepoSidebarIdentity } from "@/components/repo/repo-sidebar-identity"; import type { ContributorAvatarsData } from "@/lib/repo-data-cache"; import type { ForkSyncStatus } from "@/lib/github"; @@ -98,36 +97,14 @@ export function RepoSidebar({ <> {/* Desktop sidebar */}