UNPKG

@report-toolkit/fs

Version:

See docs at [https://ibm.github.io/report-toolkit](https://ibm.github.io/report-toolkit)

116 lines (107 loc) 2.86 kB
import {_, createDebugPipe, error, observable} from '@report-toolkit/common'; import path from 'path'; import cosmiconfig from 'cosmiconfig'; import xdgBasedir from 'xdg-basedir'; import globalDirs from 'global-dirs'; import os from 'os'; import {RC_NAMESPACE} from './constants.js'; const {RTKERR_MISSING_CONFIG} = error; const { map, mergeMap, filter, concatMap, concatMapTo, of, pipeIf, switchMapTo, take, throwRTkError } = observable; const debug = createDebugPipe('cli', 'loaders', 'config'); const EXTRA_SEARCH_DIRS = [ os.homedir(), path.join(globalDirs.npm.prefix, 'etc') ]; if (os.platform() !== 'win32') { EXTRA_SEARCH_DIRS.push(...xdgBasedir.configDirs, '/etc'); } const getExplorer = _.memoize(opts => // @ts-ignore cosmiconfig( RC_NAMESPACE, _.defaultsDeep( { // @ts-ignore loaders: {noExt: cosmiconfig.loadJs} }, opts ) ) ); /** * * @param {import('cosmiconfig').Options} [opts] - Extra opts for cosmiconfig * @returns {import('rxjs').OperatorFunction<string,object>} */ function toConfigFromSearchPath(opts = {}) { const explorer = getExplorer(opts); return observable => observable.pipe( mergeMap(searchpath => explorer.search(searchpath)), pipeIf( _.isObject, debug(config => `found config at ${config.filepath}`), map(_.get('config.config')) ) ); } /** * * @param {import('cosmiconfig').Options} [opts] - Extra opts for cosmiconfig * @returns {import('rxjs').OperatorFunction<string,object>} */ function toConfigFromFilepath(opts = {}) { const explorer = getExplorer(opts); return observable => observable.pipe( mergeMap(filepath => explorer.load(filepath)), map(_.get('config.config')) ); } export const fromFilesystemToConfig = ({ config: rawConfigOrFilepath = {}, searchPath = process.cwd(), search = true } = {}) => { const allSearchPaths = [searchPath, ...EXTRA_SEARCH_DIRS]; return of(rawConfigOrFilepath).pipe( pipeIf(_.isString, toConfigFromFilepath()), pipeIf( /** @param {object} rawConfig */ rawConfig => _.isEmpty(rawConfig) && search, concatMapTo(allSearchPaths), debug(allSearchPath => `searching in ${allSearchPath} for config`), concatMap(allSearchPath => of(allSearchPath).pipe( pipeIf(allSearchPath === searchPath, toConfigFromSearchPath()), pipeIf( allSearchPath !== searchPath, toConfigFromSearchPath({stopDir: allSearchPath}) ) ) ), filter(_.negate(_.isEmpty)), take(1) ), pipeIf( _.isEmpty && _.isString(rawConfigOrFilepath), switchMapTo( throwRTkError( RTKERR_MISSING_CONFIG, `No config file found at ${rawConfigOrFilepath}` ) ) ) ); };