yargs 13.0.0-candidate.0 → 13.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,66 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [13.2.2](https://github.com/yargs/yargs/compare/v13.2.1...v13.2.2) (2019-03-06)
6
+
7
+
8
+
9
+ ## [13.2.1](https://github.com/yargs/yargs/compare/v13.2.0...v13.2.1) (2019-02-18)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * add zsh script to files array ([3180224](https://github.com/yargs/yargs/commit/3180224))
15
+ * support options/sub-commands in zsh completion ([0a96394](https://github.com/yargs/yargs/commit/0a96394))
16
+
17
+
18
+
19
+ <a name="13.1.0"></a>
20
+ # [13.1.0](https://github.com/yargs/yargs/compare/v13.0.0...v13.1.0) (2019-02-12)
21
+
22
+
23
+ ### Features
24
+
25
+ * add applyBeforeValidation, for applying sync middleware before validation ([5be206a](https://github.com/yargs/yargs/commit/5be206a))
26
+
27
+
28
+
29
+ <a name="13.0.0"></a>
30
+ # [13.0.0](https://github.com/yargs/yargs/compare/v12.0.5...v13.0.0) (2019-02-02)
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * **deps:** Update os-locale to avoid security vulnerability ([#1270](https://github.com/yargs/yargs/issues/1270)) ([27bf739](https://github.com/yargs/yargs/commit/27bf739))
36
+ * **validation:** Use the error as a message when none exists otherwise ([#1268](https://github.com/yargs/yargs/issues/1268)) ([0510fe6](https://github.com/yargs/yargs/commit/0510fe6))
37
+ * better bash path completion ([#1272](https://github.com/yargs/yargs/issues/1272)) ([da75ea2](https://github.com/yargs/yargs/commit/da75ea2))
38
+ * middleware added multiple times due to reference bug ([#1282](https://github.com/yargs/yargs/issues/1282)) ([64af518](https://github.com/yargs/yargs/commit/64af518))
39
+
40
+
41
+ ### Chores
42
+
43
+ * ~drop Node 6 from testing matrix ([#1287](https://github.com/yargs/yargs/issues/1287)) ([ef16792](https://github.com/yargs/yargs/commit/ef16792))~
44
+ * _opting to not drop Node 6 support until April, [see](https://github.com/nodejs/Release)._
45
+ * update dependencies ([#1284](https://github.com/yargs/yargs/issues/1284)) ([f25de4f](https://github.com/yargs/yargs/commit/f25de4f))
46
+
47
+
48
+ ### Features
49
+
50
+ * Add `.parserConfiguration()` method, deprecating package.json config ([#1262](https://github.com/yargs/yargs/issues/1262)) ([3c6869a](https://github.com/yargs/yargs/commit/3c6869a))
51
+ * adds config option for sorting command output ([#1256](https://github.com/yargs/yargs/issues/1256)) ([6916ce9](https://github.com/yargs/yargs/commit/6916ce9))
52
+ * options/positionals with leading '+' and '0' no longer parse as numbers ([#1286](https://github.com/yargs/yargs/issues/1286)) ([e9dc3aa](https://github.com/yargs/yargs/commit/e9dc3aa))
53
+ * support promises in middleware ([f3a4e4f](https://github.com/yargs/yargs/commit/f3a4e4f))
54
+
55
+
56
+ ### BREAKING CHANGES
57
+
58
+ * options with leading '+' or '0' now parse as strings
59
+ * dropping Node 6 which hits end of life in April 2019
60
+ * see [yargs-parser@12.0.0 CHANGELOG](https://github.com/yargs/yargs-parser/blob/master/CHANGELOG.md#breaking-changes)
61
+ * we now warn if the yargs stanza package.json is used.
62
+
63
+
64
+
5
65
  <a name="12.0.5"></a>
6
66
  ## [12.0.5](https://github.com/yargs/yargs/compare/v12.0.4...v12.0.5) (2018-11-19)
7
67
 
package/README.md CHANGED
@@ -31,12 +31,12 @@ It gives you:
31
31
 
32
32
  Stable version:
33
33
  ```bash
34
- npm i yargs --save
34
+ npm i yargs
35
35
  ```
36
36
 
37
37
  Bleeding edge version with the most recent features:
38
38
  ```bash
39
- npm i yargs@next --save
39
+ npm i yargs@next
40
40
  ```
41
41
 
42
42
  ## Usage :
@@ -0,0 +1,17 @@
1
+ ###-begin-{{app_name}}-completions-###
2
+ #
3
+ # yargs command completion script
4
+ #
5
+ # Installation: {{app_path}} {{completion_command}} >> ~/.zshrc
6
+ # or {{app_path}} {{completion_command}} >> ~/.zsh_profile on OSX.
7
+ #
8
+ _{{app_name}}_yargs_completions()
9
+ {
10
+ local reply
11
+ local si=$IFS
12
+ IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" {{app_path}} --get-yargs-completions "${words[@]}"))
13
+ IFS=$si
14
+ _describe 'values' reply
15
+ }
16
+ compdef _{{app_name}}_yargs_completions {{app_name}}
17
+ ###-end-{{app_name}}-completions-###
package/lib/argsert.js CHANGED
@@ -1,16 +1,18 @@
1
1
  'use strict'
2
+
3
+ // hoisted due to circular dependency on command.
4
+ module.exports = argsert
2
5
  const command = require('./command')()
3
6
  const YError = require('./yerror')
4
7
 
5
8
  const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
6
-
7
- module.exports = function argsert (expected, callerArguments, length) {
9
+ function argsert (expected, callerArguments, length) {
8
10
  // TODO: should this eventually raise an exception.
9
11
  try {
10
12
  // preface the argument description with "cmd", so
11
13
  // that we can run it through yargs' command parser.
12
14
  let position = 0
13
- let parsed = {demanded: [], optional: []}
15
+ let parsed = { demanded: [], optional: [] }
14
16
  if (typeof expected === 'object') {
15
17
  length = callerArguments
16
18
  callerArguments = expected
package/lib/command.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const inspect = require('util').inspect
4
4
  const isPromise = require('./is-promise')
5
- const {applyMiddleware} = require('./middleware')
5
+ const { applyMiddleware, commandMiddlewareFactory } = require('./middleware')
6
6
  const path = require('path')
7
7
  const Parser = require('yargs-parser')
8
8
 
@@ -17,9 +17,10 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
17
17
  let aliasMap = {}
18
18
  let defaultCommand
19
19
  globalMiddleware = globalMiddleware || []
20
- self.addHandler = function addHandler (cmd, description, builder, handler, _middlewares) {
20
+
21
+ self.addHandler = function addHandler (cmd, description, builder, handler, commandMiddleware) {
21
22
  let aliases = []
22
- const middlewares = (_middlewares || []).slice(0)
23
+ const middlewares = commandMiddlewareFactory(commandMiddleware)
23
24
  handler = handler || (() => {})
24
25
 
25
26
  if (Array.isArray(cmd)) {
@@ -224,6 +225,9 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
224
225
  positionalMap = populatePositionals(commandHandler, innerArgv, currentContext, yargs)
225
226
  }
226
227
 
228
+ const middlewares = globalMiddleware.slice(0).concat(commandHandler.middlewares || [])
229
+ applyMiddleware(innerArgv, yargs, middlewares, true)
230
+
227
231
  // we apply validation post-hoc, so that custom
228
232
  // checks get passed populated positional arguments.
229
233
  if (!yargs._hasOutput()) yargs._runValidation(innerArgv, aliases, positionalMap, yargs.parsed.error)
@@ -231,9 +235,7 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
231
235
  if (commandHandler.handler && !yargs._hasOutput()) {
232
236
  yargs._setHasOutput()
233
237
 
234
- const middlewares = globalMiddleware.slice(0).concat(commandHandler.middlewares || [])
235
-
236
- innerArgv = applyMiddleware(innerArgv, middlewares)
238
+ innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false)
237
239
 
238
240
  const handlerResult = isPromise(innerArgv)
239
241
  ? innerArgv.then(argv => commandHandler.handler(argv))
package/lib/completion.js CHANGED
@@ -9,6 +9,7 @@ module.exports = function completion (yargs, usage, command) {
9
9
  completionKey: 'get-yargs-completions'
10
10
  }
11
11
 
12
+ const zshShell = process.env.SHELL && process.env.SHELL.indexOf('zsh') !== -1
12
13
  // get a list of completion commands.
13
14
  // 'args' is the array of strings from the line to be completed
14
15
  self.getCompletion = function getCompletion (args, done) {
@@ -16,6 +17,7 @@ module.exports = function completion (yargs, usage, command) {
16
17
  const current = args.length ? args[args.length - 1] : ''
17
18
  const argv = yargs.parse(args, true)
18
19
  const aliases = yargs.parsed.aliases
20
+ const parentCommands = yargs.getContext().commands
19
21
 
20
22
  // a custom completion function can be provided
21
23
  // to completion().
@@ -54,22 +56,33 @@ module.exports = function completion (yargs, usage, command) {
54
56
  }
55
57
  }
56
58
 
57
- if (!current.match(/^-/)) {
59
+ if (!current.match(/^-/) && parentCommands[parentCommands.length - 1] !== current) {
58
60
  usage.getCommands().forEach((usageCommand) => {
59
61
  const commandName = command.parseCommand(usageCommand[0]).cmd
60
62
  if (args.indexOf(commandName) === -1) {
61
- completions.push(commandName)
63
+ if (!zshShell) {
64
+ completions.push(commandName)
65
+ } else {
66
+ const desc = usageCommand[1] || ''
67
+ completions.push(commandName.replace(/:/g, '\\:') + ':' + desc)
68
+ }
62
69
  }
63
70
  })
64
71
  }
65
72
 
66
- if (current.match(/^-/)) {
73
+ if (current.match(/^-/) || (current === '' && completions.length === 0)) {
74
+ const descs = usage.getDescriptions()
67
75
  Object.keys(yargs.getOptions().key).forEach((key) => {
68
76
  // If the key and its aliases aren't in 'args', add the key to 'completions'
69
77
  const keyAndAliases = [key].concat(aliases[key] || [])
70
78
  const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1)
71
79
  if (notInArgs) {
72
- completions.push(`--${key}`)
80
+ if (!zshShell) {
81
+ completions.push(`--${key}`)
82
+ } else {
83
+ const desc = descs[key] || ''
84
+ completions.push(`--${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`)
85
+ }
73
86
  }
74
87
  })
75
88
  }
@@ -80,7 +93,7 @@ module.exports = function completion (yargs, usage, command) {
80
93
  // generate the completion script to add to your .bashrc.
81
94
  self.generateCompletionScript = function generateCompletionScript ($0, cmd) {
82
95
  let script = fs.readFileSync(
83
- path.resolve(__dirname, '../completion.sh.hbs'),
96
+ path.resolve(__dirname, zshShell ? '../completion.zsh.hbs' : '../completion.sh.hbs'),
84
97
  'utf-8'
85
98
  )
86
99
  const name = path.basename($0)
package/lib/middleware.js CHANGED
@@ -1,29 +1,61 @@
1
+ 'use strict'
2
+
3
+ // hoisted due to circular dependency on command.
4
+ module.exports = {
5
+ applyMiddleware,
6
+ commandMiddlewareFactory,
7
+ globalMiddlewareFactory
8
+ }
1
9
  const isPromise = require('./is-promise')
10
+ const argsert = require('./argsert')
2
11
 
3
- module.exports = function (globalMiddleware, context) {
4
- return function (callback) {
12
+ function globalMiddlewareFactory (globalMiddleware, context) {
13
+ return function (callback, applyBeforeValidation = false) {
14
+ argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length)
5
15
  if (Array.isArray(callback)) {
16
+ for (let i = 0; i < callback.length; i++) {
17
+ if (typeof callback[i] !== 'function') {
18
+ throw Error('middleware must be a function')
19
+ }
20
+ callback[i].applyBeforeValidation = applyBeforeValidation
21
+ }
6
22
  Array.prototype.push.apply(globalMiddleware, callback)
7
23
  } else if (typeof callback === 'function') {
24
+ callback.applyBeforeValidation = applyBeforeValidation
8
25
  globalMiddleware.push(callback)
9
26
  }
10
27
  return context
11
28
  }
12
29
  }
13
30
 
14
- module.exports.applyMiddleware = function (argv, middlewares) {
31
+ function commandMiddlewareFactory (commandMiddleware) {
32
+ if (!commandMiddleware) return []
33
+ return commandMiddleware.map(middleware => {
34
+ middleware.applyBeforeValidation = false
35
+ return middleware
36
+ })
37
+ }
38
+
39
+ function applyMiddleware (argv, yargs, middlewares, beforeValidation) {
40
+ const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true')
15
41
  return middlewares
16
42
  .reduce((accumulation, middleware) => {
43
+ if (middleware.applyBeforeValidation !== beforeValidation &&
44
+ !isPromise(accumulation)) {
45
+ return accumulation
46
+ }
47
+
17
48
  if (isPromise(accumulation)) {
18
49
  return accumulation
19
50
  .then(initialObj =>
20
- Promise.all([initialObj, middleware(initialObj)])
51
+ Promise.all([initialObj, middleware(initialObj, yargs)])
21
52
  )
22
53
  .then(([initialObj, middlewareObj]) =>
23
54
  Object.assign(initialObj, middlewareObj)
24
55
  )
25
56
  } else {
26
- const result = middleware(argv)
57
+ const result = middleware(argv, yargs)
58
+ if (beforeValidation && isPromise(result)) throw beforeValidationError
27
59
 
28
60
  return isPromise(result)
29
61
  ? result.then(middlewareObj => Object.assign(accumulation, middlewareObj))
package/lib/usage.js CHANGED
@@ -181,7 +181,7 @@ module.exports = function usage (yargs, y18n) {
181
181
  usages.forEach((usage) => {
182
182
  ui.div(`${usage[0].replace(/\$0/g, base$0)}`)
183
183
  if (usage[1]) {
184
- ui.div({text: `${usage[1]}`, padding: [1, 0, 0, 0]})
184
+ ui.div({ text: `${usage[1]}`, padding: [1, 0, 0, 0] })
185
185
  }
186
186
  })
187
187
  ui.div()
@@ -217,7 +217,7 @@ module.exports = function usage (yargs, y18n) {
217
217
  padding: [0, 2, 0, 2],
218
218
  width: maxWidth(commands, theWrap, `${base$0}${parentCommands}`) + 4
219
219
  },
220
- {text: command[1]}
220
+ { text: command[1] }
221
221
  )
222
222
  const hints = []
223
223
  if (command[2]) hints.push(`[${__('default:').slice(0, -1)}]`) // TODO hacking around i18n here
@@ -225,7 +225,7 @@ module.exports = function usage (yargs, y18n) {
225
225
  hints.push(`[${__('aliases:')} ${command[3].join(', ')}]`)
226
226
  }
227
227
  if (hints.length) {
228
- ui.div({text: hints.join(' '), padding: [0, 0, 0, 2], align: 'right'})
228
+ ui.div({ text: hints.join(' '), padding: [0, 0, 0, 2], align: 'right' })
229
229
  } else {
230
230
  ui.div()
231
231
  }
@@ -301,11 +301,11 @@ module.exports = function usage (yargs, y18n) {
301
301
  ].filter(Boolean).join(' ')
302
302
 
303
303
  ui.span(
304
- {text: kswitch, padding: [0, 2, 0, 2], width: maxWidth(switches, theWrap) + 4},
304
+ { text: kswitch, padding: [0, 2, 0, 2], width: maxWidth(switches, theWrap) + 4 },
305
305
  desc
306
306
  )
307
307
 
308
- if (extra) ui.div({text: extra, padding: [0, 0, 0, 2], align: 'right'})
308
+ if (extra) ui.div({ text: extra, padding: [0, 0, 0, 2], align: 'right' })
309
309
  else ui.div()
310
310
  })
311
311
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yargs",
3
- "version": "13.0.0-candidate.0",
3
+ "version": "13.2.2",
4
4
  "description": "yargs the modern, pirate-themed, successor to optimist.",
5
5
  "main": "./index.js",
6
6
  "contributors": [
@@ -15,6 +15,7 @@
15
15
  "lib",
16
16
  "locales",
17
17
  "completion.sh.hbs",
18
+ "completion.zsh.hbs",
18
19
  "LICENSE"
19
20
  ],
20
21
  "dependencies": {
@@ -41,8 +42,8 @@
41
42
  "mocha": "^5.2.0",
42
43
  "nyc": "^13.2.0",
43
44
  "rimraf": "^2.6.3",
44
- "standard": "^11.0.1",
45
- "standard-version": "^4.4.0",
45
+ "standard": "^12.0.1",
46
+ "standard-version": "^5.0.0",
46
47
  "which": "^1.3.1",
47
48
  "yargs-test-extends": "^1.0.1"
48
49
  },
package/yargs.js CHANGED
@@ -11,7 +11,7 @@ const Y18n = require('y18n')
11
11
  const objFilter = require('./lib/obj-filter')
12
12
  const setBlocking = require('set-blocking')
13
13
  const applyExtends = require('./lib/apply-extends')
14
- const middlewareFactory = require('./lib/middleware')
14
+ const { globalMiddlewareFactory } = require('./lib/middleware')
15
15
  const YError = require('./lib/yerror')
16
16
 
17
17
  exports = module.exports = Yargs
@@ -33,7 +33,7 @@ function Yargs (processArgs, cwd, parentRequire) {
33
33
  updateFiles: false
34
34
  })
35
35
 
36
- self.middleware = middlewareFactory(globalMiddleware, self)
36
+ self.middleware = globalMiddlewareFactory(globalMiddleware, self)
37
37
 
38
38
  if (!cwd) cwd = process.cwd()
39
39
 
@@ -903,7 +903,7 @@ function Yargs (processArgs, cwd, parentRequire) {
903
903
  // register the completion command.
904
904
  completionCommand = cmd || 'completion'
905
905
  if (!desc && desc !== false) {
906
- desc = 'generate bash completion script'
906
+ desc = 'generate completion script'
907
907
  }
908
908
  self.command(completionCommand, desc)
909
909