Projekt

Obecné

Profil

Stáhnout (2.3 KB) Statistiky
| Větev: | Revize:
1
'use strict'
2
const command = require('./command')()
3
const YError = require('./yerror')
4

    
5
const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
6

    
7
module.exports = function argsert (expected, callerArguments, length) {
8
  // TODO: should this eventually raise an exception.
9
  try {
10
    // preface the argument description with "cmd", so
11
    // that we can run it through yargs' command parser.
12
    let position = 0
13
    let parsed = {demanded: [], optional: []}
14
    if (typeof expected === 'object') {
15
      length = callerArguments
16
      callerArguments = expected
17
    } else {
18
      parsed = command.parseCommand(`cmd ${expected}`)
19
    }
20
    const args = [].slice.call(callerArguments)
21

    
22
    while (args.length && args[args.length - 1] === undefined) args.pop()
23
    length = length || args.length
24

    
25
    if (length < parsed.demanded.length) {
26
      throw new YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`)
27
    }
28

    
29
    const totalCommands = parsed.demanded.length + parsed.optional.length
30
    if (length > totalCommands) {
31
      throw new YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`)
32
    }
33

    
34
    parsed.demanded.forEach((demanded) => {
35
      const arg = args.shift()
36
      const observedType = guessType(arg)
37
      const matchingTypes = demanded.cmd.filter(type => type === observedType || type === '*')
38
      if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position, false)
39
      position += 1
40
    })
41

    
42
    parsed.optional.forEach((optional) => {
43
      if (args.length === 0) return
44
      const arg = args.shift()
45
      const observedType = guessType(arg)
46
      const matchingTypes = optional.cmd.filter(type => type === observedType || type === '*')
47
      if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position, true)
48
      position += 1
49
    })
50
  } catch (err) {
51
    console.warn(err.stack)
52
  }
53
}
54

    
55
function guessType (arg) {
56
  if (Array.isArray(arg)) {
57
    return 'array'
58
  } else if (arg === null) {
59
    return 'null'
60
  }
61
  return typeof arg
62
}
63

    
64
function argumentTypeError (observedType, allowedTypes, position, optional) {
65
  throw new YError(`Invalid ${positionName[position] || 'manyith'} argument. Expected ${allowedTypes.join(' or ')} but received ${observedType}.`)
66
}
(2-2/10)