UNPKG

prisma-zod-generator

Version:

Prisma 2+ generator to emit Zod schemas from your Prisma schema

417 lines (404 loc) 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigurationErrorHandler = exports.ConfigurationWarning = exports.IntegrationError = exports.ModelReferenceError = exports.ConfigValidationError = exports.ConfigParsingError = exports.ConfigFilePermissionError = exports.ConfigFileNotFoundError = exports.ConfigurationErrorCategory = exports.ConfigurationError = void 0; exports.createErrorHandler = createErrorHandler; exports.isConfigurationError = isConfigurationError; exports.getErrorCode = getErrorCode; exports.getErrorCategory = getErrorCategory; /** * Base class for all configuration-related errors */ class ConfigurationError extends Error { constructor(message, cause, context = {}) { super(message); this.cause = cause; this.name = this.constructor.name; this.timestamp = new Date(); this.context = context; // Ensure the error stack trace points to the actual error location if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } /** * Convert error to structured format for logging/debugging */ toStructured() { return { name: this.name, errorCode: this.errorCode, category: this.category, message: this.message, timestamp: this.timestamp.toISOString(), context: this.context, cause: this.cause ? { name: this.cause.name, message: this.cause.message, stack: this.cause.stack, } : undefined, stack: this.stack, }; } } exports.ConfigurationError = ConfigurationError; /** * Configuration error categories */ var ConfigurationErrorCategory; (function (ConfigurationErrorCategory) { ConfigurationErrorCategory["FILE_SYSTEM"] = "FILE_SYSTEM"; ConfigurationErrorCategory["PARSING"] = "PARSING"; ConfigurationErrorCategory["VALIDATION"] = "VALIDATION"; ConfigurationErrorCategory["BUSINESS_LOGIC"] = "BUSINESS_LOGIC"; ConfigurationErrorCategory["INTEGRATION"] = "INTEGRATION"; })(ConfigurationErrorCategory || (exports.ConfigurationErrorCategory = ConfigurationErrorCategory = {})); /** * Configuration file not found error */ class ConfigFileNotFoundError extends ConfigurationError { constructor(filePath, cause) { super(`Configuration file not found: ${filePath}`, cause, { filePath }); this.errorCode = 'CONFIG_FILE_NOT_FOUND'; this.category = ConfigurationErrorCategory.FILE_SYSTEM; } getUserFriendlyMessage() { const filePath = this.context.filePath; return `Configuration file not found: ${filePath} Troubleshooting steps: 1. Check if the file path is correct: ${filePath} 2. Verify the file exists and is readable 3. Ensure the file has proper permissions 4. If using a relative path, check your current working directory Alternative solutions: - Create a new configuration file at: ${filePath} - Use auto-discovery by creating: zod-generator.config.json - Remove the config option to use default settings`; } } exports.ConfigFileNotFoundError = ConfigFileNotFoundError; /** * Configuration file permission error */ class ConfigFilePermissionError extends ConfigurationError { constructor(filePath, operation, cause) { super(`Permission denied accessing configuration file: ${filePath}`, cause, { filePath, operation, }); this.errorCode = 'CONFIG_FILE_PERMISSION_DENIED'; this.category = ConfigurationErrorCategory.FILE_SYSTEM; } getUserFriendlyMessage() { const filePath = this.context.filePath; const operation = this.context.operation; return `Permission denied ${operation} configuration file: ${filePath} Troubleshooting steps: 1. Check file permissions: ls -la "${filePath}" 2. Ensure you have read access to the file 3. Verify the directory permissions 4. Try running with appropriate permissions Fix suggestions: - Change file permissions: chmod 644 "${filePath}" - Check directory permissions: chmod 755 "$(dirname "${filePath}")" - Run as a user with appropriate access`; } } exports.ConfigFilePermissionError = ConfigFilePermissionError; /** * Configuration parsing error (JSON syntax, etc.) */ class ConfigParsingError extends ConfigurationError { constructor(filePath, parseError, line, column, cause) { super(`Failed to parse configuration file: ${filePath}`, cause, { filePath, parseError, line, column, }); this.errorCode = 'CONFIG_PARSING_FAILED'; this.category = ConfigurationErrorCategory.PARSING; } getUserFriendlyMessage() { const filePath = this.context.filePath; const parseError = this.context.parseError; const line = this.context.line; const column = this.context.column; let message = `Failed to parse configuration file: ${filePath} Parse error: ${parseError}`; if (line !== undefined && column !== undefined) { message += ` Location: Line ${line}, Column ${column}`; } message += ` Troubleshooting steps: 1. Validate JSON syntax using a JSON validator 2. Check for common JSON errors: - Missing quotes around strings - Trailing commas - Unmatched brackets or braces - Invalid escape sequences Common fixes: - Use double quotes (") not single quotes (') - Remove trailing commas in arrays and objects - Ensure proper nesting of brackets and braces - Escape special characters in strings`; return message; } } exports.ConfigParsingError = ConfigParsingError; /** * Configuration validation error (schema violations) */ class ConfigValidationError extends ConfigurationError { constructor(validationErrors, filePath) { const errorCount = validationErrors.length; super(`Configuration validation failed with ${errorCount} error(s)`, undefined, { validationErrors, filePath, errorCount, }); this.errorCode = 'CONFIG_VALIDATION_FAILED'; this.category = ConfigurationErrorCategory.VALIDATION; } getUserFriendlyMessage() { const validationErrors = this.context.validationErrors; const filePath = this.context.filePath; let message = `Configuration validation failed`; if (filePath) { message += ` in file: ${filePath}`; } message += `\n\nValidation errors (${validationErrors.length}):\n`; validationErrors.forEach((error, index) => { message += `\n${index + 1}. ${error.message}`; message += `\n Path: ${error.path}`; if (error.value !== undefined) { message += `\n Current value: ${JSON.stringify(error.value)}`; } if (error.allowedValues && error.allowedValues.length > 0) { message += `\n Allowed values: ${error.allowedValues.join(', ')}`; } message += '\n'; }); message += `\nTroubleshooting: 1. Review each validation error above 2. Check the configuration schema documentation 3. Verify property names and values match requirements 4. Ensure required properties are present Common fixes: - Use correct property names (case-sensitive) - Check data types (string, boolean, array, object) - Verify enum values are from allowed list - Remove unknown/additional properties`; return message; } } exports.ConfigValidationError = ConfigValidationError; /** * Model reference error (model not found in Prisma schema) */ class ModelReferenceError extends ConfigurationError { constructor(modelName, availableModels, configPath) { super(`Model "${modelName}" not found in Prisma schema`, undefined, { modelName, availableModels, configPath, }); this.errorCode = 'MODEL_REFERENCE_INVALID'; this.category = ConfigurationErrorCategory.BUSINESS_LOGIC; } getUserFriendlyMessage() { const modelName = this.context.modelName; const availableModels = this.context.availableModels; const configPath = this.context.configPath; let message = `Model reference error: "${modelName}" not found in Prisma schema`; if (configPath) { message += `\nConfiguration path: ${configPath}`; } message += `\nAvailable models: ${availableModels.join(', ')} Troubleshooting: 1. Check if the model name matches exactly (case-sensitive) 2. Verify the model exists in your Prisma schema 3. Ensure Prisma schema is up to date 4. Check for typos in the model name Fix suggestions: - Update model name to match Prisma schema - Run "prisma generate" to ensure schema is current - Remove invalid model configuration - Use one of the available models: ${availableModels.slice(0, 3).join(', ')}${availableModels.length > 3 ? '...' : ''}`; return message; } } exports.ModelReferenceError = ModelReferenceError; /** * Integration error (Prisma schema issues, dependency problems) */ class IntegrationError extends ConfigurationError { constructor(component, issue, cause) { super(`Integration error with ${component}: ${issue}`, cause, { component, issue }); this.errorCode = 'INTEGRATION_FAILED'; this.category = ConfigurationErrorCategory.INTEGRATION; } getUserFriendlyMessage() { const component = this.context.component; const issue = this.context.issue; return `Integration error with ${component}: ${issue} This error typically indicates a problem with external dependencies or configuration. Troubleshooting steps: 1. Verify ${component} is properly installed and configured 2. Check for version compatibility issues 3. Ensure all required dependencies are available 4. Review configuration for ${component} integration Common solutions: - Update dependencies to compatible versions - Check ${component} documentation for configuration requirements - Verify environment setup and configuration files - Review integration settings in your configuration`; } } exports.IntegrationError = IntegrationError; /** * Configuration warning (non-critical issues) */ class ConfigurationWarning { constructor(message, path, context = {}) { this.message = message; this.path = path; this.context = context; this.timestamp = new Date(); } toString() { let message = `Warning: ${this.message}`; if (this.path) { message += ` (at ${this.path})`; } return message; } getUserFriendlyMessage() { let message = `⚠️ ${this.message}`; if (this.path) { message += `\n Location: ${this.path}`; } message += '\n This is a warning and will not prevent the generator from running.'; return message; } } exports.ConfigurationWarning = ConfigurationWarning; /** * Error handler utility class */ class ConfigurationErrorHandler { constructor(context = {}) { this.context = context; } /** * Handle file system errors */ handleFileSystemError(error, filePath, operation) { const nodeError = error; switch (nodeError.code) { case 'ENOENT': throw new ConfigFileNotFoundError(filePath, nodeError); case 'EACCES': case 'EPERM': throw new ConfigFilePermissionError(filePath, operation, nodeError); default: throw new IntegrationError('file system', `Failed to ${operation} file: ${nodeError.message}`, nodeError); } } /** * Handle parsing errors */ handleParsingError(error, filePath) { if (error instanceof SyntaxError) { // Try to extract line/column information from JSON syntax error const match = error.message.match(/at position (\d+)|line (\d+)|column (\d+)/i); const position = match ? parseInt(match[1] || match[2] || match[3], 10) : undefined; throw new ConfigParsingError(filePath, error.message, position, undefined, error); } throw new IntegrationError('parser', `Unexpected parsing error: ${error.message}`, error); } /** * Handle validation errors */ handleValidationError(validationErrors, filePath) { throw new ConfigValidationError(validationErrors, filePath); } /** * Handle model reference errors */ handleModelReferenceError(modelName, availableModels, configPath) { throw new ModelReferenceError(modelName, availableModels, configPath); } /** * Create warning */ createWarning(message, path, context) { return new ConfigurationWarning(message, path, { ...this.context, ...context }); } /** * Format multiple errors for display */ formatErrors(errors) { if (errors.length === 0) { return 'No errors to display'; } if (errors.length === 1) { return errors[0].getUserFriendlyMessage(); } let message = `Multiple configuration errors (${errors.length}):\n\n`; errors.forEach((error, index) => { message += `${index + 1}. ${error.errorCode}: ${error.message}\n`; message += ` Category: ${error.category}\n`; message += ` Time: ${error.timestamp.toISOString()}\n\n`; }); message += '\nTo see detailed information for each error, resolve them one at a time.'; return message; } /** * Format multiple warnings for display */ formatWarnings(warnings) { if (warnings.length === 0) { return ''; } let message = `Configuration warnings (${warnings.length}):\n\n`; warnings.forEach((warning, index) => { message += `${index + 1}. ${warning.getUserFriendlyMessage()}\n\n`; }); return message.trim(); } } exports.ConfigurationErrorHandler = ConfigurationErrorHandler; /** * Create error handler with context */ function createErrorHandler(context = {}) { return new ConfigurationErrorHandler(context); } /** * Check if error is a configuration error */ function isConfigurationError(error) { return error instanceof ConfigurationError; } /** * Extract error code from configuration error */ function getErrorCode(error) { if (isConfigurationError(error)) { return error.errorCode; } return undefined; } /** * Extract error category from configuration error */ function getErrorCategory(error) { if (isConfigurationError(error)) { return error.category; } return undefined; } //# sourceMappingURL=errors.js.map