UNPKG

@anolilab/rc

Version:
125 lines (121 loc) 4.28 kB
import { homedir } from 'node:os'; import { cwd, env } from 'node:process'; import { readFileSync, isAccessibleSync } from '@visulima/fs'; import { parseJson, stripJsonComments } from '@visulima/fs/utils'; import { join, dirname } from '@visulima/path'; import { parse } from 'ini'; import { merge } from 'ts-deepmerge'; var __defProp$1 = Object.defineProperty; var __name$1 = (target, value) => __defProp$1(target, "name", { value, configurable: true }); const isJson = /* @__PURE__ */ __name$1((value) => { try { JSON.parse(value); } catch { return false; } return true; }, "isJson"); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); /** * Modified copy of the env function from https://github.com/dominictarr/rc/blob/a97f6adcc37ee1cad06ab7dc9b0bd842bbc5c664/lib/utils.js#L42. * @license https://github.com/dominictarr/rc/blob/master/LICENSE.APACHE2 * @license https://github.com/dominictarr/rc/blob/master/LICENSE.BSD * @license https://github.com/dominictarr/rc/blob/master/LICENSE.MIT * @param prefix * @param environment * @returns */ const getEnvironment = /* @__PURE__ */ __name((prefix, environment = env) => { const returnValue = {}; const l = prefix.length; for (const k in environment) { if (k.toLowerCase().startsWith(prefix.toLowerCase())) { const keypath = k.slice(Math.max(0, l)).split("__"); let emptyStringIndex; while ((emptyStringIndex = keypath.indexOf("")) > -1) { keypath.splice(emptyStringIndex, 1); } let cursor = returnValue; keypath.forEach((subkey, index) => { if (!subkey || typeof cursor !== "object") { return; } if (index === keypath.length - 1) { cursor[subkey] = environment[k]; } if (cursor[subkey] === void 0) { cursor[subkey] = {}; } cursor = cursor[subkey]; }); } } return returnValue; }, "getEnvironment"); const getConfigFiles = /* @__PURE__ */ __name((name, home, internalCwd, stopAt, environmentConfig, optionConfig) => { const configFiles = /* @__PURE__ */ new Set(); for (const file of [`/etc/${name}/config`, `/etc/${name}rc`]) { if (isAccessibleSync(file)) { configFiles.add(file); } } for (const file of [join(home, ".config", name, "config"), join(home, ".config", name), join(home, `.${name}`, "config"), join(home, `.${name}rc`)]) { if (isAccessibleSync(file)) { configFiles.add(file); } if (isAccessibleSync(`${file}.json`)) { configFiles.add(`${file}.json`); } } let start = internalCwd; let endOfLoop = false; const files = [join(`.${name}`, "config.json"), join(`.${name}`, "config"), join(`.${name}rc.json`), join(`.${name}rc`)]; const traversedFiles = []; do { for (const file of files) { const traverseFile = join(start, file); if (isAccessibleSync(traverseFile)) { traversedFiles.push(traverseFile); } } start = dirname(start); if (endOfLoop) { break; } endOfLoop = dirname(start) === start; } while (stopAt ? start === stopAt : true); for (const file of traversedFiles.toReversed()) { configFiles.add(file); } if (typeof environmentConfig === "string" && isAccessibleSync(environmentConfig)) { configFiles.add(environmentConfig); } if (optionConfig && isAccessibleSync(optionConfig)) { configFiles.add(optionConfig); } return [...configFiles]; }, "getConfigFiles"); const rc = /* @__PURE__ */ __name((name, options = {}) => { options = { cwd: cwd(), home: homedir(), ...options }; const { config: _, ...environment } = getEnvironment(`${name}_`); const configFiles = getConfigFiles(name, options.home, options.cwd, options.stopAt, env[`${name}_config`], options.config); const configs = []; for (const file of configFiles) { const content = readFileSync(file, { buffer: false }); if (isJson(content)) { configs.push(parseJson(stripJsonComments(content))); } else { configs.push(parse(content)); } } if (environment) { configs.push(environment); } return { config: merge(options.defaults ?? {}, ...configs), files: configFiles }; }, "rc"); export { rc };