diff --git a/.changeset/swift-beds-explain.md b/.changeset/swift-beds-explain.md new file mode 100644 index 0000000000..c6dd7905cb --- /dev/null +++ b/.changeset/swift-beds-explain.md @@ -0,0 +1,5 @@ +--- +"uploadthing": minor +--- + +Add Convex Adapter diff --git a/docs/src/app/(docs)/backend-adapters/convex/page.mdx b/docs/src/app/(docs)/backend-adapters/convex/page.mdx new file mode 100644 index 0000000000..b5838e9259 --- /dev/null +++ b/docs/src/app/(docs)/backend-adapters/convex/page.mdx @@ -0,0 +1,148 @@ +import { docsMetadata } from "@/lib/utils"; + +export const metadata = docsMetadata({ + title: "Convex", + description: "Adapter to integrate UploadThing into your Convex application", + category: "Backend Adapters", +}); + +# Getting started with Convex + +> Added in `v7.8` + +## Package Setup + +### Install the package + +```sh npm2yarn +npm install uploadthing +``` + +### Add env variables (in Convex dashboard) + + + If you don't already have a uploadthing secret key, [sign + up](https://uploadthing.com/sign-in) and create one from the + [dashboard!](https://uploadthing.com/dashboard) + + +```sh npm2yarn +npx convex env set UPLOADTHING_TOKEN=... # A token for interacting with the SDK +``` + +## Set Up A FileRouter + +### Creating your first FileRoute + +All files uploaded to uploadthing are associated with a FileRoute. The following +is a very minimalistic example, with a single FileRoute "imageUploader". Think +of a FileRoute similar to an endpoint, it has: + +- Permitted types ["image", "video", etc] +- Max file size +- How many files are allowed to be uploaded +- (Optional) `input` validation to validate client-side data sent to the route +- (Optional) `middleware` to authenticate and tag requests +- `onUploadComplete` callback for when uploads are completed + +To get full insight into what you can do with the FileRoutes, please refer to +the [File Router API](/file-routes). + +```ts {{ title: "convex/uploadthing.ts" }} +"use node"; + +import crypto from "node:crypto"; + +import { + createInternalAction, + createUploadthing, + FileRouter, +} from "uploadthing/convex"; + +import { api } from "./_generated/api"; + +globalThis.crypto = crypto as Crypto; + +const f = createUploadthing(); + +const router = { + // Define as many FileRoutes as you like, each with a unique routeSlug + imageUploader: f({ + image: { + /** + * For full list of options and defaults, see the File Route API reference + * @see https://docs.uploadthing.com/file-routes#route-config + */ + maxFileSize: "4MB", + maxFileCount: 1, + }, + }).onUploadComplete((data) => { + console.log("upload completed", data); + }), +} satisfies FileRouter; + +export type OurFileRouter = typeof router; + +export const handler = createInternalAction({ router }); +``` + +### Create an API route using the FileRouter + + + File path here doesn't matter, you can serve this from any route. We recommend + serving it from `/api/uploadthing`. + + +```ts {{ title: "convex/http.ts" }} +import { httpRouter } from "convex/server"; + +import { createRouteHandler } from "uploadthing/convex-helpers"; + +import { internal } from "./_generated/api"; + +const http = httpRouter(); + +createRouteHandler({ + http, + internalAction: internal.uploadthing.handler, + path: "/api/uploadthing", +}); + +export default http; +``` + +> See configuration options in +> [server API reference](/api-reference/server#create-route-handler) + +### Use the FileRouter in your app + +Client side usage differs ever so slightly from the fullstack framework setups +when using a separate backend server. You'll need to set the URL of your server +when you generate the components and helpers. + +```tsx +import { generateUploadButton } from "@uploadthing/react"; + +export const UploadButton = generateUploadButton({ + url: "https://your-server.com/api/uploadthing", +}); +// ... +``` + + + Please note that you might need to setup some CORS rules on your server to + allow the client to make requests to the server. + + +For the remaining usage, please refer to client side examples of the fullstack +framework guides: + +- [Next.js](/getting-started/appdir#create-the-upload-thing-components) +- [Solid.js](/getting-started/solid#creating-the-upload-thing-components) +- [Vue](https://github.com/pingdotgg/uploadthing/tree/main/examples/backend-adapters/client-vue) +- [Svelte](/getting-started/svelte#creating-the-upload-thing-helpers) + +or check out the full API reference: + +- [`@uploadthing/react`](/api-reference/react) +- [`uploadthing/client`](/api-reference/client) diff --git a/docs/src/components/Libraries.tsx b/docs/src/components/Libraries.tsx index 4a10d5159a..a87c720e30 100644 --- a/docs/src/components/Libraries.tsx +++ b/docs/src/components/Libraries.tsx @@ -2,6 +2,7 @@ import { Button } from "@/components/Button"; import { Heading } from "@/components/Heading"; import { AstroIcon, + ConvexIcon, ExpressIcon, FastifyIcon, H3Icon, @@ -60,6 +61,12 @@ const frameworks = [ ]; const backends = [ + { + href: "/backend-adapters/convex", + name: "Convex", + description: "The open-source reactive database for app developers", + Logo: ConvexIcon, + }, { href: "/backend-adapters/express", name: "Express", @@ -166,7 +173,7 @@ export function BackendAdapters() { Not using a framework? We also have adapters for common backend libraries. -
+
{backends.map((library) => (
diff --git a/docs/src/components/icons.tsx b/docs/src/components/icons.tsx index c081f83ae3..3e59395ee6 100644 --- a/docs/src/components/icons.tsx +++ b/docs/src/components/icons.tsx @@ -727,3 +727,27 @@ export function WinterCGIcon(props: IconProps) { ); } + +export function ConvexIcon(props: IconProps) { + return ( + + + + + + ); +} diff --git a/docs/src/site-config.ts b/docs/src/site-config.ts index 653f41a25a..3c6e9b4649 100644 --- a/docs/src/site-config.ts +++ b/docs/src/site-config.ts @@ -39,6 +39,7 @@ export const navigation: Array = [ { title: "Backend Adapters", links: [ + { title: "Convex", href: "/backend-adapters/convex" }, { title: "Express", href: "/backend-adapters/express" }, { title: "Fastify", href: "/backend-adapters/fastify" }, { title: "H3", href: "/backend-adapters/h3" }, diff --git a/examples/minimal-convex/.env.example b/examples/minimal-convex/.env.example new file mode 100644 index 0000000000..f28c600aee --- /dev/null +++ b/examples/minimal-convex/.env.example @@ -0,0 +1,9 @@ +# Deployment used by `npx convex dev` +CONVEX_DEPLOYMENT= + +NEXT_PUBLIC_CONVEX_URL= +NEXT_PUBLIC_CONVEX_SITE_URL= + +# Required by the UploadThing Convex adapter — set these in Convex env (not this .env): +# pnpx convex env set UPLOADTHING_TOKEN='' +# The adapter will 500/throw early if these are missing. diff --git a/examples/minimal-convex/.gitignore b/examples/minimal-convex/.gitignore new file mode 100644 index 0000000000..8c5fbb9ced --- /dev/null +++ b/examples/minimal-convex/.gitignore @@ -0,0 +1,2 @@ + +.env.local diff --git a/examples/minimal-convex/README.md b/examples/minimal-convex/README.md new file mode 100644 index 0000000000..40cc9cf292 --- /dev/null +++ b/examples/minimal-convex/README.md @@ -0,0 +1,21 @@ +# Minimal Next.js App Router + Convex example for UploadThing + + + + + +## QuickStart + +1. `pnpm i` +2. `pnpm dev:setup` +3. Add the `NEXT_PUBLIC_CONVEX_SITE_URL` to the .env file +4. Grab an API key from the UploadThing dashboard: + https://uploadthing.com/dashboard +5. `pnpm dev:convex` +6. `pnpx convex env set UPLOADTHING_TOKEN=` +7. `pnpm dev` +8. Upload files! + +## Further reference + +Check out the docs at: https://docs.uploadthing.com/backend-adapters/convex diff --git a/examples/minimal-convex/convex/README.md b/examples/minimal-convex/convex/README.md new file mode 100644 index 0000000000..7fda0c3d68 --- /dev/null +++ b/examples/minimal-convex/convex/README.md @@ -0,0 +1,90 @@ +# Welcome to your Convex functions directory! + +Write your Convex functions here. +See https://docs.convex.dev/functions for more. + +A query function that takes two arguments looks like: + +```ts +// convex/myFunctions.ts +import { query } from "./_generated/server"; +import { v } from "convex/values"; + +export const myQueryFunction = query({ + // Validators for arguments. + args: { + first: v.number(), + second: v.string(), + }, + + // Function implementation. + handler: async (ctx, args) => { + // Read the database as many times as you need here. + // See https://docs.convex.dev/database/reading-data. + const documents = await ctx.db.query("tablename").collect(); + + // Arguments passed from the client are properties of the args object. + console.log(args.first, args.second); + + // Write arbitrary JavaScript here: filter, aggregate, build derived data, + // remove non-public properties, or create new objects. + return documents; + }, +}); +``` + +Using this query function in a React component looks like: + +```ts +const data = useQuery(api.myFunctions.myQueryFunction, { + first: 10, + second: "hello", +}); +``` + +A mutation function looks like: + +```ts +// convex/myFunctions.ts +import { mutation } from "./_generated/server"; +import { v } from "convex/values"; + +export const myMutationFunction = mutation({ + // Validators for arguments. + args: { + first: v.string(), + second: v.string(), + }, + + // Function implementation. + handler: async (ctx, args) => { + // Insert or modify documents in the database here. + // Mutations can also read from the database like queries. + // See https://docs.convex.dev/database/writing-data. + const message = { body: args.first, author: args.second }; + const id = await ctx.db.insert("messages", message); + + // Optionally, return a value from your mutation. + return await ctx.db.get(id); + }, +}); +``` + +Using this mutation function in a React component looks like: + +```ts +const mutation = useMutation(api.myFunctions.myMutationFunction); +function handleButtonPress() { + // fire and forget, the most common way to use mutations + mutation({ first: "Hello!", second: "me" }); + // OR + // use the result once the mutation has completed + mutation({ first: "Hello!", second: "me" }).then((result) => + console.log(result), + ); +} +``` + +Use the Convex CLI to push your functions to a deployment. See everything +the Convex CLI can do by running `npx convex -h` in your project root +directory. To learn more, launch the docs with `npx convex docs`. diff --git a/examples/minimal-convex/convex/_generated/api.d.ts b/examples/minimal-convex/convex/_generated/api.d.ts new file mode 100644 index 0000000000..33604fc774 --- /dev/null +++ b/examples/minimal-convex/convex/_generated/api.d.ts @@ -0,0 +1,40 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + ApiFromModules, + FilterApi, + FunctionReference, +} from "convex/server"; +import type * as http from "../http.js"; +import type * as media from "../media.js"; +import type * as uploadthing from "../uploadthing.js"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +declare const fullApi: ApiFromModules<{ + http: typeof http; + media: typeof media; + uploadthing: typeof uploadthing; +}>; +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; diff --git a/examples/minimal-convex/convex/_generated/api.js b/examples/minimal-convex/convex/_generated/api.js new file mode 100644 index 0000000000..3f9c482df7 --- /dev/null +++ b/examples/minimal-convex/convex/_generated/api.js @@ -0,0 +1,22 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi } from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export const api = anyApi; +export const internal = anyApi; diff --git a/examples/minimal-convex/convex/_generated/dataModel.d.ts b/examples/minimal-convex/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000000..fb12533b8a --- /dev/null +++ b/examples/minimal-convex/convex/_generated/dataModel.d.ts @@ -0,0 +1,58 @@ +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { AnyDataModel } from "convex/server"; +import type { GenericId } from "convex/values"; + +/** + * No `schema.ts` file found! + * + * This generated code has permissive types like `Doc = any` because + * Convex doesn't know your schema. If you'd like more type safety, see + * https://docs.convex.dev/using/schemas for instructions on how to add a + * schema file. + * + * After you change a schema, rerun codegen with `npx convex dev`. + */ + +/** + * The names of all of your Convex tables. + */ +export type TableNames = string; + +/** + * The type of a document stored in Convex. + */ +export type Doc = any; + +/** + * An identifier for a document in Convex. + * + * Convex documents are uniquely identified by their `Id`, which is accessible + * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). + * + * Documents can be loaded using `db.get(id)` in query and mutation functions. + * + * IDs are just strings at runtime, but this type can be used to distinguish them from other + * strings when type checking. + */ +export type Id = + GenericId; + +/** + * A type describing your Convex data model. + * + * This type includes information about what tables you have, the type of + * documents stored in those tables, and the indexes defined on them. + * + * This type is used to parameterize methods like `queryGeneric` and + * `mutationGeneric` to make them type-safe. + */ +export type DataModel = AnyDataModel; diff --git a/examples/minimal-convex/convex/_generated/server.d.ts b/examples/minimal-convex/convex/_generated/server.d.ts new file mode 100644 index 0000000000..7f337a4382 --- /dev/null +++ b/examples/minimal-convex/convex/_generated/server.d.ts @@ -0,0 +1,142 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + ActionBuilder, + HttpActionBuilder, + MutationBuilder, + QueryBuilder, + GenericActionCtx, + GenericMutationCtx, + GenericQueryCtx, + GenericDatabaseReader, + GenericDatabaseWriter, +} from "convex/server"; +import type { DataModel } from "./dataModel.js"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const query: QueryBuilder; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const internalQuery: QueryBuilder; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const mutation: MutationBuilder; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const internalMutation: MutationBuilder; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export declare const action: ActionBuilder; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export declare const internalAction: ActionBuilder; + +/** + * Define an HTTP action. + * + * This function will be used to respond to HTTP requests received by a Convex + * deployment if the requests matches the path and method where this action + * is routed. Be sure to route your action in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export declare const httpAction: HttpActionBuilder; + +/** + * A set of services for use within Convex query functions. + * + * The query context is passed as the first argument to any Convex query + * function run on the server. + * + * This differs from the {@link MutationCtx} because all of the services are + * read-only. + */ +export type QueryCtx = GenericQueryCtx; + +/** + * A set of services for use within Convex mutation functions. + * + * The mutation context is passed as the first argument to any Convex mutation + * function run on the server. + */ +export type MutationCtx = GenericMutationCtx; + +/** + * A set of services for use within Convex action functions. + * + * The action context is passed as the first argument to any Convex action + * function run on the server. + */ +export type ActionCtx = GenericActionCtx; + +/** + * An interface to read from the database within Convex query functions. + * + * The two entry points are {@link DatabaseReader.get}, which fetches a single + * document by its {@link Id}, or {@link DatabaseReader.query}, which starts + * building a query. + */ +export type DatabaseReader = GenericDatabaseReader; + +/** + * An interface to read from and write to the database within Convex mutation + * functions. + * + * Convex guarantees that all writes within a single mutation are + * executed atomically, so you never have to worry about partial writes leaving + * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) + * for the guarantees Convex provides your functions. + */ +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/examples/minimal-convex/convex/_generated/server.js b/examples/minimal-convex/convex/_generated/server.js new file mode 100644 index 0000000000..566d4858eb --- /dev/null +++ b/examples/minimal-convex/convex/_generated/server.js @@ -0,0 +1,89 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + actionGeneric, + httpActionGeneric, + queryGeneric, + mutationGeneric, + internalActionGeneric, + internalMutationGeneric, + internalQueryGeneric, +} from "convex/server"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const query = queryGeneric; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const internalQuery = internalQueryGeneric; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const mutation = mutationGeneric; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const internalMutation = internalMutationGeneric; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export const action = actionGeneric; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export const internalAction = internalActionGeneric; + +/** + * Define a Convex HTTP action. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object + * as its second. + * @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`. + */ +export const httpAction = httpActionGeneric; diff --git a/examples/minimal-convex/convex/http.ts b/examples/minimal-convex/convex/http.ts new file mode 100644 index 0000000000..6a6e9c9ef8 --- /dev/null +++ b/examples/minimal-convex/convex/http.ts @@ -0,0 +1,27 @@ +import corsRouter from "convex-helpers/server/cors"; +import { httpRouter } from "convex/server"; + +import { createRouteHandler } from "uploadthing/convex-helpers"; + +import { internal } from "./_generated/api"; + +const http = httpRouter(); + +const cors = corsRouter(http, { + allowedOrigins: ["http://localhost:3000"], + allowedHeaders: [ + "x-uploadthing-package", + "traceparent", + "x-uploadthing-version", + "b3", + "content-type", + ], +}); + +createRouteHandler({ + http: cors, + internalAction: internal.uploadthing.handler, + path: "/api/uploadthing", +}); + +export default http; diff --git a/examples/minimal-convex/convex/media.ts b/examples/minimal-convex/convex/media.ts new file mode 100644 index 0000000000..2cd5e0e4fc --- /dev/null +++ b/examples/minimal-convex/convex/media.ts @@ -0,0 +1,9 @@ +import { mutation } from "./_generated/server"; +import { v } from "convex/values"; + +export const add = mutation({ + args: { url: v.string() }, + handler: async (ctx, args) => { + return await ctx.db.insert("media", args); + }, +}); diff --git a/examples/minimal-convex/convex/schema.ts b/examples/minimal-convex/convex/schema.ts new file mode 100644 index 0000000000..500f7e31c6 --- /dev/null +++ b/examples/minimal-convex/convex/schema.ts @@ -0,0 +1,8 @@ +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; + +export default defineSchema({ + media: defineTable({ + url: v.string(), + }), +}); diff --git a/examples/minimal-convex/convex/tsconfig.json b/examples/minimal-convex/convex/tsconfig.json new file mode 100644 index 0000000000..73741270b0 --- /dev/null +++ b/examples/minimal-convex/convex/tsconfig.json @@ -0,0 +1,25 @@ +{ + /* This TypeScript project config describes the environment that + * Convex functions run in and is used to typecheck them. + * You can modify it, but some settings are required to use Convex. + */ + "compilerOptions": { + /* These settings are not required by Convex and can be modified. */ + "allowJs": true, + "strict": true, + "moduleResolution": "Bundler", + "jsx": "react-jsx", + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + + /* These compiler options are required by Convex */ + "target": "ESNext", + "lib": ["ES2021", "dom"], + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "isolatedModules": true, + "noEmit": true + }, + "include": ["./**/*"], + "exclude": ["./_generated"] +} diff --git a/examples/minimal-convex/convex/uploadthing.ts b/examples/minimal-convex/convex/uploadthing.ts new file mode 100644 index 0000000000..bcd7b816cd --- /dev/null +++ b/examples/minimal-convex/convex/uploadthing.ts @@ -0,0 +1,71 @@ +"use node"; + +import crypto from "node:crypto"; + +import { + createInternalAction, + createUploadthing, + FileRouter, + UTFiles, +} from "uploadthing/convex"; + +globalThis.crypto = crypto as unknown as Crypto; + +const f = createUploadthing({ + /** + * Log out more information about the error, but don't return it to the client + * @see https://docs.uploadthing.com/errors#error-formatting + */ + errorFormatter: (err) => { + console.log("Error uploading file", err.message); + console.log(" - Above error caused by:", err.cause); + + return { message: err.message }; + }, +}); + +/** + * This is your Uploadthing file router. For more information: + * @see https://docs.uploadthing.com/api-reference/server#file-routes + */ +const router = { + videoAndImage: f({ + image: { + maxFileSize: "32MB", + maxFileCount: 4, + acl: "public-read", + }, + video: { + maxFileSize: "16MB", + }, + blob: { + maxFileSize: "8GB", + }, + }) + .middleware(({ req, files }) => { + // Check some condition based on the incoming request + // if (!req.headers.get("x-some-header")) { + // throw new Error("x-some-header is required"); + // } + + // (Optional) Label your files with a custom identifier + const filesWithMyIds = files.map((file, idx) => ({ + ...file, + customId: `${idx}-${crypto.randomUUID()}`, + })); + + // Return some metadata to be stored with the file + return { foo: "bar" as const, [UTFiles]: filesWithMyIds }; + }) + .onUploadComplete(({ file, metadata }) => { + metadata; + // ^? + file.customId; + // ^? + console.log("upload completed", file); + }), +} satisfies FileRouter; + +export type OurFileRouter = typeof router; + +export const handler = createInternalAction({ router }); diff --git a/examples/minimal-convex/next-env.d.ts b/examples/minimal-convex/next-env.d.ts new file mode 100644 index 0000000000..1b3be0840f --- /dev/null +++ b/examples/minimal-convex/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/examples/minimal-convex/next.config.js b/examples/minimal-convex/next.config.js new file mode 100644 index 0000000000..8d68e22f1b --- /dev/null +++ b/examples/minimal-convex/next.config.js @@ -0,0 +1,11 @@ +const analyze = require("@next/bundle-analyzer")({ + enabled: process.env.ANALYZE === "true", +}); + +/** @type {import('next').NextConfig} */ +const nextConfig = { + eslint: { ignoreDuringBuilds: true }, + typescript: { ignoreBuildErrors: true }, +}; + +module.exports = analyze(nextConfig); diff --git a/examples/minimal-convex/package.json b/examples/minimal-convex/package.json new file mode 100644 index 0000000000..0cbced5452 --- /dev/null +++ b/examples/minimal-convex/package.json @@ -0,0 +1,29 @@ +{ + "name": "@example/minimal-convex", + "private": true, + "scripts": { + "dev": "next dev", + "dev:setup": "convex dev --once --configure=new", + "dev:convex": "convex dev", + "clean": "git clean -xdf .next node_modules", + "build": "next build", + "start": "next start", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@uploadthing/react": "7.3.3", + "convex": "1.26.2", + "convex-helpers": "0.1.104", + "next": "15.3.1", + "react": "19.1.0", + "react-dom": "19.1.0", + "uploadthing": "7.7.4" + }, + "devDependencies": { + "@next/bundle-analyzer": "15.1.3", + "@types/node": "^22.10.0", + "@types/react": "19.1.2", + "@types/react-dom": "19.1.2", + "typescript": "5.8.3" + } +} diff --git a/examples/minimal-convex/src/app/layout.tsx b/examples/minimal-convex/src/app/layout.tsx new file mode 100644 index 0000000000..c105da45d9 --- /dev/null +++ b/examples/minimal-convex/src/app/layout.tsx @@ -0,0 +1,25 @@ +import "@uploadthing/react/styles.css"; + +import { Inter } from "next/font/google"; + +import { NextSSRPlugin } from "@uploadthing/react/next-ssr-plugin"; +import { extractRouterConfig } from "uploadthing/server"; + +import { uploadRouter } from "~/server/uploadthing"; + +const inter = Inter({ subsets: ["latin"] }); + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + ); +} diff --git a/examples/minimal-convex/src/app/page.tsx b/examples/minimal-convex/src/app/page.tsx new file mode 100644 index 0000000000..6a6a87c6fb --- /dev/null +++ b/examples/minimal-convex/src/app/page.tsx @@ -0,0 +1,75 @@ +"use client"; + +import { + UploadButton, + UploadDropzone, + useUploadThing, +} from "~/utils/uploadthing"; + +export default function Home() { + const { startUpload } = useUploadThing("videoAndImage", { + /** + * @see https://docs.uploadthing.com/api-reference/react#useuploadthing + */ + onBeforeUploadBegin: (files) => { + console.log("Uploading", files.length, "files"); + return files; + }, + onUploadBegin: (name) => { + console.log("Beginning upload of", name); + }, + onClientUploadComplete: (res) => { + console.log("Upload Completed.", res.length, "files uploaded"); + }, + onUploadProgress(p) { + console.log("onUploadProgress", p); + }, + }); + + return ( +
+ routeRegistry.videoAndImage} + onClientUploadComplete={(res) => { + console.log(`onClientUploadComplete`, res); + alert("Upload Completed"); + }} + onUploadBegin={() => { + console.log("upload begin"); + }} + config={{ appendOnPaste: true, mode: "manual" }} + /> + routeRegistry.videoAndImage} + onUploadAborted={() => { + alert("Upload Aborted"); + }} + onClientUploadComplete={(res) => { + console.log(`onClientUploadComplete`, res); + alert("Upload Completed"); + }} + onUploadBegin={() => { + console.log("upload begin"); + }} + /> + { + const files = Array.from(e.target.files ?? []); + + // Do something with files + + // Then start the upload + await startUpload(files); + }} + /> +
+ ); +} diff --git a/examples/minimal-convex/src/utils/uploadthing.ts b/examples/minimal-convex/src/utils/uploadthing.ts new file mode 100644 index 0000000000..888bd865bb --- /dev/null +++ b/examples/minimal-convex/src/utils/uploadthing.ts @@ -0,0 +1,18 @@ +import { + generateReactHelpers, + generateUploadButton, + generateUploadDropzone, +} from "@uploadthing/react"; + +import type { OurFileRouter } from "~/convex/uploadthing"; + +export const UploadButton = generateUploadButton({ + url: process.env.NEXT_PUBLIC_CONVEX_SITE_URL, +}); +export const UploadDropzone = generateUploadDropzone({ + url: process.env.NEXT_PUBLIC_CONVEX_SITE_URL, +}); + +export const { useUploadThing } = generateReactHelpers({ + url: process.env.NEXT_PUBLIC_CONVEX_SITE_URL, +}); diff --git a/examples/minimal-convex/tsconfig.json b/examples/minimal-convex/tsconfig.json new file mode 100644 index 0000000000..6cee7e7fb7 --- /dev/null +++ b/examples/minimal-convex/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "module": "Preserve", + "target": "ES2022", + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [{ "name": "next" }], + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"], + "~/convex/*": ["./convex/*"] + } + }, + "include": [".next/types/**/*.ts", "next-env.d.ts", "src", "*.js"], + "exclude": ["node_modules"] +} diff --git a/packages/uploadthing/package.json b/packages/uploadthing/package.json index d3df494f14..d1824114d4 100644 --- a/packages/uploadthing/package.json +++ b/packages/uploadthing/package.json @@ -126,6 +126,26 @@ "default": "./remix/index.cjs" } }, + "./convex": { + "import": { + "types": "./convex/index.d.ts", + "default": "./convex/index.js" + }, + "require": { + "types": "./convex/index.d.cts", + "default": "./convex/index.cjs" + } + }, + "./convex-helpers": { + "import": { + "types": "./convex-helpers/index.d.ts", + "default": "./convex-helpers/index.js" + }, + "require": { + "types": "./convex-helpers/index.d.cts", + "default": "./convex-helpers/index.cjs" + } + }, "./types": { "types": "./types/index.d.ts", "default": "./types/index.js" @@ -134,6 +154,8 @@ "files": [ "client", "client-future", + "convex", + "convex-helpers", "dist", "effect-platform", "express", @@ -194,6 +216,8 @@ "zod": "^3.24.1" }, "peerDependencies": { + "convex": "*", + "convex-helpers": "*", "express": "*", "h3": "*", "tailwindcss": "^3.0.0 || ^4.0.0-beta.0" @@ -211,6 +235,12 @@ "h3": { "optional": true }, + "convex": { + "optional": true + }, + "convex-helpers": { + "optional": true + }, "tailwindcss": { "optional": true } diff --git a/packages/uploadthing/src/convex-helpers.ts b/packages/uploadthing/src/convex-helpers.ts new file mode 100644 index 0000000000..caccb1c544 --- /dev/null +++ b/packages/uploadthing/src/convex-helpers.ts @@ -0,0 +1,62 @@ +import type { CorsHttpRouter } from "convex-helpers/server/cors"; +import type { FunctionReference, HttpRouter } from "convex/server"; +import { httpActionGeneric } from "convex/server"; + +export const createRouteHandler = ({ + http, + internalAction, + path = "/api/uploadthing", +}: { + http: HttpRouter | CorsHttpRouter; + internalAction: FunctionReference< + "action", + "internal", + { + request: { + url: string; + method: string; + headers: Record; + body?: string; + }; + }, + { + status: number; + statusText: string; + headers: Record; + body: string; + } + >; + path?: string; +}) => { + const handler = httpActionGeneric(async (ctx, req) => { + const headers: Record = {}; + req.headers.forEach((value, key) => { + headers[key] = value; + }); + const request = { + url: req.url, + method: req.method, + headers, + body: await req.text(), + }; + const response = await ctx.runAction(internalAction, { request }); + + return new Response(response.body, { + status: response.status, + statusText: response.statusText, + headers: response.headers, + }); + }); + + http.route({ + method: "OPTIONS", + path, + handler: httpActionGeneric(async () => + Promise.resolve(new Response(null, { status: 204 })), + ), + }); + + http.route({ method: "GET", path, handler }); + + http.route({ method: "POST", path, handler }); +}; diff --git a/packages/uploadthing/src/convex.ts b/packages/uploadthing/src/convex.ts new file mode 100644 index 0000000000..75f60db550 --- /dev/null +++ b/packages/uploadthing/src/convex.ts @@ -0,0 +1,76 @@ +import { internalActionGeneric } from "convex/server"; +import type { GenericActionCtx, GenericDataModel } from "convex/server"; +import { v } from "convex/values"; +import * as Effect from "effect/Effect"; + +import type { Json } from "@uploadthing/shared"; + +import { makeAdapterHandler } from "./_internal/handler"; +import { createBuilder } from "./_internal/upload-builder"; +import type { CreateBuilderOptions } from "./_internal/upload-builder"; +import type { FileRouter, RouteHandlerOptions } from "./types"; + +export { + UTFiles, + /** + * This is an experimental feature. + * You need to be feature flagged on our backend to use this + */ + UTRegion as experimental_UTRegion, +} from "./_internal/types"; +export type { FileRouter }; + +type AdapterArgs = { + ctx: GenericActionCtx; + req: Request; +}; + +export const createUploadthing = ( + opts?: CreateBuilderOptions, +) => createBuilder(opts); + +export const createInternalAction = ( + opts: RouteHandlerOptions, +) => { + const handler = makeAdapterHandler< + [GenericActionCtx, Request], + AdapterArgs + >( + (ctx, req) => Effect.succeed({ ctx, req }), + (_, req) => Effect.succeed(req), + opts, + "convex", + ); + + return internalActionGeneric({ + args: { + request: v.object({ + url: v.string(), + method: v.string(), + headers: v.record(v.string(), v.string()), + body: v.optional(v.string()), + }), + }, + handler: async (ctx: GenericActionCtx, args) => { + const request = new Request(args.request.url, { + method: args.request.method, + headers: new Headers(args.request.headers), + body: args.request.body ? new Blob([args.request.body]) : null, + }); + + const response = await handler(ctx, request); + + const headers: Record = {}; + response.headers.forEach((value, key) => { + headers[key] = value; + }); + + return { + status: response.status, + statusText: response.statusText, + headers, + body: await response.text(), + }; + }, + }); +}; diff --git a/packages/uploadthing/tsdown.config.ts b/packages/uploadthing/tsdown.config.ts index 8cdba7bffb..b38271526c 100644 --- a/packages/uploadthing/tsdown.config.ts +++ b/packages/uploadthing/tsdown.config.ts @@ -15,6 +15,8 @@ export default defineConfig({ "../h3/index": "src/h3.ts", "../remix/index": "src/remix.ts", "../types/index": "src/types.ts", + "../convex/index": "src/convex.ts", + "../convex-helpers/index": "src/convex-helpers.ts", }, format: ["esm", "cjs"], dts: { diff --git a/packages/uploadthing/turbo.json b/packages/uploadthing/turbo.json index 45186d17c4..78fca0662d 100644 --- a/packages/uploadthing/turbo.json +++ b/packages/uploadthing/turbo.json @@ -6,6 +6,8 @@ "outputs": [ "client/**", "client-future/**", + "convex/**", + "convex-helpers/**", "dist/**", "effect-platform/**", "express/**", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 475529174c..5e454b7291 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -432,6 +432,46 @@ importers: specifier: 5.8.3 version: 5.8.3 + examples/minimal-convex: + dependencies: + '@uploadthing/react': + specifier: 7.3.3 + version: link:../../packages/react + convex: + specifier: 1.26.2 + version: 1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + convex-helpers: + specifier: 0.1.104 + version: 0.1.104(@standard-schema/spec@1.0.0)(convex@1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0))(hono@4.6.15)(react@19.1.0)(typescript@5.8.3)(zod@3.25.67) + next: + specifier: 15.3.1 + version: 15.3.1(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: 19.1.0 + version: 19.1.0 + react-dom: + specifier: 19.1.0 + version: 19.1.0(react@19.1.0) + uploadthing: + specifier: 7.7.4 + version: link:../../packages/uploadthing + devDependencies: + '@next/bundle-analyzer': + specifier: 15.1.3 + version: 15.1.3 + '@types/node': + specifier: ^22.10.0 + version: 22.12.0 + '@types/react': + specifier: 19.1.2 + version: 19.1.2 + '@types/react-dom': + specifier: 19.1.2 + version: 19.1.2(@types/react@19.1.2) + typescript: + specifier: 5.8.3 + version: 5.8.3 + examples/minimal-expo: dependencies: '@bacons/text-decoder': @@ -1632,6 +1672,12 @@ importers: '@uploadthing/shared': specifier: workspace:* version: link:../shared + convex: + specifier: '*' + version: 1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + convex-helpers: + specifier: '*' + version: 0.1.104(@standard-schema/spec@1.0.0-beta.4)(convex@1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0))(hono@4.6.15)(react@19.1.0)(typescript@5.8.3)(zod@3.25.67) effect: specifier: 3.17.7 version: 3.17.7 @@ -3303,6 +3349,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.5': resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} @@ -3351,6 +3403,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.5': resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} @@ -3399,6 +3457,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.5': resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} @@ -3447,6 +3511,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.5': resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} @@ -3495,6 +3565,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.5': resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} @@ -3543,6 +3619,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.5': resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} @@ -3591,6 +3673,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.5': resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} @@ -3639,6 +3727,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.5': resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} @@ -3687,6 +3781,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.5': resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} @@ -3735,6 +3835,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.5': resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} @@ -3783,6 +3889,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.5': resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} @@ -3831,6 +3943,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.5': resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} @@ -3879,6 +3997,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.5': resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} @@ -3927,6 +4051,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.5': resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} @@ -3975,6 +4105,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.5': resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} @@ -4023,6 +4159,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.5': resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} @@ -4071,6 +4213,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.5': resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} @@ -4083,6 +4231,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.25.5': resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} @@ -4131,6 +4285,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.5': resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} @@ -4149,6 +4309,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.25.5': resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} @@ -4197,6 +4363,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.5': resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} @@ -4245,6 +4417,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.5': resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} @@ -4293,6 +4471,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.5': resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} @@ -4341,6 +4525,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.5': resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} @@ -4389,6 +4579,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.5': resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} @@ -4730,12 +4926,6 @@ packages: cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.1': - resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - '@img/sharp-darwin-arm64@0.34.3': resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4748,12 +4938,6 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.1': - resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - '@img/sharp-darwin-x64@0.34.3': resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4765,11 +4949,6 @@ packages: cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} - cpu: [arm64] - os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] @@ -4780,11 +4959,6 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] @@ -4795,11 +4969,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linux-arm64@1.2.0': resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] @@ -4810,21 +4979,11 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} - cpu: [arm] - os: [linux] - '@img/sharp-libvips-linux-arm@1.2.0': resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} - cpu: [ppc64] - os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.0': resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} cpu: [ppc64] @@ -4835,11 +4994,6 @@ packages: cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} - cpu: [s390x] - os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.0': resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] @@ -4850,11 +5004,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} - cpu: [x64] - os: [linux] - '@img/sharp-libvips-linux-x64@1.2.0': resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] @@ -4865,11 +5014,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] @@ -4880,11 +5024,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} - cpu: [x64] - os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] @@ -4896,12 +5035,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.1': - resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linux-arm64@0.34.3': resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4914,12 +5047,6 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.1': - resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - '@img/sharp-linux-arm@0.34.3': resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4938,12 +5065,6 @@ packages: cpu: [s390x] os: [linux] - '@img/sharp-linux-s390x@0.34.1': - resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - '@img/sharp-linux-s390x@0.34.3': resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4956,12 +5077,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.1': - resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - '@img/sharp-linux-x64@0.34.3': resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4974,12 +5089,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.1': - resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.3': resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4992,12 +5101,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.1': - resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - '@img/sharp-linuxmusl-x64@0.34.3': resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -5009,11 +5112,6 @@ packages: engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-wasm32@0.34.1': - resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - '@img/sharp-wasm32@0.34.3': resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -5031,12 +5129,6 @@ packages: cpu: [ia32] os: [win32] - '@img/sharp-win32-ia32@0.34.1': - resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - '@img/sharp-win32-ia32@0.34.3': resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -5049,12 +5141,6 @@ packages: cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.1': - resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - '@img/sharp-win32-x64@0.34.3': resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -5655,12 +5741,12 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} - '@oxc-project/runtime@0.81.0': - resolution: {integrity: sha512-zm/LDVOq9FEmHiuM8zO4DWirv0VP2Tv2VsgaiHby9nvpq+FVrcqNYgv+TysLKOITQXWZj/roluTxFvpkHP0Iuw==} + '@oxc-project/runtime@0.82.3': + resolution: {integrity: sha512-LNh5GlJvYHAnMurO+EyA8jJwN1rki7l3PSHuosDh2I7h00T6/u9rCkUjg/SvPmT1CZzvhuW0y+gf7jcqUy/Usg==} engines: {node: '>=6.9.0'} - '@oxc-project/types@0.81.0': - resolution: {integrity: sha512-CnOqkybZK8z6Gx7Wb1qF7AEnSzbol1WwcIzxYOr8e91LytGOjo0wCpgoYWZo8sdbpqX+X+TJayIzo4Pv0R/KjA==} + '@oxc-project/types@0.82.3': + resolution: {integrity: sha512-6nCUxBnGX0c6qfZW5MaF6/fmu5dHJDMiMPaioKHKs5mi5+8/FHQ7WGjgQIz1zxpmceMYfdIXkOaLYE+ejbuOtA==} '@panva/hkdf@1.2.1': resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} @@ -6939,78 +7025,78 @@ packages: resolution: {integrity: sha512-lzD84av1ZQhYUS+jsGqJiCMaJO2dn9u+RTT9n9q6D3SaKVwWqv+7AoRKqBu19bkwyE+iFRl1ymr40QS90jVFYg==} engines: {node: '>=14.15'} - '@rolldown/binding-android-arm64@1.0.0-beta.32': - resolution: {integrity: sha512-Gs+313LfR4Ka3hvifdag9r44WrdKQaohya7ZXUXzARF7yx0atzFlVZjsvxtKAw1Vmtr4hB/RjUD1jf73SW7zDw==} + '@rolldown/binding-android-arm64@1.0.0-beta.34': + resolution: {integrity: sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA==} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.32': - resolution: {integrity: sha512-W8oMqzGcI7wKPXUtS3WJNXzbghHfNiuM1UBAGpVb+XlUCgYRQJd2PRGP7D3WGql3rR3QEhUvSyAuCBAftPQw6Q==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.34': + resolution: {integrity: sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ==} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.32': - resolution: {integrity: sha512-pM4c4sKUk37noJrnnDkJknLhCsfZu7aWyfe67bD0GQHfzAPjV16wPeD9CmQg4/0vv+5IfHYaa4VE536xbA+W0Q==} + '@rolldown/binding-darwin-x64@1.0.0-beta.34': + resolution: {integrity: sha512-E1QuFslgLWbHQ8Qli/AqUKdfg0pockQPwRxVbhNQ74SciZEZpzLaujkdmOLSccMlSXDfFCF8RPnMoRAzQ9JV8Q==} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.32': - resolution: {integrity: sha512-M8SUgFlYb5kJJWcFC8gUMRiX4WLFxPKMed3SJ2YrxontgIrEcpizPU8nLNVsRYEStoSfKHKExpQw3OP6fm+5bw==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.34': + resolution: {integrity: sha512-VS8VInNCwnkpI9WeQaWu3kVBq9ty6g7KrHdLxYMzeqz24+w9hg712TcWdqzdY6sn+24lUoMD9jTZrZ/qfVpk0g==} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.32': - resolution: {integrity: sha512-FuQpbNC/hE//bvv29PFnk0AtpJzdPdYl5CMhlWPovd9g3Kc3lw9TrEPIbL7gRPUdhKAiq6rVaaGvOnXxsa0eww==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34': + resolution: {integrity: sha512-4St4emjcnULnxJYb/5ZDrH/kK/j6PcUgc3eAqH5STmTrcF+I9m/X2xvSF2a2bWv1DOQhxBewThu0KkwGHdgu5w==} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.32': - resolution: {integrity: sha512-hRZygRlaGCjcNTNY9GV7dDI18sG1dK3cc7ujHq72LoDad23zFDUGMQjiSxHWK+/r92iMV+j2MiHbvzayxqynsg==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34': + resolution: {integrity: sha512-a737FTqhFUoWfnebS2SnQ2BS50p0JdukdkUBwy2J06j4hZ6Eej0zEB8vTfAqoCjn8BQKkXBy+3Sx0IRkgwz1gA==} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.32': - resolution: {integrity: sha512-HzgT6h+CXLs+GKAU0Wvkt3rvcv0CmDBsDjlPhh4GHysOKbG9NjpKYX2zvjx671E9pGbTvcPpwy7gGsy7xpu+8g==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.34': + resolution: {integrity: sha512-NH+FeQWKyuw0k+PbXqpFWNfvD8RPvfJk766B/njdaWz4TmiEcSB0Nb6guNw1rBpM1FmltQYb3fFnTumtC6pRfA==} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.32': - resolution: {integrity: sha512-Ab/wbf6gdzphDbsg51UaxsC93foQ7wxhtg0SVCXd25BrV4MAJ1HoDtKN/f4h0maFmJobkqYub2DlmoasUzkvBg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.34': + resolution: {integrity: sha512-Q3RSCivp8pNadYK8ke3hLnQk08BkpZX9BmMjgwae2FWzdxhxxUiUzd9By7kneUL0vRQ4uRnhD9VkFQ+Haeqdvw==} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.32': - resolution: {integrity: sha512-VoxqGEfh5A1Yx+zBp/FR5QwAbtzbuvky2SVc+ii4g1gLD4zww6mt/hPi5zG+b88zYPFBKHpxMtsz9cWqXU5V5Q==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.34': + resolution: {integrity: sha512-wDd/HrNcVoBhWWBUW3evJHoo7GJE/RofssBy3Dsiip05YUBmokQVrYAyrboOY4dzs/lJ7HYeBtWQ9hj8wlyF0A==} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.32': - resolution: {integrity: sha512-qZ1ViyOUDGbiZrSAJ/FIAhYUElDfVxxFW6DLT/w4KeoZN3HsF4jmRP95mXtl51/oGrqzU9l9Q2f7/P4O/o2ZZA==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.34': + resolution: {integrity: sha512-dH3FTEV6KTNWpYSgjSXZzeX7vLty9oBYn6R3laEdhwZftQwq030LKL+5wyQdlbX5pnbh4h127hpv3Hl1+sj8dg==} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.32': - resolution: {integrity: sha512-hEkG3wD+f3wytV0lqwb/uCrXc4r4Ny/DWJFJPfQR3VeMWplhWGgSHNwZc2Q7k86Yi36f9NNzzWmrIuvHI9lCVw==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.34': + resolution: {integrity: sha512-y5BUf+QtO0JsIDKA51FcGwvhJmv89BYjUl8AmN7jqD6k/eU55mH6RJYnxwCsODq5m7KSSTigVb6O7/GqB8wbPw==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.32': - resolution: {integrity: sha512-k3MvDf8SiA7uP2ikP0unNouJ2YCrnwi7xcVW+RDgMp5YXVr3Xu6svmT3HGn0tkCKUuPmf+uy8I5uiHt5qWQbew==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34': + resolution: {integrity: sha512-ga5hFhdTwpaNxEiuxZHWnD3ed0GBAzbgzS5tRHpe0ObptxM1a9Xrq6TVfNQirBLwb5Y7T/FJmJi3pmdLy95ljg==} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.32': - resolution: {integrity: sha512-wAi/FxGh7arDOUG45UmnXE1sZUa0hY4cXAO2qWAjFa3f7bTgz/BqwJ7XN5SUezvAJPNkME4fEpInfnBvM25a0w==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34': + resolution: {integrity: sha512-4/MBp9T9eRnZskxWr8EXD/xHvLhdjWaeX/qY9LPRG1JdCGV3DphkLTy5AWwIQ5jhAy2ZNJR5z2fYRlpWU0sIyQ==} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.32': - resolution: {integrity: sha512-Ej0i4PZk8ltblZtzVK8ouaGUacUtxRmTm5S9794mdyU/tYxXjAJNseOfxrnHpMWKjMDrOKbqkPqJ52T9NR4LQQ==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.34': + resolution: {integrity: sha512-7O5iUBX6HSBKlQU4WykpUoEmb0wQmonb6ziKFr3dJTHud2kzDnWMqk344T0qm3uGv9Ddq6Re/94pInxo1G2d4w==} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.32': - resolution: {integrity: sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==} + '@rolldown/pluginutils@1.0.0-beta.34': + resolution: {integrity: sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==} '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} @@ -9793,6 +9879,44 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + convex-helpers@0.1.104: + resolution: {integrity: sha512-7CYvx7T3K6n+McDTK4ZQaQNNGBzq5aWezpjzsKbOxPXx7oNcTP9wrpef3JxeXWFzkByJv5hRCjseh9B7eNJ7Ig==} + hasBin: true + peerDependencies: + '@standard-schema/spec': ^1.0.0 + convex: ^1.24.0 + hono: ^4.0.5 + react: ^17.0.2 || ^18.0.0 || ^19.0.0 + typescript: ^5.5 + zod: ^3.22.4 || ^4.0.15 + peerDependenciesMeta: + '@standard-schema/spec': + optional: true + hono: + optional: true + react: + optional: true + typescript: + optional: true + zod: + optional: true + + convex@1.26.2: + resolution: {integrity: sha512-QG3zvZ9GTTeeBS+N5PJj73TULHYu99eVSOI3KU2hMnB9q40fHxkMFJ+AYox+K81roTakciBvNTvGlhfz+M10fQ==} + engines: {node: '>=18.0.0', npm: '>=7.0.0'} + hasBin: true + peerDependencies: + '@auth0/auth0-react': ^2.0.1 + '@clerk/clerk-react': ^4.12.8 || ^5.0.0 + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + peerDependenciesMeta: + '@auth0/auth0-react': + optional: true + '@clerk/clerk-react': + optional: true + react: + optional: true + cookie-es@1.2.2: resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} @@ -10717,6 +10841,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.25.5: resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} @@ -16148,8 +16277,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.32: - resolution: {integrity: sha512-vxI2sPN07MMaoYKlFrVva5qZ1Y7DAZkgp7MQwTnyHt4FUMz9Sh+YeCzNFV9JYHI6ZNwoGWLCfCViE3XVsRC1cg==} + rolldown@1.0.0-beta.34: + resolution: {integrity: sha512-Wwh7EwalMzzX3Yy3VN58VEajeR2Si8+HDNMf706jPLIqU7CxneRW+dQVfznf5O0TWTnJyu4npelwg2bzTXB1Nw==} hasBin: true rollup-plugin-dts@6.2.1: @@ -16378,10 +16507,6 @@ packages: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.1: - resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.3: resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -20444,6 +20569,9 @@ snapshots: '@esbuild/aix-ppc64@0.24.2': optional: true + '@esbuild/aix-ppc64@0.25.4': + optional: true + '@esbuild/aix-ppc64@0.25.5': optional: true @@ -20468,6 +20596,9 @@ snapshots: '@esbuild/android-arm64@0.24.2': optional: true + '@esbuild/android-arm64@0.25.4': + optional: true + '@esbuild/android-arm64@0.25.5': optional: true @@ -20492,6 +20623,9 @@ snapshots: '@esbuild/android-arm@0.24.2': optional: true + '@esbuild/android-arm@0.25.4': + optional: true + '@esbuild/android-arm@0.25.5': optional: true @@ -20516,6 +20650,9 @@ snapshots: '@esbuild/android-x64@0.24.2': optional: true + '@esbuild/android-x64@0.25.4': + optional: true + '@esbuild/android-x64@0.25.5': optional: true @@ -20540,6 +20677,9 @@ snapshots: '@esbuild/darwin-arm64@0.24.2': optional: true + '@esbuild/darwin-arm64@0.25.4': + optional: true + '@esbuild/darwin-arm64@0.25.5': optional: true @@ -20564,6 +20704,9 @@ snapshots: '@esbuild/darwin-x64@0.24.2': optional: true + '@esbuild/darwin-x64@0.25.4': + optional: true + '@esbuild/darwin-x64@0.25.5': optional: true @@ -20588,6 +20731,9 @@ snapshots: '@esbuild/freebsd-arm64@0.24.2': optional: true + '@esbuild/freebsd-arm64@0.25.4': + optional: true + '@esbuild/freebsd-arm64@0.25.5': optional: true @@ -20612,6 +20758,9 @@ snapshots: '@esbuild/freebsd-x64@0.24.2': optional: true + '@esbuild/freebsd-x64@0.25.4': + optional: true + '@esbuild/freebsd-x64@0.25.5': optional: true @@ -20636,6 +20785,9 @@ snapshots: '@esbuild/linux-arm64@0.24.2': optional: true + '@esbuild/linux-arm64@0.25.4': + optional: true + '@esbuild/linux-arm64@0.25.5': optional: true @@ -20660,6 +20812,9 @@ snapshots: '@esbuild/linux-arm@0.24.2': optional: true + '@esbuild/linux-arm@0.25.4': + optional: true + '@esbuild/linux-arm@0.25.5': optional: true @@ -20684,6 +20839,9 @@ snapshots: '@esbuild/linux-ia32@0.24.2': optional: true + '@esbuild/linux-ia32@0.25.4': + optional: true + '@esbuild/linux-ia32@0.25.5': optional: true @@ -20708,6 +20866,9 @@ snapshots: '@esbuild/linux-loong64@0.24.2': optional: true + '@esbuild/linux-loong64@0.25.4': + optional: true + '@esbuild/linux-loong64@0.25.5': optional: true @@ -20732,6 +20893,9 @@ snapshots: '@esbuild/linux-mips64el@0.24.2': optional: true + '@esbuild/linux-mips64el@0.25.4': + optional: true + '@esbuild/linux-mips64el@0.25.5': optional: true @@ -20756,6 +20920,9 @@ snapshots: '@esbuild/linux-ppc64@0.24.2': optional: true + '@esbuild/linux-ppc64@0.25.4': + optional: true + '@esbuild/linux-ppc64@0.25.5': optional: true @@ -20780,6 +20947,9 @@ snapshots: '@esbuild/linux-riscv64@0.24.2': optional: true + '@esbuild/linux-riscv64@0.25.4': + optional: true + '@esbuild/linux-riscv64@0.25.5': optional: true @@ -20804,6 +20974,9 @@ snapshots: '@esbuild/linux-s390x@0.24.2': optional: true + '@esbuild/linux-s390x@0.25.4': + optional: true + '@esbuild/linux-s390x@0.25.5': optional: true @@ -20828,12 +21001,18 @@ snapshots: '@esbuild/linux-x64@0.24.2': optional: true + '@esbuild/linux-x64@0.25.4': + optional: true + '@esbuild/linux-x64@0.25.5': optional: true '@esbuild/netbsd-arm64@0.24.2': optional: true + '@esbuild/netbsd-arm64@0.25.4': + optional: true + '@esbuild/netbsd-arm64@0.25.5': optional: true @@ -20858,6 +21037,9 @@ snapshots: '@esbuild/netbsd-x64@0.24.2': optional: true + '@esbuild/netbsd-x64@0.25.4': + optional: true + '@esbuild/netbsd-x64@0.25.5': optional: true @@ -20867,6 +21049,9 @@ snapshots: '@esbuild/openbsd-arm64@0.24.2': optional: true + '@esbuild/openbsd-arm64@0.25.4': + optional: true + '@esbuild/openbsd-arm64@0.25.5': optional: true @@ -20891,6 +21076,9 @@ snapshots: '@esbuild/openbsd-x64@0.24.2': optional: true + '@esbuild/openbsd-x64@0.25.4': + optional: true + '@esbuild/openbsd-x64@0.25.5': optional: true @@ -20915,6 +21103,9 @@ snapshots: '@esbuild/sunos-x64@0.24.2': optional: true + '@esbuild/sunos-x64@0.25.4': + optional: true + '@esbuild/sunos-x64@0.25.5': optional: true @@ -20939,6 +21130,9 @@ snapshots: '@esbuild/win32-arm64@0.24.2': optional: true + '@esbuild/win32-arm64@0.25.4': + optional: true + '@esbuild/win32-arm64@0.25.5': optional: true @@ -20963,6 +21157,9 @@ snapshots: '@esbuild/win32-ia32@0.24.2': optional: true + '@esbuild/win32-ia32@0.25.4': + optional: true + '@esbuild/win32-ia32@0.25.5': optional: true @@ -20987,6 +21184,9 @@ snapshots: '@esbuild/win32-x64@0.24.2': optional: true + '@esbuild/win32-x64@0.25.4': + optional: true + '@esbuild/win32-x64@0.25.5': optional: true @@ -21730,11 +21930,6 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true - '@img/sharp-darwin-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 - optional: true - '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.2.0 @@ -21745,11 +21940,6 @@ snapshots: '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true - '@img/sharp-darwin-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 - optional: true - '@img/sharp-darwin-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.2.0 @@ -21758,78 +21948,51 @@ snapshots: '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.1.0': - optional: true - '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true '@img/sharp-libvips-darwin-x64@1.0.4': optional: true - '@img/sharp-libvips-darwin-x64@1.1.0': - optional: true - '@img/sharp-libvips-darwin-x64@1.2.0': optional: true '@img/sharp-libvips-linux-arm64@1.0.4': optional: true - '@img/sharp-libvips-linux-arm64@1.1.0': - optional: true - '@img/sharp-libvips-linux-arm64@1.2.0': optional: true '@img/sharp-libvips-linux-arm@1.0.5': optional: true - '@img/sharp-libvips-linux-arm@1.1.0': - optional: true - '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.1.0': - optional: true - '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true '@img/sharp-libvips-linux-s390x@1.0.4': optional: true - '@img/sharp-libvips-linux-s390x@1.1.0': - optional: true - '@img/sharp-libvips-linux-s390x@1.2.0': optional: true '@img/sharp-libvips-linux-x64@1.0.4': optional: true - '@img/sharp-libvips-linux-x64@1.1.0': - optional: true - '@img/sharp-libvips-linux-x64@1.2.0': optional: true '@img/sharp-libvips-linuxmusl-arm64@1.0.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true '@img/sharp-libvips-linuxmusl-x64@1.0.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true @@ -21838,11 +22001,6 @@ snapshots: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true - '@img/sharp-linux-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 - optional: true - '@img/sharp-linux-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.2.0 @@ -21853,11 +22011,6 @@ snapshots: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true - '@img/sharp-linux-arm@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 - optional: true - '@img/sharp-linux-arm@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.2.0 @@ -21873,11 +22026,6 @@ snapshots: '@img/sharp-libvips-linux-s390x': 1.0.4 optional: true - '@img/sharp-linux-s390x@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 - optional: true - '@img/sharp-linux-s390x@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.2.0 @@ -21888,11 +22036,6 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.0.4 optional: true - '@img/sharp-linux-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 - optional: true - '@img/sharp-linux-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.2.0 @@ -21903,11 +22046,6 @@ snapshots: '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 optional: true - '@img/sharp-linuxmusl-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - optional: true - '@img/sharp-linuxmusl-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 @@ -21918,11 +22056,6 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64': 1.0.4 optional: true - '@img/sharp-linuxmusl-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - optional: true - '@img/sharp-linuxmusl-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.2.0 @@ -21933,11 +22066,6 @@ snapshots: '@emnapi/runtime': 1.4.5 optional: true - '@img/sharp-wasm32@0.34.1': - dependencies: - '@emnapi/runtime': 1.4.5 - optional: true - '@img/sharp-wasm32@0.34.3': dependencies: '@emnapi/runtime': 1.4.5 @@ -21949,18 +22077,12 @@ snapshots: '@img/sharp-win32-ia32@0.33.5': optional: true - '@img/sharp-win32-ia32@0.34.1': - optional: true - '@img/sharp-win32-ia32@0.34.3': optional: true '@img/sharp-win32-x64@0.33.5': optional: true - '@img/sharp-win32-x64@0.34.1': - optional: true - '@img/sharp-win32-x64@0.34.3': optional: true @@ -23122,9 +23244,9 @@ snapshots: '@oslojs/encoding@1.1.0': {} - '@oxc-project/runtime@0.81.0': {} + '@oxc-project/runtime@0.82.3': {} - '@oxc-project/types@0.81.0': {} + '@oxc-project/types@0.82.3': {} '@panva/hkdf@1.2.1': {} @@ -24934,51 +25056,51 @@ snapshots: transitivePeerDependencies: - supports-color - '@rolldown/binding-android-arm64@1.0.0-beta.32': + '@rolldown/binding-android-arm64@1.0.0-beta.34': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.32': + '@rolldown/binding-darwin-arm64@1.0.0-beta.34': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.32': + '@rolldown/binding-darwin-x64@1.0.0-beta.34': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.32': + '@rolldown/binding-freebsd-x64@1.0.0-beta.34': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.32': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.32': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.32': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.34': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.32': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.34': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.32': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.34': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.32': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.34': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.32': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.34': dependencies: '@napi-rs/wasm-runtime': 1.0.3 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.32': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.32': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.32': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.34': optional: true - '@rolldown/pluginutils@1.0.0-beta.32': {} + '@rolldown/pluginutils@1.0.0-beta.34': {} '@rollup/plugin-alias@5.1.1(rollup@3.29.5)': optionalDependencies: @@ -28731,6 +28853,35 @@ snapshots: convert-source-map@2.0.0: {} + convex-helpers@0.1.104(@standard-schema/spec@1.0.0)(convex@1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0))(hono@4.6.15)(react@19.1.0)(typescript@5.8.3)(zod@3.25.67): + dependencies: + convex: 1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + optionalDependencies: + '@standard-schema/spec': 1.0.0 + hono: 4.6.15 + react: 19.1.0 + typescript: 5.8.3 + zod: 3.25.67 + + convex-helpers@0.1.104(@standard-schema/spec@1.0.0-beta.4)(convex@1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0))(hono@4.6.15)(react@19.1.0)(typescript@5.8.3)(zod@3.25.67): + dependencies: + convex: 1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + optionalDependencies: + '@standard-schema/spec': 1.0.0-beta.4 + hono: 4.6.15 + react: 19.1.0 + typescript: 5.8.3 + zod: 3.25.67 + + convex@1.26.2(@clerk/clerk-react@5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): + dependencies: + esbuild: 0.25.4 + jwt-decode: 4.0.0 + prettier: 3.5.3 + optionalDependencies: + '@clerk/clerk-react': 5.22.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + cookie-es@1.2.2: {} cookie-es@2.0.0: {} @@ -29732,6 +29883,34 @@ snapshots: '@esbuild/win32-ia32': 0.24.2 '@esbuild/win32-x64': 0.24.2 + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + esbuild@0.25.5: optionalDependencies: '@esbuild/aix-ppc64': 0.25.5 @@ -34118,7 +34297,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 15.3.1 '@next/swc-win32-x64-msvc': 15.3.1 '@playwright/test': 1.52.0 - sharp: 0.34.1 + sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -36862,7 +37041,7 @@ snapshots: dependencies: glob: 10.4.5 - rolldown-plugin-dts@0.15.6(rolldown@1.0.0-beta.32)(typescript@5.8.3): + rolldown-plugin-dts@0.15.6(rolldown@1.0.0-beta.34)(typescript@5.8.3): dependencies: '@babel/generator': 7.28.3 '@babel/parser': 7.28.3 @@ -36872,34 +37051,34 @@ snapshots: debug: 4.4.1 dts-resolver: 2.1.1 get-tsconfig: 4.10.1 - rolldown: 1.0.0-beta.32 + rolldown: 1.0.0-beta.34 optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.32: + rolldown@1.0.0-beta.34: dependencies: - '@oxc-project/runtime': 0.81.0 - '@oxc-project/types': 0.81.0 - '@rolldown/pluginutils': 1.0.0-beta.32 + '@oxc-project/runtime': 0.82.3 + '@oxc-project/types': 0.82.3 + '@rolldown/pluginutils': 1.0.0-beta.34 ansis: 4.1.0 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.32 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.32 - '@rolldown/binding-darwin-x64': 1.0.0-beta.32 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.32 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.32 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.32 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.32 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.32 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.32 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.32 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.32 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.32 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.32 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.32 + '@rolldown/binding-android-arm64': 1.0.0-beta.34 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.34 + '@rolldown/binding-darwin-x64': 1.0.0-beta.34 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.34 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.34 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.34 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.34 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.34 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.34 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.34 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.34 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.34 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.34 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.34 rollup-plugin-dts@6.2.1(rollup@3.29.5)(typescript@5.8.3): dependencies: @@ -37256,34 +37435,6 @@ snapshots: '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 - sharp@0.34.1: - dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.1 - '@img/sharp-darwin-x64': 0.34.1 - '@img/sharp-libvips-darwin-arm64': 1.1.0 - '@img/sharp-libvips-darwin-x64': 1.1.0 - '@img/sharp-libvips-linux-arm': 1.1.0 - '@img/sharp-libvips-linux-arm64': 1.1.0 - '@img/sharp-libvips-linux-ppc64': 1.1.0 - '@img/sharp-libvips-linux-s390x': 1.1.0 - '@img/sharp-libvips-linux-x64': 1.1.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.1 - '@img/sharp-linux-arm64': 0.34.1 - '@img/sharp-linux-s390x': 0.34.1 - '@img/sharp-linux-x64': 0.34.1 - '@img/sharp-linuxmusl-arm64': 0.34.1 - '@img/sharp-linuxmusl-x64': 0.34.1 - '@img/sharp-wasm32': 0.34.1 - '@img/sharp-win32-ia32': 0.34.1 - '@img/sharp-win32-x64': 0.34.1 - optional: true - sharp@0.34.3: dependencies: color: 4.2.3 @@ -38181,8 +38332,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.32 - rolldown-plugin-dts: 0.15.6(rolldown@1.0.0-beta.32)(typescript@5.8.3) + rolldown: 1.0.0-beta.34 + rolldown-plugin-dts: 0.15.6(rolldown@1.0.0-beta.34)(typescript@5.8.3) semver: 7.7.2 tinyexec: 1.0.1 tinyglobby: 0.2.14