Skip to main content
zodipus-custom-schemas Define custom Zod schemas for Prisma JSON fields using @zodSchema annotations. Use when working with typed JSON, metadata fields, settings objects, complex JSON structures in Prisma, or custom-schemas.ts.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/bratsos/zodipus --skill zodipus-custom-schemasLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt Migrate to Zodipus from other Prisma-Zod generators like prisma-zod-generator, zod-prisma, zod-prisma-types, or zmodel. Use when switching from another Prisma validation library.
Build type-safe, composable Prisma queries with automatic Zod validation. Use when working with createRegistry, query builders, select/include patterns, validated database queries, findMany validation, or type-safe Prisma results.
Install and configure Zodipus Prisma generator. Use when installing zodipus, setting up generator options, configuring output paths, choosing date formats, or integrating with Next.js/Express/Fastify/tRPC.
Explorateur de fichiers
2 fichiers Métiers associés SOC
Basé sur la classification professionnelle SOC
name zodipus-custom-schemas description Define custom Zod schemas for Prisma JSON fields using @zodSchema annotations. Use when working with typed JSON, metadata fields, settings objects, complex JSON structures in Prisma, or custom-schemas.ts. license MIT metadata {"author":"zodipus","version":"1.0.0"}
Custom JSON Schemas
Type your Prisma JSON fields with custom Zod schemas using @zodSchema annotations.
When to Apply
User has JSON fields in Prisma schema
User mentions @zodSchema annotation
User wants typed metadata, settings, or config fields
User asks about custom-schemas.ts
User needs validation for JSON data
User mentions "typed JSON" or "JSON validation"
The Problem
Prisma's Json type has no runtime type safety:
model Post {
id String @id
metadata Json? // Type: JsonValue (any)
}
post.metadata = { random : 'stuff' , 123 : true };
post.metadata = ;
post. = [ , , ];
'just a string'
metadata
1
2
3
The Solution Use @zodSchema to define exactly what your JSON should contain.
Step 1: Annotate in Prisma Schema Add a triple-slash comment with @zodSchema SchemaName above your JSON field:
model Post {
id String @id @default(cuid())
title String
content String?
/// @zodSchema PostMetadataSchema
metadata Json?
}
model User {
id String @id @default(cuid())
email String @unique
/// @zodSchema UserSettingsSchema
settings Json @default("{}")
/// @zodSchema UserPreferencesSchema
preferences Json?
}
Step 2: Run Generation This creates a custom-schemas.ts file with placeholder schemas:
import { z } from 'zod' ;
export const PostMetadataSchema = z.unknown ();
export const UserSettingsSchema = z.unknown ();
export const UserPreferencesSchema = z.unknown ();
Step 3: Define Your Schemas Replace the placeholders with real schemas:
import { z } from 'zod' ;
export const PostMetadataSchema = z.object ({
tags : z.array (z.string ()).default ([]),
views : z.number ().int ().nonnegative ().default (0 ),
featured : z.boolean ().default (false ),
seo : z.object ({
title : z.string ().max (60 ).optional (),
description : z.string ().max (160 ).optional (),
keywords : z.array (z.string ()).optional (),
}).optional (),
});
export const UserSettingsSchema = z.object ({
theme : z.enum (['light' , 'dark' , 'system' ]).default ('system' ),
notifications : z.object ({
email : z.boolean ().default (true ),
push : z.boolean ().default (false ),
sms : z.boolean ().default (false ),
}).default ({}),
language : z.string ().default ('en' ),
timezone : z.string ().default ('UTC' ),
});
export const UserPreferencesSchema = z.object ({
dashboard : z.object ({
layout : z.enum (['grid' , 'list' ]).default ('grid' ),
itemsPerPage : z.number ().int ().min (10 ).max (100 ).default (20 ),
}).optional (),
privacy : z.object ({
showEmail : z.boolean ().default (false ),
showActivity : z.boolean ().default (true ),
}).optional (),
});
Step 4: Use It Now your schemas have full type safety:
import { PostSchema , UserSchema } from './generated' ;
const post = PostSchema .parse ({
id : '123' ,
title : 'My Post' ,
content : 'Hello world' ,
metadata : {
tags : ['tutorial' , 'prisma' ],
views : 100 ,
featured : true ,
seo : {
title : 'My Post - Tutorial' ,
description : 'Learn about Prisma' ,
},
},
});
post.metadata .tags ;
post.metadata .views ;
post.metadata .seo ?.title ;
Common Patterns
Settings Object export const AppSettingsSchema = z.object ({
theme : z.enum (['light' , 'dark' , 'system' ]).default ('system' ),
fontSize : z.enum (['small' , 'medium' , 'large' ]).default ('medium' ),
compactMode : z.boolean ().default (false ),
sidebar : z.object ({
collapsed : z.boolean ().default (false ),
width : z.number ().int ().min (200 ).max (400 ).default (280 ),
}).default ({}),
});
Metadata with Timestamps export const AuditMetadataSchema = z.object ({
createdBy : z.string ().optional (),
updatedBy : z.string ().optional (),
version : z.number ().int ().default (1 ),
changelog : z.array (z.object ({
date : z.coerce .date (),
user : z.string (),
action : z.string (),
})).default ([]),
});
Configuration with Defaults export const NotificationConfigSchema = z.object ({
enabled : z.boolean ().default (true ),
channels : z.object ({
email : z.boolean ().default (true ),
slack : z.boolean ().default (false ),
webhook : z.string ().url ().optional (),
}).default ({}),
frequency : z.enum (['instant' , 'hourly' , 'daily' ]).default ('instant' ),
quietHours : z.object ({
enabled : z.boolean ().default (false ),
start : z.string ().regex (/^\d{2}:\d{2}$/ ).optional (),
end : z.string ().regex (/^\d{2}:\d{2}$/ ).optional (),
}).optional (),
});
Array of Objects export const ProductVariantsSchema = z.array (z.object ({
sku : z.string (),
name : z.string (),
price : z.number ().positive (),
stock : z.number ().int ().nonnegative (),
attributes : z.record (z.string ()).optional (),
}));
Union/Discriminated Union Types
export const PaymentMethodSchema = z.union ([
z.object ({
type : z.literal ('card' ),
last4 : z.string ().length (4 ),
brand : z.enum (['visa' , 'mastercard' , 'amex' ]),
expiryMonth : z.number ().int ().min (1 ).max (12 ),
expiryYear : z.number ().int (),
}),
z.object ({
type : z.literal ('bank' ),
bankName : z.string (),
accountLast4 : z.string ().length (4 ),
}),
z.object ({
type : z.literal ('paypal' ),
email : z.string ().email (),
}),
]);
export const PaymentMethodSchema = z.discriminatedUnion ('type' , [
z.object ({
type : z.literal ('card' ),
last4 : z.string ().length (4 ),
brand : z.enum (['visa' , 'mastercard' , 'amex' ]),
}),
z.object ({
type : z.literal ('bank' ),
bankName : z.string (),
accountLast4 : z.string ().length (4 ),
}),
]);
Recursive/Nested Structures
interface TreeNode {
id : string ;
name : string ;
children ?: TreeNode [];
}
export const TreeNodeSchema : z.ZodType <TreeNode > = z.lazy (() =>
z.object ({
id : z.string (),
name : z.string (),
children : z.array (TreeNodeSchema ).optional (),
})
);
export const MenuSchema = z.array (TreeNodeSchema );
Flexible Key-Value Store
export const CustomFieldsSchema = z.record (
z.string (),
z.union ([z.string (), z.number (), z.boolean (), z.null ()])
);
export const LabeledFieldsSchema = z.record (
z.string ().regex (/^[a-z_][a-z0-9_]*$/ ),
z.string ().max (500 )
);
Best Practices
1. Always Use Defaults Prevents null/undefined issues when creating new records:
export const SettingsSchema = z.object ({
theme : z.enum (['light' , 'dark' ]).default ('light' ),
notifications : z.boolean ().default (true ),
}).default ({});
2. Make Optional Fields Explicit Be clear about what's required vs optional:
export const ProfileSchema = z.object ({
displayName : z.string ().min (1 ).max (50 ),
bio : z.string ().max (500 ).optional (),
avatarUrl : z.string ().url ().nullable (),
isPublic : z.boolean ().default (true ),
});
3. Validate Constraints Add business rule validations:
export const PriceSchema = z.object ({
amount : z.number ().positive (),
currency : z.enum (['USD' , 'EUR' , 'GBP' ]),
discount : z.number ().min (0 ).max (100 ).optional (),
}).refine (
(data ) => !data.discount || data.amount > 0 ,
{ message : 'Discount requires positive amount' }
);
4. Document with .describe() Add descriptions for documentation:
export const ApiConfigSchema = z.object ({
endpoint : z.string ().url ().describe ('API base URL' ),
timeout : z.number ().int ().positive ().default (30000 ).describe ('Request timeout in ms' ),
retries : z.number ().int ().min (0 ).max (5 ).default (3 ).describe ('Number of retry attempts' ),
});
Regeneration Behavior When you run npx prisma generate:
New @zodSchema annotations : Adds placeholder to custom-schemas.ts
Existing schemas : Preserved - your definitions are NOT overwritten
Removed annotations : Schema export remains (manual cleanup needed)
Troubleshooting
Schema Not Being Used Ensure the annotation is a triple-slash comment :
// Wrong - single slash
// @zodSchema MySchema
metadata Json?
// Wrong - double slash doc comment
/** @zodSchema MySchema */
metadata Json?
// Correct - triple slash
/// @zodSchema MySchema
metadata Json?
Type Errors After Editing custom-schemas.ts Run generation again to update model schemas:
Schema Name Must Match Export The annotation name must exactly match the export:
/// @zodSchema PostMetadataSchema
metadata Json?
export const PostMetadataSchema = z.object ({...});