Socket
Book a DemoInstallSign in
Socket

prisma-orpc-generator

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prisma-orpc-generator

Prisma generator that creates fully-featured oRPC routers

1.1.0
latest
Source
npmnpm
Version published
Weekly downloads
245
16.11%
Maintainers
1
Weekly downloads
Β 
Created
Source

⚑ Prisma oRPC Generator

Generate typed oRPC routers, Zod schemas, and docs straight from your Prisma schema.

npm CI license node prisma TypeScript Prettier

Prisma v6+, Node 18.18+/20.9+/22.11+, TypeScript β‰₯ 5.1.

TL;DR β€” Add the generator to your Prisma schema and run Prisma generate. That’s it.

generator client {
  provider = "prisma-client-js"
}

generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"

  // Optional config (booleans are strings)
  schemaLibrary = "zod"
  generateInputValidation  = "true"
  generateOutputValidation = "true"

  // Shield authorization (optional)
  generateShield = "true"
  defaultReadRule = "allow"
  defaultWriteRule = "auth"
}
# generate
npx prisma generate

πŸ“‹ Table of Contents

⚑ Quickstart

Click to expand quickstart guide

Prerequisites

  • Node: 18.18.0+, 20.9.0+, or 22.11.0+
  • Prisma CLI (v6+) in your project
  • TypeScript β‰₯ 5.1.0 recommended

Install

# npm
npm install -D prisma-orpc-generator zod prisma @prisma/client

# pnpm
pnpm add -D prisma-orpc-generator zod prisma @prisma/client

# yarn
yarn add -D prisma-orpc-generator zod prisma @prisma/client

Add the generator (minimal)

generator client {
  provider = "prisma-client-js"
}

generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"
}

Generate

npx prisma generate

🧩 Compatibility

Click to expand compatibility info - Prisma ORM: v6+ - Node.js minimums for Prisma v6: - 18.18.0+ - 20.9.0+ - 22.11.0+ - Not supported: 16, 17, 19, 21 - TypeScript: β‰₯ 5.1.0

πŸ—οΈ What Gets Generated

Click to expand generated files overview A generated surface mirroring your domain:
src/generated/orpc/
β”œβ”€ routers/
β”‚  β”œβ”€ models/           # per-model routers
β”‚  └─ helpers/          # common utilities
β”œβ”€ tests/               # generated tests
β”œβ”€ zod-schemas/         # zod (if enabled)
└─ documentation/       # docs (if enabled)

Explore the example outputs:

πŸ› οΈ Usage

Click to expand usage guide - Runs as part of Prisma’s generator pipeline. - Default output directory is `./src/generated/orpc` (configurable via the generator block). - Import the generated code into your server/app. See the runnable example server in [examples/basic/src/server.ts](examples/basic/src/server.ts).

Tip: Browse the example’s generated root for real structure: examples/basic/src/generated/orpc.

βš™οΈ Configuration

Click to expand configuration options Where configuration lives - Inside your generator block in [schema.prisma](examples/basic/schema.prisma) - Booleans are strings: "true"/"false"; numbers as strings are supported

Validated against src/config/schema.ts. Below are the most commonly used options.

Core options

OptionTypeDefaultValuesDescription
outputstring./src/generated/orpcβ€”Directory for generated oRPC artifacts
schemaLibraryenum"zod"zodSchema validation library
generateInputValidationboolean (string)"true""true", "false"Emit Zod validation for inputs
generateOutputValidationboolean (string)"true""true", "false"Emit Zod validation for outputs
strictValidationboolean (string)"true""true", "false"Stricter Zod shapes for safety
zodSchemasOutputPathstring./zod-schemasβ€”Relative path (under output) for Zod files
externalZodImportPathstring./zod-schemasβ€”Module/path used when importing Zod schemas
zodDateTimeStrategyenum"coerce""date", "coerce", "isoString"How DateTime fields are modeled in Zod
zodConfigPathstringβ€”β€”Path to custom zod.config.json file (relative to schema or absolute)

Operational options

OptionTypeDefaultValuesDescription
generateModelActionsstring listallsee noteComma-separated actions to emit (see note below)
showModelNameInProcedureboolean (string)"true""true", "false"Prefix procedures with model name
enableSoftDeletesboolean (string)"false""true", "false"Add soft-delete semantics where applicable
generateRelationResolversboolean (string)"true""true", "false"Emit helpers to resolve relations
wrapResponsesboolean (string)"false""true", "false"Wrap handler results in an envelope

DX and formatting

OptionTypeDefaultValuesDescription
useBarrelExportsboolean (string)"true""true", "false"Generate index.ts barrel exports
codeStyleenum"prettier""prettier", "none"Format generated code with Prettier
generateDocumentationboolean (string)"false""true", "false"Generate API documentation
generateTestsboolean (string)"false""true", "false"Generate test files
enableDebugLoggingboolean (string)"false""true", "false"Extra logs during generation

Runtime and integration

OptionTypeDefaultValuesDescription
prismaClientPathstring@prisma/clientβ€”Import path for PrismaClient
contextPathstring""β€”Optional path to your app's Context module
serverPortnumber (string)3000β€”Port used by optional docs/server helpers
apiPrefixstring""β€”Prefix used by optional docs/server helpers
apiTitlestringGenerated APIβ€”API title for documentation
apiDescriptionstringAuto-generated API from Prisma schemaβ€”API description for documentation
apiVersionstring1.0.0β€”API version for documentation

Shield / Authorization

OptionTypeDefaultValuesDescription
generateShieldboolean (string)"true""true", "false"Enable shield generation
shieldPathstringβ€”β€”Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier)
defaultReadRuleenum"allow""allow", "deny", "auth"Default rule for read operations
defaultWriteRuleenum"auth""auth", "deny", "allow"Default rule for write operations
denyErrorCodestring"FORBIDDEN"β€”Error code for denied access
debugboolean (string)"false""true", "false"Enable debug logging
allowExternalErrorsboolean (string)"false""true", "false"Allow detailed error messages from shields
Notes
  • generateModelActions supports: create, createMany, findFirst, findFirstOrThrow, findMany, findUnique, findUniqueOrThrow, update, updateMany, upsert, delete, deleteMany, aggregate, groupBy, count, findRaw, aggregateRaw.
  • Booleans are strings in Prisma generator config: use "true" or "false".
  • The full, authoritative shape lives in src/config/schema.ts.
Example: focused configuration with Zod and docs
generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"

  schemaLibrary             = "zod"
  zodDateTimeStrategy       = "coerce"
  generateInputValidation   = "true"
  generateOutputValidation  = "true"
  generateDocumentation     = "true"
  useBarrelExports          = "true"
  codeStyle                 = "prettier"
}

πŸ”§ Zod Schemas Generation

Click to expand zod schemas info

This generator leverages prisma-zod-generator to create Zod schemas from your Prisma models. Here's how the process works:

Generation Process

  • Automatic Integration: When schemaLibrary = "zod" is set, the generator automatically calls prisma-zod-generator
  • Configuration Management: Creates a zod.config.json file with optimized settings for oRPC usage
  • Schema Output: Generates Zod schemas in the zod-schemas/ subdirectory of your output path
  • Import Integration: Generated oRPC routers automatically import and use these schemas for validation

Configuration File

The generator creates a minimal zod.config.json file:

{
  "mode": "full",
  "output": "./zod-schemas"
}

Additional settings are only added when they differ from defaults:

{
  "mode": "full", 
  "output": "./zod-schemas",
  "dateTimeStrategy": "date"
}

DateTime Handling Strategy

The zodDateTimeStrategy option controls how Prisma DateTime fields are modeled in Zod schemas:

StrategyZod SchemaDescriptionprisma-zod-generator equivalent
"coerce" (default)z.coerce.date()Automatically converts strings/numbers to Date objectsdateTimeStrategy: "coerce"
"date"z.date()Requires actual Date objects, no conversiondateTimeStrategy: "date"
"isoString"z.string().regex(ISO).transform()Validates ISO string format, transforms to DatedateTimeStrategy: "isoString"

Custom Zod Configuration

For advanced use cases, you can provide your own zod.config.json:

generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"
  
  zodConfigPath = "./custom-zod.config.json"  // Path to your config file
}

When zodConfigPath is specified:

  • The generator uses your existing configuration
  • oRPC-specific settings are passed as generator options instead of modifying the config file
  • Your custom configuration takes precedence

File Structure

Generated Zod schemas follow this structure:

src/generated/orpc/
β”œβ”€ zod-schemas/
β”‚  β”œβ”€ index.ts           # Barrel exports
β”‚  β”œβ”€ objects/           # Model schemas
β”‚  β”‚  β”œβ”€ UserSchema.ts
β”‚  β”‚  └─ PostSchema.ts
β”‚  └─ inputTypeSchemas/  # Input validation schemas
β”‚     β”œβ”€ UserCreateInput.ts
β”‚     └─ UserUpdateInput.ts
└─ routers/              # oRPC routers (import from ../zod-schemas)

πŸ›‘οΈ Shield Authorization

Click to expand shield authorization guide

The generator can automatically generate orpc-shield configurations for type-safe authorization. Shield provides declarative rules, composable operators, and path-based permissions.

Shield Configuration

Add shield options to your generator config:

generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"

  // Enable shield generation
  generateShield = "true"

  // Option 1: Auto-generate shield rules
  defaultReadRule  = "allow"  // "allow", "deny", "auth"
  defaultWriteRule = "auth"   // "auth", "deny"

  // Option 2: Use custom shield file (relative to output dir)
  // shieldPath = "../auth/my-custom-shield"

  // Error handling
  denyErrorCode = "FORBIDDEN"
  debug = "false"
}

What Gets Generated

Shield generation creates:

src/generated/orpc/
β”œβ”€ shield.ts              # Shield rules and permissions (auto-generated)
β”œβ”€ routers/
β”‚  β”œβ”€ index.ts           # App router with shield exports
β”‚  └─ helpers/
β”‚     └─ createRouter.ts # Base router with shield middleware integration

When shieldPath is provided: The generator skips auto-generation and dynamically integrates your custom shield file into the generated middleware chain.

Dynamic Shield Path Resolution ✨

The generator now features smart dynamic path resolution for shield files. When you specify a shieldPath, the generator automatically:

  • βœ… Resolves relative paths from your project structure
  • βœ… Handles different output directory layouts
  • βœ… Integrates shield middleware using the proper oRPC pattern
  • βœ… Generates correct import paths regardless of nesting depth
  • βœ… Applies middleware to all generated procedures through inheritance

Example Generated Integration:

// In src/generated/orpc/routers/helpers/createRouter.ts
import { permissions } from '../../../../custom-shield';
export const or = os.$context<Context>().use(permissions);

Using Custom Shield Files

For advanced use cases, you can provide your own shield file instead of auto-generation:

generator orpc {
  provider = "prisma-orpc-generator"
  output   = "./src/generated/orpc"

  generateShield = "true"
  shieldPath = "../../src/custom-shield"  // Dynamically resolved!
}

Supported Path Formats:

  • Relative paths: "../../src/auth/shield"
  • Project root relative: "src/auth/shield"
  • Absolute paths: "/absolute/path/to/shield"

Your custom shield file should export a permissions object:

// src/custom-shield.ts
import { rule, allow, deny, shield, or } from 'orpc-shield';
import type { Context } from '../generated/orpc/routers/helpers/createRouter';

const isAuthenticated = rule<Context>()(({ ctx }) => !!ctx.user);
const isAdmin = rule<Context>()(({ ctx }) => ctx.user?.role === 'admin');
const isOwner = rule<Context>()(({ ctx, input }) => {
  return ctx.user?.id === (input as any)?.userId;
});

export const permissions = shield<Context>({
  user: {
    userFindMany: allow,           // Match generated procedure names
    userCreate: isAuthenticated,   
    userUpdate: isAuthenticated,
    userDelete: or(isAdmin, isOwner),
    userDeleteMany: deny,          // Explicitly deny dangerous operations
  },
  post: {
    postFindMany: allow,
    postCreate: isAuthenticated,
    postUpdate: isAuthenticated,
    postDelete: isAuthenticated,
  },
}, {
  denyErrorCode: 'FORBIDDEN',      // Maps to HTTP 403
  debug: true,                     // Enable debug logging
  allowExternalErrors: true,       // Allow detailed error messages
});

Important: Shield procedure names should match your generated router names (e.g., userCreate, postFindMany).

Note: When using shieldPath, the generator will skip auto-generation and use your custom shield file instead.

Generated Shield Rules

The generator creates rules based on your Prisma models:

// Built-in rules (generated automatically)
const isAuthenticated = rule<Context>()(({ ctx }) => !!ctx.user);

// Example custom rules (user-defined)
const isAdmin = rule<Context>()(({ ctx }) => ctx.user?.role === 'admin');

// Model-specific rules (generated based on config)
const canReadUser = allow;           // Read operations: allow
const canWriteUser = isAuthenticated; // Write operations: require auth

// Shield configuration
export const permissions = shield<Context>({
  user: {
    list: canReadUser,
    findById: canReadUser,
    create: canWriteUser,
    update: canWriteUser,
    delete: canWriteUser,
  },
  post: {
    list: allow,
    create: isAuthenticated,
    update: isAuthenticated,
  },
});

Using Shield in Your Server

Import and use the generated shield:

import { appRouter, permissions } from './generated/orpc/routers';

// Apply shield at server level
const server = createServer(appRouter, {
  // Shield is applied via middleware
  middleware: [permissions]
});

// Or use with oRPC handlers
import { OpenAPIHandler } from '@orpc/openapi';

const handler = new OpenAPIHandler(appRouter, {
  // Shield permissions are automatically applied
  interceptors: [/* your interceptors */]
});

Context Requirements

Shield rules expect a Context with user information:

interface Context {
  prisma: PrismaClient;
  user?: {
    id: string;
    email?: string;
    name?: string;
    roles?: string[];
    permissions?: string[];
  };
}

Customization

Override default rules by modifying the generated shield.ts:

// Custom rule for post ownership
const isPostOwner = rule<Context>()(({ ctx, input }) => {
  return ctx.user?.id === (input as any)?.authorId;
});

// Use in shield config
const permissions = shield<Context>({
  post: {
    update: and(isAuthenticated, isPostOwner), // Auth + ownership
    delete: or(isAdmin, isPostOwner),          // Admin or owner
  },
});

Shield Options

OptionTypeDefaultValuesDescription
generateShieldboolean (string)"true""true", "false"Enable shield generation
shieldPathstringβ€”β€”Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier)
defaultReadRuleenum"allow""allow", "deny", "auth"Default rule for read operations
defaultWriteRuleenum"auth""auth", "deny", "allow"Default rule for write operations
denyErrorCodestring"FORBIDDEN"β€”Error code for denied access
debugboolean (string)"false""true", "false"Enable debug logging
allowExternalErrorsboolean (string)"false""true", "false"Allow detailed error messages from shields

πŸ§ͺ Examples

Click to expand examples Run the repo example end-to-end ```bash npm run example:basic ```

What it does

  • Builds the generator
  • Generates Prisma artifacts
  • Seeds a local DB
  • Starts a small server using the generated routers/schemas

Notable files

❓ FAQ / Troubleshooting

Click to expand FAQ and troubleshooting Prisma version mismatch - Symptom: generator fails or types not aligned - Action: ensure Prisma v6+ in dev deps and runtime - `npm i -D prisma @prisma/client` - Regenerate: `npx prisma generate`

Node version or ESM issues

  • Symptom: runtime errors about module type or syntax
  • Action: use Node 18.18.0+, 20.9.0+, or 22.11.0+; align package type with your build, then rebuild npm run build

Generated path is unexpected

Schema/config validation failures

  • Symptom: errors referencing invalid options
  • Action: check inputs against src/config/schema.ts; fix paths/booleans; re-run generation

Docs not emitted

Shield path resolution errors

  • Symptom: "Cannot find module" errors for shield imports
  • Action: verify shieldPath points to correct file; check file exports permissions object; ensure path is relative to project root or absolute
  • Note: generator now handles dynamic path resolution automatically for common directory structures

πŸ§‘β€πŸ’» Development (Contributing)

Click to expand development guide Repo quicklinks - Source: [src/](src) - Generators: [src/generators/](src/generators) - Entry point: [src/bin.ts](src/bin.ts) - Public exports: [src/index.ts](src/index.ts) - Tests: [tests/](tests)

Local dev loop

npm run dev         # watch build
npm run build       # one-off build
npm run lint        # lint
npm run lint:fix    # lint + fix
npm run format      # prettier
npm run typecheck   # types only

Local development (monorepo) provider example

generator orpc {
  provider = "../../lib/bin.js" // relative path to built generator
  output   = "./src/generated/orpc"
}

Testing

npm test               # unit/integration
npm run test:watch     # watch
npm run test:e2e       # Prisma-backed CRUD
npm run test:coverage  # coverage

Conventions

  • Conventional Commits
  • Ensure npm run build and npm run typecheck pass before PR
  • Update README.md if flags/outputs change

πŸ—ΊοΈ Roadmap

  • βœ… Integration with oRPC Shield - Built-in authorization with dynamic path resolution
  • Schema-based Auth Configuration - Define authorization rules directly in Prisma schema, JSON, or TypeScript config files
  • Plugin hooks for custom emitters
  • Config discovery and overrides

πŸ“„ License

  • License: MIT β€” see the LICENSE file.
  • Copyright Β© 2025 Omar Dulaimi.

πŸ™ Acknowledgements

  • Prisma and its ecosystem
  • oRPC community and patterns
  • Zod for runtime validation
  • TypeScript tooling
  • Vitest and contributors

πŸ“ Changelog

See CHANGELOG.md

Made with ❀️ by Omar Dulaimi

Keywords

prisma

FAQs

Package last updated on 04 Sep 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚑️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.