318 lines
9.0 KiB
TypeScript
318 lines
9.0 KiB
TypeScript
import { Response } from 'express';
|
|
import { AuthRequest } from '../middleware/auth';
|
|
import { mainPool } from '../config/database';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
export const getEndpoints = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { search, folder_id } = req.query;
|
|
|
|
let query = `
|
|
SELECT e.*, f.name as folder_name
|
|
FROM endpoints e
|
|
LEFT JOIN folders f ON e.folder_id = f.id
|
|
WHERE 1=1
|
|
`;
|
|
const params: any[] = [];
|
|
|
|
if (folder_id) {
|
|
query += ` AND e.folder_id = $${params.length + 1}`;
|
|
params.push(folder_id);
|
|
}
|
|
|
|
if (search) {
|
|
const searchIndex = params.length + 1;
|
|
query += ` AND (
|
|
e.name ILIKE $${searchIndex} OR
|
|
e.description ILIKE $${searchIndex} OR
|
|
e.sql_query ILIKE $${searchIndex} OR
|
|
e.path ILIKE $${searchIndex}
|
|
)`;
|
|
params.push(`%${search}%`);
|
|
}
|
|
|
|
query += ` ORDER BY e.created_at DESC`;
|
|
|
|
const result = await mainPool.query(query, params);
|
|
res.json(result.rows);
|
|
} catch (error) {
|
|
console.error('Get endpoints error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
export const getEndpoint = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const result = await mainPool.query(
|
|
`SELECT e.*, f.name as folder_name
|
|
FROM endpoints e
|
|
LEFT JOIN folders f ON e.folder_id = f.id
|
|
WHERE e.id = $1`,
|
|
[id]
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Endpoint not found' });
|
|
}
|
|
|
|
res.json(result.rows[0]);
|
|
} catch (error) {
|
|
console.error('Get endpoint error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
export const createEndpoint = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const {
|
|
name,
|
|
description,
|
|
method,
|
|
path,
|
|
database_id,
|
|
sql_query,
|
|
parameters,
|
|
folder_id,
|
|
is_public,
|
|
enable_logging,
|
|
execution_type,
|
|
script_language,
|
|
script_code,
|
|
script_queries,
|
|
} = req.body;
|
|
|
|
if (!name || !method || !path) {
|
|
return res.status(400).json({ error: 'Missing required fields' });
|
|
}
|
|
|
|
const execType = execution_type || 'sql';
|
|
|
|
// Валидация для типа SQL
|
|
if (execType === 'sql') {
|
|
if (!database_id || !sql_query) {
|
|
return res.status(400).json({ error: 'Database ID and SQL query are required for SQL execution type' });
|
|
}
|
|
}
|
|
|
|
// Валидация для типа Script
|
|
if (execType === 'script') {
|
|
if (!script_language || !script_code || !script_queries) {
|
|
return res.status(400).json({ error: 'Script language, code, and queries are required for script execution type' });
|
|
}
|
|
}
|
|
|
|
const result = await mainPool.query(
|
|
`INSERT INTO endpoints (
|
|
name, description, method, path, database_id, sql_query, parameters,
|
|
folder_id, user_id, is_public, enable_logging,
|
|
execution_type, script_language, script_code, script_queries
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
|
RETURNING *`,
|
|
[
|
|
name,
|
|
description || '',
|
|
method,
|
|
path,
|
|
database_id || null,
|
|
sql_query || '',
|
|
JSON.stringify(parameters || []),
|
|
folder_id || null,
|
|
req.user!.id,
|
|
is_public || false,
|
|
enable_logging || false,
|
|
execType,
|
|
script_language || null,
|
|
script_code || null,
|
|
JSON.stringify(script_queries || []),
|
|
]
|
|
);
|
|
|
|
res.status(201).json(result.rows[0]);
|
|
} catch (error: any) {
|
|
console.error('Create endpoint error:', error);
|
|
if (error.code === '23505') {
|
|
return res.status(400).json({ error: 'Endpoint path already exists' });
|
|
}
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
export const updateEndpoint = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const {
|
|
name,
|
|
description,
|
|
method,
|
|
path,
|
|
database_id,
|
|
sql_query,
|
|
parameters,
|
|
folder_id,
|
|
is_public,
|
|
enable_logging,
|
|
execution_type,
|
|
script_language,
|
|
script_code,
|
|
script_queries,
|
|
} = req.body;
|
|
|
|
const result = await mainPool.query(
|
|
`UPDATE endpoints
|
|
SET name = $1,
|
|
description = $2,
|
|
method = $3,
|
|
path = $4,
|
|
database_id = $5,
|
|
sql_query = $6,
|
|
parameters = $7,
|
|
folder_id = $8,
|
|
is_public = $9,
|
|
enable_logging = $10,
|
|
execution_type = $11,
|
|
script_language = $12,
|
|
script_code = $13,
|
|
script_queries = $14,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = $15
|
|
RETURNING *`,
|
|
[
|
|
name,
|
|
description,
|
|
method,
|
|
path,
|
|
database_id || null,
|
|
sql_query,
|
|
parameters ? JSON.stringify(parameters) : null,
|
|
folder_id || null,
|
|
is_public,
|
|
enable_logging,
|
|
execution_type,
|
|
script_language || null,
|
|
script_code || null,
|
|
script_queries ? JSON.stringify(script_queries) : null,
|
|
id,
|
|
]
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Endpoint not found' });
|
|
}
|
|
|
|
res.json(result.rows[0]);
|
|
} catch (error: any) {
|
|
console.error('Update endpoint error:', error);
|
|
if (error.code === '23505') {
|
|
return res.status(400).json({ error: 'Endpoint path already exists' });
|
|
}
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
export const deleteEndpoint = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const result = await mainPool.query(
|
|
'DELETE FROM endpoints WHERE id = $1 RETURNING id',
|
|
[id]
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Endpoint not found' });
|
|
}
|
|
|
|
res.json({ message: 'Endpoint deleted successfully' });
|
|
} catch (error) {
|
|
console.error('Delete endpoint error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
};
|
|
|
|
export const testEndpoint = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const {
|
|
database_id,
|
|
sql_query,
|
|
parameters,
|
|
endpoint_parameters,
|
|
execution_type,
|
|
script_language,
|
|
script_code,
|
|
script_queries
|
|
} = req.body;
|
|
|
|
const execType = execution_type || 'sql';
|
|
|
|
if (execType === 'sql') {
|
|
if (!database_id) {
|
|
return res.status(400).json({ error: 'Missing database_id for SQL execution' });
|
|
}
|
|
if (!sql_query) {
|
|
return res.status(400).json({ error: 'Missing sql_query' });
|
|
}
|
|
|
|
// Преобразуем именованные параметры ($paramName) в позиционные ($1, $2, $3...)
|
|
let processedQuery = sql_query;
|
|
|
|
if (endpoint_parameters && Array.isArray(endpoint_parameters)) {
|
|
endpoint_parameters.forEach((param: any, index: number) => {
|
|
const paramName = param.name;
|
|
const position = index + 1;
|
|
|
|
// Заменяем все вхождения $paramName на $position
|
|
const regex = new RegExp(`\\$${paramName}\\b`, 'g');
|
|
processedQuery = processedQuery.replace(regex, `$${position}`);
|
|
});
|
|
}
|
|
|
|
const { sqlExecutor } = require('../services/SqlExecutor');
|
|
const result = await sqlExecutor.executeQuery(database_id, processedQuery, parameters || []);
|
|
|
|
res.json({
|
|
success: true,
|
|
data: result.rows,
|
|
rowCount: result.rowCount,
|
|
executionTime: result.executionTime,
|
|
});
|
|
} else if (execType === 'script') {
|
|
if (!script_language || !script_code) {
|
|
return res.status(400).json({ error: 'Missing script_language or script_code' });
|
|
}
|
|
|
|
// Собираем параметры из тестовых значений
|
|
const requestParams: Record<string, any> = {};
|
|
if (endpoint_parameters && Array.isArray(endpoint_parameters) && parameters && Array.isArray(parameters)) {
|
|
endpoint_parameters.forEach((param: any, index: number) => {
|
|
requestParams[param.name] = parameters[index];
|
|
});
|
|
}
|
|
|
|
const { scriptExecutor } = require('../services/scriptExecutor');
|
|
const scriptResult = await scriptExecutor.execute(script_language, script_code, {
|
|
databaseId: database_id,
|
|
scriptQueries: script_queries || [],
|
|
requestParams,
|
|
endpointParameters: endpoint_parameters || [],
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: scriptResult.data || scriptResult,
|
|
rowCount: scriptResult.rowCount || (Array.isArray(scriptResult.data) ? scriptResult.data.length : 0),
|
|
executionTime: scriptResult.executionTime || 0,
|
|
});
|
|
} else {
|
|
return res.status(400).json({ error: 'Invalid execution_type' });
|
|
}
|
|
} catch (error: any) {
|
|
res.status(400).json({
|
|
success: false,
|
|
error: error.message,
|
|
});
|
|
}
|
|
};
|