diff --git a/scripts/api/scheduleStore.js b/scripts/api/scheduleStore.js index 07736db7..699387e5 100644 --- a/scripts/api/scheduleStore.js +++ b/scripts/api/scheduleStore.js @@ -10,7 +10,7 @@ const CRON_FIELD_RANGES = [ { min: 0, max: 23 }, // hour { min: 1, max: 31 }, // day of month { min: 1, max: 12 }, // month - { min: 0, max: 7 } // day of week (7 == Sunday) + { min: 0, max: 7 } // day of week (7 == Sunday) ] function validateField(expr, { min, max }) { @@ -101,10 +101,9 @@ export function writeSchedule(projectRoot, patch) { if ('cron' in patch) { if (typeof patch.cron !== 'string' || !isValidCron(patch.cron)) { - throw Object.assign( - new Error('Invalid cron expression (5 fields, e.g. "0 9 * * *").'), - { code: 'BAD_REQUEST' } - ) + throw Object.assign(new Error('Invalid cron expression (5 fields, e.g. "0 9 * * *").'), { + code: 'BAD_REQUEST' + }) } next.cron = patch.cron.trim() } @@ -116,10 +115,9 @@ export function writeSchedule(projectRoot, patch) { } const indexes = [...new Set(patch.excludedAccountIndexes.map(Number))] if (indexes.some(i => !Number.isSafeInteger(i) || i < 1)) { - throw Object.assign( - new Error('excludedAccountIndexes must contain only positive integers.'), - { code: 'BAD_REQUEST' } - ) + throw Object.assign(new Error('excludedAccountIndexes must contain only positive integers.'), { + code: 'BAD_REQUEST' + }) } next.excludedAccountIndexes = indexes.sort((a, b) => a - b) } @@ -168,10 +166,9 @@ export function applyCrontab({ enabled, cron }) { } if (!fs.existsSync(CRON_TEMPLATE)) { - throw Object.assign( - new Error(`Cron template not found at ${CRON_TEMPLATE} — image may be corrupt.`), - { code: 'TEMPLATE_MISSING' } - ) + throw Object.assign(new Error(`Cron template not found at ${CRON_TEMPLATE} — image may be corrupt.`), { + code: 'TEMPLATE_MISSING' + }) } const tz = process.env.TZ || 'UTC' diff --git a/scripts/api/server.js b/scripts/api/server.js index 9bf275c2..ea9a440b 100644 --- a/scripts/api/server.js +++ b/scripts/api/server.js @@ -34,7 +34,7 @@ try { const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8')) pkgVersion = pkg.version ?? pkgVersion pkgName = pkg.name ?? pkgName -} catch { } +} catch {} const HOST = envStr('API_HOST') ?? (typeof cliArgs.host === 'string' ? cliArgs.host : '127.0.0.1') const PORT = Number(cliArgs.port) || envInt('API_PORT', 3010) @@ -422,7 +422,7 @@ const requestHandler = async (req, res) => { const force = Boolean(body.force) try { const stopping = pm.stop({ force }) - stopping.catch(() => { }) + stopping.catch(() => {}) return sendJson(res, 202, { stopping: true, force }) } catch (err) { if (err.code === 'NOT_RUNNING') return sendJson(res, 409, { error: err.message, code: err.code }) @@ -554,14 +554,14 @@ function listDiagnostics() { let error = null try { files = fs.readdirSync(full) - } catch { } + } catch {} try { createdAt = fs.statSync(full).mtime.toISOString() - } catch { } + } catch {} if (files.includes('error.txt')) { try { error = fs.readFileSync(path.join(full, 'error.txt'), 'utf8').slice(0, 2000) - } catch { } + } catch {} } return { name: d.name, diff --git a/scripts/docker/schedule-store.js b/scripts/docker/schedule-store.js index 144c7700..a8e05da7 100644 --- a/scripts/docker/schedule-store.js +++ b/scripts/docker/schedule-store.js @@ -3,31 +3,29 @@ const SCHEDULE_FILE = envStr('SCHEDULE_FILE') ?? path.join(projectRoot, 'config', 'schedule.json') function readSchedule() { - if (fs.existsSync(SCHEDULE_FILE)) { - return JSON.parse(fs.readFileSync(SCHEDULE_FILE, 'utf8')) // source: 'override' - } - // Fall back to the env-configured default so nothing breaks for - // no-frontend users who only ever set CRON_SCHEDULE. - return { - enabled: Boolean(process.env.CRON_SCHEDULE), - cron: process.env.CRON_SCHEDULE || null, - skipIfRunning: true, - excludedAccountIndexes: [], - source: 'env' - } + if (fs.existsSync(SCHEDULE_FILE)) { + return JSON.parse(fs.readFileSync(SCHEDULE_FILE, 'utf8')) // source: 'override' + } + // Fall back to the env-configured default so nothing breaks for + // no-frontend users who only ever set CRON_SCHEDULE. + return { + enabled: Boolean(process.env.CRON_SCHEDULE), + cron: process.env.CRON_SCHEDULE || null, + skipIfRunning: true, + excludedAccountIndexes: [], + source: 'env' + } } function writeSchedule(next) { - writeConfigAtomic(SCHEDULE_FILE, next) // reuse the atomic-write helper already in configEditor.js - applyCrontab(next) // regenerate /etc/cron.d file + `crontab` it live + writeConfigAtomic(SCHEDULE_FILE, next) // reuse the atomic-write helper already in configEditor.js + applyCrontab(next) // regenerate /etc/cron.d file + `crontab` it live } function applyCrontab({ enabled, cron }) { - if (!enabled || !cron) return execSync('crontab -r', { stdio: 'ignore' }) // no-op if none exists - const template = fs.readFileSync('/etc/cron.d/microsoft-rewards-cron.template', 'utf8') - const rendered = template - .replace('${CRON_SCHEDULE}', cron) - .replace('${TZ}', process.env.TZ || 'UTC') - fs.writeFileSync('/etc/cron.d/microsoft-rewards-cron', rendered, { mode: 0o644 }) - execSync('crontab /etc/cron.d/microsoft-rewards-cron') -} \ No newline at end of file + if (!enabled || !cron) return execSync('crontab -r', { stdio: 'ignore' }) // no-op if none exists + const template = fs.readFileSync('/etc/cron.d/microsoft-rewards-cron.template', 'utf8') + const rendered = template.replace('${CRON_SCHEDULE}', cron).replace('${TZ}', process.env.TZ || 'UTC') + fs.writeFileSync('/etc/cron.d/microsoft-rewards-cron', rendered, { mode: 0o644 }) + execSync('crontab /etc/cron.d/microsoft-rewards-cron') +}