Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions convex/README.md
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("messages", 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`.
3 changes: 2 additions & 1 deletion convex/githubImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ export const previewGitHubImportCandidate = action({
defaultSelectedPaths,
})

const baseForNaming = candidate.path ? (candidate.path.split('/').at(-1) ?? '') : resolved.repo
const pathParts = candidate.path ? candidate.path.split('/') : []
const baseForNaming = candidate.path ? (pathParts[pathParts.length - 1] ?? '') : resolved.repo
const suggestedDisplayName = suggestDisplayName(candidate, baseForNaming)

const rawSlugBase = sanitizeSlug(candidate.path ? baseForNaming : resolved.repo)
Expand Down
6 changes: 4 additions & 2 deletions convex/lib/githubImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ async function resolveHeadCommit(parsed: GitHubImportUrl, fetcher: typeof fetch)
url = next.toString()
}

const maybe = url.split('/').at(-1) ?? ''
const urlParts = url.split('/')
const maybe = urlParts[urlParts.length - 1] ?? ''
if (!/^[a-f0-9]{40}$/i.test(maybe)) {
throw new Error('Could not resolve commit for HEAD')
}
Expand Down Expand Up @@ -363,7 +364,8 @@ function isUnderRoot(path: string, rootWithSlash: string) {

function isTextPath(path: string) {
const lower = path.toLowerCase()
const ext = lower.split('.').at(-1) ?? ''
const extParts = lower.split('.')
const ext = extParts[extParts.length - 1] ?? ''
if (!ext) return false
return TEXT_FILE_EXTENSION_SET.has(ext)
}
Expand Down
2 changes: 1 addition & 1 deletion convex/lib/skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function isTextFile(path: string, contentType?: string | null) {
const trimmed = path.trim().toLowerCase()
if (!trimmed) return false
const parts = trimmed.split('.')
const extension = parts.length > 1 ? (parts.at(-1) ?? '') : ''
const extension = parts.length > 1 ? (parts[parts.length - 1] ?? '') : ''
if (contentType) {
if (isTextContentType(contentType)) return true
}
Expand Down
24 changes: 21 additions & 3 deletions convex/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
{
"extends": "../tsconfig.json",
/* 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",
"skipLibCheck": true
}
"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"]
}