You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							68 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
	
	
							68 lines
						
					
					
						
							2.4 KiB
						
					
					
				'use strict' | 
						|
 | 
						|
// hoisted due to circular dependency on command. | 
						|
module.exports = argsert | 
						|
const command = require('./command')() | 
						|
const YError = require('./yerror') | 
						|
 | 
						|
const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'] | 
						|
function argsert (expected, callerArguments, length) { | 
						|
  // TODO: should this eventually raise an exception. | 
						|
  try { | 
						|
    // preface the argument description with "cmd", so | 
						|
    // that we can run it through yargs' command parser. | 
						|
    let position = 0 | 
						|
    let parsed = { demanded: [], optional: [] } | 
						|
    if (typeof expected === 'object') { | 
						|
      length = callerArguments | 
						|
      callerArguments = expected | 
						|
    } else { | 
						|
      parsed = command.parseCommand(`cmd ${expected}`) | 
						|
    } | 
						|
    const args = [].slice.call(callerArguments) | 
						|
 | 
						|
    while (args.length && args[args.length - 1] === undefined) args.pop() | 
						|
    length = length || args.length | 
						|
 | 
						|
    if (length < parsed.demanded.length) { | 
						|
      throw new YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`) | 
						|
    } | 
						|
 | 
						|
    const totalCommands = parsed.demanded.length + parsed.optional.length | 
						|
    if (length > totalCommands) { | 
						|
      throw new YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`) | 
						|
    } | 
						|
 | 
						|
    parsed.demanded.forEach((demanded) => { | 
						|
      const arg = args.shift() | 
						|
      const observedType = guessType(arg) | 
						|
      const matchingTypes = demanded.cmd.filter(type => type === observedType || type === '*') | 
						|
      if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position, false) | 
						|
      position += 1 | 
						|
    }) | 
						|
 | 
						|
    parsed.optional.forEach((optional) => { | 
						|
      if (args.length === 0) return | 
						|
      const arg = args.shift() | 
						|
      const observedType = guessType(arg) | 
						|
      const matchingTypes = optional.cmd.filter(type => type === observedType || type === '*') | 
						|
      if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position, true) | 
						|
      position += 1 | 
						|
    }) | 
						|
  } catch (err) { | 
						|
    console.warn(err.stack) | 
						|
  } | 
						|
} | 
						|
 | 
						|
function guessType (arg) { | 
						|
  if (Array.isArray(arg)) { | 
						|
    return 'array' | 
						|
  } else if (arg === null) { | 
						|
    return 'null' | 
						|
  } | 
						|
  return typeof arg | 
						|
} | 
						|
 | 
						|
function argumentTypeError (observedType, allowedTypes, position, optional) { | 
						|
  throw new YError(`Invalid ${positionName[position] || 'manyith'} argument. Expected ${allowedTypes.join(' or ')} but received ${observedType}.`) | 
						|
}
 | 
						|
 |