All files / src/foo parser.js

100% Statements 34/34
100% Branches 23/23
100% Functions 8/8
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x 1x 1x 1x 1x   1x                 32x   32x                     1x         32x 32x 32x   32x 51x   51x 8x   8x 8x   43x       32x         32x 32x 32x   32x 39x   39x   39x 39x     32x         51x            
const {pipe}                = require('../pipe')
const {toOpts:   TO_OPTS}   = require('./toOpts')
const {fromArgs: FROM_ARGS} = require('./fromArgs')
const {toArgs:   TO_ARGS}   = require('./toArgs')
const {toArgv:   TO_ARGV}   = require('./toArgv')
 
const parser = (stages = {}, parsers = {}) => {
  const {
    toArgv   = TO_ARGV,
    argv     = [],
    toOpts   = TO_OPTS,
    opts     = [],
    toArgs   = TO_ARGS,
    args     = [],
    fromArgs = FROM_ARGS
  } = stages
 
  return opt => (any, errs = []) => pipe(
    toArgv,
    ...argv,
    toOpts(opt),
    recurseOpts(opts),
    toArgs,
    transformArgs(args),
    fromArgs
  )({errs, any})
}
 
module.exports = {
  parser
}
 
function recurseOpts (optsStages) {
  return ({errs = [], opts = []} = {errs: [], opts: []}) => {
    let errs2   = []
    const opts2 = []
 
    for (let i = 0; i < opts.length; i++) {
      const opt = opts[i]
 
      if (isSubcommand(opt)) {
        const {errs: errs3, opts: opts3} = pipe(...optsStages)({errs: [], opts: opt.values})
        
        errs2 = [...errs2, ...errs3]
        opts2.push({...opt, values: opts3})
      } else {
        opts2.push(opt)
      }
    }
 
    return {errs: [...errs, ...errs2], opts: opts2}
  }
}
 
function transformArgs (argsStages) {
  return ({errs = [], args = []} = {errs: [], args: []}) => {
    let errs2   = []
    const args2 = []
 
    for (let i = 0; i < args.length; i++) {
      const arg = args[i]
 
      const {errs: errs3, args: args3} = pipe(...argsStages)({errs: [], args: arg})
 
      errs2 = [...errs2, ...errs3]
      args2.push(args3)
    }
 
    return {errs: [...errs, ...errs2], args: args2}
  }
}
 
function isSubcommand ({key, args, types, opts}) {
  return (
    typeof key === 'string' &&
    Array.isArray(args) && args.length > 0 &&
    typeof types === 'undefined' &&
    Array.isArray(opts)
  )
}