All files / src lexer.js

21.43% Statements 6/28
0% Branches 0/31
7.69% Functions 1/13
23.08% Lines 6/26

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 80 81 82 83 84 85 86 87 885x 5x 5x 5x   5x             10x                                                                                                                                                      
const {Async}           = require('./Async')
const {Sync}            = require('./Sync')
const {toArgv: TO_ARGV} = require('./toArgv')
const {toOpts: TO_OPTS} = require('./toOpts')
 
module.exports = {
  lexerF,
  lexer:     lexerF(Async),
  lexerSync: lexerF(Sync)
}
 
function lexerF (Mode) {
  return (stages = {}, substages = {}) => {
    const {
      toArgv = TO_ARGV,
      argv   = [],
      toOpts = TO_OPTS,
      opts   = []
    } = stages
 
    return opt => Mode.then(
      toArgv,
      ...argv,
      toOpts(opt),
      recurseOpts(Mode)(opts, substages)
    )
  }
}
 
function recurseOpts (Mode) {
  return (optsStages, substages, optsStages2) => ({errs = [], opts = []} = {errs: [], opts: []}) => {
    const stages = optsStages2 || optsStages
 
    const promise1 = Mode.then(...stages)({errs, opts})
    
    return Mode.then(result => {
      const {errs: errs3 = [], opts: opts3 = []} = result || {errs, opts: []}
 
      const promises = opts3.map(opt => {
        if (isSubcommand(opt) && hasValues(opt)) {
          const stages = (
            Array.isArray(substages[opt.key]) ? substages[opt.key] :
            Array.isArray(substages._)        ? substages._
                                              : undefined
          )
          const substages2 = substages[opt.key] || substages._ || {}
  
          const promise2 = recurseOpts(Mode)(optsStages, substages2, stages)({errs: [], opts: opt.values})
          
          return Mode.then(({errs: errs4, opts: opts4}) => {
            return {
              errs: errs4,
              opts: [{...opt, values: opts4}]
            }
          })(promise2)
        } else {
          return Mode.resolve({
            errs: [],
            opts: [opt]
          })
        }
      })
 
      return Mode.then(results => {
        return results.reduce(
          ({errs, opts}, {errs: errs2, opts: opts2}) => ({
            errs: [...errs, ...errs2],
            opts: [...opts, ...opts2],
          }),
          {errs: errs3, opts: []}
        )
      })(Mode.all(promises))
    })(promise1)
  }
}
 
function isSubcommand ({key, args, types, opts}) {
  return (
    typeof key === 'string' &&
    Array.isArray(args) && args.length > 0 &&
    typeof types === 'undefined' &&
    Array.isArray(opts)
  )
}
 
function hasValues ({values}) {
  return Array.isArray(values)
}