feat: Оптимизация структуры server.js с модульным подходом, добавление новых маршрутов и улучшение обработки ошибок. Обновление валидаторов для MikroTik с использованием общих функций. Улучшение кода компонентов приложения для повышения читаемости и производительности.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Вспомогательные утилиты
|
||||
*/
|
||||
|
||||
const crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* Конвертировать дату в ISO строку
|
||||
*/
|
||||
function toIso(x) {
|
||||
try { return new Date(x).toISOString(); } catch { return null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Разбить строку по пробелам
|
||||
*/
|
||||
function splitWhitespace(line) {
|
||||
return String(line || '').trim().split(/\s+/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Вычислить SHA256 хэш строки
|
||||
*/
|
||||
function sha256OfString(s) {
|
||||
return crypto.createHash('sha256').update(Buffer.from(String(s), 'utf-8')).digest('hex');
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразовать ошибки AJV в читаемый формат
|
||||
*/
|
||||
function mapAjvErrors(errors) {
|
||||
if (!Array.isArray(errors)) return [];
|
||||
return errors.map((e) => ({
|
||||
message: e.message,
|
||||
instancePath: e.instancePath,
|
||||
keyword: e.keyword,
|
||||
params: e.params,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Маппинг UI ресурсов на S3 ключи (для истории версий)
|
||||
*/
|
||||
function resourceToKey(resource) {
|
||||
switch (resource) {
|
||||
case 'domains-new': return 'bgp_data/domains_community.txt';
|
||||
case 'ip-ranges': return 'bgp_data/ips.txt';
|
||||
case 'asns': return 'bgp_data/asns.txt';
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Построить вложенные if/else блоки для MikroTik конфигурации
|
||||
*/
|
||||
function buildNestedGatewayBlocks(gatewayGroups, baseIndentSpaces = 4) {
|
||||
const indent = (n) => ' '.repeat(n);
|
||||
const entries = Object.entries(gatewayGroups);
|
||||
if (entries.length === 0) return '';
|
||||
|
||||
function buildAt(index, pad) {
|
||||
const [gateway, communities] = entries[index];
|
||||
let s = '';
|
||||
s += `${indent(pad)}if (\n`;
|
||||
communities.forEach((community, i) => {
|
||||
s += `${indent(pad + 4)}(bgp-communities includes ${community})`;
|
||||
if (i < communities.length - 1) s += ' or \n';
|
||||
});
|
||||
s += `\n${indent(pad)})\n`;
|
||||
s += `${indent(pad)}{\n${indent(pad + 8 - 4)}set gw ${gateway}; accept;\n${indent(pad)}}\n`;
|
||||
if (index < entries.length - 1) {
|
||||
s += `${indent(pad)}else\n${indent(pad)}{\n`;
|
||||
s += buildAt(index + 1, pad + 4);
|
||||
s += `\n${indent(pad)}}`;
|
||||
} else {
|
||||
s += `${indent(pad)}else\n${indent(pad)}{\n${indent(pad + 4)}reject;\n${indent(pad)}}`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
return buildAt(0, baseIndentSpaces);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
toIso,
|
||||
splitWhitespace,
|
||||
sha256OfString,
|
||||
mapAjvErrors,
|
||||
resourceToKey,
|
||||
buildNestedGatewayBlocks,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user