From 5836a989311824554ae591e337fccffaf119f032 Mon Sep 17 00:00:00 2001 From: Alhwyn Date: Mon, 15 Dec 2025 21:31:20 -0800 Subject: [PATCH 1/4] Refactor build script for Cafe CLI, updating help text and improving argument parsing. Add TypeScript dependency and enhance UI colors in various components for better visibility. Implement new filtering options in SendCredits screen and ensure data refresh on entry. Update ContactTable and UploadAttendees components for consistent styling. --- build.ts | 47 +++++++++++++-------------------- bun.lock | 3 +++ package.json | 3 ++- src/cli.tsx | 14 +++++----- src/components/ContactTable.tsx | 2 +- src/screens/SendCredits.tsx | 30 ++++++++++++++++++--- src/screens/UploadAttendees.tsx | 10 +++---- src/utils/attendeeParser.ts | 4 +-- test/businessLogic.test.ts | 8 +++--- 9 files changed, 69 insertions(+), 52 deletions(-) mode change 100644 => 100755 src/cli.tsx diff --git a/build.ts b/build.ts index 3af4a58..5d50fb7 100644 --- a/build.ts +++ b/build.ts @@ -1,39 +1,28 @@ #!/usr/bin/env bun -import plugin from "bun-plugin-tailwind"; import { existsSync } from "fs"; import { rm } from "fs/promises"; import path from "path"; if (process.argv.includes("--help") || process.argv.includes("-h")) { console.log(` -šŸ—ļø Bun Build Script +šŸ—ļø Cafe CLI Build Script Usage: bun run build.ts [options] Common Options: --outdir Output directory (default: "dist") - --minify Enable minification (or --minify.grayspace, --minify.syntax, etc) - --sourcemap Sourcemap type: none|linked|inline|external - --target Build target: browser|bun|node - --format Output format: esm|cjs|iife - --splitting Enable code splitting - --packages Package handling: bundle|external - --public-path Public path for assets - --env Environment handling: inline|disable|prefix* - --conditions Package.json export conditions (comma separated) - --external External packages (comma separated) - --banner Add banner text to output - --footer Add footer text to output - --define Define global constants (e.g. --define.VERSION=1.0.0) + --minify Enable minification + --sourcemap Sourcemap type: none|linked|inline|external + --target Build target: bun|node --help, -h Show this help message Example: - bun run build.ts --outdir=dist --minify --sourcemap=linked --external=react,react-dom + bun run build.ts --outdir=dist --minify --sourcemap=linked `); process.exit(0); } -const toCamelCase = (str: string): string => str.replace(/-([a-z])/g, g => g[1].toUpperCase()); +const toCamelCase = (str: string): string => str.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()); const parseValue = (value: string): any => { if (value === "true") return true; @@ -47,8 +36,8 @@ const parseValue = (value: string): any => { return value; }; -function parseArgs(): Partial { - const config: Partial = {}; +function parseArgs(): Record { + const config: Record = {}; const args = process.argv.slice(2); for (let i = 0; i < args.length; i++) { @@ -81,9 +70,9 @@ function parseArgs(): Partial { key = toCamelCase(key); if (key.includes(".")) { - const [parentKey, childKey] = key.split("."); + const [parentKey, childKey] = key.split(".", 2) as [string, string]; config[parentKey] = config[parentKey] || {}; - config[parentKey][childKey] = parseValue(value); + (config[parentKey] as Record)[childKey] = parseValue(value); } else { config[key] = parseValue(value); } @@ -108,7 +97,7 @@ const formatFileSize = (bytes: number): string => { console.log("\nšŸš€ Starting build process...\n"); const cliConfig = parseArgs(); -const outdir = cliConfig.outdir || path.join(process.cwd(), "dist"); +const outdir = (typeof cliConfig.outdir === "string" ? cliConfig.outdir : null) || path.join(process.cwd(), "dist"); if (existsSync(outdir)) { console.log(`šŸ—‘ļø Cleaning previous build at ${outdir}`); @@ -117,18 +106,20 @@ if (existsSync(outdir)) { const start = performance.now(); -const entrypoints = [...new Bun.Glob("**.html").scanSync("src")] - .map(a => path.resolve("src", a)) - .filter(dir => !dir.includes("node_modules")); -console.log(`šŸ“„ Found ${entrypoints.length} HTML ${entrypoints.length === 1 ? "file" : "files"} to process\n`); +const entrypoints = [path.resolve("src", "cli.tsx")]; +console.log(`šŸ“„ Building CLI from ${entrypoints[0]}\n`); const result = await Bun.build({ entrypoints, outdir, - plugins: [plugin], minify: true, - target: "browser", + target: "bun", sourcemap: "linked", + external: [ + "react-devtools-core", + "electron", + "chromium-bidi", + ], define: { "process.env.NODE_ENV": JSON.stringify("production"), }, diff --git a/bun.lock b/bun.lock index 504c8c6..a16a193 100644 --- a/bun.lock +++ b/bun.lock @@ -25,6 +25,7 @@ "@types/figlet": "^1.7.0", "@types/react": "^19", "@types/react-dom": "^19", + "typescript": "^5.9.3", }, }, }, @@ -313,6 +314,8 @@ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="], diff --git a/package.json b/package.json index 71235af..5c44e6a 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@types/bun": "latest", "@types/figlet": "^1.7.0", "@types/react": "^19", - "@types/react-dom": "^19" + "@types/react-dom": "^19", + "typescript": "^5.9.3" } } diff --git a/src/cli.tsx b/src/cli.tsx old mode 100644 new mode 100755 index e3b8e64..e5cd62c --- a/src/cli.tsx +++ b/src/cli.tsx @@ -70,9 +70,9 @@ const MainMenu = () => { }); const menuItems = [ - { label: "1. Send Cursor Credits", value: "send" }, - { label: "2. Upload Cursor Credits", value: "upload" }, - { label: "3. Upload Attendees", value: "attendees" }, + { label: "Send Cursor Credits", value: "send" }, + { label: "Upload Cursor Credits", value: "upload" }, + { label: "Upload Attendees", value: "attendees" }, ]; const handleSelect = (item: { label: string; value: string }) => { @@ -133,10 +133,10 @@ const MainMenu = () => { /> - 1 Send - 2 Credits - 3 Attendees - Q Quit + 1 Send + 2 Credits + 3 Attendees + Q Quit diff --git a/src/components/ContactTable.tsx b/src/components/ContactTable.tsx index b20e8df..fcf890d 100644 --- a/src/components/ContactTable.tsx +++ b/src/components/ContactTable.tsx @@ -111,7 +111,7 @@ const ContactTable = ({ contacts, onSelect, onBack, isActive = true }: ContactTa {/* Header */} - + {" "} {padRight("Name", cols.name)} {padRight("Email", cols.email)} diff --git a/src/screens/SendCredits.tsx b/src/screens/SendCredits.tsx index 1a15b29..7b76f94 100644 --- a/src/screens/SendCredits.tsx +++ b/src/screens/SendCredits.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo } from "react"; +import React, { useState, useMemo, useEffect } from "react"; import { Box, Text, useInput } from "ink"; import TextInput from "ink-text-input"; import ContactTable from "../components/ContactTable.js"; @@ -17,6 +17,7 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { const [isSearchFocused, setIsSearchFocused] = useState(false); const [selectedContact, setSelectedContact] = useState(null); const [showNotSentOnly, setShowNotSentOnly] = useState(false); + const [showSentOnly, setShowSentOnly] = useState(false); // Email sending state const [isSending, setIsSending] = useState(false); @@ -28,6 +29,19 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { const { data: creditTally, refresh: refreshCredits } = useCreditTally(); const sendCredits = useSendCredits(); + // Refresh data when entering the page + useEffect(() => { + refreshPeople(); + refreshCredits(); + }, []); + + // Handle going back - refresh data before leaving + const handleBack = () => { + refreshPeople(); + refreshCredits(); + onBack(); + }; + // Transform database people to Contact format const contacts: Contact[] = useMemo(() => { if (!people) return []; @@ -52,6 +66,8 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { // Filter by sent status if (showNotSentOnly) { filtered = filtered.filter((contact) => !contact.sent); + } else if (showSentOnly) { + filtered = filtered.filter((contact) => contact.sent); } // Filter by search query @@ -67,7 +83,7 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { } return filtered; - }, [contacts, searchQuery, showNotSentOnly]); + }, [contacts, searchQuery, showNotSentOnly, showSentOnly]); // Toggle focus between search and table useInput((input, key) => { @@ -81,6 +97,10 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { setIsSearchFocused(true); } else if (input === "f" && !isSearchFocused) { setShowNotSentOnly((prev) => !prev); + setShowSentOnly(false); + } else if (input === "s" && !isSearchFocused) { + setShowSentOnly((prev) => !prev); + setShowNotSentOnly(false); } }); @@ -181,12 +201,13 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { Send Cursor Credits ({filteredContacts.length} recipients) {showNotSentOnly && [Not Sent Only]} + {showSentOnly && [Sent Only]} @@ -220,7 +241,8 @@ const SendCredits = ({ onBack }: SendCreditsProps) => { Up/Down Navigate Enter Select Tab {isSearchFocused ? "Exit Search" : "Search"} - F Filter Not Sent + F Not Sent + S Sent Only Q Back diff --git a/src/screens/UploadAttendees.tsx b/src/screens/UploadAttendees.tsx index 4de15a1..7595dbf 100644 --- a/src/screens/UploadAttendees.tsx +++ b/src/screens/UploadAttendees.tsx @@ -143,7 +143,7 @@ const UploadAttendees = ({ onBack }: UploadAttendeesProps) => { - Expected CSV columns: + Expected CSV columns: - first_name (required) - last_name (required) - email (required) @@ -208,7 +208,7 @@ const UploadAttendees = ({ onBack }: UploadAttendeesProps) => { Processing: - {filepath} + {filepath} @@ -242,8 +242,8 @@ const UploadAttendees = ({ onBack }: UploadAttendeesProps) => { {result.imported} - Skipped (duplicates): - {result.skipped} + Skipped (duplicates): + {result.skipped} @@ -275,4 +275,4 @@ const UploadAttendees = ({ onBack }: UploadAttendeesProps) => { ); }; -export default UploadAttendees; +export default UploadAttendees; \ No newline at end of file diff --git a/src/utils/attendeeParser.ts b/src/utils/attendeeParser.ts index 490e884..98d54b6 100644 --- a/src/utils/attendeeParser.ts +++ b/src/utils/attendeeParser.ts @@ -56,7 +56,7 @@ export async function parseAttendeeCSV(filepath: string): Promise { throw new Error("CSV must have a header row and at least one data row"); } - const headers = parseCSVLine(lines[0]); + const headers = parseCSVLine(lines[0]!); const columnIndexes: Partial> = {}; // Map headers to column indexes @@ -81,7 +81,7 @@ export async function parseAttendeeCSV(filepath: string): Promise { const attendees: Attendee[] = []; for (let i = 1; i < lines.length; i++) { - const values = parseCSVLine(lines[i]); + const values = parseCSVLine(lines[i]!); const firstName = values[columnIndexes.firstName!] || ""; const lastName = values[columnIndexes.lastName!] || ""; diff --git a/test/businessLogic.test.ts b/test/businessLogic.test.ts index b30b40f..fd75584 100644 --- a/test/businessLogic.test.ts +++ b/test/businessLogic.test.ts @@ -86,11 +86,11 @@ describe("People Storage", () => { const result = addPerson(testCase.person, tempDir); - expect(result.added).toBe(testCase.expected.added); - expect(result.skipped).toBe(testCase.expected.skipped); + expect(result.added).toBe(testCase.expected.added!); + expect(result.skipped).toBe(testCase.expected.skipped!); const people = loadPeople(tempDir); - expect(people.length).toBe(testCase.expected.totalPeople); + expect(people.length).toBe(testCase.expected.totalPeople!); }); test("skips duplicate email (case insensitive)", () => { @@ -163,7 +163,7 @@ describe("Credits Storage", () => { const result = addCreditIfNotExists(testCase.credit!, tempDir); - expect(result.added).toBe(testCase.expected.added); + expect(result.added).toBe(testCase.expected.added!); const credits = loadCredits(tempDir); expect(credits.length).toBe(1); From 6a23ec7f56f8d8a4703807097f496d86d639dd75 Mon Sep 17 00:00:00 2001 From: Alhwyn Date: Mon, 15 Dec 2025 21:33:44 -0800 Subject: [PATCH 2/4] types --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 5c44e6a..c826bbc 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "ink-select-input": "^6.2.0", "ink-text-input": "^6.0.0", "node-html-parser": "^7.0.1", + "papaparse": "^5.5.3", "playwright": "^1.57.0", "react": "^19", "react-dom": "^19", @@ -31,6 +32,7 @@ "devDependencies": { "@types/bun": "latest", "@types/figlet": "^1.7.0", + "@types/papaparse": "^5.3.15", "@types/react": "^19", "@types/react-dom": "^19", "typescript": "^5.9.3" From bd544c8ca2c127c774d55bdc720386f4ba35c532 Mon Sep 17 00:00:00 2001 From: Alhwyn Date: Mon, 15 Dec 2025 21:36:06 -0800 Subject: [PATCH 3/4] test --- .github/workflows/ci.yml | 3 +++ README.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 247d10b..77b420c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,9 @@ jobs: - name: Install dependencies run: bun install + - name: Generate Convex types + run: bunx convex codegen + - name: Install Playwright browsers run: bunx playwright install --with-deps chromium diff --git a/README.md b/README.md index 1c22fe8..af96ee4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ā•šā•ā•ā•ā•ā•ā•ā•šā•ā• ā•šā•ā•ā•šā•ā• ā•šā•ā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā• ā•šā•ā•ā•šā•ā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā• ā•šā•ā• ``` -# Cafe Cursor CLI +# Cafe Cursor CLI [![CI](https://github.com/Alhwyn/cafe-cursor-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/Alhwyn/cafe-cursor-cli/actions/workflows/ci.yml) A CLI tool for managing and sending Cursor credits to event attendees via email. From cb138e09cedfe71d4ba253289b8f83df8330b0b0 Mon Sep 17 00:00:00 2001 From: Alhwyn Date: Mon, 15 Dec 2025 21:39:14 -0800 Subject: [PATCH 4/4] gen --- .github/workflows/ci.yml | 3 - .gitignore | 2 +- convex/_generated/api.d.ts | 55 ++++++++++++ convex/_generated/api.js | 23 +++++ convex/_generated/dataModel.d.ts | 60 +++++++++++++ convex/_generated/server.d.ts | 143 +++++++++++++++++++++++++++++++ convex/_generated/server.js | 93 ++++++++++++++++++++ 7 files changed, 375 insertions(+), 4 deletions(-) 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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77b420c..247d10b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,6 @@ jobs: - name: Install dependencies run: bun install - - name: Generate Convex types - run: bunx convex codegen - - name: Install Playwright browsers run: bunx playwright install --with-deps chromium diff --git a/.gitignore b/.gitignore index ccfa293..f0b3199 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json .DS_Store cafe_cursor.csv credits.csv -convex/_generated +# convex/_generated is now committed with stubs for CI diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts new file mode 100644 index 0000000..abe4afe --- /dev/null +++ b/convex/_generated/api.d.ts @@ -0,0 +1,55 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type * as credits from "../credits.js"; +import type * as email from "../email.js"; +import type * as emailHelpers from "../emailHelpers.js"; +import type * as people from "../people.js"; + +import type { + ApiFromModules, + FilterApi, + FunctionReference, +} from "convex/server"; + +declare const fullApi: ApiFromModules<{ + credits: typeof credits; + email: typeof email; + emailHelpers: typeof emailHelpers; + people: typeof people; +}>; + +/** + * A utility for referencing Convex functions in your app's public API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; + +/** + * A utility for referencing Convex functions in your app's internal API. + * + * Usage: + * ```js + * const myFunctionReference = internal.myModule.myFunction; + * ``` + */ +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; + +export declare const components: {}; diff --git a/convex/_generated/api.js b/convex/_generated/api.js new file mode 100644 index 0000000..44bf985 --- /dev/null +++ b/convex/_generated/api.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi, componentsGeneric } 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; +export const components = componentsGeneric(); diff --git a/convex/_generated/dataModel.d.ts b/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000..f97fd19 --- /dev/null +++ b/convex/_generated/dataModel.d.ts @@ -0,0 +1,60 @@ +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + DataModelFromSchemaDefinition, + DocumentByName, + TableNamesInDataModel, + SystemTableNames, +} from "convex/server"; +import type { GenericId } from "convex/values"; +import schema from "../schema.js"; + +/** + * The names of all of your Convex tables. + */ +export type TableNames = TableNamesInDataModel; + +/** + * The type of a document stored in Convex. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +export type Doc = DocumentByName< + DataModel, + TableName +>; + +/** + * 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(tableName, 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. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +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 = DataModelFromSchemaDefinition; diff --git a/convex/_generated/server.d.ts b/convex/_generated/server.d.ts new file mode 100644 index 0000000..bec05e6 --- /dev/null +++ b/convex/_generated/server.d.ts @@ -0,0 +1,143 @@ +/* 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. + * + * The wrapped 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 httpAction in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument + * and a Fetch API `Request` object as its second. + * @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..bf3d25a --- /dev/null +++ b/convex/_generated/server.js @@ -0,0 +1,93 @@ +/* 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 an HTTP action. + * + * The wrapped 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 httpAction in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument + * and a Fetch API `Request` object as its second. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export const httpAction = httpActionGeneric;