Skip to content

Commit

Permalink
setup convex
Browse files Browse the repository at this point in the history
  • Loading branch information
bahiensed committed Jul 23, 2024
1 parent 08ea75f commit b7c04b3
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 28 deletions.
4 changes: 4 additions & 0 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import type {
FilterApi,
FunctionReference,
} from "convex/server";
import type * as http from "../http.js";
import type * as tasks from "../tasks.js";
import type * as users from "../users.js";

/**
* A utility for referencing Convex functions in your app's API.
Expand All @@ -25,7 +27,9 @@ import type * as tasks from "../tasks.js";
* ```
*/
declare const fullApi: ApiFromModules<{
http: typeof http;
tasks: typeof tasks;
users: typeof users;
}>;
export declare const api: FilterApi<
typeof fullApi,
Expand Down
34 changes: 18 additions & 16 deletions convex/_generated/dataModel.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@
* @module
*/

import { AnyDataModel } from "convex/server";
import type {
DataModelFromSchemaDefinition,
DocumentByName,
TableNamesInDataModel,
SystemTableNames,
} 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`.
*/
import schema from "../schema.js";

/**
* The names of all of your Convex tables.
*/
export type TableNames = string;
export type TableNames = TableNamesInDataModel<DataModel>;

/**
* The type of a document stored in Convex.
*
* @typeParam TableName - A string literal type of the table name (like "users").
*/
export type Doc = any;
export type Doc<TableName extends TableNames> = DocumentByName<
DataModel,
TableName
>;

/**
* An identifier for a document in Convex.
Expand All @@ -43,8 +43,10 @@ export type Doc = any;
*
* IDs are just strings at runtime, but this type can be used to distinguish them from other
* strings when type checking.
*
* @typeParam TableName - A string literal type of the table name (like "users").
*/
export type Id<TableName extends TableNames = TableNames> =
export type Id<TableName extends TableNames | SystemTableNames> =
GenericId<TableName>;

/**
Expand All @@ -56,4 +58,4 @@ export type Id<TableName extends TableNames = TableNames> =
* This type is used to parameterize methods like `queryGeneric` and
* `mutationGeneric` to make them type-safe.
*/
export type DataModel = AnyDataModel;
export type DataModel = DataModelFromSchemaDefinition<typeof schema>;
10 changes: 10 additions & 0 deletions convex/auth.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const authConfig = {
providers: [
{
domain: "https://evident-skink-35.clerk.accounts.dev",
applicationID: "convex",
},
]
};

export default authConfig;
72 changes: 72 additions & 0 deletions convex/http.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// ===== reference links =====
// https://www.convex.dev/templates (open the link and choose for clerk than you will get the github link mentioned below)
// https://github.dev/webdevcody/thumbnail-critique/blob/6637671d72513cfe13d00cb7a2990b23801eb327/convex/schema.ts

import type { WebhookEvent } from "@clerk/nextjs/server";
import { httpRouter } from "convex/server";
import { Webhook } from "svix";

import { internal } from "./_generated/api";
import { httpAction } from "./_generated/server";

const handleClerkWebhook = httpAction(async (ctx, request) => {
const event = await validateRequest(request);
if (!event) {
return new Response("Invalid request", { status: 400 });
}
switch (event.type) {
case "user.created":
await ctx.runMutation(internal.users.createUser, {
clerkId: event.data.id,
email: event.data.email_addresses[0].email_address,
imageUrl: event.data.image_url,
name: event.data.first_name as string,
});
break;
case "user.updated":
await ctx.runMutation(internal.users.updateUser, {
clerkId: event.data.id,
imageUrl: event.data.image_url,
email: event.data.email_addresses[0].email_address,
});
break;
case "user.deleted":
await ctx.runMutation(internal.users.deleteUser, {
clerkId: event.data.id as string,
});
break;
}
return new Response(null, {
status: 200,
});
});

const http = httpRouter();

http.route({
path: "/clerk",
method: "POST",
handler: handleClerkWebhook,
});

const validateRequest = async (
req: Request
): Promise<WebhookEvent | undefined> => {
// key note : add the webhook secret variable to the environment variables field in convex dashboard setting
const webhookSecret = process.env.CLERK_WEBHOOK_SECRET!;
if (!webhookSecret) {
throw new Error("CLERK_WEBHOOK_SECRET is not defined");
}
const payloadString = await req.text();
const headerPayload = req.headers;
const svixHeaders = {
"svix-id": headerPayload.get("svix-id")!,
"svix-timestamp": headerPayload.get("svix-timestamp")!,
"svix-signature": headerPayload.get("svix-signature")!,
};
const wh = new Webhook(webhookSecret);
const event = wh.verify(payloadString, svixHeaders);
return event as unknown as WebhookEvent;
};

export default http;
4 changes: 2 additions & 2 deletions convex/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { query } from "./_generated/server";
/*import { query } from "./_generated/server";
export const get = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("tasks").collect();
},
});
});*/
31 changes: 31 additions & 0 deletions providers/ConvexClerkProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { ReactNode } from "react";
import { ClerkProvider, useAuth } from "@clerk/nextjs";
import { ConvexProviderWithClerk } from "convex/react-clerk";
import { ConvexReactClient } from "convex/react";

const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL as string);

const ConvexClerkProvider = ({ children }: { children: ReactNode}) => (
<ClerkProvider publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY as string} appearance={{
layout: {
socialButtonsVariant: 'iconButton',
logoImageUrl: '/icons/auth-logo.svg',
},
variables: {
colorBackground: '#15171c',
colorPrimary: '',
colorText: 'white',
colorInputBackground: '#1b1f29',
colorInputText: 'white',

}
}}>
<ConvexProviderWithClerk client={convex} useAuth={useAuth}>
{ children }
</ConvexProviderWithClerk>
</ClerkProvider>
);

export default ConvexClerkProvider;
10 changes: 0 additions & 10 deletions providers/ConvexClientProvider.tsx

This file was deleted.

0 comments on commit b7c04b3

Please sign in to comment.