
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
prisma-orpc-generator
Advanced tools
Generate typed oRPC routers, Zod schemas, and docs straight from your Prisma schema.
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
Prerequisites
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
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:
Tip: Browse the exampleβs generated root for real structure: examples/basic/src/generated/orpc.
Validated against src/config/schema.ts. Below are the most commonly used options.
Core options
Option | Type | Default | Values | Description |
---|---|---|---|---|
output | string | ./src/generated/orpc | β | Directory for generated oRPC artifacts |
schemaLibrary | enum | "zod" | zod | Schema validation library |
generateInputValidation | boolean (string) | "true" | "true", "false" | Emit Zod validation for inputs |
generateOutputValidation | boolean (string) | "true" | "true", "false" | Emit Zod validation for outputs |
strictValidation | boolean (string) | "true" | "true", "false" | Stricter Zod shapes for safety |
zodSchemasOutputPath | string | ./zod-schemas | β | Relative path (under output) for Zod files |
externalZodImportPath | string | ./zod-schemas | β | Module/path used when importing Zod schemas |
zodDateTimeStrategy | enum | "coerce" | "date", "coerce", "isoString" | How DateTime fields are modeled in Zod |
zodConfigPath | string | β | β | Path to custom zod.config.json file (relative to schema or absolute) |
Operational options
Option | Type | Default | Values | Description |
---|---|---|---|---|
generateModelActions | string list | all | see note | Comma-separated actions to emit (see note below) |
showModelNameInProcedure | boolean (string) | "true" | "true", "false" | Prefix procedures with model name |
enableSoftDeletes | boolean (string) | "false" | "true", "false" | Add soft-delete semantics where applicable |
generateRelationResolvers | boolean (string) | "true" | "true", "false" | Emit helpers to resolve relations |
wrapResponses | boolean (string) | "false" | "true", "false" | Wrap handler results in an envelope |
DX and formatting
Option | Type | Default | Values | Description |
---|---|---|---|---|
useBarrelExports | boolean (string) | "true" | "true", "false" | Generate index.ts barrel exports |
codeStyle | enum | "prettier" | "prettier", "none" | Format generated code with Prettier |
generateDocumentation | boolean (string) | "false" | "true", "false" | Generate API documentation |
generateTests | boolean (string) | "false" | "true", "false" | Generate test files |
enableDebugLogging | boolean (string) | "false" | "true", "false" | Extra logs during generation |
Runtime and integration
Option | Type | Default | Values | Description |
---|---|---|---|---|
prismaClientPath | string | @prisma/client | β | Import path for PrismaClient |
contextPath | string | "" | β | Optional path to your app's Context module |
serverPort | number (string) | 3000 | β | Port used by optional docs/server helpers |
apiPrefix | string | "" | β | Prefix used by optional docs/server helpers |
apiTitle | string | Generated API | β | API title for documentation |
apiDescription | string | Auto-generated API from Prisma schema | β | API description for documentation |
apiVersion | string | 1.0.0 | β | API version for documentation |
Shield / Authorization
Option | Type | Default | Values | Description |
---|---|---|---|---|
generateShield | boolean (string) | "true" | "true", "false" | Enable shield generation |
shieldPath | string | β | β | Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier) |
defaultReadRule | enum | "allow" | "allow", "deny", "auth" | Default rule for read operations |
defaultWriteRule | enum | "auth" | "auth", "deny", "allow" | Default rule for write operations |
denyErrorCode | string | "FORBIDDEN" | β | Error code for denied access |
debug | boolean (string) | "false" | "true", "false" | Enable debug logging |
allowExternalErrors | boolean (string) | "false" | "true", "false" | Allow detailed error messages from shields |
Notes |
generator orpc {
provider = "prisma-orpc-generator"
output = "./src/generated/orpc"
schemaLibrary = "zod"
zodDateTimeStrategy = "coerce"
generateInputValidation = "true"
generateOutputValidation = "true"
generateDocumentation = "true"
useBarrelExports = "true"
codeStyle = "prettier"
}
This generator leverages prisma-zod-generator to create Zod schemas from your Prisma models. Here's how the process works:
schemaLibrary = "zod"
is set, the generator automatically calls prisma-zod-generator
zod.config.json
file with optimized settings for oRPC usagezod-schemas/
subdirectory of your output pathThe 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"
}
The zodDateTimeStrategy
option controls how Prisma DateTime fields are modeled in Zod schemas:
Strategy | Zod Schema | Description | prisma-zod-generator equivalent |
---|---|---|---|
"coerce" (default) | z.coerce.date() | Automatically converts strings/numbers to Date objects | dateTimeStrategy: "coerce" |
"date" | z.date() | Requires actual Date objects, no conversion | dateTimeStrategy: "date" |
"isoString" | z.string().regex(ISO).transform() | Validates ISO string format, transforms to Date | dateTimeStrategy: "isoString" |
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:
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)
The generator can automatically generate orpc-shield configurations for type-safe authorization. Shield provides declarative rules, composable operators, and path-based permissions.
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"
}
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.
The generator now features smart dynamic path resolution for shield files. When you specify a shieldPath
, the generator automatically:
Example Generated Integration:
// In src/generated/orpc/routers/helpers/createRouter.ts
import { permissions } from '../../../../custom-shield';
export const or = os.$context<Context>().use(permissions);
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:
"../../src/auth/shield"
"src/auth/shield"
"/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.
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,
},
});
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 */]
});
Shield rules expect a Context
with user information:
interface Context {
prisma: PrismaClient;
user?: {
id: string;
email?: string;
name?: string;
roles?: string[];
permissions?: string[];
};
}
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
},
});
Option | Type | Default | Values | Description |
---|---|---|---|---|
generateShield | boolean (string) | "true" | "true", "false" | Enable shield generation |
shieldPath | string | β | β | Path to custom shield file (absolute, relative to project root, relative to output dir, or module specifier) |
defaultReadRule | enum | "allow" | "allow", "deny", "auth" | Default rule for read operations |
defaultWriteRule | enum | "auth" | "auth", "deny", "allow" | Default rule for write operations |
denyErrorCode | string | "FORBIDDEN" | β | Error code for denied access |
debug | boolean (string) | "false" | "true", "false" | Enable debug logging |
allowExternalErrors | boolean (string) | "false" | "true", "false" | Allow detailed error messages from shields |
What it does
Notable files
Node version or ESM issues
npm run build
Generated path is unexpected
Schema/config validation failures
Docs not emitted
generateDocumentation = "true"
and inspect src/generators/documentation-generator.tsShield path resolution errors
shieldPath
points to correct file; check file exports permissions
object; ensure path is relative to project root or absoluteLocal 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
npm run build
and npm run typecheck
pass before PRLICENSE
file.See CHANGELOG.md
Made with β€οΈ by Omar Dulaimi
1.1.0 (2025-09-04)
FAQs
Prisma generator that creates fully-featured oRPC routers
The npm package prisma-orpc-generator receives a total of 240 weekly downloads. As such, prisma-orpc-generator popularity was classified as not popular.
We found that prisma-orpc-generator demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last weekβs supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.