Skip to main content
Glama
posts.ts3.79 kB
import { v } from "convex/values"; import { mutation, query, getMutationTable, getQueryTable } from "./functions"; export const createPost = mutation({ args: { title: v.string(), slug: v.string(), content: v.string(), authorId: v.id("users"), published: v.boolean(), tagIds: v.optional(v.array(v.id("tags"))), }, handler: async (ctx, { tagIds, ...args }) => { const table = getMutationTable(ctx); const postId = await table("posts").insert({ ...args, createdAt: Date.now(), tags: tagIds, }); return postId; }, }); export const getPostBySlug = query({ args: { slug: v.string() }, handler: async (ctx, { slug }) => { const table = getQueryTable(ctx); const post = await table("posts").get("slug", slug); if (!post) return null; const author = await post.edge("author"); const tags = await post.edge("tags"); const comments = await post.edge("comments"); return { _id: post._id, title: post.title, slug: post.slug, content: post.content, published: post.published, createdAt: post.createdAt, author: { _id: author._id, name: author.name, email: author.email, }, tags: tags.map((tag) => ({ _id: tag._id, name: tag.name, slug: tag.slug, })), comments: await Promise.all( comments.map(async (comment) => { const commentAuthor = await comment.edge("author"); return { _id: comment._id, text: comment.text, createdAt: comment.createdAt, author: { _id: commentAuthor._id, name: commentAuthor.name, }, }; }), ), }; }, }); export const listPublishedPosts = query({ args: {}, handler: async (ctx) => { const table = getQueryTable(ctx); const posts = await table("posts") .filter((q) => q.eq(q.field("published"), true)) .map(async (post) => { const author = await post.edge("author"); const tags = await post.edge("tags"); return { _id: post._id, title: post.title, slug: post.slug, content: post.content.substring(0, 200) + "...", createdAt: post.createdAt, author: { _id: author._id, name: author.name, }, tags: tags.map((tag) => ({ _id: tag._id, name: tag.name, })), }; }); return posts; }, }); export const addTagToPost = mutation({ args: { postId: v.id("posts"), tagId: v.id("tags"), }, handler: async (ctx, { postId, tagId }) => { const table = getMutationTable(ctx); const post = await table("posts").getX(postId); await post.patch({ tags: { add: [tagId] } }); }, }); export const removeTagFromPost = mutation({ args: { postId: v.id("posts"), tagId: v.id("tags"), }, handler: async (ctx, { postId, tagId }) => { const table = getMutationTable(ctx); const post = await table("posts").getX(postId); await post.patch({ tags: { remove: [tagId] } }); }, }); export const updatePost = mutation({ args: { postId: v.id("posts"), title: v.optional(v.string()), content: v.optional(v.string()), published: v.optional(v.boolean()), }, handler: async (ctx, { postId, ...updates }) => { const table = getMutationTable(ctx); const post = await table("posts").getX(postId); await post.patch(updates); }, }); export const deletePost = mutation({ args: { postId: v.id("posts") }, handler: async (ctx, { postId }) => { const table = getMutationTable(ctx); const post = await table("posts").getX(postId); await post.delete(); }, });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server