import { SmartDaemon } from './smartdaemon.classes.smartdaemon.js'; import { SmartDaemonService } from './smartdaemon.classes.service.js'; export class SmartDaemonTemplateManager { public smartdaemonRef: SmartDaemon; constructor(smartdaemonRefArg: SmartDaemon) { this.smartdaemonRef = smartdaemonRefArg; } private generateEnvironmentLines(serviceArg: SmartDaemonService): string { const environment = serviceArg.environment || {}; return Object.entries(environment) .map(([key, value]) => { if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) { throw new Error(`Invalid systemd environment key: ${key}`); } const escapedValue = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); return `Environment="${key}=${escapedValue}"`; }) .join('\n'); } public generateUnitFileForService = (serviceArg: SmartDaemonService) => { const environmentLines = this.generateEnvironmentLines(serviceArg); return `# --- # name: ${serviceArg.name} # version: ${serviceArg.version} # description: ${serviceArg.description} # command: ${serviceArg.command} # workingDir: ${serviceArg.workingDir}${serviceArg.user ? ` # user: ${serviceArg.user}` : ''}${serviceArg.group ? ` # group: ${serviceArg.group}` : ''} # --- [Unit] Description=${serviceArg.description} Requires=network.target After=network.target [Service] Type=simple${serviceArg.user ? ` User=${serviceArg.user}` : ''}${serviceArg.group ? ` Group=${serviceArg.group}` : ''}${environmentLines ? ` ${environmentLines}` : ''} ExecStart=/bin/bash -c "cd ${serviceArg.workingDir} && ${serviceArg.command}" WorkingDirectory=${serviceArg.workingDir} Restart=on-failure LimitNOFILE=infinity LimitCORE=infinity StandardInput=null StandardOutput=syslog StandardError=syslog Restart=always [Install] WantedBy=multi-user.target `; }; }