[Service] Integrate DeviceHome and SignalingServer
[platform/framework/web/wrtjs.git] / device_home / node_modules / yargs / lib / argsert.js
1 'use strict'
2
3 // hoisted due to circular dependency on command.
4 module.exports = argsert
5 const command = require('./command')()
6 const YError = require('./yerror')
7
8 const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
9 function argsert (expected, callerArguments, length) {
10   // TODO: should this eventually raise an exception.
11   try {
12     // preface the argument description with "cmd", so
13     // that we can run it through yargs' command parser.
14     let position = 0
15     let parsed = { demanded: [], optional: [] }
16     if (typeof expected === 'object') {
17       length = callerArguments
18       callerArguments = expected
19     } else {
20       parsed = command.parseCommand(`cmd ${expected}`)
21     }
22     const args = [].slice.call(callerArguments)
23
24     while (args.length && args[args.length - 1] === undefined) args.pop()
25     length = length || args.length
26
27     if (length < parsed.demanded.length) {
28       throw new YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`)
29     }
30
31     const totalCommands = parsed.demanded.length + parsed.optional.length
32     if (length > totalCommands) {
33       throw new YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`)
34     }
35
36     parsed.demanded.forEach((demanded) => {
37       const arg = args.shift()
38       const observedType = guessType(arg)
39       const matchingTypes = demanded.cmd.filter(type => type === observedType || type === '*')
40       if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position, false)
41       position += 1
42     })
43
44     parsed.optional.forEach((optional) => {
45       if (args.length === 0) return
46       const arg = args.shift()
47       const observedType = guessType(arg)
48       const matchingTypes = optional.cmd.filter(type => type === observedType || type === '*')
49       if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position, true)
50       position += 1
51     })
52   } catch (err) {
53     console.warn(err.stack)
54   }
55 }
56
57 function guessType (arg) {
58   if (Array.isArray(arg)) {
59     return 'array'
60   } else if (arg === null) {
61     return 'null'
62   }
63   return typeof arg
64 }
65
66 function argumentTypeError (observedType, allowedTypes, position, optional) {
67   throw new YError(`Invalid ${positionName[position] || 'manyith'} argument. Expected ${allowedTypes.join(' or ')} but received ${observedType}.`)
68 }