You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.2 KiB
127 lines
3.2 KiB
import fs from 'fs-extra';
|
|
import path from 'path';
|
|
import JSON5 from 'json5';
|
|
import isUndefined from 'lodash/isUndefined.js';
|
|
|
|
import type { Config, SSH, Server, SSL } from './interfaces';
|
|
import {
|
|
sshDefault,
|
|
serverDefault,
|
|
forceSSHDefault,
|
|
defaultCommand,
|
|
} from './defaults.js';
|
|
|
|
type confValue = boolean | string | number | undefined | SSH | Server | SSL;
|
|
/**
|
|
* Cast given value to boolean
|
|
*
|
|
* @param value - variable to cast
|
|
* @returns variable cast to boolean
|
|
*/
|
|
function ensureBoolean(value: confValue): boolean {
|
|
switch (value) {
|
|
case true:
|
|
case 'true':
|
|
case 1:
|
|
case '1':
|
|
case 'on':
|
|
case 'yes':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load JSON5 config from file and merge with default args
|
|
* If no path is provided the default config is returned
|
|
*
|
|
* @param filepath - path to config to load
|
|
* @returns variable cast to boolean
|
|
*/
|
|
export async function loadConfigFile(filepath?: string): Promise<Config> {
|
|
if (isUndefined(filepath)) {
|
|
return {
|
|
ssh: sshDefault,
|
|
server: serverDefault,
|
|
command: defaultCommand,
|
|
forceSSH: forceSSHDefault,
|
|
};
|
|
}
|
|
const content = await fs.readFile(path.resolve(filepath));
|
|
const parsed = JSON5.parse(content.toString()) as Config;
|
|
return {
|
|
ssh: isUndefined(parsed.ssh)
|
|
? sshDefault
|
|
: Object.assign(sshDefault, parsed.ssh),
|
|
server: isUndefined(parsed.server)
|
|
? serverDefault
|
|
: Object.assign(serverDefault, parsed.server),
|
|
command: isUndefined(parsed.command) ? defaultCommand : `${parsed.command}`,
|
|
forceSSH: isUndefined(parsed.forceSSH)
|
|
? forceSSHDefault
|
|
: ensureBoolean(parsed.forceSSH),
|
|
ssl: parsed.ssl,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Merge 2 objects removing undefined fields
|
|
*
|
|
* @param target - base object
|
|
* @param source - object to get new values from
|
|
* @returns merged object
|
|
*
|
|
*/
|
|
const objectAssign = (
|
|
target: SSH | Server,
|
|
source: Record<string, confValue>,
|
|
): SSH | Server =>
|
|
Object.fromEntries(
|
|
Object.entries(source).map(([key, value]) => [
|
|
key,
|
|
isUndefined(source[key]) ? target[key] : value,
|
|
]),
|
|
) as SSH | Server;
|
|
|
|
/**
|
|
* Merge cli arguemens with config object
|
|
*
|
|
* @param opts - Object containing cli args
|
|
* @param config - Config object
|
|
* @returns merged configuration
|
|
*
|
|
*/
|
|
export function mergeCliConf(
|
|
opts: Record<string, confValue>,
|
|
config: Config,
|
|
): Config {
|
|
const ssl = {
|
|
key: opts['ssl-key'],
|
|
cert: opts['ssl-cert'],
|
|
...config.ssl,
|
|
} as SSL;
|
|
return {
|
|
ssh: objectAssign(config.ssh, {
|
|
user: opts['ssh-user'],
|
|
host: opts['ssh-host'],
|
|
auth: opts['ssh-auth'],
|
|
port: opts['ssh-port'],
|
|
pass: opts['ssh-pass'],
|
|
key: opts['ssh-key'],
|
|
knownHosts: opts['known-hosts'],
|
|
}) as SSH,
|
|
server: objectAssign(config.server, {
|
|
base: opts.base,
|
|
host: opts.host,
|
|
port: opts.port,
|
|
title: opts.title,
|
|
bypassHelmet: opts['bypass-helmet'],
|
|
}) as Server,
|
|
command: isUndefined(opts.command) ? config.command : `${opts.command}`,
|
|
forceSSH: isUndefined(opts['force-ssh'])
|
|
? config.forceSSH
|
|
: ensureBoolean(opts['force-ssh']),
|
|
ssl: isUndefined(ssl.key) || isUndefined(ssl.cert) ? undefined : ssl,
|
|
};
|
|
}
|
|
|