Blame view

node_modules/yargs/lib/argsert.js 2.42 KB
aaac7fed   liuqimichale   add
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
  const command = require('./command')()
  const YError = require('./yerror')
  
  const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
  
  module.exports = function (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.
      var position = 0
      var 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(function (demanded) {
        const arg = args.shift()
        const observedType = guessType(arg)
        const matchingTypes = demanded.cmd.filter(function (type) {
          return type === observedType || type === '*'
        })
        if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position, false)
        position += 1
      })
  
      parsed.optional.forEach(function (optional) {
        if (args.length === 0) return
        const arg = args.shift()
        const observedType = guessType(arg)
        const matchingTypes = optional.cmd.filter(function (type) {
          return 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 + '.')
  }