-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Add tauri trpc rules #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add tauri trpc rules #154
Conversation
- hono-typescript-cloudflare: Edge-first APIs with Hono v4 and Cloudflare Workers - drizzle-orm-typescript: Type-safe database layer with Drizzle ORM - remix-react-typescript: Full-stack web apps with Remix v2 and React - bun-typescript-runtime: Fast all-in-one JavaScript runtime with Bun
- Fix variable redeclaration in Bun file I/O example (file -> metaFile) - Fix async test assertion to use rejects.toThrow() - Add missing useRouteError, isRouteErrorResponse imports in Remix - Add SESSION_SECRET validation before use - Add language identifiers to README code blocks
Tauri v2 Desktop & Mobile: - Cross-platform development (Windows, macOS, Linux, iOS, Android) - Rust backend with async commands and state management - Frontend integration with TypeScript/React - Capability-based security system - Plugin usage patterns (fs, dialog, notification, etc.) - Mobile-specific patterns and platform detection tRPC End-to-End Type-Safe API: - tRPC v11 patterns with React Query integration - Zod input validation with type inference - Authentication middleware (protected/admin procedures) - Cursor pagination for infinite scroll - Optimistic updates and cache invalidation - Next.js App Router integration - Server-side rendering patterns
WalkthroughIntroduces six new Cursor Rules prompt files ( Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🧹 Nitpick comments (6)
rules/drizzle-orm-typescript-cursorrules-prompt-file/.cursorrules (1)
89-114: Clarify that these are alternative connection examples, not a single file.The code block shows two separate database connection examples (PostgreSQL and Turso/LibSQL) with duplicate
import { drizzle }andexport const dbstatements. This could confuse users who copy the entire block.Consider separating these into distinct code blocks with clear headers:
-### Database Connection - -```typescript -// PostgreSQL with node-postgres -import { drizzle } from 'drizzle-orm/node-postgres' -... -export const db = drizzle(pool, { schema, logger: true }) - -// Turso/LibSQL -import { drizzle } from 'drizzle-orm/libsql' -... -export const db = drizzle(client, { schema }) -``` +### Database Connection + +#### PostgreSQL with node-postgres +```typescript +import { drizzle } from 'drizzle-orm/node-postgres' +... +export const db = drizzle(pool, { schema, logger: true }) +``` + +#### Turso/LibSQL +```typescript +import { drizzle } from 'drizzle-orm/libsql' +... +export const db = drizzle(client, { schema }) +```rules/remix-react-typescript-cursorrules-prompt-file/README.md (1)
37-51: Consider updating example structure for Remix v2 with Vite.The example project structure shows
remix.config.js, but Remix v2 recommends using Vite withvite.config.ts. Since the rules target Remix v2.x, consider updating the example:my-remix-app/ ├── app/ │ ├── routes/ │ ├── components/ │ ├── lib/ │ ├── models/ │ └── root.tsx ├── public/ -├── remix.config.js +├── vite.config.ts ├── package.json └── .cursorrulesrules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.md (1)
23-23: Minor: Consider hyphenating "Full-Stack" for consistency.When used as a compound adjective before a noun ("Full Stack Type Safety"), it's typically hyphenated as "Full-Stack Type Safety".
-### Full Stack Type Safety +### Full-Stack Type Safetyrules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules (3)
481-486: Addas constfor consistency with other routers.The
mode: 'insensitive'lacks theas constassertion that's used in the user router (lines 366-367). This inconsistency may cause TypeScript inference issues in strict configurations....(search && { OR: [ - { title: { contains: search, mode: 'insensitive' } }, - { content: { contains: search, mode: 'insensitive' } }, + { title: { contains: search, mode: 'insensitive' as const } }, + { content: { contains: search, mode: 'insensitive' as const } }, ], }),
911-924: UsecreateCallerFactoryand consider Next.js 15 async params.Two concerns:
Line 920: Uses
appRouter.createCaller(ctx)which is the older pattern. The guide already exportscreateCallerFactory(line 117) - use it for consistency with tRPC v11 best practices.Lines 911-913: In Next.js 15+, page params are async and must be awaited. The current signature may cause issues.
+import { createCallerFactory } from '@/server/trpc'; + +const createCaller = createCallerFactory(appRouter); + interface Props { - params: { id: string }; + params: Promise<{ id: string }>; } export default async function PostPage({ params }: Props) { + const { id } = await params; const session = await getServerSession(authOptions); const ctx = createInnerContext(session); // Create server-side caller - const caller = appRouter.createCaller(ctx); + const caller = createCaller(ctx); try { - const post = await caller.post.byId({ id: params.id }); + const post = await caller.post.byId({ id });
1027-1034: Improve test isolation by creating context per test.Creating the context and caller outside test blocks (lines 1028-1029) means all tests share the same instance. For proper test isolation, especially with authentication states, create fresh instances per test.
describe('User Router', () => { - const ctx = createInnerContext(); - const caller = appRouter.createCaller(ctx); + let caller: ReturnType<typeof appRouter.createCaller>; beforeEach(async () => { await prisma.user.deleteMany(); + const ctx = createInnerContext(); + caller = appRouter.createCaller(ctx); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
rules/bun-typescript-runtime-cursorrules-prompt-file/.cursorrules(1 hunks)rules/bun-typescript-runtime-cursorrules-prompt-file/README.md(1 hunks)rules/drizzle-orm-typescript-cursorrules-prompt-file/.cursorrules(1 hunks)rules/drizzle-orm-typescript-cursorrules-prompt-file/README.md(1 hunks)rules/hono-typescript-cloudflare-cursorrules-prompt-file/.cursorrules(1 hunks)rules/hono-typescript-cloudflare-cursorrules-prompt-file/README.md(1 hunks)rules/remix-react-typescript-cursorrules-prompt-file/.cursorrules(1 hunks)rules/remix-react-typescript-cursorrules-prompt-file/README.md(1 hunks)rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/.cursorrules(1 hunks)rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/README.md(1 hunks)rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules(1 hunks)rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.md
📄 CodeRabbit inference engine (.cursorrules)
Always use Markdown for documentation and README files
Files:
rules/drizzle-orm-typescript-cursorrules-prompt-file/README.mdrules/bun-typescript-runtime-cursorrules-prompt-file/README.mdrules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.mdrules/tauri-v2-desktop-mobile-cursorrules-prompt-file/README.mdrules/hono-typescript-cloudflare-cursorrules-prompt-file/README.mdrules/remix-react-typescript-cursorrules-prompt-file/README.md
rules/*/README.md
📄 CodeRabbit inference engine (.cursorrules)
rules/*/README.md: Refer to the README in each folder for guidance on naming conventions and descriptions
Each .cursorrules file may have an accompanying README.md file in its folder; use this README to provide credit to the original author and a brief description of the .cursorrules file's purpose
Files:
rules/drizzle-orm-typescript-cursorrules-prompt-file/README.mdrules/bun-typescript-runtime-cursorrules-prompt-file/README.mdrules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.mdrules/tauri-v2-desktop-mobile-cursorrules-prompt-file/README.mdrules/hono-typescript-cloudflare-cursorrules-prompt-file/README.mdrules/remix-react-typescript-cursorrules-prompt-file/README.md
**/*.{md,cursorrules}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{md,cursorrules}: Use clear and concise language in all documentation and .cursorrules files
When adding examples or explanations, focus on practical use cases for Cursor AI users
Files:
rules/drizzle-orm-typescript-cursorrules-prompt-file/README.mdrules/bun-typescript-runtime-cursorrules-prompt-file/README.mdrules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.mdrules/tauri-v2-desktop-mobile-cursorrules-prompt-file/README.mdrules/hono-typescript-cloudflare-cursorrules-prompt-file/README.mdrules/remix-react-typescript-cursorrules-prompt-file/README.md
🪛 LanguageTool
rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.md
[uncategorized] ~23-~23: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...e safety - Instant feedback in IDE ### Full Stack Type Safety - Input validation with Zod...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🔇 Additional comments (14)
rules/hono-typescript-cloudflare-cursorrules-prompt-file/README.md (1)
1-59: Well-structured README with clear documentation.The README provides comprehensive coverage of the Hono TypeScript Cloudflare Workers rules, including tech stack, features, usage instructions, and example project structure. The documentation follows Markdown best practices and provides practical guidance for Cursor AI users.
rules/bun-typescript-runtime-cursorrules-prompt-file/README.md (1)
1-61: Clear and practical documentation for Bun runtime rules.The README is well-organized with installation instructions, feature coverage, and example project structure. The inclusion of the Bun installation command in the usage section is helpful for new users.
rules/bun-typescript-runtime-cursorrules-prompt-file/.cursorrules (1)
1-375: Comprehensive Bun runtime expert rules with practical examples.The .cursorrules file provides excellent coverage of Bun-specific patterns including HTTP servers, SQLite, testing, and bundling. The code examples follow Bun idioms and best practices correctly.
rules/hono-typescript-cloudflare-cursorrules-prompt-file/.cursorrules (1)
1-256: Excellent Hono + Cloudflare Workers expert rules.The .cursorrules file provides thorough coverage of Hono v4 patterns, Cloudflare bindings, middleware creation, and type-safe API development. The code examples are accurate and follow current best practices.
rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/README.md (1)
1-72: Well-documented Tauri v2 rules with clear feature highlights.The README effectively communicates Tauri v2's cross-platform capabilities, security-first approach, and modern stack. The usage instructions and example project structure provide practical guidance.
rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/.cursorrules (1)
1-960: Comprehensive and well-structured Tauri v2 development guide.This is an excellent resource covering the full Tauri v2 stack: Rust backend with async commands, state management, error handling, frontend TypeScript/React integration, mobile patterns, event system, and security best practices. The code examples are practical and follow Tauri v2 idioms.
rules/drizzle-orm-typescript-cursorrules-prompt-file/.cursorrules (1)
1-356: Comprehensive and well-structured Drizzle ORM cursor rules.The document covers schema design, query patterns, prepared statements, migrations, error handling, and repository patterns with practical TypeScript examples. The guidance on type safety and SQL-like patterns aligns well with Drizzle ORM's philosophy.
rules/drizzle-orm-typescript-cursorrules-prompt-file/README.md (1)
1-63: Well-structured README with clear documentation.The README provides a good overview of the Drizzle ORM cursor rules, including tech stack, coverage areas, usage instructions, and example project structure. The documentation follows the repository's conventions.
rules/remix-react-typescript-cursorrules-prompt-file/README.md (1)
1-61: Clear and well-organized README.The README provides appropriate context for the Remix cursor rules with good coverage of features and usage instructions.
rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/README.md (1)
1-70: Good README with clear feature documentation.The README effectively documents the tRPC cursor rules, highlighting key features like zero code generation, React Query integration, and the example project structure.
rules/remix-react-typescript-cursorrules-prompt-file/.cursorrules (1)
1-405: Comprehensive and well-structured Remix cursor rules.The document provides excellent coverage of Remix v2 patterns including flat routes, loaders/actions, deferred data loading, form validation with Conform, authentication, error boundaries, and optimistic UI. The progressive enhancement emphasis aligns well with Remix's philosophy.
rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules (3)
160-206: Well-structured authentication middleware pattern.The middleware chaining approach is correct:
adminProcedurebuilds onprotectedProcedure, ensuringisAuthenticatedruns beforeisAdmin. This properly narrows the context types through the middleware chain.
1061-1098: Good error factory pattern.The custom error factory functions with explicit
neverreturn types are a clean pattern for consistent error handling. The usage example (lines 1090-1097) is a code fragment - consider showing it within a full procedure definition for clarity.
70-89: The dependency versions are correctly specified for tRPC v11. The @trpc/next package is fully supported in v11 for both Pages Router and App Router, with enhanced React Server Component support specifically added in v11. No changes needed.
| // Zod schemas for validation | ||
| export const insertUserSchema = createInsertSchema(users, { | ||
| email: (schema) => schema.email.email(), | ||
| name: (schema) => schema.name.min(1).max(100), | ||
| }) | ||
|
|
||
| export const selectUserSchema = createSelectSchema(users) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
drizzle-zod createInsertSchema refinement API correct syntax
💡 Result:
Short answer: createInsertSchema accepts an optional second arg that can be (A) an object mapping field names to either a Zod schema (to overwrite) or a function (schema => modifiedSchema) to extend/modify, or (B) a callback (schema => ({ ... })) that returns the per-field overrides. You can then call Zod refinements (.refine/.superRefine) on the returned schema.
Examples:
-
Overwrite a field with a Zod schema:
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
const userInsert = createInsertSchema(users, {
role: z.enum(["admin","user"]) // overwrite
}); -
Extend a generated field schema via function:
const userInsert = createInsertSchema(users, {
name: (s) => s.min(2, "too short"), // extends generated z.string()
email: (s) => s.email("invalid")
}); -
Use a callback that receives the whole generated schema (for more control):
const userInsert = createInsertSchema(users, (schema) => ({
id: schema.id.positive(),
createdAt: schema.createdAt.min(new Date())
})); -
Add cross-field validation with Zod refinements:
const userInsert = createInsertSchema(users, { /* overrides */ })
.refine((data) => data.age >= 18 || data.parentConsent === true, {
message: "Underage users need parental consent",
path: ["parentConsent"],
});
Sources: Drizzle docs (createInsertSchema + refinements) and examples. [1][2]
References:
[1] Drizzle ORM — drizzle-zod docs (createInsertSchema, refinements).
[2] drizzle-zod / npm readme examples.
Fix the createInsertSchema refinement syntax in the Zod schema examples.
The refinement object must use field names as keys mapping to modifier functions. The code should be:
export const insertUserSchema = createInsertSchema(users, {
email: (schema) => schema.email(),
name: (schema) => schema.min(1).max(100),
})Or use a callback that returns an object with field overrides:
export const insertUserSchema = createInsertSchema(users, (schema) => ({
email: schema.email.email(),
name: schema.name.min(1).max(100),
}))The current syntax incorrectly tries to chain .email.email() on the root schema object without the proper field key structure.
🤖 Prompt for AI Agents
In rules/drizzle-orm-typescript-cursorrules-prompt-file/.cursorrules around
lines 74 to 80, the createInsertSchema refinement uses incorrect chaining on the
root schema (e.g., schema.email.email()); change the refinement to use field
keys mapping to modifier functions or a callback that returns an overrides
object: either pass an object where keys are field names and each value is a
function that receives the field schema and applies modifiers (email: (s) =>
s.email(), name: (s) => s.min(1).max(100)), or pass a single callback (schema)
=> ({ email: schema.email.email(), name: schema.name.min(1).max(100) }) so field
modifiers are applied to the correct field schemas.
| ### Resource Routes (API) | ||
| ```typescript | ||
| // app/routes/api.users.tsx | ||
| import { json, type LoaderFunctionArgs } from '@remix-run/node' | ||
|
|
||
| export async function loader({ request }: LoaderFunctionArgs) { | ||
| const url = new URL(request.url) | ||
| const query = url.searchParams.get('q') | ||
|
|
||
| const users = await searchUsers(query) | ||
|
|
||
| return json(users, { | ||
| headers: { | ||
| 'Cache-Control': 'public, max-age=60', | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| export async function action({ request }: ActionFunctionArgs) { | ||
| if (request.method !== 'POST') { | ||
| return json({ error: 'Method not allowed' }, { status: 405 }) | ||
| } | ||
|
|
||
| const data = await request.json() | ||
| const user = await createUser(data) | ||
|
|
||
| return json(user, { status: 201 }) | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing ActionFunctionArgs import in resource routes example.
The action function uses ActionFunctionArgs type annotation, but this type is not included in the import statement at line 288.
// app/routes/api.users.tsx
-import { json, type LoaderFunctionArgs } from '@remix-run/node'
+import { json, type LoaderFunctionArgs, type ActionFunctionArgs } from '@remix-run/node'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Resource Routes (API) | |
| ```typescript | |
| // app/routes/api.users.tsx | |
| import { json, type LoaderFunctionArgs } from '@remix-run/node' | |
| export async function loader({ request }: LoaderFunctionArgs) { | |
| const url = new URL(request.url) | |
| const query = url.searchParams.get('q') | |
| const users = await searchUsers(query) | |
| return json(users, { | |
| headers: { | |
| 'Cache-Control': 'public, max-age=60', | |
| }, | |
| }) | |
| } | |
| export async function action({ request }: ActionFunctionArgs) { | |
| if (request.method !== 'POST') { | |
| return json({ error: 'Method not allowed' }, { status: 405 }) | |
| } | |
| const data = await request.json() | |
| const user = await createUser(data) | |
| return json(user, { status: 201 }) | |
| } | |
| ``` | |
| // app/routes/api.users.tsx | |
| import { json, type LoaderFunctionArgs, type ActionFunctionArgs } from '@remix-run/node' | |
| export async function loader({ request }: LoaderFunctionArgs) { | |
| const url = new URL(request.url) | |
| const query = url.searchParams.get('q') | |
| const users = await searchUsers(query) | |
| return json(users, { | |
| headers: { | |
| 'Cache-Control': 'public, max-age=60', | |
| }, | |
| }) | |
| } | |
| export async function action({ request }: ActionFunctionArgs) { | |
| if (request.method !== 'POST') { | |
| return json({ error: 'Method not allowed' }, { status: 405 }) | |
| } | |
| const data = await request.json() | |
| const user = await createUser(data) | |
| return json(user, { status: 201 }) | |
| } |
🤖 Prompt for AI Agents
In rules/remix-react-typescript-cursorrules-prompt-file/.cursorrules around
lines 285 to 313 the ActionFunctionArgs type is used in the action function but
not imported; update the import from '@remix-run/node' to include
ActionFunctionArgs alongside json and LoaderFunctionArgs so the type is
available and TypeScript compiles correctly.
| hostname: hostname::get() | ||
| .map(|h| h.to_string_lossy().to_string()) | ||
| .unwrap_or_else(|_| "unknown".to_string()), | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing hostname crate in Cargo.toml dependencies.
The get_system_info command uses hostname::get(), but the hostname crate is not listed in the Cargo.toml dependencies section (lines 77-138). Users following this guide would encounter a compilation error.
Add the missing dependency to the Cargo.toml example:
# Logging
log = "0.4"
env_logger = "0.11"
+
+# System info
+hostname = "0.4"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/.cursorrules around
lines 460 to 464, the code calls hostname::get() but the example Cargo.toml
dependencies (lines ~77-138) do not include the hostname crate; add the hostname
crate to the Cargo.toml [dependencies] block (pick a compatible version such as
a recent 0.3.x), save the file, and run cargo build/cargo update to ensure the
new dependency is fetched and the project compiles.
| export function useSystemInfo() { | ||
| const [info, setInfo] = useState<SystemInfo | null>(null); | ||
|
|
||
| useEffect(() => { | ||
| commands.getSystemInfo().then(setInfo); | ||
| }, []); | ||
|
|
||
| return info; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing SystemInfo type import in useSystemInfo hook.
The useSystemInfo hook uses SystemInfo type on line 733, but this type is not imported. The import statement on line 684 only imports Item from ../lib/tauri.
Update the import to include SystemInfo:
-import { commands, type Item } from '../lib/tauri';
+import { commands, type Item, type SystemInfo } from '../lib/tauri';Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/tauri-v2-desktop-mobile-cursorrules-prompt-file/.cursorrules around
lines 732 to 740, the useSystemInfo hook references the SystemInfo type but it
is not imported; update the existing import statement near line 684 that
currently imports Item from ../lib/tauri to also import SystemInfo (e.g., add
SystemInfo to the named imports from ../lib/tauri) so the type is available to
the hook.
| ```typescript | ||
| // src/server/context.ts | ||
| import { type inferAsyncReturnType } from '@trpc/server'; | ||
| import { type FetchCreateContextFnOptions } from '@trpc/server/adapters/fetch'; | ||
| import { getServerSession } from 'next-auth'; | ||
| import { prisma } from '@/lib/prisma'; | ||
| import { authOptions } from '@/lib/auth'; | ||
|
|
||
| export async function createContext(opts: FetchCreateContextFnOptions) { | ||
| const session = await getServerSession(authOptions); | ||
|
|
||
| return { | ||
| session, | ||
| user: session?.user, | ||
| prisma, | ||
| headers: opts.req.headers, | ||
| }; | ||
| } | ||
|
|
||
| export type Context = inferAsyncReturnType<typeof createContext>; | ||
|
|
||
| // For server-side calls without request | ||
| export function createInnerContext(session?: Session) { | ||
| return { | ||
| session, | ||
| user: session?.user, | ||
| prisma, | ||
| headers: new Headers(), | ||
| }; | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix missing Session type import and consider updating deprecated API.
Two issues in this code example:
-
Line 150: The
Sessiontype is used as a parameter type but is never imported. This would cause a TypeScript compilation error. -
Line 130, 147:
inferAsyncReturnTypewas the legacy approach. In tRPC v11, the idiomatic pattern is to use TypeScript's built-inAwaited<ReturnType<typeof createContext>>.
// src/server/context.ts
-import { type inferAsyncReturnType } from '@trpc/server';
import { type FetchCreateContextFnOptions } from '@trpc/server/adapters/fetch';
-import { getServerSession } from 'next-auth';
+import { getServerSession, type Session } from 'next-auth';
import { prisma } from '@/lib/prisma';
import { authOptions } from '@/lib/auth';
// ... createContext function ...
-export type Context = inferAsyncReturnType<typeof createContext>;
+export type Context = Awaited<ReturnType<typeof createContext>>;
// For server-side calls without request
export function createInnerContext(session?: Session) {🤖 Prompt for AI Agents
In rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules
around lines 128 to 158, the code uses the Session type for createInnerContext
and uses the legacy inferAsyncReturnType; fix by importing Session from
'next-auth' (or the correct next-auth package export) at the top, and change the
Context type alias to use TypeScript's Awaited<ReturnType<typeof createContext>>
instead of inferAsyncReturnType<typeof createContext>; ensure the import for
Session is added alongside other imports and update the type line to: export
type Context = Awaited<ReturnType<typeof createContext>>.
| index === 0 | ||
| ? { | ||
| ...page, | ||
| posts: [ | ||
| { ...newPost, id: 'temp', createdAt: new Date() } as any, | ||
| ...page.posts, | ||
| ], | ||
| } | ||
| : page | ||
| ), | ||
| }; | ||
| } | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid as any - contradicts the "Never use any" principle.
Line 819 uses as any for the optimistic post, which contradicts the core principle stated on line 15: "Never use any - leverage TypeScript's full power."
Consider creating a more type-safe optimistic update structure or documenting this as an accepted tradeoff for optimistic UI patterns.
? {
...page,
posts: [
- { ...newPost, id: 'temp', createdAt: new Date() } as any,
+ {
+ ...newPost,
+ id: 'temp',
+ createdAt: new Date(),
+ author: { id: '', name: 'Loading...', image: null },
+ _count: { comments: 0, likes: 0 },
+ } as typeof page.posts[number],
...page.posts,
],
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules
around lines 815 to 827, the optimistic post is cast with "as any" which
violates the project's "Never use any" rule; replace that cast by constructing a
properly typed optimistic object (e.g., build an object that satisfies the Post
type or a Partial<Post> then assert to Post) and update the surrounding types so
the updater expects the correct Post type (or explicitly type the optimistic
variable as Post) instead of using any; if some fields are intentionally
missing, use Partial<Post> and fill required fields (id, createdAt) or use a
safer cast like "as unknown as Post" only as a last resort and add a short
comment explaining the optimistic tradeoff.
| const logout = async () => { | ||
| // Clear cache on logout | ||
| utils.invalidate(); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete logout implementation.
The logout function only invalidates the cache but doesn't actually sign the user out. For NextAuth integration, this should call signOut() from next-auth/react.
+import { signOut } from 'next-auth/react';
const logout = async () => {
+ await signOut();
// Clear cache on logout
utils.invalidate();
};Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules
around lines 962 to 965, the logout function currently only calls
utils.invalidate() but does not perform an actual sign-out; import signOut from
next-auth/react (if not already imported) and call signOut() (await signOut() if
the surrounding context is async) inside logout (keep the cache invalidation),
optionally wrap the signOut call in a try/catch to surface errors.
| const updateMutation = trpc.post.update.useMutation({ | ||
| onSuccess: (data) => { | ||
| utils.post.byId.setData({ id: data.id }, data); | ||
| utils.post.infiniteList.invalidate(); | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential cache data mismatch in setData.
The update mutation response may not include all fields (author, comments) that the byId query provides. Using setData could overwrite the cache with incomplete data, causing UI issues. Consider using invalidate instead or ensuring the mutation returns the full shape.
const updateMutation = trpc.post.update.useMutation({
onSuccess: (data) => {
- utils.post.byId.setData({ id: data.id }, data);
+ // Invalidate to refetch with full data including relations
+ utils.post.byId.invalidate({ id: data.id });
utils.post.infiniteList.invalidate();
},
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const updateMutation = trpc.post.update.useMutation({ | |
| onSuccess: (data) => { | |
| utils.post.byId.setData({ id: data.id }, data); | |
| utils.post.infiniteList.invalidate(); | |
| }, | |
| }); | |
| const updateMutation = trpc.post.update.useMutation({ | |
| onSuccess: (data) => { | |
| // Invalidate to refetch with full data including relations | |
| utils.post.byId.invalidate({ id: data.id }); | |
| utils.post.infiniteList.invalidate(); | |
| }, | |
| }); |
🤖 Prompt for AI Agents
In rules/trpc-typescript-typesafe-api-cursorrules-prompt-file/.cursorrules
around lines 993 to 998, the update mutation calls utils.post.byId.setData with
the mutation response which may be partial and can overwrite cached fields
(author, comments); either change this to call utils.post.byId.invalidate() and
utils.post.infiniteList.invalidate() so the queries refetch full data, or fetch
the current cache via utils.post.byId.getData({ id: data.id }) and setData with
a merged object (spread existingCache and the mutation response) to preserve
missing fields before invalidating if necessary.
✨ Add Tauri v2 & tRPC Development Rules
Description
This PR adds comprehensive cursor rules for two highly requested technologies:
🖥️ Tauri v2 Desktop & Mobile (800+ lines)
Why Tauri v2?
Covers:
🔗 tRPC End-to-End Type-Safe API (1,400+ lines)
Why tRPC?
Covers:
Folder Structure
rules/
├── tauri-v2-desktop-mobile-cursorrules-prompt-file/
│ ├── .cursorrules
│ └── README.md
└── trpc-typescript-typesafe-api-cursorrules-prompt-file/
├── .cursorrules
└── README.md
Related
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.