New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cmdline

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cmdline - npm Package Compare versions

Comparing version 1.0.9 to 1.1.0

2

bin/cli.js

@@ -13,3 +13,3 @@ #!/usr/bin/env node

})
.option('-t', { type: 'switch' })
.option('-t', 'switch')
.command('start', function (cmd, t) {

@@ -16,0 +16,0 @@ console.log('cmd:', t);

const Class = require('cify').Class;
const fs = require('fs');
const os = require('os');
const utils = require('ntils');

@@ -36,21 +38,21 @@ const types = require('./types');

if (!names) return this;
this._commands = this._commands || {};
if (utils.isFunction(pattern)) {
fn = [pattern, pattern = fn][0];
}
if (!utils.isFunction(fn)) {
fn = NOOP_FUNCTION;
};
this._commands = this._commands || {};
fn = utils.isFunction(fn) ? fn : NOOP_FUNCTION;
pattern = (pattern === true ? { arguments: true } : pattern) || {};
names = utils.isArray(names) ? names : [names];
names.forEach(function (name) {
//name 有可能是正则表达式,所以显式转换一下
this._commands[String(name)] = {
names: names,
names: names,//声明关联的 commands
regexp: name instanceof RegExp ? name : new RegExp(name)
};
if (pattern === true) {
pattern = { arguments: true };
}
pattern = (utils.isObject(pattern) ? pattern : {}) || {};
pattern.command = name;
this.handle(pattern, fn);
//防止多个 command 之间影响「拷贝」pattern
var _pattern = utils.copy(pattern);
//为每个 command 指定 'command 匹配' 的 handle
//但如果 pattern 还有其它规则,并 and 的关系生效
_pattern.command = name;
this.handle(_pattern, fn);
}, this);

@@ -67,3 +69,5 @@ return this;

}
if (!utils.isFunction(fn)) return this;
if (!utils.isFunction(fn) || fn == NOOP_FUNCTION) {
return this;
}
pattern = pattern || {};

@@ -83,30 +87,27 @@ if (utils.isString(pattern.command)) {

**/
option: function (names, settings, fn) {
option: function (names, setting, fn) {
if (!names) return this;
if (utils.isFunction(settings)) {
fn = [settings, settings = fn][0];
this._options = this._options || {};
if (utils.isFunction(setting)) {
fn = [setting, setting = fn][0];
}
if (!utils.isFunction(fn)) {
fn = NOOP_FUNCTION;
};
this._options = this._options || {};
settings = (utils.isArray(settings) ? settings : [settings]).map(function (setting) {
setting = setting || {};
var typeDefine = this._types[setting.type];
if (!typeDefine) return setting;
setting.regexp = setting.regexp || typeDefine.regexp;
setting.default = setting.default || typeDefine.default;
setting.convert = setting.convert || typeDefine.convert;
return setting;
}, this);
fn = utils.isFunction(fn) ? fn : NOOP_FUNCTION;
//处理 setting 开始
setting = (utils.isString(setting) ? { type: setting } : setting) || {};
var typeDefine = this._types[setting.type];
if (!typeDefine) return setting;
utils.each(typeDefine, function (name, value) {
setting[name] = setting[name] || value;
}.bind(this));
//处理 setting 结束
names = utils.isArray(names) ? names : [names];
names.forEach(function (name) {
if (this._options[name]) {
throw new Error('Repeated Option: ' + name);
}
settings.names = names;
this._options[name] = settings;
this.handle({
options: [name]
}, fn);
if (this._options[name]) throw new Error('Repeated Option: ' + name);
//防止多个 options 之间影响「拷贝」setting
var _setting = utils.copy(setting);
_setting.names = names; //声明关联的 options
this._options[name] = _setting;
//为每个 option 添加 handle
//option 的 handle 不能自行配置,只要出现包含的选项,就会执行
this.handle({ options: [name] }, fn);
}, this);

@@ -149,9 +150,23 @@ return this;

/**
* 字符串或文件内容
**/
_strOrFile: function (str) {
if (utils.isNull(str)) return str;
if (str[0] != '@') return str;
try {
return fs.readFileSync(str.substr(1), 'utf8');
} catch (err) {
return str;
}
},
/**
* 添加「版本」选项
**/
version: function (version) {
this._version = this._strOrFile(version);
this.option(['-v', '--version'], {
type: 'switch'
}, function ($self) {
$self._console.log(version || 'unknow');
$self._console.log($self._version || 'unknow');
return false;

@@ -166,6 +181,7 @@ });

help: function (help) {
this._help = this._strOrFile(help);
this.option(['-h', '--help'], {
type: 'switch'
}, function ($self) {
$self._console.log(help || 'unknow');
$self._console.log($self._help || 'unknow');
return false;

@@ -250,3 +266,2 @@ });

_parseTokensForComboOptions: function () {
var invalidOptions = [];
this._tokens.forEach(function (token, index) {

@@ -256,5 +271,3 @@ if (!OPTION_REGEXP.test(token)) return; //如果不是 option

var trimedName = this._trimOptionName(token);
if (trimedName.length < 2 || this._hasRepeatChar(trimedName)) {
return invalidOptions.push(token);
}
if (trimedName.length < 2 || this._hasRepeatChar(trimedName)) return;
var shortOptions = trimedName.split('').map(function (char) {

@@ -266,10 +279,6 @@ return '-' + char;

}, this);
if (!allExsits) {
return invalidOptions.push(token);
}
if (!allExsits) return;
//将分解后的短参插入
[].splice.apply(this._tokens, [index, 1].concat(shortOptions));
}, this);
return invalidOptions.length > 0 ?
new Error('Invalid option: ' + invalidOptions.join(' ')) : null;
},

@@ -303,27 +312,37 @@

this.options = {};
var index = 0, length = this._tokens.length;
while (index < length) {
var invalidOptions = [], index = -1, len = this._tokens.length;
while ((++index) < len) {
var token = this._tokens[index];
if (OPTION_REGEXP.test(token)) {
var settings = this._options[token];
var values = settings.map(function (setting) {
index++;
var nextToken = this._tokens[index];
if (!OPTION_REGEXP.test(nextToken) &&
(!setting.regexp || setting.regexp.test(nextToken))) {
var value = utils.isNull(nextToken) ?
setting.default : nextToken.toString();
return setting.convert ? setting.convert(value) : value;
} else {
index--;
return setting.default;
}
}, this);
this.options[token] = values;
if (OPTION_REGEXP.test(token)) { //如果是一个 options
index++;
var setting = this._options[token];
//如果「选项」不存在,添加到 invalidOptions
if (utils.isNull(setting)) {
invalidOptions.push(token);
continue;
}
//如果存在,则检查后边紧临的 token 是否符合「正则」这义的规则
var nextToken = this._tokens[index];
if ((!OPTION_REGEXP.test(nextToken) || setting.greed) &&
(!setting.regexp || setting.regexp.test(nextToken))) {
var value = utils.isNull(nextToken) ?
setting.default : nextToken.toString();
this.options[token] = setting.convert ? setting.convert(value) : value;
} else {
//如果后边紧临的 token 不符合「正则」这义的规则,则回退 index
//并将「默认」值赋值给当前选项
index--;
this.options[token] = setting.default;
}
} else if (token.type != TOKEN_TYPE_OPTION_VALUE) {
//如果不是 option,也不是「=」号后的「只能作为选项值」的 token
//则放到 argv 数组中
this.argv.push(token);
}
index++;
}
//得到参数个数 argc
this.argc = this.argv.length;
//检果是否有无效的 option 并返回
return invalidOptions.length > 0 ?
new Error('Invalid option: ' + invalidOptions.join(',')) : null;
},

@@ -405,2 +424,10 @@

/**
* 在没有找到 handlers 时执行
**/
noHandle: function () {
if (this._help) return this._console.log(this._help);
this._emitError(new Error('No processing'));
},
/**
* 启动处理

@@ -420,9 +447,6 @@ **/

//检查预处理并执行下一步
if (firstError) {
return this._emitError(firstError);
}
if (firstError) return this._emitError(firstError);
//查找 handles 并执行
var handlers = this._findHandlers();
if (handlers.length < 1) {
return this._emitError(new Error('No processing'));
}
if (handlers.length < 1) return this.noHandle();
utils.each(handlers, function (i, handler) {

@@ -429,0 +453,0 @@ return this._callHandler(handler) === false || null;

module.exports = {
string: {
"string": {
regexp: /[\S\s]*/i,
default: '',
},
number: {
"string*": {
regexp: /[\S\s]*/i,
default: '',
greed: true
},
"number": {
regexp: /^[0-9]*$/i,

@@ -11,10 +16,10 @@ default: 0,

},
boolean: {
"boolean": {
regexp: /^(1|0|true|false|yes|no){1}$/i,
default: true,
convert: function (str) {
return ["1", "true", "yes"].indexOf(str) > -1;
return ['1', 'true', 'yes'].indexOf(str) > -1;
}
},
switch: {
"switch": {
regexp: /^$/i,

@@ -21,0 +26,0 @@ default: true

{
"name": "cmdline",
"rawName": "cmdline",
"version": "1.0.9",
"version": "1.1.0",
"description": "cmdline is a process.argv parser",

@@ -6,0 +6,0 @@ "main": "./lib/index.js",

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