UNPKG

a3ensite

Version:

Apache/Nginx/Config Manager, JSON based

293 lines (292 loc) 10.7 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const minimist_1 = __importDefault(require("minimist")); //{ accessSync, constants } const default_argv = { template: "./a3ensite.conf", config: "./a3ensite.json", }; function print_error(...args) { console.warn(...args); console.warn("-----------------------------\n"); process.exit(0); } function print_log(...args) { console.log(...args); } print_log("-> Still Lovin You"); const app$argv = (0, minimist_1.default)(process.argv.slice(2), { default: default_argv, }); const app$config = setup_config(); const tasks = { make: { hosts: $make_hosts, sites: $make_sites, }, unmake: { hosts: null, sites: null, }, status: $sites_status, }; let task = tasks; for (let i = 0; i < app$argv._.length; i++) { const taskname = app$argv._[i]; if (!task) break; task = task[taskname]; } if (typeof task != "function") print_error(`error: '${app$argv._.join("->")}' ~ Invalid task \n Help \n--config a3ensite.json \n--template a3ensite.conf`); else { task(); print_log(`success = '${app$argv._.join("->")}'`); } print_log("\n"); function $make_hosts() { var _a; const start_tag = "#a3ensite-start"; const end_tag = "#a3ensite-end"; if (!access$check(app$config.options.hosts.EnabledLoc)) { print_error("Hosts file not writable config: options.hosts.EnabledLoc"); } const curr_hosts = fs_1.default.readFileSync(app$config.options.hosts.EnabledLoc, "utf8"); const start_pos = curr_hosts.indexOf(start_tag); const end_pos = curr_hosts.indexOf(end_tag); let new_hosts = curr_hosts; if (start_pos > -1 && end_pos > -1) { new_hosts = `${curr_hosts.substring(0, start_pos)}${curr_hosts.substring(end_pos + end_tag.length, curr_hosts.length)}`; } const local_hosts = []; local_hosts.push(`${start_tag} #### DO NOT EDIT`); for (let i = 0; i < app$config.sites.length; i++) { const site = app$config.sites[i]; let $ip = site[app$config.options.hosts.HostIpKey] || app$config.defaults[app$config.options.hosts.HostIpKey]; let $name = (_a = site[app$config.options.hosts.HostNameKey]) !== null && _a !== void 0 ? _a : app$config.defaults[app$config.options.hosts.HostNameKey]; local_hosts.push(`${$ip} ${$name}`); } local_hosts.push(end_tag); new_hosts = new_hosts + local_hosts.join("\n"); fs_1.default.writeFileSync(app$config.options.hosts.EnabledLoc, new_hosts); } function $build() { const body = setup_template(app$argv); if (!Array.isArray(app$config.sites)) print_error("[Array] config.sites is required"); const sites = app$config.sites; const var_builds = []; const defaults = app$config.defaults; for (let site of sites) { const var_build = { graph: [], count: 1, }; for (let input of body) { const varlist = input.varlist; let line = input.line; const _varlist = []; for (const var_ of varlist) { let _value = []; if (site[var_.name] !== undefined) { if (var_.typed != "display") { if (Array.isArray(site[var_.name])) _value.push(...site[var_.name]); else _value.push(site[var_.name]); } } else if (app$config.defaults[var_.name] !== undefined) { if (var_.typed != "display") { if (Array.isArray(defaults[var_.name])) _value.push(...defaults[var_.name]); else _value.push(defaults[var_.name]); } //_value.push(app$config.defaults[var_.name]); } else { if (var_.typed == "optional" || var_.typed == "display") { line = null; break; } else { print_error(`Missing ${var_.name}`); } } if (_value.length == 0) continue; //if there array, they should all be the same size if (_value.length == 1) { } else if (var_build.count == 1) { var_build.count = _value.length; } else if (var_build.count != 1 && _value.length != 1) { var_build.count = _value.length; } else if (_value.length != var_build.count) { print_error(`${input.template_file}: ${input.numberline} Expected ${var_build.count} values, Found ${_value.length} values`); } _varlist.push({ name: var_.name, pos: var_.pos, value: _value, }); } if (line === null) continue; var_build.graph.push({ line: line, varlist: [..._varlist], }); } var_builds.push(var_build); } const output = []; for (let var_build of var_builds) { for (let i = 0; i < var_build.count; i++) { for (let build of var_build.graph) { const varlist = [...build.varlist]; let line = build.line; while (varlist.length) { const var_ = varlist.pop(); let _value = var_.value.length != 1 ? var_.value[i] : var_.value[0]; line = line.replace(`~//${var_.pos}//~`, _value); } output.push(line); } } } return output.join("\n"); } function enabled$loc() { const loc = app$config.server.EnabledLoc; const output_file = app$config.server.OutputFile; if (!access$check(loc)) print_error(`config.server.EnabledLoc ${loc} is unaccessable.`); return path_1.default.join(loc, output_file); } function $make_sites() { const output = $build(); const loc = enabled$loc(); fs_1.default.writeFileSync(loc, output); print_log("-> a3ensite applied"); $sites_status(); } function $disable() { const loc = enabled$loc(); const state = { enabled: fs_1.default.existsSync(loc), }; if (!state.enabled) { print_log("-> a3ensite already disabled"); } else { print_log("-> a3ensite disabling..."); fs_1.default.writeFileSync(loc, ""); print_log("-> a3ensite disabled"); } $sites_status(); } function $sites_status() { const loc = enabled$loc(); const state = { enabled: fs_1.default.existsSync(loc), changed: false, }; if (state.enabled) { const latest = fs_1.default.statSync(loc); state.changed = latest.mtimeMs < app$config.$changed_time; } print_log(`Sites: ${app$config.sites.length}`); print_log(`Sites EnabledLoc: ${app$config.server.EnabledLoc}`); print_log(`Sites OutputFile: ${app$config.server.OutputFile}`); print_log(`Sites Status: ${state.enabled ? "Enabled" : "Disabled"}`); print_log(`Hosts EnabledLoc: ${app$config.options.hosts.EnabledLoc}`); if (state.changed) { print_log(`Config: Config File Changed ~ ${app$config.$config_file}`); } } function setup_config() { var _a, _b; const config_file = app$argv.config; if (!fs_1.default.existsSync(config_file)) print_error(`--config file not found ${config_file}`); const config = JSON.parse(fs_1.default.readFileSync(config_file, "utf8")); const _stat = fs_1.default.statSync(config_file); const options = Object.assign(Object.assign({}, config.options), { hosts: Object.assign({ OutputFile: "a3ensite.live.conf", EnabledLoc: "/etc/hosts" }, (_a = config === null || config === void 0 ? void 0 : config.options) === null || _a === void 0 ? void 0 : _a.hosts) }); const server = Object.assign({ OutputFile: "a3ensite.live.conf" }, config.server); let _config = { options: options, server: server, defaults: config.defaults || {}, sites: config.sites, $changed_time: _stat.mtimeMs, $config_file: config_file, }; if (!((_b = _config.server) === null || _b === void 0 ? void 0 : _b.EnabledLoc)) print_error(`config.server.EnabledLoc is required`); return _config; } function setup_template(app$argv) { const template_file = app$argv.template; if (!fs_1.default.existsSync(template_file)) print_error(`--template file not found ${template_file}`); const template = fs_1.default.readFileSync(template_file, "utf8"); const lines = template.split("\n"); const output = []; let numberline = 0; for (let line of lines) { let pos = 0; const varlist = []; let var_ = line.match(/\$\??\!?\[([^\s]+)\]\$/); while (var_ && var_["index"]) { let typed = "required"; const _flag = var_[0]; const flag = var_[1]; const _i = var_["index"]; const before = line.slice(0, _i); const after = line.slice(_i + _flag.length); if (_flag.indexOf("$?") == 0) { typed = "optional"; line = `${before}~//${pos}//~${after}`; } else if (_flag.indexOf("$!") == 0) { typed = "display"; line = `${before}${after}`; } else { line = `${before}~//${pos}//~${after}`; } varlist.push({ name: flag, pos, typed, }); pos++; var_ = line.match(/\$\??\!?\[([^\s]+)\]\$/); } output.push({ template_file, numberline, varlist, line }); numberline++; } return output; } function access$check(loc) { if (!loc) return false; try { fs_1.default.accessSync(loc, fs_1.default.constants.R_OK | fs_1.default.constants.W_OK); return true; } catch (err) { return false; } }