{"id":30865723,"url":"https://github.com/omar-dulaimi/prisma-orpc-generator","last_synced_at":"2025-09-10T00:04:03.136Z","repository":{"id":312952816,"uuid":"1049429547","full_name":"omar-dulaimi/prisma-orpc-generator","owner":"omar-dulaimi","description":"Prisma generator that creates fully-featured ORPC routers","archived":false,"fork":false,"pushed_at":"2025-09-03T01:51:08.000Z","size":192,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-03T03:19:59.699Z","etag":null,"topics":["orpc","prisma","prisma-orpc-generator","prisma-zod-generator","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/omar-dulaimi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-09-03T01:06:06.000Z","updated_at":"2025-09-03T02:40:23.000Z","dependencies_parsed_at":"2025-09-03T03:31:53.029Z","dependency_job_id":null,"html_url":"https://github.com/omar-dulaimi/prisma-orpc-generator","commit_stats":null,"previous_names":["omar-dulaimi/prisma-orpc-generator"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/omar-dulaimi/prisma-orpc-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omar-dulaimi%2Fprisma-orpc-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omar-dulaimi%2Fprisma-orpc-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omar-dulaimi%2Fprisma-orpc-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omar-dulaimi%2Fprisma-orpc-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omar-dulaimi","download_url":"https://codeload.github.com/omar-dulaimi/prisma-orpc-generator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omar-dulaimi%2Fprisma-orpc-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274101782,"owners_count":25222446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["orpc","prisma","prisma-orpc-generator","prisma-zod-generator","zod"],"created_at":"2025-09-07T21:51:12.108Z","updated_at":"2025-09-07T21:51:14.604Z","avatar_url":"https://github.com/omar-dulaimi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ch1\u003e⚡ Prisma oRPC Generator\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eGenerate typed oRPC routers, Zod schemas, and docs straight from your Prisma schema.\u003c/strong\u003e\u003c/p\u003e\n\n\u003cp\u003e\n  \u003ca href=\"https://www.npmjs.com/package/prisma-orpc-generator\"\u003e\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/prisma-orpc-generator?style=flat\u0026label=npm\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/omar-dulaimi/prisma-orpc-generator/actions\"\u003e\u003cimg alt=\"CI\" src=\"https://img.shields.io/github/actions/workflow/status/omar-dulaimi/prisma-orpc-generator/release.yml?branch=master\u0026label=CI\u0026style=flat\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat\"\u003e\u003c/a\u003e\n  \u003ca href=\"#quickstart\"\u003e\u003cimg alt=\"node\" src=\"https://img.shields.io/badge/node-18.18%2B%20%7C%2020.9%2B%20%7C%2022.11%2B-2ea44f?style=flat\"\u003e\u003c/a\u003e\n  \u003ca href=\"#compatibility\"\u003e\u003cimg alt=\"prisma\" src=\"https://img.shields.io/badge/prisma-6%2B-2D3748?style=flat\"\u003e\u003c/a\u003e\n  \u003ca href=\"tsconfig.json\"\u003e\u003cimg alt=\"TypeScript\" src=\"https://img.shields.io/badge/TypeScript-%E2%89%A5%205.1-3178C6?style=flat\"\u003e\u003c/a\u003e\n  \u003ca href=\".prettierrc\"\u003e\u003cimg alt=\"Prettier\" src=\"https://img.shields.io/badge/Code%20Style-Prettier-F7B93E?style=flat\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp\u003e\u003cem\u003ePrisma v6+, Node 18.18+/20.9+/22.11+, TypeScript ≥ 5.1.\u003c/em\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\u003e TL;DR — Add the generator to your Prisma schema and run Prisma generate. That’s it.\n\n```prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n\n  // Optional config (booleans are strings)\n  schemaLibrary = \"zod\"\n  generateInputValidation  = \"true\"\n  generateOutputValidation = \"true\"\n\n  // Shield authorization (optional)\n  generateShield = \"true\"\n  defaultReadRule = \"allow\"\n  defaultWriteRule = \"auth\"\n}\n```\n\n```bash\n# generate\nnpx prisma generate\n```\n\n---\n\n## 📋 Table of Contents\n\n- [⚡ Quickstart](#quickstart) - Get up and running in minutes\n- [🏗️ What Gets Generated](#what-gets-generated) - See what files are created\n- [⚙️ Configuration](#configuration) - All available options\n- [🔧 Zod Schemas Generation](#zod-schemas-generation) - Schema validation setup\n- [🛡️ Shield Authorization](#shield-authorization) - Type-safe permissions and rules\n- [🧪 Examples](#examples) - Working examples to explore\n- [❓ FAQ / Troubleshooting](#faq--troubleshooting) - Common issues and solutions\n- [🧑‍💻 Development](#development-contributing) - Contributing guidelines\n- [🗺️ Roadmap](#roadmap) - Planned features and improvements\n- [📄 License](#license) - Licensing information\n- [🙏 Acknowledgements](#acknowledgements) - Credits and thanks\n- [📝 Changelog](#changelog) - Version history and changes\n\n---\n\n\u003ca id=\"quickstart\"\u003e\u003c/a\u003e\n## ⚡ Quickstart\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand quickstart guide\u003c/summary\u003e\n\n**Prerequisites**\n- Node: 18.18.0+, 20.9.0+, or 22.11.0+\n- Prisma CLI (v6+) in your project\n- TypeScript ≥ 5.1.0 recommended\n\n**Install**\n```bash\n# npm\nnpm install -D prisma-orpc-generator zod prisma @prisma/client\n\n# pnpm\npnpm add -D prisma-orpc-generator zod prisma @prisma/client\n\n# yarn\nyarn add -D prisma-orpc-generator zod prisma @prisma/client\n```\n\nAdd the generator (minimal)\n```prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n}\n```\n**Generate**\n```bash\nnpx prisma generate\n```\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"compatibility\"\u003e\u003c/a\u003e\n## 🧩 Compatibility\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand compatibility info\u003c/summary\u003e\n- Prisma ORM: v6+\n- Node.js minimums for Prisma v6:\n  - 18.18.0+\n  - 20.9.0+\n  - 22.11.0+\n  - Not supported: 16, 17, 19, 21\n- TypeScript: ≥ 5.1.0\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"what-gets-generated\"\u003e\u003c/a\u003e\n## 🏗️ What Gets Generated\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand generated files overview\u003c/summary\u003e\nA generated surface mirroring your domain:\n\n```\nsrc/generated/orpc/\n├─ routers/\n│  ├─ models/           # per-model routers\n│  └─ helpers/          # common utilities\n├─ tests/               # generated tests\n├─ zod-schemas/         # zod (if enabled)\n└─ documentation/       # docs (if enabled)\n```\n\nExplore the example outputs:\n- Routers: [examples/basic/src/generated/orpc/routers](examples/basic/src/generated/orpc/routers)\n- Zod schemas: [examples/basic/src/generated/orpc/zod-schemas](examples/basic/src/generated/orpc/zod-schemas)\n- Tests: [examples/basic/src/generated/orpc/tests](examples/basic/src/generated/orpc/tests)\n- Docs: [examples/basic/src/generated/orpc/documentation](examples/basic/src/generated/orpc/documentation)\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"usage\"\u003e\u003c/a\u003e\n## 🛠️ Usage\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand usage guide\u003c/summary\u003e\n- Runs as part of Prisma’s generator pipeline.\n- Default output directory is `./src/generated/orpc` (configurable via the generator block).\n- Import the generated code into your server/app. See the runnable example server in [examples/basic/src/server.ts](examples/basic/src/server.ts).\n\nTip: Browse the example’s generated root for real structure: [examples/basic/src/generated/orpc](examples/basic/src/generated/orpc).\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"configuration\"\u003e\u003c/a\u003e\n## ⚙️ Configuration\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand configuration options\u003c/summary\u003e\nWhere configuration lives\n- Inside your generator block in [schema.prisma](examples/basic/schema.prisma)\n- Booleans are strings: \"true\"/\"false\"; numbers as strings are supported\n\nValidated against [src/config/schema.ts](src/config/schema.ts). Below are the most commonly used options.\n\nCore options\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| output | string | ./src/generated/orpc | — | Directory for generated oRPC artifacts |\n| schemaLibrary | enum | \"zod\" | zod | Schema validation library |\n| generateInputValidation | boolean (string) | \"true\" | \"true\", \"false\" | Emit Zod validation for inputs |\n| generateOutputValidation | boolean (string) | \"true\" | \"true\", \"false\" | Emit Zod validation for outputs |\n| strictValidation | boolean (string) | \"true\" | \"true\", \"false\" | Stricter Zod shapes for safety |\n| zodSchemasOutputPath | string | ./zod-schemas | — | Relative path (under output) for Zod files |\n| externalZodImportPath | string | ./zod-schemas | — | Module/path used when importing Zod schemas |\n| zodDateTimeStrategy | enum | \"coerce\" | \"date\", \"coerce\", \"isoString\" | How DateTime fields are modeled in Zod |\n| zodConfigPath | string | — | — | Path to custom zod.config.json file (relative to schema or absolute) |\n\nOperational options\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| generateModelActions | string list | all | see note | Comma-separated actions to emit (see note below) |\n| showModelNameInProcedure | boolean (string) | \"true\" | \"true\", \"false\" | Prefix procedures with model name |\n| enableSoftDeletes | boolean (string) | \"false\" | \"true\", \"false\" | Add soft-delete semantics where applicable |\n| generateRelationResolvers | boolean (string) | \"true\" | \"true\", \"false\" | Emit helpers to resolve relations |\n| wrapResponses | boolean (string) | \"false\" | \"true\", \"false\" | Wrap handler results in an envelope |\n\nDX and formatting\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| useBarrelExports | boolean (string) | \"true\" | \"true\", \"false\" | Generate index.ts barrel exports |\n| codeStyle | enum | \"prettier\" | \"prettier\", \"none\" | Format generated code with Prettier |\n| generateDocumentation | boolean (string) | \"false\" | \"true\", \"false\" | Generate API documentation |\n| generateTests | boolean (string) | \"false\" | \"true\", \"false\" | Generate test files |\n| enableDebugLogging | boolean (string) | \"false\" | \"true\", \"false\" | Extra logs during generation |\n\nRuntime and integration\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| prismaClientPath | string | @prisma/client | — | Import path for PrismaClient |\n| contextPath | string | \"\" | — | Optional path to your app's Context module |\n| serverPort | number (string) | 3000 | — | Port used by optional docs/server helpers |\n| apiPrefix | string | \"\" | — | Prefix used by optional docs/server helpers |\n| apiTitle | string | Generated API | — | API title for documentation |\n| apiDescription | string | Auto-generated API from Prisma schema | — | API description for documentation |\n| apiVersion | string | 1.0.0 | — | API version for documentation |\n\nShield / Authorization\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| generateShield | boolean (string) | \"true\" | \"true\", \"false\" | Enable shield generation |\n| shieldPath | string | — | — | Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier) |\n| defaultReadRule | enum | \"allow\" | \"allow\", \"deny\", \"auth\" | Default rule for read operations |\n| defaultWriteRule | enum | \"auth\" | \"auth\", \"deny\", \"allow\" | Default rule for write operations |\n| denyErrorCode | string | \"FORBIDDEN\" | — | Error code for denied access |\n| debug | boolean (string) | \"false\" | \"true\", \"false\" | Enable debug logging |\n| allowExternalErrors | boolean (string) | \"false\" | \"true\", \"false\" | Allow detailed error messages from shields |\nNotes\n- generateModelActions supports: create, createMany, findFirst, findFirstOrThrow, findMany, findUnique, findUniqueOrThrow, update, updateMany, upsert, delete, deleteMany, aggregate, groupBy, count, findRaw, aggregateRaw.\n- Booleans are strings in Prisma generator config: use \"true\" or \"false\".\n- The full, authoritative shape lives in [src/config/schema.ts](src/config/schema.ts).\n\n\u003cdetails\u003e\n\u003csummary\u003eExample: focused configuration with Zod and docs\u003c/summary\u003e\n\n```prisma\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n\n  schemaLibrary             = \"zod\"\n  zodDateTimeStrategy       = \"coerce\"\n  generateInputValidation   = \"true\"\n  generateOutputValidation  = \"true\"\n  generateDocumentation     = \"true\"\n  useBarrelExports          = \"true\"\n  codeStyle                 = \"prettier\"\n}\n```\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"zod-schemas-generation\"\u003e\u003c/a\u003e\n## 🔧 Zod Schemas Generation\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand zod schemas info\u003c/summary\u003e\n\nThis generator leverages [prisma-zod-generator](https://github.com/omar-dulaimi/prisma-zod-generator) to create Zod schemas from your Prisma models. Here's how the process works:\n\n### Generation Process\n\n1. **Automatic Integration**: When `schemaLibrary = \"zod\"` is set, the generator automatically calls `prisma-zod-generator` \n2. **Configuration Management**: Creates a `zod.config.json` file with optimized settings for oRPC usage\n3. **Schema Output**: Generates Zod schemas in the `zod-schemas/` subdirectory of your output path\n4. **Import Integration**: Generated oRPC routers automatically import and use these schemas for validation\n\n### Configuration File\n\nThe generator creates a minimal `zod.config.json` file:\n\n```json\n{\n  \"mode\": \"full\",\n  \"output\": \"./zod-schemas\"\n}\n```\n\nAdditional settings are only added when they differ from defaults:\n\n```json\n{\n  \"mode\": \"full\", \n  \"output\": \"./zod-schemas\",\n  \"dateTimeStrategy\": \"date\"\n}\n```\n\n### DateTime Handling Strategy\n\nThe `zodDateTimeStrategy` option controls how Prisma DateTime fields are modeled in Zod schemas:\n\n| Strategy | Zod Schema | Description | prisma-zod-generator equivalent |\n|---|---|---|---|\n| `\"coerce\"` (default) | `z.coerce.date()` | Automatically converts strings/numbers to Date objects | `dateTimeStrategy: \"coerce\"` |\n| `\"date\"` | `z.date()` | Requires actual Date objects, no conversion | `dateTimeStrategy: \"date\"` |\n| `\"isoString\"` | `z.string().regex(ISO).transform()` | Validates ISO string format, transforms to Date | `dateTimeStrategy: \"isoString\"` |\n\n### Custom Zod Configuration\n\nFor advanced use cases, you can provide your own `zod.config.json`:\n\n```prisma\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n  \n  zodConfigPath = \"./custom-zod.config.json\"  // Path to your config file\n}\n```\n\nWhen `zodConfigPath` is specified:\n- The generator uses your existing configuration\n- oRPC-specific settings are passed as generator options instead of modifying the config file\n- Your custom configuration takes precedence\n\n### File Structure\n\nGenerated Zod schemas follow this structure:\n\n```\nsrc/generated/orpc/\n├─ zod-schemas/\n│  ├─ index.ts           # Barrel exports\n│  ├─ objects/           # Model schemas\n│  │  ├─ UserSchema.ts\n│  │  └─ PostSchema.ts\n│  └─ inputTypeSchemas/  # Input validation schemas\n│     ├─ UserCreateInput.ts\n│     └─ UserUpdateInput.ts\n└─ routers/              # oRPC routers (import from ../zod-schemas)\n```\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"shield-authorization\"\u003e\u003c/a\u003e\n## 🛡️ Shield Authorization\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand shield authorization guide\u003c/summary\u003e\n\nThe generator can automatically generate [orpc-shield](https://github.com/omar-dulaimi/orpc-shield) configurations for type-safe authorization. Shield provides declarative rules, composable operators, and path-based permissions.\n\n### Shield Configuration\n\nAdd shield options to your generator config:\n\n```prisma\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n\n  // Enable shield generation\n  generateShield = \"true\"\n\n  // Option 1: Auto-generate shield rules\n  defaultReadRule  = \"allow\"  // \"allow\", \"deny\", \"auth\"\n  defaultWriteRule = \"auth\"   // \"auth\", \"deny\"\n\n  // Option 2: Use custom shield file (relative to output dir)\n  // shieldPath = \"../auth/my-custom-shield\"\n\n  // Error handling\n  denyErrorCode = \"FORBIDDEN\"\n  debug = \"false\"\n}\n```\n\n### What Gets Generated\n\nShield generation creates:\n\n```\nsrc/generated/orpc/\n├─ shield.ts              # Shield rules and permissions (auto-generated)\n├─ routers/\n│  ├─ index.ts           # App router with shield exports\n│  └─ helpers/\n│     └─ createRouter.ts # Base router with shield middleware integration\n```\n\n**When `shieldPath` is provided:** The generator skips auto-generation and dynamically integrates your custom shield file into the generated middleware chain.\n\n### Dynamic Shield Path Resolution ✨\n\nThe generator now features **smart dynamic path resolution** for shield files. When you specify a `shieldPath`, the generator automatically:\n\n- ✅ **Resolves relative paths** from your project structure\n- ✅ **Handles different output directory layouts** \n- ✅ **Integrates shield middleware** using the proper oRPC pattern\n- ✅ **Generates correct import paths** regardless of nesting depth\n- ✅ **Applies middleware to all generated procedures** through inheritance\n\n**Example Generated Integration:**\n```typescript\n// In src/generated/orpc/routers/helpers/createRouter.ts\nimport { permissions } from '../../../../custom-shield';\nexport const or = os.$context\u003cContext\u003e().use(permissions);\n```\n\n### Using Custom Shield Files\n\nFor advanced use cases, you can provide your own shield file instead of auto-generation:\n\n```prisma\ngenerator orpc {\n  provider = \"prisma-orpc-generator\"\n  output   = \"./src/generated/orpc\"\n\n  generateShield = \"true\"\n  shieldPath = \"../../src/custom-shield\"  // Dynamically resolved!\n}\n```\n\n**Supported Path Formats:**\n- Relative paths: `\"../../src/auth/shield\"`\n- Project root relative: `\"src/auth/shield\"`  \n- Absolute paths: `\"/absolute/path/to/shield\"`\n\nYour custom shield file should export a `permissions` object:\n\n```typescript\n// src/custom-shield.ts\nimport { rule, allow, deny, shield, or } from 'orpc-shield';\nimport type { Context } from '../generated/orpc/routers/helpers/createRouter';\n\nconst isAuthenticated = rule\u003cContext\u003e()(({ ctx }) =\u003e !!ctx.user);\nconst isAdmin = rule\u003cContext\u003e()(({ ctx }) =\u003e ctx.user?.role === 'admin');\nconst isOwner = rule\u003cContext\u003e()(({ ctx, input }) =\u003e {\n  return ctx.user?.id === (input as any)?.userId;\n});\n\nexport const permissions = shield\u003cContext\u003e({\n  user: {\n    userFindMany: allow,           // Match generated procedure names\n    userCreate: isAuthenticated,   \n    userUpdate: isAuthenticated,\n    userDelete: or(isAdmin, isOwner),\n    userDeleteMany: deny,          // Explicitly deny dangerous operations\n  },\n  post: {\n    postFindMany: allow,\n    postCreate: isAuthenticated,\n    postUpdate: isAuthenticated,\n    postDelete: isAuthenticated,\n  },\n}, {\n  denyErrorCode: 'FORBIDDEN',      // Maps to HTTP 403\n  debug: true,                     // Enable debug logging\n  allowExternalErrors: true,       // Allow detailed error messages\n});\n```\n\n**Important:** Shield procedure names should match your generated router names (e.g., `userCreate`, `postFindMany`).\n\n**Note:** When using `shieldPath`, the generator will skip auto-generation and use your custom shield file instead.\n\n### Generated Shield Rules\n\nThe generator creates rules based on your Prisma models:\n\n```typescript\n// Built-in rules (generated automatically)\nconst isAuthenticated = rule\u003cContext\u003e()(({ ctx }) =\u003e !!ctx.user);\n\n// Example custom rules (user-defined)\nconst isAdmin = rule\u003cContext\u003e()(({ ctx }) =\u003e ctx.user?.role === 'admin');\n\n// Model-specific rules (generated based on config)\nconst canReadUser = allow;           // Read operations: allow\nconst canWriteUser = isAuthenticated; // Write operations: require auth\n\n// Shield configuration\nexport const permissions = shield\u003cContext\u003e({\n  user: {\n    list: canReadUser,\n    findById: canReadUser,\n    create: canWriteUser,\n    update: canWriteUser,\n    delete: canWriteUser,\n  },\n  post: {\n    list: allow,\n    create: isAuthenticated,\n    update: isAuthenticated,\n  },\n});\n```\n\n### Using Shield in Your Server\n\nImport and use the generated shield:\n\n```typescript\nimport { appRouter, permissions } from './generated/orpc/routers';\n\n// Apply shield at server level\nconst server = createServer(appRouter, {\n  // Shield is applied via middleware\n  middleware: [permissions]\n});\n\n// Or use with oRPC handlers\nimport { OpenAPIHandler } from '@orpc/openapi';\n\nconst handler = new OpenAPIHandler(appRouter, {\n  // Shield permissions are automatically applied\n  interceptors: [/* your interceptors */]\n});\n```\n\n### Context Requirements\n\nShield rules expect a `Context` with user information:\n\n```typescript\ninterface Context {\n  prisma: PrismaClient;\n  user?: {\n    id: string;\n    email?: string;\n    name?: string;\n    roles?: string[];\n    permissions?: string[];\n  };\n}\n```\n\n### Customization\n\nOverride default rules by modifying the generated `shield.ts`:\n\n```typescript\n// Custom rule for post ownership\nconst isPostOwner = rule\u003cContext\u003e()(({ ctx, input }) =\u003e {\n  return ctx.user?.id === (input as any)?.authorId;\n});\n\n// Use in shield config\nconst permissions = shield\u003cContext\u003e({\n  post: {\n    update: and(isAuthenticated, isPostOwner), // Auth + ownership\n    delete: or(isAdmin, isPostOwner),          // Admin or owner\n  },\n});\n```\n\n### Shield Options\n\n| Option | Type | Default | Values | Description |\n|---|---|---|---|---|\n| generateShield | boolean (string) | \"true\" | \"true\", \"false\" | Enable shield generation |\n| shieldPath | string | — | — | Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier) |\n| defaultReadRule | enum | \"allow\" | \"allow\", \"deny\", \"auth\" | Default rule for read operations |\n| defaultWriteRule | enum | \"auth\" | \"auth\", \"deny\", \"allow\" | Default rule for write operations |\n| denyErrorCode | string | \"FORBIDDEN\" | — | Error code for denied access |\n| debug | boolean (string) | \"false\" | \"true\", \"false\" | Enable debug logging |\n| allowExternalErrors | boolean (string) | \"false\" | \"true\", \"false\" | Allow detailed error messages from shields |\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"examples\"\u003e\u003c/a\u003e\n## 🧪 Examples\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand examples\u003c/summary\u003e\nRun the repo example end-to-end\n```bash\nnpm run example:basic\n```\n\nWhat it does\n- Builds the generator\n- Generates Prisma artifacts\n- Seeds a local DB\n- Starts a small server using the generated routers/schemas\n\nNotable files\n- Server: [examples/basic/src/server.ts](examples/basic/src/server.ts)\n- Seed: [examples/basic/src/seed.ts](examples/basic/src/seed.ts)\n- Lib utilities: [examples/basic/src/lib](examples/basic/src/lib)\n- Example scripts: [examples/basic/package.json](examples/basic/package.json)\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"faq--troubleshooting\"\u003e\u003c/a\u003e\n## ❓ FAQ / Troubleshooting\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand FAQ and troubleshooting\u003c/summary\u003e\nPrisma version mismatch\n- Symptom: generator fails or types not aligned\n- Action: ensure Prisma v6+ in dev deps and runtime\n  - `npm i -D prisma @prisma/client`\n  - Regenerate: `npx prisma generate`\n\nNode version or ESM issues\n- Symptom: runtime errors about module type or syntax\n- Action: use Node 18.18.0+, 20.9.0+, or 22.11.0+; align package type with your build, then rebuild `npm run build`\n\nGenerated path is unexpected\n- Symptom: files not where you expect\n- Action: verify your generator output path and config; compare with [examples/basic/src/generated/orpc](examples/basic/src/generated/orpc)\n\nSchema/config validation failures\n- Symptom: errors referencing invalid options\n- Action: check inputs against [src/config/schema.ts](src/config/schema.ts); fix paths/booleans; re-run generation\n\nDocs not emitted\n- Symptom: documentation folder missing\n- Action: set `generateDocumentation = \"true\"` and inspect [src/generators/documentation-generator.ts](src/generators/documentation-generator.ts)\n\nShield path resolution errors\n- Symptom: \"Cannot find module\" errors for shield imports\n- Action: verify `shieldPath` points to correct file; check file exports `permissions` object; ensure path is relative to project root or absolute\n- Note: generator now handles dynamic path resolution automatically for common directory structures\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"development-contributing\"\u003e\u003c/a\u003e\n## 🧑‍💻 Development (Contributing)\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand development guide\u003c/summary\u003e\nRepo quicklinks\n- Source: [src/](src)\n- Generators: [src/generators/](src/generators)\n- Entry point: [src/bin.ts](src/bin.ts)\n- Public exports: [src/index.ts](src/index.ts)\n- Tests: [tests/](tests)\n\nLocal dev loop\n```bash\nnpm run dev         # watch build\nnpm run build       # one-off build\nnpm run lint        # lint\nnpm run lint:fix    # lint + fix\nnpm run format      # prettier\nnpm run typecheck   # types only\n```\n\nLocal development (monorepo) provider example\n```prisma\ngenerator orpc {\n  provider = \"../../lib/bin.js\" // relative path to built generator\n  output   = \"./src/generated/orpc\"\n}\n```\n\nTesting\n```bash\nnpm test               # unit/integration\nnpm run test:watch     # watch\nnpm run test:e2e       # Prisma-backed CRUD\nnpm run test:coverage  # coverage\n```\n\nConventions\n- Conventional Commits\n- Ensure `npm run build` and `npm run typecheck` pass before PR\n- Update [README.md](README.md) if flags/outputs change\n\n\u003c/details\u003e\n\n---\n\n\u003ca id=\"roadmap\"\u003e\u003c/a\u003e\n## 🗺️ Roadmap\n\n- ✅ **Integration with oRPC Shield** - Built-in authorization with dynamic path resolution\n- **Schema-based Auth Configuration** - Define authorization rules directly in Prisma schema, JSON, or TypeScript config files\n- Plugin hooks for custom emitters\n- Config discovery and overrides\n\n---\n\n\u003ca id=\"license\"\u003e\u003c/a\u003e\n## 📄 License\n\n- License: MIT — see the `LICENSE` file.\n- Copyright © 2025 Omar Dulaimi.\n\n---\n\n\u003ca id=\"acknowledgements\"\u003e\u003c/a\u003e\n## 🙏 Acknowledgements\n\n- Prisma and its ecosystem\n- oRPC community and patterns\n- Zod for runtime validation\n- TypeScript tooling\n- Vitest and contributors\n\n\u003ca id=\"changelog\"\u003e\u003c/a\u003e\n## 📝 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md)\n\n---\n\nMade with ❤️ by [Omar Dulaimi](https://github.com/omar-dulaimi)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomar-dulaimi%2Fprisma-orpc-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomar-dulaimi%2Fprisma-orpc-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomar-dulaimi%2Fprisma-orpc-generator/lists"}