-
Notifications
You must be signed in to change notification settings - Fork 392
feat: Add Convex Adapter #1235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
IslamIhab
wants to merge
15
commits into
pingdotgg:main
Choose a base branch
from
IslamIhab:convex-adapter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: Add Convex Adapter #1235
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
b5b704b
feat: attempt to add Convex Adapter
IslamIhab 50e71a9
refactor: simplify ConvexBuilderOptions by removing SchemaDefinition …
IslamIhab 084228b
fix: add changeset
IslamIhab e20ad2b
fix: improve response header
IslamIhab b4ab843
refactor: enhance createRouteHandler to accept customizable path para…
IslamIhab 6b8145d
feat: add Convex backend adapter and corresponding icon to documentation
IslamIhab 45a1f12
feat: added example
IslamIhab 2d4bb76
fix: a couple of fixes to the example
IslamIhab b481f13
fix: update README and HTTP route for UploadThing integration
IslamIhab de178e7
fix: replace randomUUID with crypto.randomUUID for custom file IDs in…
IslamIhab 121f21a
chore: update .env.example with UploadThing Convex adapter requiremen…
IslamIhab b79d51b
feat: integrate convex-helpers for easier cors handling and updating …
IslamIhab 681e127
chore: update the backend adapters to be alphabetical
IslamIhab f840666
fix: correct typo in comment for request validation in UploadThing ex…
IslamIhab 75f4383
feat: add allowedHeaders to CORS in example
IslamIhab File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"uploadthing": minor | ||
--- | ||
|
||
Add Convex Adapter |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
||
<Note> | ||
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) | ||
</Note> | ||
|
||
```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 | ||
|
||
<Note> | ||
File path here doesn't matter, you can serve this from any route. We recommend | ||
serving it from `/api/uploadthing`. | ||
</Note> | ||
|
||
```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", | ||
}); | ||
// ... | ||
``` | ||
|
||
<Note> | ||
Please note that you might need to setup some CORS rules on your server to | ||
allow the client to make requests to the server. | ||
</Note> | ||
|
||
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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Deployment used by `npx convex dev` | ||
CONVEX_DEPLOYMENT= | ||
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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='<your-uploadthing-token>' | ||
# The adapter will 500/throw early if these are missing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
.env.local |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Minimal Next.js App Router + Convex example for UploadThing | ||
|
||
<a href="https://stackblitz.com/github/pingdotgg/uploadthing/tree/main/examples/minimal-convex"> | ||
<img height="64" src="https://github.com/pingdotgg/uploadthing/assets/51714798/45907a4e-aa64-401a-afb3-b6c6df6eb71f" /> | ||
</a> | ||
|
||
## 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=<your-token>` | ||
7. `pnpm dev` | ||
8. Upload files! | ||
|
||
## Further reference | ||
|
||
Check out the docs at: https://docs.uploadthing.com/backend-adapters/convex |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<any, "public"> | ||
>; | ||
export declare const internal: FilterApi< | ||
typeof fullApi, | ||
FunctionReference<any, "internal"> | ||
>; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.