157 lines
3.8 KiB
TypeScript
157 lines
3.8 KiB
TypeScript
import { z } from "zod";
|
|
import { router, publicProcedure } from "../trpc";
|
|
|
|
/**
|
|
* Posts Router
|
|
*
|
|
* Another example sub-router showing a different domain.
|
|
* Demonstrates relationships (author references users).
|
|
*
|
|
* Example using TaylorDB queryBuilder (available via ctx.queryBuilder):
|
|
*
|
|
* // Query all posts
|
|
* const posts = await ctx.queryBuilder.from("posts").select("*");
|
|
*
|
|
* // Query with filters
|
|
* const publishedPosts = await ctx.queryBuilder
|
|
* .from("posts")
|
|
* .where({ published: true })
|
|
* .select("*");
|
|
*
|
|
* // Create a new post
|
|
* const newPost = await ctx.queryBuilder
|
|
* .from("posts")
|
|
* .insert({
|
|
* title: "My Title",
|
|
* content: "My Content",
|
|
* authorId: 1,
|
|
* published: false
|
|
* });
|
|
*
|
|
* // Update a post
|
|
* const updatedPost = await ctx.queryBuilder
|
|
* .from("posts")
|
|
* .where({ id: 1 })
|
|
* .update({ published: true });
|
|
*
|
|
* // Delete a post
|
|
* await ctx.queryBuilder
|
|
* .from("posts")
|
|
* .where({ id: 1 })
|
|
* .delete();
|
|
*/
|
|
|
|
// In-memory store for demonstration
|
|
const posts: {
|
|
id: number;
|
|
title: string;
|
|
content: string;
|
|
authorId: number;
|
|
published: boolean;
|
|
createdAt: Date;
|
|
}[] = [
|
|
{
|
|
id: 1,
|
|
title: "Hello World",
|
|
content: "This is my first post!",
|
|
authorId: 1,
|
|
published: true,
|
|
createdAt: new Date(),
|
|
},
|
|
];
|
|
let nextId = 2;
|
|
|
|
export const postsRouter = router({
|
|
getAll: publicProcedure
|
|
.input(
|
|
z
|
|
.object({
|
|
published: z.boolean().optional(),
|
|
authorId: z.number().optional(),
|
|
})
|
|
.optional(),
|
|
)
|
|
.query(({ input }) => {
|
|
let result = posts;
|
|
|
|
if (input?.published !== undefined) {
|
|
result = result.filter((p) => p.published === input.published);
|
|
}
|
|
if (input?.authorId !== undefined) {
|
|
result = result.filter((p) => p.authorId === input.authorId);
|
|
}
|
|
|
|
return result;
|
|
}),
|
|
|
|
getById: publicProcedure
|
|
.input(z.object({ id: z.number() }))
|
|
.query(({ input }) => {
|
|
const post = posts.find((p) => p.id === input.id);
|
|
if (!post) throw new Error("Post not found");
|
|
return post;
|
|
}),
|
|
|
|
create: publicProcedure
|
|
.input(
|
|
z.object({
|
|
title: z.string().min(1).max(200),
|
|
content: z.string().min(1),
|
|
authorId: z.number(),
|
|
published: z.boolean().default(false),
|
|
})
|
|
)
|
|
.mutation(({ input }) => {
|
|
const newPost = {
|
|
id: nextId++,
|
|
title: input.title,
|
|
content: input.content,
|
|
authorId: input.authorId,
|
|
published: input.published,
|
|
createdAt: new Date(),
|
|
};
|
|
posts.push(newPost);
|
|
return newPost;
|
|
}),
|
|
|
|
update: publicProcedure
|
|
.input(
|
|
z.object({
|
|
id: z.number(),
|
|
title: z.string().min(1).max(200).optional(),
|
|
content: z.string().min(1).optional(),
|
|
published: z.boolean().optional(),
|
|
}),
|
|
)
|
|
.mutation(({ input }) => {
|
|
const post = posts.find((p) => p.id === input.id);
|
|
if (!post) throw new Error("Post not found");
|
|
|
|
if (input.title) post.title = input.title;
|
|
if (input.content) post.content = input.content;
|
|
if (input.published !== undefined) post.published = input.published;
|
|
return post;
|
|
}),
|
|
|
|
delete: publicProcedure
|
|
.input(z.object({ id: z.number() }))
|
|
.mutation(({ input }) => {
|
|
const index = posts.findIndex((p) => p.id === input.id);
|
|
if (index === -1) throw new Error("Post not found");
|
|
|
|
const [deleted] = posts.splice(index, 1);
|
|
return deleted;
|
|
}),
|
|
|
|
// Example of a more specific procedure
|
|
publish: publicProcedure
|
|
.input(z.object({ id: z.number() }))
|
|
.mutation(({ input }) => {
|
|
const post = posts.find((p) => p.id === input.id);
|
|
if (!post) throw new Error("Post not found");
|
|
|
|
post.published = true;
|
|
return post;
|
|
}),
|
|
});
|