Spaces:
Running
Running
File size: 4,384 Bytes
473668f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import type { PreviewError } from "@/types/preview-error";
// Sanitize error messages to prevent prompt injection
function sanitizeErrorMessage(message: string): string {
return message
.replace(/[<>]/g, "") // Remove potential HTML tags
.replace(/```/g, "'''") // Escape code blocks
.slice(0, 500); // Limit length
}
export function formatErrorsForAI(
errors: PreviewError[],
html: string
): string {
if (!errors || errors.length === 0) return "";
// Validate errors array
const validErrors = errors.filter((e) => e && typeof e.message === "string");
if (validErrors.length === 0) return "";
// Group errors by type for better organization
const errorGroups = validErrors.reduce((acc, error) => {
const type = error.errorType || error.type;
if (!acc[type]) acc[type] = [];
acc[type].push(error);
return acc;
}, {} as Record<string, PreviewError[]>);
let formattedErrors =
"The following errors were detected in the preview:\n\n";
// Format each error group
Object.entries(errorGroups).forEach(([type, groupErrors]) => {
formattedErrors += `### ${type} (${groupErrors.length} error${
groupErrors.length > 1 ? "s" : ""
})\n\n`;
groupErrors.forEach((error, index) => {
const sanitizedMessage = sanitizeErrorMessage(error.message);
formattedErrors += `${index + 1}. **${sanitizedMessage}**\n`;
if (error.lineNumber) {
formattedErrors += ` - Line: ${error.lineNumber}`;
if (error.columnNumber) {
formattedErrors += `, Column: ${error.columnNumber}`;
}
formattedErrors += "\n";
}
if (error.fileName && error.fileName !== "undefined") {
formattedErrors += ` - File: ${error.fileName}\n`;
}
// For resource errors, include the problematic resource
if (error.type === "resource-error" && error.src) {
formattedErrors += ` - Resource: ${error.src}\n`;
formattedErrors += ` - Tag: <${error.tagName?.toLowerCase()}>\n`;
}
// Include relevant code snippet if we have line numbers
if (error.lineNumber && html) {
const lines = html.split("\n");
const startLine = Math.max(0, error.lineNumber - 3);
const endLine = Math.min(lines.length, error.lineNumber + 2);
if (lines[error.lineNumber - 1]) {
formattedErrors += " - Code context:\n";
formattedErrors += " ```html\n";
for (let i = startLine; i < endLine; i++) {
const marker = i === error.lineNumber - 1 ? ">" : " ";
formattedErrors += ` ${marker} ${i + 1}: ${lines[i]}\n`;
}
formattedErrors += " ```\n";
}
}
formattedErrors += "\n";
});
});
return formattedErrors;
}
export function createErrorFixPrompt(
errors: PreviewError[],
html: string
): string {
const formattedErrors = formatErrorsForAI(errors, html);
return `${formattedErrors}
Please fix these errors in the HTML code. Focus on:
1. Fixing JavaScript syntax errors
2. Resolving undefined variables or functions
3. Fixing broken resource links (404s)
4. Ensuring all referenced libraries are properly loaded
5. Fixing any HTML structure issues
Make the minimum necessary changes to fix the errors while preserving the intended functionality.`;
}
// Check if errors are likely fixable by AI
export function areErrorsFixable(errors: PreviewError[]): boolean {
if (!errors || errors.length === 0) return false;
// Filter out errors that are likely not fixable
const fixableErrors = errors.filter((error) => {
// Skip errors from external resources
if (
error.fileName &&
(error.fileName.includes("http://") ||
error.fileName.includes("https://"))
) {
return false;
}
// Skip certain console errors that might be intentional
if (
error.type === "console-error" &&
error.message.includes("Development mode")
) {
return false;
}
return true;
});
return fixableErrors.length > 0;
}
// Deduplicate similar errors
export function deduplicateErrors(errors: PreviewError[]): PreviewError[] {
const seen = new Set<string>();
return errors.filter((error) => {
const key = `${error.type}-${error.message}-${error.lineNumber || 0}`;
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
|