@aradox/multi-orm
Version:
Type-safe ORM with multi-datasource support, row-level security, and Prisma-like API for PostgreSQL, SQL Server, and HTTP APIs
146 lines • 5.08 kB
JavaScript
;
/**
* Parser Error Handling Module
*
* Provides structured error reporting with source locations (file, line, column)
* and optional suggestions for fixes.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParserErrorCollection = exports.DSLParserError = void 0;
exports.createParserError = createParserError;
exports.calculateColumn = calculateColumn;
exports.findTokenColumn = findTokenColumn;
/**
* Custom error class for parser errors with source locations
*/
class DSLParserError extends Error {
location;
severity;
suggestion;
code;
constructor(message, location, options) {
// Format message with location
const locationStr = `${location.file}:${location.line}:${location.column}`;
super(`${locationStr} - ${message}`);
this.name = 'DSLParserError';
this.location = location;
this.severity = options?.severity || 'error';
this.suggestion = options?.suggestion;
this.code = options?.code;
// Maintains proper stack trace for where error was thrown
if (Error.captureStackTrace) {
Error.captureStackTrace(this, DSLParserError);
}
}
/**
* Format error for display with source context
*/
format(sourceLines) {
const parts = [];
// Header: file:line:col - message
parts.push(`❌ ${this.location.file}:${this.location.line}:${this.location.column} - ${this.message}`);
// Show source line with error indicator
if (sourceLines && this.location.line <= sourceLines.length) {
const line = sourceLines[this.location.line - 1];
parts.push(` ${line}`);
// Add caret pointing to error location
const spaces = ' '.repeat(this.location.column + 2); // +2 for " " prefix
const carets = '^'.repeat(this.location.length || 1);
parts.push(`${spaces}${carets}`);
}
// Add suggestion if available
if (this.suggestion) {
parts.push(` 💡 Suggestion: ${this.suggestion}`);
}
// Add error code if available
if (this.code) {
parts.push(` Code: ${this.code}`);
}
return parts.join('\n');
}
/**
* Convert to JSON for structured error reporting
*/
toJSON() {
return {
message: this.message,
location: this.location,
severity: this.severity,
suggestion: this.suggestion,
code: this.code
};
}
}
exports.DSLParserError = DSLParserError;
/**
* Collection of parser errors that can accumulate multiple issues
*/
class ParserErrorCollection extends Error {
errors;
constructor(errors) {
const errorCount = errors.filter(e => e.severity === 'error').length;
const warningCount = errors.filter(e => e.severity === 'warning').length;
super(`Parser found ${errorCount} error(s) and ${warningCount} warning(s)`);
this.name = 'ParserErrorCollection';
this.errors = errors;
}
/**
* Format all errors for display
*/
format(sourceLines) {
const parts = [];
// Group by severity
const errors = this.errors.filter(e => e.severity === 'error');
const warnings = this.errors.filter(e => e.severity === 'warning');
if (errors.length > 0) {
parts.push(`\n❌ Found ${errors.length} error(s):\n`);
errors.forEach(err => {
parts.push(err.format(sourceLines));
parts.push(''); // Empty line between errors
});
}
if (warnings.length > 0) {
parts.push(`\n⚠️ Found ${warnings.length} warning(s):\n`);
warnings.forEach(warn => {
parts.push(warn.format(sourceLines));
parts.push('');
});
}
return parts.join('\n');
}
/**
* Check if collection contains any errors (not just warnings)
*/
hasErrors() {
return this.errors.some(e => e.severity === 'error');
}
/**
* Convert to JSON for structured error reporting
*/
toJSON() {
return this.errors.map(e => e.toJSON());
}
}
exports.ParserErrorCollection = ParserErrorCollection;
/**
* Helper function to create a parser error
*/
function createParserError(message, location, options) {
return new DSLParserError(message, location, options);
}
/**
* Helper to calculate column position in original source
* Handles trimmed lines by finding the first non-whitespace character
*/
function calculateColumn(originalLine, trimmedLine) {
const leadingWhitespace = originalLine.indexOf(trimmedLine);
return leadingWhitespace >= 0 ? leadingWhitespace + 1 : 1; // 1-indexed
}
/**
* Helper to find token position within a line
*/
function findTokenColumn(line, token, startOffset = 0) {
const index = line.indexOf(token, startOffset);
return index >= 0 ? index + 1 : 1; // 1-indexed
}
//# sourceMappingURL=errors.js.map