priestine/versions

View on GitHub
src/pure/getters/get-config-from-file.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { IEither, Either } from '../../utils/either'
import type { IAppCtx } from '../../types/app-ctx'
import type { Unary } from 'types/common-types'
import { Switch } from '../../utils/switch'
import * as YAML from 'yaml'
import * as TOML from 'toml'
import { resolve } from 'path'

interface IDeps {
    readFileEither: Unary<string, IEither<string, Error>>
}

export const getConfigFromFile = ({ readFileEither }: IDeps) => (ctx: IAppCtx): any =>
    Either.fromNullable(ctx.configFile)
        .chain(() =>
            readFileEither(getAbsolutePath(ctx.configFile)).map(
                Switch.of(ctx.configFile)
                    .case((x) => /\.ya?ml$/.test(x), YAML.parse)
                    .case((x) => x.endsWith('.json'), JSON.parse)
                    .case((x) => x.endsWith('.toml'), TOML.parse)
                    .default(() => ({})),
            ),
        )
        .fold(() => ({}), mergeObjects(ctx))

// ------------------------------------------------------------------------------------------------

const getAbsolutePath = (path: string) => resolve(process.cwd(), path)

const mergeObjects = <T extends Record<string, any>, K extends Partial<T> = T>(previous: T) => (
    next: K,
) =>
    Object.keys(next).reduce((result: T, key: keyof T) => {
        if (typeof previous[key] === 'undefined') {
            return result
        }

        result[key] = next[key] as any

        return result
    }, previous)