prisma-trpc-shield-generator
v1.0.1
Published
Prisma +2 generator to emit a tRPC shield from your Prisma schema
Maintainers
Readme
Prisma tRPC Shield Generator
🛡️ Automatically generate tRPC Shield permissions from your Prisma schema
A powerful Prisma generator that creates tRPC Shield configurations from your Prisma schema. Automatically generates type-safe permission rules for all your database operations, saving you time and reducing boilerplate code.
💖 Support This Project
If this tool helps you build better applications, please consider supporting its development:
Your sponsorship helps maintain and improve this project. Thank you! 🙏
🚀 Latest Release
Now with full Prisma 6 & tRPC 11 support!
npm install prisma-trpc-shield-generatorThis release includes major upgrades to the latest Prisma 6+ and tRPC v11+ - bringing compatibility with the latest versions and their breaking changes. Report any issues to help us continue improving!
📖 Table of Contents
- Features
- Quick Start
- Generated Output
- Configuration Options
- Advanced Usage
- Examples
- Troubleshooting
- Contributing
- License
- Related Projects
✨ Features
- 🚀 Zero Configuration - Works out of the box with sensible defaults
- 🔄 Auto-Generated - Updates every time you run
prisma generate - 🛡️ Type Safe - Full TypeScript support with proper typing
- 🎯 Comprehensive - Covers all Prisma operations (queries, mutations, aggregations)
- ⚙️ Configurable - Customize output directory and context path
- 📦 Lightweight - Minimal dependencies and fast generation
🚀 Quick Start
Installation
npm install prisma-trpc-shield-generator trpc-shieldSetup
- Add the generator to your
schema.prisma:
generator trpc_shield {
provider = "prisma-trpc-shield-generator"
contextPath = "../src/context"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}- Generate your shield:
npx prisma generate- Use the generated permissions:
import { permissions } from './generated/shield';
import { t } from './trpc';
export const permissionsMiddleware = t.middleware(permissions);
export const protectedProcedure = t.procedure.use(permissionsMiddleware);📋 Generated Output
The generator creates a comprehensive shield configuration with all CRUD operations:
import { shield, allow } from 'trpc-shield';
import { Context } from '../../../context';
export const permissions = shield<Context>({
query: {
// Find operations
findUniqueUser: allow,
findFirstUser: allow,
findManyUser: allow,
findUniquePost: allow,
findFirstPost: allow,
findManyPost: allow,
// Aggregation operations
aggregateUser: allow,
aggregatePost: allow,
groupByUser: allow,
groupByPost: allow,
},
mutation: {
// Create operations
createOneUser: allow,
createOnePost: allow,
// Update operations
updateOneUser: allow,
updateOnePost: allow,
updateManyUser: allow,
updateManyPost: allow,
// Delete operations
deleteOneUser: allow,
deleteOnePost: allow,
deleteManyUser: allow,
deleteManyPost: allow,
// Upsert operations
upsertOneUser: allow,
upsertOnePost: allow,
},
});⚙️ Configuration Options
| Option | Description | Type | Default |
|---------------|------------------------------------------------------|----------|---------------------------|
| output | Output directory for the generated shield | string | ./generated |
| contextPath | Path to your tRPC context file (relative to output) | string | ../../../../src/context |
Example Configuration
generator trpc_shield {
provider = "prisma-trpc-shield-generator"
output = "./src/shields"
contextPath = "../context"
}🔧 Advanced Usage
Custom Permission Rules
Replace the default allow rules with your custom logic:
import { permissions } from './generated/shield';
import { rule, and, or } from 'trpc-shield';
const isAuthenticated = rule()(async (parent, args, ctx) => {
return ctx.user !== null;
});
const isOwner = rule()(async (parent, args, ctx) => {
const post = await ctx.prisma.post.findUnique({
where: { id: args.where.id },
select: { authorId: true }
});
return post?.authorId === ctx.user?.id;
});
// Override specific permissions
export const customPermissions = {
...permissions,
mutation: {
...permissions.mutation,
createOnePost: and(isAuthenticated),
updateOnePost: and(isAuthenticated, isOwner),
deleteOnePost: and(isAuthenticated, isOwner),
}
};Integration with tRPC Router
import { initTRPC } from '@trpc/server';
import { customPermissions } from './shields/permissions';
const t = initTRPC.context<Context>().create();
export const permissionsMiddleware = t.middleware(customPermissions);
export const protectedProcedure = t.procedure.use(permissionsMiddleware);
export const appRouter = t.router({
user: t.router({
create: protectedProcedure
.input(z.object({ name: z.string(), email: z.string() }))
.mutation(({ input, ctx }) => {
return ctx.prisma.user.create({ data: input });
}),
}),
});📚 Examples
Basic CRUD with Authentication
import { rule, and } from 'trpc-shield';
const isAuthenticated = rule()(async (parent, args, ctx) => {
return !!ctx.user;
});
const canManagePosts = rule()(async (parent, args, ctx) => {
if (!ctx.user) return false;
// Admin can manage all posts
if (ctx.user.role === 'ADMIN') return true;
// Users can only manage their own posts
if (args.where?.authorId) {
return args.where.authorId === ctx.user.id;
}
return false;
});
export const permissions = shield<Context>({
query: {
findManyPost: allow, // Public read access
findUniquePost: allow,
findManyUser: isAuthenticated, // Authenticated read access
},
mutation: {
createOnePost: isAuthenticated,
updateOnePost: and(isAuthenticated, canManagePosts),
deleteOnePost: and(isAuthenticated, canManagePosts),
},
});🔍 Troubleshooting
Common Issues
Error: Cannot find module '../context'
- Ensure your
contextPathis correct relative to the output directory - Check that your context file exports a
Contexttype
TypeScript errors in generated shield
- Make sure
trpc-shieldis installed and up to date - Verify your tRPC context is properly typed
Shield not updating after schema changes
- Run
npx prisma generateafter modifying your schema - Check that the generator is properly configured in
schema.prisma
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Related Projects
- tRPC Shield - The permission system this generator creates
- Prisma - The database toolkit this integrates with
- tRPC - The TypeScript RPC framework this works with
