'use strict'; const fs = require('fs'); const LOG_ROTATION_DEFAULT_MAX_MB = 20; const LOG_ROTATION_DEFAULT_BACKUP_COUNT = 3; function normalizeUrl(value) { try { const url = new URL(value); if (!url.pathname.endsWith('/')) { url.pathname += '/'; } return url.toString(); } catch { return 'http://127.0.0.1:6185/'; } } function ensureDir(value) { if (!value) { return; } if (fs.existsSync(value)) { return; } fs.mkdirSync(value, { recursive: true }); } function parseEnvInt(raw, defaultValue) { const parsed = Number.parseInt(`${raw ?? ''}`, 10); return Number.isFinite(parsed) ? parsed : defaultValue; } function isLogRotationDebugEnabled() { return ( process.env.ASTRBOT_LOG_ROTATION_DEBUG === '1' || process.env.NODE_ENV === 'development' ); } function parseLogMaxBytes(envValue) { const mb = parseEnvInt(envValue, LOG_ROTATION_DEFAULT_MAX_MB); const maxMb = mb > 0 ? mb : LOG_ROTATION_DEFAULT_MAX_MB; return maxMb * 1024 * 1024; } function parseLogBackupCount(envValue) { const count = parseEnvInt(envValue, LOG_ROTATION_DEFAULT_BACKUP_COUNT); return count >= 0 ? count : LOG_ROTATION_DEFAULT_BACKUP_COUNT; } function isIgnorableFsError(error) { return Boolean(error && typeof error === 'object' && error.code === 'ENOENT'); } function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function waitForProcessExit(child, timeoutMs = 5000) { if (!child) { return Promise.resolve('missing'); } if (child.exitCode !== null || child.signalCode !== null) { return Promise.resolve('exited'); } return new Promise((resolve) => { let settled = false; const finish = (reason) => { if (settled) { return; } settled = true; clearTimeout(timeout); resolve(reason); }; const timeout = setTimeout(() => finish('timeout'), timeoutMs); child.once('exit', () => finish('exit')); child.once('error', () => finish('error')); }); } function formatLogTimestamp(date = new Date()) { const year = date.getFullYear(); const month = `${date.getMonth() + 1}`.padStart(2, '0'); const day = `${date.getDate()}`.padStart(2, '0'); const hour = `${date.getHours()}`.padStart(2, '0'); const minute = `${date.getMinutes()}`.padStart(2, '0'); const second = `${date.getSeconds()}`.padStart(2, '0'); const millisecond = `${date.getMilliseconds()}`.padStart(3, '0'); const offsetMinutes = -date.getTimezoneOffset(); const offsetSign = offsetMinutes >= 0 ? '+' : '-'; const absOffsetMinutes = Math.abs(offsetMinutes); const offsetHour = `${Math.floor(absOffsetMinutes / 60)}`.padStart(2, '0'); const offsetMinute = `${absOffsetMinutes % 60}`.padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond} ${offsetSign}${offsetHour}${offsetMinute}`; } module.exports = { LOG_ROTATION_DEFAULT_BACKUP_COUNT, LOG_ROTATION_DEFAULT_MAX_MB, delay, ensureDir, formatLogTimestamp, isIgnorableFsError, isLogRotationDebugEnabled, normalizeUrl, parseEnvInt, parseLogBackupCount, parseLogMaxBytes, waitForProcessExit, };