africa
Version:
A library to interactively create and read configuration files.
104 lines (87 loc) • 2.83 kB
JavaScript
import { resolve } from 'path'
import { homedir as home } from 'os'
import bosom from 'bosom'
import exists from '@wrote/exists'
import { Recursive } from '../src$/recursive'
import { askQuestionsAndWrite, merge, forceQuestions } from './lib'
/**
* @type {_africa.africa}
*/
export default async function africa(packageName, questions = {}, config = {}) {
if (typeof packageName != 'string')
throw new Error('Package name is required.')
const {
homedir = home(),
rcNameFunction = p => `.${p}rc`,
force = false,
local = false,
questionsTimeout: timeout,
} = config
let { recursive = false } = config
if (recursive) {
if (!process.cwd().startsWith(resolve(homedir))) {
console.error('The path %s is not under `homedir` which is %s. Settings merging via `recursive` won\'t work.',
process.cwd(), resolve(homedir))
recursive = false
// throw new Error('To use recursive feature, your cwd needs to be inside HOME.')
}
}
const RC = rcNameFunction(packageName)
const path = resolve(homedir, RC)
const LOCAL_PATH = resolve(RC)
const homeEx = await exists(path)
if (local) {
const c = await handleLocal(homeEx, path, LOCAL_PATH, questions, timeout, force)
return c
}
if (recursive) {
return Recursive(RC, LOCAL_PATH, questions, config)
}
const c = await handleHome(homeEx, path, questions, timeout, force)
return c
}
const handleHome = async (homeEx, path, questions, timeout, force) => {
if (!homeEx) {
const conf = await askQuestionsAndWrite(questions, path, { timeout })
return conf
}
const p = await getParsed(path, questions, force, timeout)
return p
}
// todo: move groups to reloquent.
/**
* Parse configuration file from the filesystem.
* @param {string} path The path to the JSON file to parse.
* @param {_reloquent.Questions} questions
* @param {boolean} force
* @param {number|undefined} [timeout]
* @param {!Object} [extra]
*/
const getParsed = async (path, questions, force, timeout, extra = {}) => {
const parsed = await bosom(path)
const all = merge(parsed, extra)
if (force) {
const c = await forceQuestions(questions, path, all, timeout)
return c
}
return all
}
const handleLocal = async (homeEx, path, localPath, questions, timeout, force) => {
const localEx = await exists(localPath)
if (!localEx) {
const h = homeEx ? await bosom(path) : {}
const conf = await forceQuestions(questions, localPath, h, timeout)
return conf
}
const p = await getParsed(localPath, questions, force, timeout)
return p
}
export { default as Group } from './lib/Group'
/**
* @suppress {nonStandardJsDocs}
* @typedef {import('..').Questions} _reloquent.Questions
*/
/**
* @suppress {nonStandardJsDocs}
* @typedef {import('../types').africa} _africa.africa
*/