#!/usr/bin/env node // Get arguments const [,, ...args] = process.argv import os from 'os' import fs from 'fs/promises' import Util from './core/util.mjs' import Core from './core/core.mjs' import path from 'path' if (!args.length) PrintHelp() if (args[0] !== 'checkconfig' && args[0] !== 'install' && args[0] !== 'uninstall') PrintHelp let configFile = 'config.json' if (args[1]) { configFile = args[1] } const basicRunnerTemplate = ` import fs from 'fs' import { runner } from 'service-core' runner(import.meta.url, '${configFile}', 'db.json') .then( function(core) { core.log.info('core is running') }, function(err) { runner.log.error(err, 'Error starting runner') process.exit(1) } ) ` const util = new Util(import.meta.url) function PrintHelp() { console.log('') console.log('Usage: sccli [config.json]') console.log('') console.log('') console.log(' checkconfig : Test local config.json for errors') console.log(' install : Install local config.json as service') console.log(' uninstall : Uninstall local config.json as a service') console.log('') process.exit(1) } if (args[0] === 'checkconfig') { fs.readFile(configFile) .then(async function(content) { let config = JSON.parse(content) util.verifyConfig(config) let names = util.getAppNames(config) if (!names.length) { return Promise.reject(new Error('No application names were found')) } for (let name of names) { let provConstructor = Core.providers.get(config[name].provider) let provider = new provConstructor(config[name]) await provider.checkConfig(config[name]) } console.log(`${configFile} is a valid config with ${names.length} application${names.length > 1 ? 's' : ''}:`) for (let name of names) { console.log(` * ${name} (${config[name].provider}${config[name].url ? ': ' + config[name].url : ' provider'})`) } }) .catch(function(err) { console.log('Error checking config:', err) process.exit(2) }) .then(function() { process.exit(0) }) } else if (args[0] === 'install') { if(os.platform() === 'win32') { const runner = path.join(process.cwd(), './runner.mjs') fs.stat(runner).catch(function() { console.log('Creating runner.mjs') return fs.writeFile(runner, basicRunnerTemplate) }).then(function() { console.log('Linking local service-core instance') return util.runCommand('npm', ['link', 'service-core'], null, function(stream) { console.log(stream.replace('\n', '')) }) }).then(function() { return Promise.all([ util.runCommand('npm', ['link', 'service-core'], null, function(stream) { console.log(stream.replace('\n', '')) }), fs.readFile(configFile), import('node-windows'), ]) }).then(function([content, nodewindows]) { let config = JSON.parse(content) const Service = nodewindows.Service let serviceConfig = { name: config.title || config.name, description: config.description, script: runner, env: { name: 'NODE_ENV', value: 'production', }, wait: 0, grow: .5, maxRestarts: 10 //, workingDirectory: '...' //, allowServiceLogon: true } console.log('Service', serviceConfig) // Create a new service object let svc = new Service(serviceConfig); svc.on('install',function(){ svc.start(); process.exit(0) }); svc.on('alreadyinstalled',function(){ svc.start(); process.exit(0) }); svc.install(); }) } else { const runner = path.join(process.cwd(), './runner.mjs') fs.stat(runner).catch(function() { console.log('Creating runner.mjs') return fs.writeFile(runner, basicRunnerTemplate) }).then(function() { console.log('Linking local service-core instance') return util.runCommand('npm', ['link', 'service-core'], null, function(stream) { console.log(stream.replace('\n', '')) }) }).then(function() { console.log('Runner is ready to be added to init.d') }) } } else if (args[0] === 'uninstall') { if(os.platform() === 'win32') { const runner = path.join(process.cwd(), './runner.mjs') fs.stat(runner).catch(function() { return fs.writeFile(runner, basicRunnerTemplate) }).then(function() { return Promise.all([ fs.readFile(configFile), import('node-windows'), ]) }).then(function([content, nodewindows]) { let config = JSON.parse(content) const Service = nodewindows.Service let serviceConfig = { name: config.title || config.name, description: config.description, script: runner, env: { name: 'NODE_ENV', value: 'production', }, wait: 0, grow: .5, maxRestarts: 10 //, workingDirectory: '...' //, allowServiceLogon: true } console.log('Service', serviceConfig) // Create a new service object let svc = new Service(serviceConfig); svc.on('uninstall',function(){ console.log('Uninstall complete.'); console.log('The service exists: ',svc.exists); process.exit(0) }); svc.uninstall(); }) } else { console.log('non windows install targets are currently unsupported') process.exit(2) } }