a3ensite
Version:
Apache/Nginx/Config Manager, JSON based
293 lines (292 loc) • 10.7 kB
JavaScript
;
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;
}
}