UNPKG

2.35 kBJavaScriptView Raw
1'use strict'
2const arrayify = require('array-back')
3const option = require('./option')
4
5/**
6 * Handles parsing different argv notations
7 *
8 * @module argv
9 * @private
10 */
11
12class Argv extends Array {
13 load (argv) {
14 if (argv) {
15 argv = arrayify(argv)
16 } else {
17 /* if no argv supplied, assume we are parsing process.argv */
18 argv = process.argv.slice(0)
19 argv.splice(0, 2)
20 }
21 argv.forEach(arg => this.push(arg))
22 }
23
24 clear () {
25 this.length = 0
26 }
27
28 /**
29 * expand --option=value style args. The value is clearly marked to indicate it is definitely a value (which would otherwise be unclear if the value is `--value`, which would be parsed as an option). The special marker is removed in parsing phase.
30 */
31 expandOptionEqualsNotation () {
32 const optEquals = option.optEquals
33 if (this.some(optEquals.test.bind(optEquals))) {
34 const expandedArgs = []
35 this.forEach(arg => {
36 const matches = arg.match(optEquals)
37 if (matches) {
38 expandedArgs.push(matches[1], option.VALUE_MARKER + matches[2])
39 } else {
40 expandedArgs.push(arg)
41 }
42 })
43 this.clear()
44 this.load(expandedArgs)
45 }
46 }
47
48 /**
49 * expand getopt-style combined options
50 */
51 expandGetoptNotation () {
52 const findReplace = require('find-replace')
53 const combinedArg = option.combined
54 const hasGetopt = this.some(combinedArg.test.bind(combinedArg))
55 if (hasGetopt) {
56 findReplace(this, combinedArg, arg => {
57 arg = arg.slice(1)
58 return arg.split('').map(letter => '-' + letter)
59 })
60 }
61 }
62
63 /**
64 * Inspect the user-supplied options for validation issues.
65 * @throws `UNKNOWN_OPTION`
66 */
67 validate (definitions, options) {
68 options = options || {}
69 let invalidOption
70
71 if (!options.partial) {
72 const optionWithoutDefinition = this
73 .filter(arg => option.isOption(arg))
74 .some(arg => {
75 if (definitions.get(arg) === undefined) {
76 invalidOption = arg
77 return true
78 }
79 })
80 if (optionWithoutDefinition) {
81 halt(
82 'UNKNOWN_OPTION',
83 'Unknown option: ' + invalidOption
84 )
85 }
86 }
87 }
88}
89
90function halt (name, message) {
91 const err = new Error(message)
92 err.name = name
93 throw err
94}
95
96module.exports = Argv