Socket
Socket
Sign inDemoInstall

cac

Package Overview
Dependencies
Maintainers
1
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cac - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

261

index.js

@@ -1,120 +0,201 @@

'use strict'
const Path = require('path')
const co = require('co')
const isGeneratorFunction = require('is-generator-function')
const minimist = require('minimist')
const camelcaseKeys = require('camelcase-keys')
const readPkgUp = require('read-pkg-up')
const assign = require('deep-assign')
'use strict';
const parentDir = Path.dirname(module.parent.filename)
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
function formatArgv(argv) {
const input = argv._
delete argv._
return {
input,
flags: camelcaseKeys(argv, {exclude: ['--']})
var minimist = _interopDefault(require('minimist'));
var table = _interopDefault(require('text-table'));
var indent = _interopDefault(require('indent-string'));
var chalk = _interopDefault(require('chalk'));
var camelcase = _interopDefault(require('camelcase-keys'));
var readPkg = _interopDefault(require('read-pkg-up'));
var prefixedOption = function (option, aliasOptions) {
var options = [option]
if (aliasOptions[option]) {
options.push(aliasOptions[option])
}
return options
.map(function (name) { return name.length > 1 ? ("--" + name) : ("-" + name); })
.join(', ')
}
function printWrap(pkg, text) {
const header = pkg.description
? `\n ${pkg.description}\n`
: ''
console.log(header + text)
var showDefaultValue = function (value) {
return (typeof value === 'undefined') ?
'' :
chalk.grey(("[default: " + value + "]"))
}
const Cac = function (help, options) {
if (!(this instanceof Cac)) {
return new Cac(help, options)
var parseNames = function (names) {
if (names === '*') {
return {name: '*'}
}
this.commands = {}
this.rawCommands = []
this.help = help || ''
this.options = options || {}
this.pkg = readPkgUp.sync({
cwd: parentDir,
normalize: false
}).pkg
var splitNames = names
.match(/([\w\.]+)\s*,?\s*([\w\.]*)/)
.slice(1, 3)
.sort()
.reverse()
return {
name: splitNames[0],
alias: splitNames[1]
}
}
const _ = Cac.prototype
_.command = function (name, fn) {
name.split(',').forEach(val => {
val = val.trim()
this.commands[val] = fn
this.rawCommands.push(val)
var parseArgv = function (argv, options) {
var result = {}
var args = minimist(argv, options)
var input = args._
delete args._
result.input = input
result.flags = args
return camelcase(result, {
excludeKeys: ['--']
})
}
_.parse = function (argv) {
argv = argv || process.argv.slice(2)
var defaultOptions = {
help: {
description: 'Output usage information'
},
version: {
description: 'Output version number'
}
}
const options = assign({}, {
alias: {
v: 'version',
h: 'help'
}
}, this.options)
var CAC = function CAC() {
var this$1 = this;
this.argv = formatArgv(minimist(argv, options))
this.bootstrap()
}
if (!(this instanceof CAC)) {
return new CAC()
}
this.commands = {}
this.aliasCommands = {}
this.defaultValues = {}
this.options = defaultOptions
this.aliasOptions = {}
this.handleError = function (err) {
throw err
}
this.pkg = readPkg.sync().pkg
_.bootstrap = function () {
const title = this.pkg.bin
? Object.keys(this.pkg.bin)[0]
: this.pkg.name
process.title = title
this
.addAliasOption('version', 'v')
.addAliasOption('help', 'h')
if (this.argv.flags.help) {
this.showHelp()
return
this
.command('help', 'Display help', function () { return this$1.showHelp(); })
};
CAC.prototype.onError = function onError (fn) {
this.handleError = fn
return this
};
CAC.prototype.addAliasOption = function addAliasOption (long, short) {
this.aliasOptions[long] = short
return this
};
CAC.prototype.aliasCommand = function aliasCommand (long, short) {
this.aliasCommands[long] = short
if (long && short) {
this.commands[short] = this.commands[long]
}
};
if (this.argv.flags.version && this.pkg.version) {
console.log(this.pkg.version)
return
CAC.prototype.option = function option (names, description, defaultValue) {
var ref = parseNames(names);
var name = ref.name;
var alias = ref.alias;
this.options[name] = {
description: description,
defaultValue: defaultValue
}
if (typeof defaultValue !== 'undefined') {
this.defaultValues[name] = defaultValue
}
const command = this.argv.input[0]
if (this.rawCommands.indexOf(command) === -1) {
this.runCommand(this.commands['*'])
} else {
this.runCommand(this.commands[command])
if (alias) {
this.addAliasOption(name, alias)
}
}
_.runCommand = function (commandFn) {
if (commandFn) {
const context = {
input: this.argv.input,
flags: this.argv.flags,
showHelp: this.showHelp.bind(this),
rawCommands: this.rawCommands
return this
};
CAC.prototype.showHelp = function showHelp () {
var this$1 = this;
var optionsTable = table(Object.keys(this.options).map(function (option) { return [
chalk.yellow(prefixedOption(option, this$1.aliasOptions)),
chalk.grey(this$1.options[option].description),
showDefaultValue(this$1.options[option].defaultValue)
]; }))
var commandsTable = table(Object.keys(this.aliasCommands).map(function (command) {
var alias = this$1.aliasCommands[command]
return [
chalk.yellow(("" + command + (alias ? (", " + alias) : ''))),
chalk.grey(this$1.commands[command].description)
]
}))
var help = (this.pkg.description ? ("\n" + (this.pkg.description) + "\n") : '') + "\nUsage: " + (chalk.yellow(this.pkg.name)) + " " + (chalk.grey('[options] [commands]')) + "\n\nCommands:\n\n" + (indent(commandsTable, 2)) + "\n\nOptions:\n\n" + (indent(optionsTable, 2)) + "\n"
console.log(indent(help, 2))
process.exit(0)
};
CAC.prototype.command = function command (names, description, fn) {
var ref = parseNames(names);
var name = ref.name;
var alias = ref.alias;
this.commands[name] = {
description: description,
fn: fn
}
this.aliasCommand(name, alias)
return this
};
CAC.prototype.runCommand = function runCommand (command) {
var commandFn = command && command.fn
if (typeof commandFn === 'function') {
var result
try {
result = commandFn(this.argv.input, this.argv.flags)
} catch (err) {
this.handleError(err)
}
if (isGeneratorFunction(commandFn)) {
co(commandFn.bind(context)).catch(this.onError.bind(context))
} else {
commandFn.call(context)
if (result && result.then) {
result.catch(this.handleError)
}
}
}
_.showHelp = function () {
if (this.help) {
if (Array.isArray(this.help)) {
printWrap.call(this.pkg, this.help.join('\n'))
} else {
printWrap(this.pkg, this.help)
}
return this
};
CAC.prototype.showVersion = function showVersion () {
console.log(this.pkg.version)
process.exit(0)
};
CAC.prototype.parse = function parse (argv) {
argv = argv || process.argv.slice(2)
this.argv = parseArgv(argv, {
alias: this.aliasOptions,
default: this.defaultValues
})
if (this.argv.flags.help) {
this.showHelp()
}
}
if (this.argv.flags.version) {
this.showVersion()
}
_.onError = function (e) {
console.log(e.stack || e.message || e.name)
}
var command = this.commands[this.argv.input[0] || '*']
this.runCommand(command)
module.exports = Cac
return this
};
module.exports = CAC;
{
"name": "cac",
"version": "1.0.0",
"description": "Command And Conquer.",
"version": "2.0.0",
"description": "Command & Conquer, the command-line queen.",
"license": "MIT",
"repository": "egoist/cac",
"author": {
"name": "EGOIST",
"name": "egoist",
"email": "0x142857@gmail.com",

@@ -16,5 +16,5 @@ "url": "github.com/egoist"

"scripts": {
"test": "xo && nyc ava",
"example:help": "node examples/help -h",
"example:alias-command": "node examples/alias-command r"
"test": "xo src/index.js",
"test2": "npm run build && npm test",
"build": "bubleup"
},

@@ -27,2 +27,4 @@ "files": [

"commander",
"yargs",
"args",
"meow",

@@ -32,6 +34,2 @@ "minimist"

"devDependencies": {
"ava": "latest",
"coveralls": "^2.11.9",
"nyc": "^6.4.0",
"then-sleep": "^1.0.1",
"xo": "latest"

@@ -43,25 +41,21 @@ },

"rules": {
"operator-linebreak": [
2,
"before"
],
"no-warning-comments": [
2,
{
"terms": [
"fixme"
],
"location": "start"
}
]
"xo/no-process-exit": 0
}
},
"dependencies": {
"camelcase-keys": "^2.1.0",
"co": "^4.6.0",
"deep-assign": "^2.0.0",
"is-generator-function": "^1.0.3",
"camelcase-keys": "^3.0.0",
"chalk": "^1.1.3",
"indent-string": "^3.0.0",
"minimist": "^1.2.0",
"read-pkg-up": "^1.0.1"
"read-pkg-up": "^1.0.1",
"text-table": "^0.2.0"
},
"bubleup": {
"transforms": {
"dangerousForOf": true
}
},
"kanpai": {
"testScript": "test2"
}
}

@@ -1,15 +0,7 @@

# CAC [![NPM version](https://img.shields.io/npm/v/cac.svg)](https://npmjs.com/package/cac) [![NPM downloads](https://img.shields.io/npm/dm/cac.svg)](https://npmjs.com/package/cac) [![Build Status](https://img.shields.io/circleci/project/egoist/cac/master.svg)](https://circleci.com/gh/egoist/cac) [![Coveralls branch](https://img.shields.io/coveralls/egoist/cac/master.svg)](https://github.com/egoist/cac)
# cac [![NPM version](https://img.shields.io/npm/v/cac.svg)](https://npmjs.com/package/cac) [![NPM downloads](https://img.shields.io/npm/dm/cac.svg)](https://npmjs.com/package/cac) [![Build Status](https://img.shields.io/circleci/project/egoist/cac/master.svg)](https://circleci.com/gh/egoist/cac)
**C**ommand **A**nd **C**onquer, the queen living in your command line.
## Features
<img src="http://i.giphy.com/v3FeH4swox9mg.gif" width="400"/>
- [x] Simplified [commander.js](https://github.com/tj/commander.js)
- [x] Camelcased keys, eg `--disable-input` => `disableInput`
- [x] Automatically read `package.json`, parse package meta
- [x] Automatically print related data when `--version` and `--help`
- [x] Change `process.title` for you
- [x] Support [co](https://github.com/tj/co) flow
- [x] Well tested
## Install

@@ -23,62 +15,50 @@

Start your first CLI app in `example.js`:
```js
const cac = require('cac')
const fs = require('fs-promise')
const cli = cac(`
Usage:
node example.js create <filename> -m [content]
Commands:
c, create Create a file with specific content
Options:
-m, --message File content
-h, --help Print help (You are here!)
`, {
alias: {
m: message,
h: help
}
})
// initialize your cli program
const cli = cac()
cli.command('c, create', function* () {
const fileName = this.input[1]
const content = this.flags.message
yield fs.createFile(fileName, 'hello')
console.log('Done!')
// add your very first command
cli.command('hi', 'Say hi!', (input) => {
console.log(`hi ${input[1] || 'boy'}!`)
})
cli.command('*', function () {
console.log('Everything else')
}}
// use .parse() to bootstrap the CLI
// parse arguments and bootstrap
cli.parse()
```
All set! Just run:
<img src="http://ww4.sinaimg.cn/large/a15b4afegw1f79ix3vc2uj20p00akjsj.jpg" width="400" />
```bash
$ node example.js create lol.txt -m "just lol 😂"
```
### Default commands and options
- Options: `--help` `-h` `--version` `-v`
- Commands: `help`
<img src="http://ww4.sinaimg.cn/large/a15b4afegw1f79k0eifspj20ug0g0mz3.jpg" width="400" />
## API
### cac([help], [options])
## .option(options, description, defaultValue)
#### help
- **options**: `string`, it could be `option` or `option, alias` or `alias, option`, the order does not matter. eg: `.option('install, i')`
- **description**: `string`, option description, will be used to output cli usage
- **defaultValue**: `any`, give a default value to this option
Type: `string` `array`
## .command(commands, description, fn)
The help info.
- **commands**: `string`, it could be `command` or `command, alias` or `alias, command`, the order does not matter. eg: `.command('clone, c')`. It can also be a wildcard symbol `*`, which means always been triggered if no command was specified by user.
- **description**: `string`, command description, will be used to output cli usage
- **fn**: `function`, command function, will be triggered when this command matches user's input
#### options
## .parse(argv)
The [minimist](https://github.com/substack/minimist) options.
- **argv**: `array`, default is `process.argv.slice(2)`
## .onError(handleError)
- **handleError**: `function`, triggered when your program throws an error or was rejected by a Promise call.
## License
MIT © [EGOIST](https://github.com/egoist)
MIT © [egoist](https://github.com/egoist)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc