prisma-zod-generator
Version:
Prisma 2+ generator to emit Zod schemas from your Prisma schema
417 lines (404 loc) • 14.9 kB
JavaScript
;
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