/** * Вспомогательные утилиты */ 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, };