From c18410e243f146df095381239974ae9899f4e6ce Mon Sep 17 00:00:00 2001 From: Nayan Sawyer <33187059+GShadow5@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:07:02 -0400 Subject: [PATCH] add convex and clerk --- bun.lockb | Bin 167332 -> 186322 bytes convex/README.md | 90 ++++++++++++++++++++ convex/_generated/api.d.ts | 33 +++++++ convex/_generated/api.js | 22 +++++ convex/_generated/dataModel.d.ts | 58 +++++++++++++ convex/_generated/server.d.ts | 142 +++++++++++++++++++++++++++++++ convex/_generated/server.js | 89 +++++++++++++++++++ convex/tsconfig.json | 25 ++++++ package.json | 2 + 9 files changed, 461 insertions(+) create mode 100644 convex/README.md create mode 100644 convex/_generated/api.d.ts create mode 100644 convex/_generated/api.js create mode 100644 convex/_generated/dataModel.d.ts create mode 100644 convex/_generated/server.d.ts create mode 100644 convex/_generated/server.js create mode 100644 convex/tsconfig.json diff --git a/bun.lockb b/bun.lockb index d5d094c147de18a40b4420b0c897ef47e57a03c4..40b2861c9e64c7599a987bf69d44d30166d99d7e 100644 GIT binary patch delta 42926 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 diff --git a/convex/README.md b/convex/README.md new file mode 100644 index 0000000..4d82e13 --- /dev/null +++ b/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 +// functions.js +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.functions.myQueryFunction, { + first: 10, + second: "hello", +}); +``` + +A mutation function looks like: + +```ts +// functions.js +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.functions.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/convex/_generated/api.d.ts b/convex/_generated/api.d.ts new file mode 100644 index 0000000..7d71a01 --- /dev/null +++ b/convex/_generated/api.d.ts @@ -0,0 +1,33 @@ +/* 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"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +declare const fullApi: ApiFromModules<{}>; +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; diff --git a/convex/_generated/api.js b/convex/_generated/api.js new file mode 100644 index 0000000..3f9c482 --- /dev/null +++ b/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/convex/_generated/dataModel.d.ts b/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000..fb12533 --- /dev/null +++ b/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/convex/_generated/server.d.ts b/convex/_generated/server.d.ts new file mode 100644 index 0000000..7f337a4 --- /dev/null +++ b/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/convex/_generated/server.js b/convex/_generated/server.js new file mode 100644 index 0000000..566d485 --- /dev/null +++ b/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/convex/tsconfig.json b/convex/tsconfig.json new file mode 100644 index 0000000..7374127 --- /dev/null +++ b/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/package.json b/package.json index fa5ea8b..aff887d 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "format:check": "prettier --check \"**/*.{ts,tsx,md,json,html}\"" }, "dependencies": { + "@clerk/nextjs": "^6.22.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "convex": "^1.24.8", "lucide-react": "^0.514.0", "next": "15.3.3", "react": "^19.0.0",