347 lines
11 KiB
JavaScript
347 lines
11 KiB
JavaScript
const express = require('express');
|
|
const multer = require('multer');
|
|
const upload = multer({ dest: 'uploads/' });
|
|
const fs = require('fs');
|
|
|
|
const ExecutorService = require('../services/executor');
|
|
const { takeScreenshot } = require("../services/screenshot_service");
|
|
|
|
const wrapAsync = require('../helpers').wrapAsync;
|
|
|
|
const router = express.Router();
|
|
|
|
router.post(
|
|
'/read_project_tree',
|
|
wrapAsync(async (req, res) => {
|
|
const { path } = req.body;
|
|
const tree = await ExecutorService.readProjectTree(path);
|
|
res.status(200).send(tree);
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/read_file',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, showLines } = req.body;
|
|
const content = await ExecutorService.readFileContents(path, showLines);
|
|
res.status(200).send(content);
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/count_file_lines',
|
|
wrapAsync(async (req, res) => {
|
|
const { path } = req.body;
|
|
const content = await ExecutorService.countFileLines(path);
|
|
res.status(200).send(content);
|
|
}),
|
|
);
|
|
|
|
// router.post(
|
|
// '/read_file_header',
|
|
// wrapAsync(async (req, res) => {
|
|
// const { path, N } = req.body;
|
|
// try {
|
|
// const header = await ExecutorService.readFileHeader(path, N);
|
|
// res.status(200).send(header);
|
|
// } catch (error) {
|
|
// res.status(500).send({
|
|
// error: true,
|
|
// message: error.message,
|
|
// details: error.details || error.stack,
|
|
// validation: error.validation
|
|
// });
|
|
// }
|
|
// }),
|
|
// );
|
|
|
|
router.post(
|
|
'/read_file_line_context',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, lineNumber, windowSize, showLines } = req.body;
|
|
try {
|
|
const context = await ExecutorService.readFileLineContext(path, lineNumber, windowSize, showLines);
|
|
res.status(200).send(context);
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/write_file',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, fileContents, comment } = req.body;
|
|
try {
|
|
await ExecutorService.writeFile(path, fileContents, comment);
|
|
res.status(200).send({ message: 'File written successfully' });
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/insert_file_content',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, lineNumber, newContent, message } = req.body;
|
|
try {
|
|
await ExecutorService.insertFileContent(path, lineNumber, newContent, message);
|
|
res.status(200).send({ message: 'File written successfully' });
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/replace_file_line',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, lineNumber, newText } = req.body;
|
|
try {
|
|
const result = await ExecutorService.replaceFileLine(path, lineNumber, newText);
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
router.post(
|
|
'/replace_file_chunk',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, startLine, endLine, newCode } = req.body;
|
|
try {
|
|
const result = await ExecutorService.replaceFileChunk(path, startLine, endLine, newCode);
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/delete_file_lines',
|
|
wrapAsync(async (req, res) => {
|
|
const { path, startLine, endLine, message } = req.body;
|
|
try {
|
|
const result = await ExecutorService.deleteFileLines(path, startLine, endLine, message);
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/validate_file',
|
|
wrapAsync(async (req, res) => {
|
|
const { path } = req.body;
|
|
try {
|
|
const validationResult = await ExecutorService.validateFile(path);
|
|
res.status(200).send({ validationResult });
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
});
|
|
}
|
|
}),
|
|
);
|
|
|
|
|
|
router.post(
|
|
'/check_frontend_runtime_error',
|
|
wrapAsync(async (req, res) => {
|
|
try {
|
|
const result = await ExecutorService.checkFrontendRuntimeLogs();
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({ error: error });
|
|
}
|
|
}),
|
|
);
|
|
|
|
|
|
router.post(
|
|
'/replace_code_block',
|
|
wrapAsync(async (req, res) => {
|
|
const {path, oldCode, newCode, message} = req.body;
|
|
try {
|
|
const response = await ExecutorService.replaceCodeBlock(path, oldCode, newCode, message);
|
|
res.status(200).send(response);
|
|
} catch (error) {
|
|
res.status(500).send({
|
|
error: true,
|
|
message: error.message,
|
|
details: error.details || error.stack,
|
|
validation: error.validation
|
|
})
|
|
}
|
|
})
|
|
)
|
|
|
|
router.post('/update_project_files_from_scheme',
|
|
upload.single('file'), // 'file' - name of the field in the form
|
|
async (req, res) => {
|
|
console.log('Request received');
|
|
console.log('Headers:', req.headers);
|
|
if (!req.file) {
|
|
return res.status(400).json({ error: 'No file uploaded' });
|
|
}
|
|
|
|
console.log('File info:', {
|
|
originalname: req.file.originalname,
|
|
path: req.file.path,
|
|
size: req.file.size,
|
|
mimetype: req.file.mimetype
|
|
});
|
|
|
|
try {
|
|
console.log('Starting update process...');
|
|
const result = await ExecutorService.updateProjectFilesFromScheme(req.file.path);
|
|
console.log('Update completed, result:', result);
|
|
|
|
console.log('Removing temp file...');
|
|
fs.unlinkSync(req.file.path);
|
|
console.log('Temp file removed');
|
|
|
|
console.log('Sending response...');
|
|
return res.json(result);
|
|
} catch (error) {
|
|
console.error('Error in route handler:', error);
|
|
if (req.file) {
|
|
try {
|
|
fs.unlinkSync(req.file.path);
|
|
console.log('Temp file removed after error');
|
|
} catch (unlinkError) {
|
|
console.error('Error removing temp file:', unlinkError);
|
|
}
|
|
}
|
|
console.error('Update project files error:', error);
|
|
return res.status(500).json({
|
|
error: error.message,
|
|
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
|
|
});
|
|
}
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/get_db_schema',
|
|
wrapAsync(async (req, res) => {
|
|
try {
|
|
|
|
const jsonSchema = await ExecutorService.getDBSchema();
|
|
res.status(200).send({ jsonSchema });
|
|
} catch (error) {
|
|
res.status(500).send({ error: error });
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/execute_sql',
|
|
wrapAsync(async (req, res) => {
|
|
try {
|
|
const { query } = req.body;
|
|
const result = await ExecutorService.executeSQL(query);
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({ error: error });
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/search_files',
|
|
wrapAsync(async (req, res) => {
|
|
try {
|
|
const { searchStrings } = req.body;
|
|
|
|
if (
|
|
typeof searchStrings !== 'string' &&
|
|
!(
|
|
Array.isArray(searchStrings) &&
|
|
searchStrings.every(item => typeof item === 'string')
|
|
)
|
|
) {
|
|
return res.status(400).send({ error: 'searchStrings must be a string or an array of strings' });
|
|
}
|
|
|
|
const result = await ExecutorService.searchFiles(searchStrings);
|
|
res.status(200).send(result);
|
|
} catch (error) {
|
|
res.status(500).send({ error: error.message });
|
|
}
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/screenshot',
|
|
wrapAsync(async (req, res) => {
|
|
const FRONT_PORT = process.env.FRONT_PORT || 3001;
|
|
const targetUrl = `http://localhost:${FRONT_PORT}${req.body.url || '/'}`;
|
|
|
|
const filename = req.query.filename || `screenshot-${Date.now()}.png`;
|
|
const fullPage = req.query.fullPage !== 'false';
|
|
|
|
try {
|
|
console.log(`[App-Shell/Screenshot Route]: request to take screenshot of ${targetUrl} with filename ${filename} and fullPage=${fullPage}`);
|
|
const outputPath = await takeScreenshot(targetUrl, filename, fullPage);
|
|
|
|
res.sendFile(outputPath, async (err) => {
|
|
if (err) {
|
|
console.error(`[App-Shell/Screenshot Route]: error sending screenshot ${outputPath}:`, err);
|
|
if (err.code === 'ENOENT') {
|
|
res.status(404).send('Screenshot not found.');
|
|
} else {
|
|
res.status(500).send('Error sending screenshot: ' + err.message);
|
|
}
|
|
} else {
|
|
console.log(`[App-Shell/Screenshot Route]: Screenshot sent successfully: ${outputPath}`);
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error(`[App-Shell/Screenshot Route]: Could not take screenshot of ${targetUrl}:`, error);
|
|
res.status(500).send(`Error taking screenshot: ${error.message}`);
|
|
}
|
|
})
|
|
)
|
|
|
|
router.use('/', require('../helpers').commonErrorHandler);
|
|
|
|
module.exports = router;
|