future-id/mdr-cli

View on GitHub
src/utils/Utils.ts

Summary

Maintainability
A
0 mins
Test Coverage
import path from "path";
import ora from "ora";
import chalk from "chalk";
import Logger from "./Logger";
import TOML from "@iarna/toml";
import ofs, { promises as fs } from "fs";
import { Config, ConfigType } from "./Config";
import { AuthType } from "./Types";
import { name } from "../../package.json";

export const Regex = {
    domain: /^\w+\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2,3})?$/gui
};

export const logger = new Logger();
export const spinner = ora("Loading");

export const fileName = "settings";
export const fileType = "toml";

// Platform dir only tested on linux Pop-OS 20.04
// According to google and stack overflow these paths should be correct for all systems
// There is a slight chance it might not properly work on some systems ¯\_(ツ)_/¯
export const PLATFORM_DIR = process.env.APPDATA || (process.platform === "darwin" ? `${process.env.HOME}/Library/Preferences` : `${process.env.HOME}/.config`);
export const CONFIG_DIR = path.join(PLATFORM_DIR, name);
export const CONFIG_FILE = path.join(CONFIG_DIR, `${fileName}.${fileType}`);

export const defaultConf = `authType = "md5"
user = ""
password = ""
host = "manager.mijndomeinreseller.nl"
apiPath = "/api/"
useSSL = true
lastNotification = ${Date.now()}`;

export function capitalize(str: string): string {
    return str.charAt(0).toUpperCase() + str.slice(1);
}

export function checkType(type: string): AuthType {
    switch (type) {
        case "plain":
        case "md5":
            return type;
        default:
            logger.error(
                `Invalid auth type in ${CONFIG_FILE}\n` +
                "Auth type can only be md5 or plain"
            );
            process.exit(1);
    }
}

export function isYarnGlobal(): boolean {
    const yarnPath = process.platform === "win32" ? path.join("Yarn", "config", "global") : path.join(".config", "yarn", "global");
    return __dirname.includes(yarnPath);
}

export function isYarnLocal(): boolean {
    return ofs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
}

export function isYarn(): boolean {
    return (isYarnLocal() || isYarnGlobal());
}

export function isDev(): boolean {
    return process.env.NODE_ENV === "development";
}

export function isDebug(): boolean {
    return yn(process.env.MDR_DEBUG, false);
}

export function configExists(): boolean {
    const dirExists = ofs.existsSync(CONFIG_DIR);
    const fileExists = ofs.existsSync(CONFIG_FILE);
    return dirExists && fileExists;
}

export async function createConfig(): Promise<void> {
    const dirExists = ofs.existsSync(CONFIG_DIR);
    if (!dirExists) {
        await fs.mkdir(CONFIG_DIR);
    }

    const fileExists = ofs.existsSync(CONFIG_FILE);
    if (!fileExists) {
        await fs.writeFile(CONFIG_FILE, defaultConf, "utf-8");
        logger.info(
            `Config file created at ${CONFIG_FILE}.\n` +
            `Please set a username and password using ${chalk.bold("mdr set")} command before continuing!\n` +
            "It is recommended to not manually edit this file."
        );
        process.exit(0);
    }
}

export async function getConfig(): Promise<Config> {
    const toml = await fs.readFile(CONFIG_FILE, "utf-8");
    const cfg = (await TOML.parse.async(toml)) as ConfigType;
    return new Config(cfg);
}

export function getConfigSync(): Config {
    const toml = ofs.readFileSync(CONFIG_FILE, "utf-8");
    const cfg = TOML.parse(toml) as ConfigType;
    return new Config(cfg);
}

// Signature 1
export function yn(input: unknown, default_: boolean): boolean;
// Signature 2
export function yn(input: unknown, default_?: boolean): boolean | undefined;
// Implementation of both signatures (aka: implementation signature)
export function yn(input: unknown, default_?: boolean): boolean | undefined {
    const value = String(input).trim();

    if (/^(?:y|yes|true|1|on)$/i.test(value)) {
        return true;
    }

    if (/^(?:n|no|false|0|off)$/i.test(value)) {
        return false;
    }

    return default_;
}