import type { ConnectorType, DMMF as PrismaDMMF } from '@prisma/generator-helper'; import type { GeneratorConfig as ZodGeneratorConfig } from './config/parser'; import { type EnhancedModelInfo } from './helpers/zod-integration'; import type { CustomImport } from './parsers/zod-comments'; import { SchemaEnumWithValues, TransformerParams } from './types'; import type { GeneratedManifest } from './utils/safeOutputManagement'; import { type StrictModeResolver } from './utils/strict-mode-resolver'; /** * Filter validation result interface */ interface FilterValidationResult { isValid: boolean; errors: string[]; warnings: string[]; suggestions: string[]; } export default class Transformer { name: string; fields: PrismaDMMF.SchemaArg[]; schemaImports: Set; models: PrismaDMMF.Model[]; modelOperations: PrismaDMMF.ModelMapping[]; enumTypes: SchemaEnumWithValues[]; enhancedModels: EnhancedModelInfo[]; static enumNames: string[]; static rawOpsMap: { [name: string]: string; }; static provider: ConnectorType; static previewFeatures: string[] | undefined; private static outputPath; private hasJson; private hasDecimal; private static prismaClientOutputPath; private static isCustomPrismaClientOutputPath; private static prismaClientProvider; private static prismaClientConfig; private static isGenerateSelect; private static isGenerateInclude; private static generatorConfig; private static strictModeResolver; private static usedSchemaFilePaths; private static isJsonSchemaModeEnabled; private static getJsonSchemaOptions; private static exportTypedSchemas; private static exportZodSchemas; private static typedSchemaSuffix; private static zodSchemaSuffix; private lastExcludedFieldNames; private static jsonHelpersWritten; private static decimalHelpersWritten; private static currentManifest; constructor(params: TransformerParams); static setOutputPath(outPath: string): void; static setIsGenerateSelect(isGenerateSelect: boolean): void; static setIsGenerateInclude(isGenerateInclude: boolean): void; static setGeneratorConfig(config: ZodGeneratorConfig): void; static getGeneratorConfig(): ZodGeneratorConfig | null; static getStrictModeResolver(): StrictModeResolver | null; private static escapeRegExp; /** * Check if a model should be generated based on configuration */ static isModelEnabled(modelName: string): boolean; /** * Get list of enabled models for generation */ static getEnabledModels(allModels: PrismaDMMF.Model[]): PrismaDMMF.Model[]; /** * Log information about model filtering */ static logModelFiltering(allModels: PrismaDMMF.Model[]): void; /** * Check if a specific operation should be generated for a model */ static isOperationEnabled(modelName: string, operationName: string): boolean; /** * Get list of enabled operations for a model */ static getEnabledOperations(modelName: string, allOperations: string[]): string[]; /** * Log information about operation filtering for a model */ static logOperationFiltering(modelName: string, allOperations: string[]): void; /** * Check if a field should be included in schema generation */ static isFieldEnabled(fieldName: string, modelName?: string, variant?: 'pure' | 'input' | 'result'): boolean; /** * Check if a field name matches any pattern in the exclusion list * Supports wildcards: *field, field*, *field* */ static isFieldMatchingPatterns(fieldName: string, patterns: string[]): boolean; /** * Filter fields based on configuration and relationship preservation */ static filterFields(fields: PrismaDMMF.SchemaArg[], modelName?: string, variant?: 'pure' | 'input' | 'result', models?: PrismaDMMF.Model[], schemaName?: string): PrismaDMMF.SchemaArg[]; /** * Get excluded relation fields by comparing original and filtered fields */ static getExcludedRelationFields(originalFields: PrismaDMMF.SchemaArg[], filteredFields: PrismaDMMF.SchemaArg[], model: PrismaDMMF.Model): PrismaDMMF.Field[]; /** * Get foreign key schema args for excluded relation fields */ static getForeignKeyFieldsForExcludedRelations(excludedRelationFields: PrismaDMMF.Field[], model: PrismaDMMF.Model): PrismaDMMF.SchemaArg[]; /** * Check if a schema arg represents a relation field */ static isRelationFieldArg(field: PrismaDMMF.SchemaArg): boolean; /** * Extract related model name from field arg */ static extractRelatedModelFromFieldArg(field: PrismaDMMF.SchemaArg): string | null; /** * Extract model name from object schema context */ static extractModelNameFromContext(schemaName: string): string | null; /** * Determine schema variant from context */ static determineSchemaVariant(schemaName: string): 'pure' | 'input' | 'result'; /** * Log information about field filtering */ static logFieldFiltering(originalCount: number, filteredCount: number, modelName?: string, variant?: string): void; /** * Check if a model has relationships to other ENABLED models * This is a filtered version of checkModelHasModelRelation that only considers enabled models */ static checkModelHasEnabledModelRelation(model: PrismaDMMF.Model): boolean; /** * Check if a relation field points to an enabled model */ static isEnabledRelationField(modelField: PrismaDMMF.Field): boolean; /** * Filter relation fields to only include those pointing to enabled models */ static filterRelationFields(fields: PrismaDMMF.Field[]): PrismaDMMF.Field[]; /** * Get list of enabled related models for a given model */ static getEnabledRelatedModels(model: PrismaDMMF.Model): string[]; /** * Check if a model should have include schemas generated * Only if it has relationships to other enabled models */ static shouldGenerateIncludeSchema(model: PrismaDMMF.Model): boolean; /** * Check if a model should have select schemas generated */ static shouldGenerateSelectSchema(_model: PrismaDMMF.Model): boolean; /** * Log relationship preservation information */ static logRelationshipPreservation(model: PrismaDMMF.Model): void; static setExportTypedSchemas(exportTypedSchemas: boolean): void; static setExportZodSchemas(exportZodSchemas: boolean): void; static setTypedSchemaSuffix(typedSchemaSuffix: string): void; static setZodSchemaSuffix(zodSchemaSuffix: string): void; /** * Generate the correct object schema name based on export settings */ static getObjectSchemaName(baseName: string): string; static getOutputPath(): string; static setCurrentManifest(manifest: GeneratedManifest | null): void; static getCurrentManifest(): GeneratedManifest | null; static setPrismaClientOutputPath(prismaClientCustomPath: string): void; /** * Resolve the import specifier for Prisma Client relative to a target directory. * Falls back to '@prisma/client' when user did not configure a custom output. */ static resolvePrismaImportPath(targetDir: string): string; static setPrismaClientProvider(provider: string): void; static setPrismaClientConfig(config: Record): void; static getPrismaClientProvider(): string; static getPrismaClientConfig(): Record; /** * Determines the schemas directory path based on the output path. * If the output path already ends with 'schemas', use it directly. * Otherwise, append 'schemas' to the output path. */ static getSchemasPath(): string; static generateIndex(): Promise; generateEnumSchemas(): Promise; /** * Check if an enum schema should be generated based on enabled models */ private isEnumSchemaEnabled; /** * Shared regex patterns for model-specific enum detection */ private static readonly modelEnumPatterns; /** * Extract model name from enum name */ private extractModelNameFromEnum; /** * Normalize enum names to match import expectations * For model-related enums, use Pascal case model names consistently */ private normalizeEnumName; /** * Convert model names to DMMF aggregate input names * For doc_parser_agent model: matches Prisma's DMMF format Doc_parser_agentCountAggregateInput */ private getAggregateInputName; /** * Get the correct Prisma type name for model types * Prisma uses the original model name as-is (e.g., doc_parser_agent -> Prisma.doc_parser_agentSelect) */ private getPrismaTypeName; /** * Check if a model has numeric fields that support avg/sum operations */ private modelHasNumericFields; generateImportZodStatement(): "import * as z from 'zod';\n" | "import * as z from 'zod/v4';\n" | "import { z } from 'zod/v3';\n"; /** * Generate custom import statements from @zod.import() annotations * * @param customImports - Array of custom import objects * @param outputPath - Current output path for relative import adjustment * @returns Generated import statements string */ generateCustomImportStatements(customImports: CustomImport[] | undefined, outputPath?: string): string; /** * Get custom imports for a specific schema context * This method is called AFTER the schema content is generated to determine which imports are actually needed * * @param modelName - Name of the model * @param schemaContent - The generated schema content to analyze for import usage * @returns Array of custom imports needed for this specific schema */ getCustomImportsForModel(modelName: string | null, schemaContent?: string): CustomImport[]; /** * Check if a field actually contains custom validation logic */ private fieldContainsCustomValidation; /** * Get custom schema for a specific field * * @param fieldName - Name of the field * @returns Custom schema string or null if not found */ getCustomSchemaForField(fieldName: string): string | null; /** * Adjust relative import paths based on output directory structure * * @param importStatement - Original import statement * @param outputPath - Current output path * @returns Adjusted import statement */ private adjustRelativeImportPath; generateExportSchemaStatement(name: string, schema: string): string; generateObjectSchema(): Promise; generateObjectSchemaFields(): string[]; generateObjectSchemaField(field: PrismaDMMF.SchemaArg): [string, PrismaDMMF.SchemaArg, boolean][]; wrapWithZodValidators(mainValidator: string, field: PrismaDMMF.SchemaArg, inputType: PrismaDMMF.SchemaArg['inputTypes'][0], skipZodAnnotations?: boolean): string; addSchemaImport(name: string): void; /** * Check if a schema import should be included based on minimal mode configuration */ private isSchemaImportEnabled; /** * Extract model name from schema name for import filtering */ private extractModelNameFromSchema; /** * Extract max length constraint from native type (e.g., @db.VarChar(255) -> 255) */ private extractMaxLengthFromNativeType; /** * Extract existing max constraint from @zod validations */ private extractExistingMaxConstraint; /** * Replace all max constraints in a validation string with a single constraint */ private replaceAllMaxConstraints; /** * Extract @zod validations for a specific field using the enhanced model information */ private extractZodValidationsForField; generatePrismaStringLine(field: PrismaDMMF.SchemaArg, inputType: PrismaDMMF.SchemaArg['inputTypes'][0], inputsLength: number): string; generateFieldValidators(zodStringWithMainType: string, field: PrismaDMMF.SchemaArg): string; prepareObjectSchema(zodObjectSchemaFields: string[]): string; generateExportObjectSchemaStatement(schema: string): string; /** * Emit a manual TS type and a `satisfies z.ZodType<...>` check for Zod-only, self-recursive schemas. * This avoids TS7022 and keeps output variable types unchanged. */ private generateZodOnlySanityCheck; /** * Resolve the appropriate Prisma type identifier for an object schema export. * In Prisma 6, certain aggregate input types are exported with a `Type` suffix. * Example: Prisma.PlanetCountAggregateInputType instead of Prisma.PlanetCountAggregateInput */ private resolvePrismaTypeForObject; addFinalWrappers({ zodStringFields }: { zodStringFields: string[]; }): string; generateJsonSchemaImplementation(): string; private static ensureJsonHelpersFile; private static ensureDecimalHelpersFile; generateObjectSchemaImportStatements(customImports?: CustomImport[]): string; /** * Get the file extension to use for imports based on Prisma client configuration * For ESM with importFileExtension = "js", we need to add .js extension */ private getImportFileExtension; /** * Convert model name to PascalCase for consistent file naming */ private getPascalCaseModelName; /** * Resolve an input object import honoring naming.input patterns, aliasing to stable identifiers. */ private generateInputImport; /** * Generate enum import honoring naming.enum patterns, aliasing to stable identifiers. */ private generateEnumImport; /** * Generate input import for object schemas honoring naming.input patterns. * Similar to generateInputImport but for object-to-object imports using './' prefix. */ private generateObjectInputImport; /** * Generate schema file name with collision detection and custom naming support */ private static generateSchemaFileName; /** * Check for and handle file path collisions */ private static checkSchemaFileCollision; /** * Generate schema file with collision detection and consistent naming */ private static writeSchemaFile; /** * Clear collision detection state (called at start of generation) */ static clearSchemaFileCollisions(): void; /** * Generate import statement with validation - only if target will be generated */ static generateValidatedImportStatement(importName: string, importPath: string, modelName?: string): string; /** * Check if an import should be generated based on filtering rules */ static shouldGenerateImport(importName: string, relatedModelName?: string): boolean; /** * Extract model name from import name */ static extractModelFromImportName(importName: string): string | null; /** * Get import file extension (static version) */ static getImportFileExtension(): string; generateSchemaImports(): string; checkIsModelQueryType(type: string): { isModelQueryType: boolean; modelName: string; queryName: string; } | { isModelQueryType: boolean; modelName?: undefined; queryName?: undefined; }; resolveModelQuerySchemaName(modelName: string, queryName: string): string; wrapWithZodObject(zodStringFields: string | string[]): string; resolveObjectSchemaName(): string; generateModelSchemas(): Promise; /** * Generate result schemas for all enabled models */ generateResultSchemas(): Promise; generateImportStatements(imports: (string | undefined)[]): string; /** * Clean and validate import array, removing empty and invalid imports */ static cleanAndValidateImports(imports: (string | undefined)[]): string[]; /** * Parse import statement to extract information */ static parseImportStatement(importStatement: string): { importName: string; importPath: string; relatedModel?: string; } | null; /** * Generate smart import statement that checks if target exists */ generateSmartImportStatement(importName: string, importPath: string, relatedModel?: string): string; /** * Log import management information */ static logImportManagement(originalImports: (string | undefined)[], cleanedImports: string[], context?: string): void; /** * Validate filter combinations and detect conflicts */ static validateFilterCombinations(allModels: PrismaDMMF.Model[]): FilterValidationResult; /** * Validate model dependencies and relationships */ static validateModelDependencies(allModels: PrismaDMMF.Model[], result: FilterValidationResult): void; /** * Validate operation consistency across models */ static validateOperationConsistency(allModels: PrismaDMMF.Model[], result: FilterValidationResult): void; /** * Validate field exclusion conflicts */ static validateFieldExclusions(allModels: PrismaDMMF.Model[], result: FilterValidationResult): void; /** * Validate variant consistency */ static validateVariantConsistency(result: FilterValidationResult): void; /** * Validate mode consistency */ static validateModeConsistency(result: FilterValidationResult): void; /** * Log filter validation results */ static logFilterValidation(validationResult: FilterValidationResult): void; /** * Perform comprehensive filter validation */ static performFilterValidation(allModels: PrismaDMMF.Model[]): boolean; resolveSelectIncludeImportAndZodSchemaLine(model: PrismaDMMF.Model): { selectImport: string; includeImport: string; selectZodSchemaLine: string; includeZodSchemaLine: string; selectZodSchemaLineLazy: string; includeZodSchemaLineLazy: string; selectValueExpr: string; includeValueExpr: string; }; private resolveIncludeFieldReference; resolveOrderByWithRelationImportAndZodSchemaLine(model: PrismaDMMF.Model): { orderByImport: string; orderByZodSchemaLine: string; }; /** * Determines if a select schema should be inlined to avoid circular dependencies. * Following community generator approach: ALWAYS inline select schemas. * Use lazy loading only for specific relation fields within the inlined schema. */ shouldInlineSelectSchema(_model: PrismaDMMF.Model): boolean; /** * Generates inline select schema definition code within the FindMany file. * This prevents circular imports by defining the schema locally. * Follows community generator pattern with aggressive inlining. */ generateInlineSelectSchema(model: PrismaDMMF.Model): string; /** * Generates the additional imports needed for inlined select schemas. * Returns import statements for Args schemas referenced in relation fields. */ generateInlineSelectImports(_model: PrismaDMMF.Model): string[]; /** * Generates dual schema exports: typed version and Zod-method-friendly version */ generateDualSchemaExports(modelName: string, operationType: string, schemaDefinition: string, prismaType: string): string; /** * Generates dual select schema exports for inlined schemas */ generateDualSelectSchemaExports(model: PrismaDMMF.Model, operation?: 'FindFirst' | 'FindFirstOrThrow' | 'FindMany' | 'FindUnique' | 'FindUniqueOrThrow'): string; /** * Generates just the schema definition without export statement */ generateInlineSelectSchemaDefinition(model: PrismaDMMF.Model): string; } export {};