prisma-zod-generator
Version:
Prisma 2+ generator to emit Zod schemas from your Prisma schema
790 lines • 32.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationErrorType = exports.MINIMAL_OPERATIONS = exports.DEFAULT_CONFIG = exports.SCHEMA_VARIANTS = exports.GENERATION_MODES = exports.PRISMA_OPERATIONS = exports.SuffixSchema = exports.OutputPathSchema = exports.ModelNameSchema = exports.FieldNameSchema = exports.ConfigurationSchema = void 0;
exports.isValidFieldName = isValidFieldName;
exports.isValidModelName = isValidModelName;
exports.isValidOperation = isValidOperation;
exports.isValidMode = isValidMode;
exports.isValidVariant = isValidVariant;
exports.isValidSuffix = isValidSuffix;
exports.getSchemaSection = getSchemaSection;
exports.createPartialSchema = createPartialSchema;
/**
* Comprehensive JSON Schema for Prisma Zod Generator configuration
*
* This schema defines strict validation rules for all configuration options
* including data types, constraints, and allowed values.
*/
exports.ConfigurationSchema = {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'Prisma Zod Generator Configuration',
description: 'Configuration schema for the Prisma Zod Generator',
type: 'object',
additionalProperties: false,
properties: {
$schema: {
type: 'string',
default: 'http://json-schema.org/draft-07/schema#', // Placeholder most likely would be https://omar-dulaimi.github.io/prisma-zod-generator/docs/schema.json
description: 'JSON Schema for the Prisma Zod Generator configuration',
},
mode: {
type: 'string',
enum: ['full', 'minimal', 'custom'],
default: 'full',
description: 'Generation mode: full (all schemas), minimal (basic CRUD only), or custom',
},
output: {
type: 'string',
minLength: 1,
pattern: '^[^<>:"|?*\\x00-\\x1f]+$',
description: 'Output directory path for generated schemas',
},
useMultipleFiles: {
type: 'boolean',
default: true,
description: 'When true (default), generate multiple files; when false, generate a single bundled file',
},
singleFileName: {
type: 'string',
minLength: 1,
default: 'schemas.ts',
description: 'Name of the single bundled file when useMultipleFiles is false',
},
placeSingleFileAtRoot: {
type: 'boolean',
default: true,
description: 'When bundling to a single file, place it at the output root instead of a schemas/ subdirectory',
},
placeArrayVariantsAtRoot: {
type: 'boolean',
default: true,
description: 'When using array-based variants, place them at schemas root; if false, under variants/',
},
formatGeneratedSchemas: {
type: 'boolean',
default: false,
description: 'Whether to run a formatter on generated schemas',
},
pureModels: {
type: 'boolean',
default: false,
description: 'Whether to generate pure model schemas',
},
pureModelsLean: {
type: 'boolean',
default: true,
description: 'Emit lean pure model schemas (no verbose JSDoc/statistics/comments)',
},
pureModelsIncludeRelations: {
type: 'boolean',
default: false,
description: 'When pureModels is true, include relation fields. Default false (omit relation fields for slimmer models)',
},
pureModelsExcludeCircularRelations: {
type: 'boolean',
default: false,
description: 'When pureModelsIncludeRelations is true, exclude relation fields that would create circular references. Keeps foreign key fields but omits relation object fields to avoid TypeScript circular dependency errors.',
},
naming: {
type: 'object',
additionalProperties: false,
description: 'Optional naming customization settings (experimental)',
properties: {
preset: {
type: 'string',
enum: ['default', 'zod-prisma', 'zod-prisma-types', 'legacy-model-suffix'],
description: 'Predefined naming preset to apply',
},
pureModel: {
type: 'object',
additionalProperties: false,
description: 'Overrides for pure model file and symbol naming',
properties: {
filePattern: {
type: 'string',
minLength: 3,
maxLength: 80,
description: 'Pattern for pure model file names. Tokens: {Model}, {model}, {camel}, {kebab}. Must end with .ts',
pattern: '.*\\.ts$',
},
schemaSuffix: {
type: 'string',
minLength: 0,
maxLength: 30,
pattern: '^[A-Z][A-Za-z0-9_]*$|^$',
description: 'Suffix appended to schema variable (e.g. Schema). Empty string allowed.',
},
typeSuffix: {
type: 'string',
minLength: 0,
maxLength: 30,
pattern: '^[A-Z][A-Za-z0-9_]*$|^$',
description: 'Suffix appended to inferred type export (e.g. Type). Empty string allowed.',
},
exportNamePattern: {
type: 'string',
minLength: 0,
maxLength: 80,
description: 'Pattern for schema export variable. Tokens: {Model} {model} plus optional suffix tokens {SchemaSuffix}. Defaults derived from schemaSuffix.',
},
legacyAliases: {
type: 'boolean',
default: false,
description: 'Emit deprecated alias exports (e.g. UserModel) for compatibility when preset supplies them.',
},
},
},
schema: {
type: 'object',
additionalProperties: false,
description: 'Overrides for CRUD operation schema file and symbol naming',
properties: {
filePattern: {
type: 'string',
minLength: 3,
maxLength: 80,
description: 'Pattern for schema file names. Tokens: {Model}, {model}, {camel}, {kebab}. Must end with .ts',
pattern: '.*\\.ts$',
},
exportNamePattern: {
type: 'string',
minLength: 0,
maxLength: 80,
description: 'Pattern for schema export variable. Tokens: {Model}, {model}, {Operation}.',
},
},
},
input: {
type: 'object',
additionalProperties: false,
description: 'Overrides for input object file and symbol naming',
properties: {
filePattern: {
type: 'string',
minLength: 3,
maxLength: 80,
description: 'Pattern for input file names. Tokens: {Model}, {model}, {camel}, {kebab}, {InputType}. Must end with .ts',
pattern: '.*\\.ts$',
},
exportNamePattern: {
type: 'string',
minLength: 0,
maxLength: 80,
description: 'Pattern for input export variable. Tokens: {Model}, {model}, {InputType}.',
},
},
},
enum: {
type: 'object',
additionalProperties: false,
description: 'Overrides for enum file and symbol naming',
properties: {
filePattern: {
type: 'string',
minLength: 3,
maxLength: 80,
description: 'Pattern for enum file names. Tokens: {Enum}, {enum}, {camel}, {kebab}. Must end with .ts',
pattern: '.*\\.ts$',
},
exportNamePattern: {
type: 'string',
minLength: 0,
maxLength: 80,
description: 'Pattern for enum export variable. Tokens: {Enum}, {enum}.',
},
},
},
},
},
dateTimeStrategy: {
type: 'string',
enum: ['date', 'coerce', 'isoString'],
default: 'date',
description: 'How DateTime fields are represented: date (z.date()), coerce (z.coerce.date()), isoString (ISO string validated & transformed)',
},
dateTimeSplitStrategy: {
type: 'boolean',
default: true,
description: 'When true and dateTimeStrategy is unset, use coerce for input schemas and date for pure/result schemas (split strategy)',
},
jsonSchemaCompatible: {
type: 'boolean',
default: false,
description: 'Generate schemas compatible with z.toJSONSchema() for API documentation. When enabled, overrides dateTimeStrategy and removes transforms. Trade-off: No runtime type conversion.',
},
jsonSchemaOptions: {
type: 'object',
properties: {
dateTimeFormat: {
type: 'string',
enum: ['isoString', 'isoDate'],
default: 'isoString',
description: 'Format for DateTime fields in JSON Schema compatible mode',
},
bigIntFormat: {
type: 'string',
enum: ['string', 'number'],
default: 'string',
description: 'Format for BigInt fields in JSON Schema compatible mode',
},
bytesFormat: {
type: 'string',
enum: ['base64String', 'hexString'],
default: 'base64String',
description: 'Format for Bytes fields in JSON Schema compatible mode',
},
conversionOptions: {
type: 'object',
additionalProperties: false,
properties: {
unrepresentable: { type: 'string', enum: ['throw', 'any'], default: 'any' },
cycles: { type: 'string', enum: ['ref', 'throw'], default: 'throw' },
reused: { type: 'string', enum: ['inline', 'ref'], default: 'inline' },
},
description: 'Options forwarded to z.toJSONSchema()',
},
},
additionalProperties: false,
description: 'Options for JSON Schema compatibility mode',
},
addSelectType: {
type: 'boolean',
default: false,
description: 'Legacy option: also generate Select type',
},
addIncludeType: {
type: 'boolean',
default: false,
description: 'Legacy option: also generate Include type',
},
strictCreateInputs: {
type: 'boolean',
default: true,
description: 'When true, Create-like inputs bypass exclusions and strictly match Prisma types',
},
preserveRequiredScalarsOnCreate: {
type: 'boolean',
default: true,
description: 'When strictCreateInputs is false, keep required non-auto scalars in Create-like inputs even if excluded',
},
inferCreateArgsFromSchemas: {
type: 'boolean',
default: false,
description: 'When true, Args for create operations infer types from generated schemas instead of Prisma.*',
},
globalExclusions: {
type: 'object',
additionalProperties: false,
description: 'Global field exclusions applied to all models',
properties: {
input: {
type: 'array',
items: {
type: 'string',
minLength: 1,
pattern: '^[a-zA-Z_][a-zA-Z0-9_]*$',
},
uniqueItems: true,
description: 'Fields to exclude from input schemas globally',
},
result: {
type: 'array',
items: {
type: 'string',
minLength: 1,
pattern: '^[a-zA-Z_][a-zA-Z0-9_]*$',
},
uniqueItems: true,
description: 'Fields to exclude from result schemas globally',
},
pure: {
type: 'array',
items: {
type: 'string',
minLength: 1,
pattern: '^[a-zA-Z_][a-zA-Z0-9_]*$',
},
uniqueItems: true,
description: 'Fields to exclude from pure model schemas globally',
},
operations: {
type: 'array',
items: {
type: 'string',
enum: [
'findMany',
'findUnique',
'findUniqueOrThrow',
'findFirst',
'findFirstOrThrow',
'create',
'createMany',
'createManyAndReturn',
'update',
'updateMany',
'updateManyAndReturn',
'upsert',
'delete',
'deleteMany',
'aggregate',
'groupBy',
'count',
],
},
uniqueItems: true,
minItems: 1,
description: 'Operations to exclude globally from all models',
},
},
},
variants: {
type: 'object',
additionalProperties: false,
description: 'Configuration for different schema variants',
properties: {
pure: {
$ref: '#/definitions/variantConfig',
description: 'Pure model schema variant configuration',
},
input: {
$ref: '#/definitions/variantConfig',
description: 'Input schema variant configuration',
},
result: {
$ref: '#/definitions/variantConfig',
description: 'Result schema variant configuration',
},
},
},
models: {
type: 'object',
additionalProperties: false,
description: 'Per-model configuration options',
patternProperties: {
'^[A-Z][a-zA-Z0-9_]*$': {
$ref: '#/definitions/modelConfig',
description: 'Model-specific configuration (model names must be PascalCase)',
},
},
},
zodImportTarget: {
type: 'string',
enum: ['auto', 'v3', 'v4'],
default: 'auto',
description: "How to import Zod in generated code: 'auto' uses import * as z from 'zod'; 'v3' uses import { z } from 'zod'; 'v4' uses import * as z from 'zod/v4'",
},
validateWhereUniqueAtLeastOne: {
type: 'boolean',
default: false,
description: 'Opt-in: add a minimal Zod superRefine to WhereUniqueInput schemas requiring at least one top-level unique selector to be present. Disabled by default.',
},
strictMode: {
type: 'object',
additionalProperties: false,
description: 'Global strict mode configuration for generated Zod schemas',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Global default for strict mode on all schemas (backward compatibility)',
},
operations: {
type: 'boolean',
default: true,
description: 'Apply strict mode to operation schemas (findMany, create, etc.)',
},
objects: {
type: 'boolean',
default: true,
description: 'Apply strict mode to object schemas (WhereInput, CreateInput, etc.)',
},
variants: {
type: 'boolean',
default: true,
description: 'Apply strict mode to variant schemas (pure, input, result)',
},
enums: {
type: 'boolean',
default: true,
description: 'Apply strict mode to enum schemas',
},
},
},
},
definitions: {
variantConfig: {
type: 'object',
additionalProperties: false,
description: 'Configuration for a specific schema variant',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Whether this variant should be generated',
},
suffix: {
type: 'string',
minLength: 1,
maxLength: 20,
pattern: '^\\.[a-zA-Z][a-zA-Z0-9_]*$',
description: 'File suffix for this variant (must start with a dot, e.g., ".model")',
},
excludeFields: {
type: 'array',
items: {
type: 'string',
minLength: 1,
pattern: '^[a-zA-Z_][a-zA-Z0-9_]*$',
},
uniqueItems: true,
description: 'Fields to exclude from this variant',
},
partial: {
type: 'boolean',
default: false,
description: 'Apply .partial() to the generated schema, making all fields optional',
},
strictMode: {
type: ['boolean', 'null'],
description: 'Override strict mode for this variant (null uses global/parent setting)',
},
},
},
modelConfig: {
type: 'object',
additionalProperties: false,
description: 'Configuration for a specific Prisma model',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Whether schemas should be generated for this model',
},
operations: {
type: 'array',
items: {
type: 'string',
enum: [
'findMany',
'findUnique',
'findUniqueOrThrow',
'findFirst',
'findFirstOrThrow',
'create',
'createMany',
'createManyAndReturn',
'update',
'updateMany',
'updateManyAndReturn',
'upsert',
'delete',
'deleteMany',
'aggregate',
'groupBy',
'count',
],
},
uniqueItems: true,
minItems: 1,
description: 'Which operations to generate schemas for',
},
strictMode: {
type: 'object',
additionalProperties: false,
description: 'Strict mode configuration for this model',
properties: {
enabled: {
type: ['boolean', 'null'],
description: 'Override global strict mode for this model (null uses global setting)',
},
operations: {
oneOf: [
{ type: 'boolean' },
{
type: 'array',
items: {
type: 'string',
enum: [
'findMany',
'findUnique',
'findUniqueOrThrow',
'findFirst',
'findFirstOrThrow',
'create',
'createMany',
'createManyAndReturn',
'update',
'updateMany',
'updateManyAndReturn',
'upsert',
'delete',
'deleteMany',
'aggregate',
'groupBy',
'count',
],
},
uniqueItems: true,
},
{ type: 'null' },
],
description: 'Control strict mode for specific operations (boolean for all, array for specific, null for global)',
},
exclude: {
type: 'array',
items: {
type: 'string',
enum: [
'findMany',
'findUnique',
'findUniqueOrThrow',
'findFirst',
'findFirstOrThrow',
'create',
'createMany',
'createManyAndReturn',
'update',
'updateMany',
'updateManyAndReturn',
'upsert',
'delete',
'deleteMany',
'aggregate',
'groupBy',
'count',
],
},
uniqueItems: true,
description: 'Operations to exclude from strict mode',
},
objects: {
type: ['boolean', 'null'],
description: 'Override strict mode for object schemas of this model (null uses global setting)',
},
variants: {
type: 'object',
additionalProperties: false,
description: 'Per-variant strict mode overrides for this model',
properties: {
pure: {
type: ['boolean', 'null'],
description: 'Override strict mode for pure variant of this model',
},
input: {
type: ['boolean', 'null'],
description: 'Override strict mode for input variant of this model',
},
result: {
type: ['boolean', 'null'],
description: 'Override strict mode for result variant of this model',
},
},
},
},
},
variants: {
type: 'object',
additionalProperties: false,
description: 'Variant-specific configuration for this model',
properties: {
pure: {
$ref: '#/definitions/variantConfig',
description: 'Pure model variant configuration for this model',
},
input: {
$ref: '#/definitions/variantConfig',
description: 'Input variant configuration for this model',
},
result: {
$ref: '#/definitions/variantConfig',
description: 'Result variant configuration for this model',
},
},
},
},
},
},
};
/**
* Schema for validating individual field names
*/
exports.FieldNameSchema = {
type: 'string',
minLength: 1,
maxLength: 64,
pattern: '^[a-zA-Z_][a-zA-Z0-9_]*$',
description: 'Valid field name (alphanumeric with underscores, cannot start with number)',
};
/**
* Schema for validating model names (PascalCase)
*/
exports.ModelNameSchema = {
type: 'string',
minLength: 1,
maxLength: 64,
pattern: '^[A-Z][a-zA-Z0-9_]*$',
description: 'Valid model name (PascalCase, alphanumeric with underscores)',
};
/**
* Schema for validating output directory paths
*/
exports.OutputPathSchema = {
type: 'string',
minLength: 1,
maxLength: 260, // Windows MAX_PATH limitation
pattern: '^[^<>:"|?*\\x00-\\x1f]+$',
description: 'Valid output directory path (no invalid filename characters)',
};
/**
* Schema for validating file suffixes
*/
exports.SuffixSchema = {
type: 'string',
minLength: 2, // At least ".x"
maxLength: 20,
pattern: '^\\.[a-zA-Z][a-zA-Z0-9_]*$',
description: 'Valid file suffix (must start with dot, followed by valid identifier)',
};
/**
* Available Prisma operations that can be configured
*/
exports.PRISMA_OPERATIONS = [
'findMany',
'findUnique',
'findUniqueOrThrow',
'findFirst',
'findFirstOrThrow',
'create',
'createMany',
'createManyAndReturn',
'update',
'updateMany',
'updateManyAndReturn',
'upsert',
'delete',
'deleteMany',
'aggregate',
'groupBy',
'count',
];
/**
* Available generation modes
*/
exports.GENERATION_MODES = ['full', 'minimal', 'custom'];
/**
* Available schema variants
*/
exports.SCHEMA_VARIANTS = ['pure', 'input', 'result'];
/**
* Default configuration values
*/
exports.DEFAULT_CONFIG = {
mode: 'full',
output: './generated',
globalExclusions: {},
variants: {
pure: {
enabled: true,
suffix: '.model',
},
input: {
enabled: true,
suffix: '.input',
},
result: {
enabled: true,
suffix: '.result',
},
},
models: {},
};
/**
* Minimal mode operation set
*/
exports.MINIMAL_OPERATIONS = [
'findMany',
'findUnique',
'findFirst',
'create',
'update',
'delete',
];
/**
* Configuration validation error types
*/
var ValidationErrorType;
(function (ValidationErrorType) {
ValidationErrorType["INVALID_JSON_SCHEMA"] = "INVALID_JSON_SCHEMA";
ValidationErrorType["INVALID_FIELD_NAME"] = "INVALID_FIELD_NAME";
ValidationErrorType["INVALID_MODEL_NAME"] = "INVALID_MODEL_NAME";
ValidationErrorType["INVALID_OPERATION"] = "INVALID_OPERATION";
ValidationErrorType["INVALID_MODE"] = "INVALID_MODE";
ValidationErrorType["INVALID_VARIANT"] = "INVALID_VARIANT";
ValidationErrorType["DUPLICATE_VALUES"] = "DUPLICATE_VALUES";
ValidationErrorType["MISSING_REQUIRED"] = "MISSING_REQUIRED";
})(ValidationErrorType || (exports.ValidationErrorType = ValidationErrorType = {}));
/**
* Utility function to validate field names
*/
function isValidFieldName(fieldName) {
return (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(fieldName) && fieldName.length > 0 && fieldName.length <= 64);
}
/**
* Utility function to validate model names (PascalCase)
*/
function isValidModelName(modelName) {
return /^[A-Z][a-zA-Z0-9_]*$/.test(modelName) && modelName.length > 0 && modelName.length <= 64;
}
/**
* Utility function to validate Prisma operations
*/
function isValidOperation(operation) {
return exports.PRISMA_OPERATIONS.includes(operation);
}
/**
* Utility function to validate generation modes
*/
function isValidMode(mode) {
return exports.GENERATION_MODES.includes(mode);
}
/**
* Utility function to validate schema variants
*/
function isValidVariant(variant) {
return exports.SCHEMA_VARIANTS.includes(variant);
}
/**
* Utility function to validate file suffixes
*/
function isValidSuffix(suffix) {
return /^\.[a-zA-Z][a-zA-Z0-9_]*$/.test(suffix) && suffix.length >= 2 && suffix.length <= 20;
}
/**
* Get schema reference for a specific configuration section
*/
function getSchemaSection(section) {
var _a;
return (_a = exports.ConfigurationSchema.definitions) === null || _a === void 0 ? void 0 : _a[section];
}
/**
* Create a custom schema for validating specific parts of the configuration
*/
function createPartialSchema(properties) {
const baseSchema = { ...exports.ConfigurationSchema };
const filteredProperties = {};
properties.forEach((prop) => {
var _a;
if ((_a = baseSchema.properties) === null || _a === void 0 ? void 0 : _a[prop]) {
const propSchema = baseSchema.properties[prop];
if (typeof propSchema === 'object') {
filteredProperties[prop] = propSchema;
}
}
});
return {
...baseSchema,
properties: filteredProperties,
required: properties.filter((prop) => { var _a; return (_a = baseSchema.required) === null || _a === void 0 ? void 0 : _a.includes(prop); }),
};
}
//# sourceMappingURL=schema.js.map