-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
shanchao.wsc
committed
Apr 21, 2018
0 parents
commit 11e6521
Showing
6 changed files
with
419 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
const minimist = require('./minimist.js'); | ||
const toString = function(obj){ | ||
return Object.prototype.toString.call(obj); | ||
}; | ||
|
||
const Samma = function(command, config){ | ||
if(toString(command) !== '[object String]'){ | ||
throw '命令需要求String类型'; | ||
} | ||
const arr = command.split(' '); | ||
const orderStr = arr[0]; | ||
// const args = arr.slice(1); | ||
const argsObj = minimist(arr); | ||
const cmdArr = config.cmd; | ||
const cmdItem = cmdArr.find(function(item){ | ||
return item.name === orderStr; | ||
}); | ||
if(cmdItem){ | ||
cmdItem.callback(argsObj, orderStr); | ||
} | ||
else{ | ||
throw `command not found ${orderStr}`; | ||
} | ||
|
||
}; | ||
|
||
const commander = function(config){ | ||
if(toString(config) !== '[object Object]'){ | ||
throw 'config要求Object类型'; | ||
} | ||
|
||
if(toString(config.cmd) !== '[object Array]'){ | ||
throw 'cmd属性要求Array类型'; | ||
} | ||
|
||
const execute = config.global || 'Samma'; | ||
const executeFn = function(command){ | ||
Samma(command, config); | ||
}; | ||
|
||
if(typeof window === 'undefined'){ | ||
return executeFn; | ||
} | ||
|
||
if(window[execute]){ | ||
throw `window下已有${execute}属性,请改变global属性值`; | ||
} | ||
else{ | ||
window[execute] = executeFn; | ||
} | ||
}; | ||
|
||
module.exports = commander; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
module.exports = function (args, opts) { | ||
if (!opts) opts = {}; | ||
|
||
var flags = { bools : {}, strings : {}, unknownFn: null }; | ||
|
||
if (typeof opts['unknown'] === 'function') { | ||
flags.unknownFn = opts['unknown']; | ||
} | ||
|
||
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { | ||
flags.allBools = true; | ||
} else { | ||
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) { | ||
flags.bools[key] = true; | ||
}); | ||
} | ||
|
||
var aliases = {}; | ||
Object.keys(opts.alias || {}).forEach(function (key) { | ||
aliases[key] = [].concat(opts.alias[key]); | ||
aliases[key].forEach(function (x) { | ||
aliases[x] = [key].concat(aliases[key].filter(function (y) { | ||
return x !== y; | ||
})); | ||
}); | ||
}); | ||
|
||
[].concat(opts.string).filter(Boolean).forEach(function (key) { | ||
flags.strings[key] = true; | ||
if (aliases[key]) { | ||
flags.strings[aliases[key]] = true; | ||
} | ||
}); | ||
|
||
var defaults = opts['default'] || {}; | ||
|
||
var argv = { _ : [] }; | ||
Object.keys(flags.bools).forEach(function (key) { | ||
setArg(key, defaults[key] === undefined ? false : defaults[key]); | ||
}); | ||
|
||
var notFlags = []; | ||
|
||
if (args.indexOf('--') !== -1) { | ||
notFlags = args.slice(args.indexOf('--')+1); | ||
args = args.slice(0, args.indexOf('--')); | ||
} | ||
|
||
function argDefined(key, arg) { | ||
return (flags.allBools && /^--[^=]+$/.test(arg)) || | ||
flags.strings[key] || flags.bools[key] || aliases[key]; | ||
} | ||
|
||
function setArg (key, val, arg) { | ||
if (arg && flags.unknownFn && !argDefined(key, arg)) { | ||
if (flags.unknownFn(arg) === false) return; | ||
} | ||
|
||
var value = !flags.strings[key] && isNumber(val) | ||
? Number(val) : val | ||
; | ||
setKey(argv, key.split('.'), value); | ||
|
||
(aliases[key] || []).forEach(function (x) { | ||
setKey(argv, x.split('.'), value); | ||
}); | ||
} | ||
|
||
function setKey (obj, keys, value) { | ||
var o = obj; | ||
keys.slice(0,-1).forEach(function (key) { | ||
if (o[key] === undefined) o[key] = {}; | ||
o = o[key]; | ||
}); | ||
|
||
var key = keys[keys.length - 1]; | ||
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { | ||
o[key] = value; | ||
} | ||
else if (Array.isArray(o[key])) { | ||
o[key].push(value); | ||
} | ||
else { | ||
o[key] = [ o[key], value ]; | ||
} | ||
} | ||
|
||
function aliasIsBoolean(key) { | ||
return aliases[key].some(function (x) { | ||
return flags.bools[x]; | ||
}); | ||
} | ||
|
||
for (var i = 0; i < args.length; i++) { | ||
var arg = args[i]; | ||
|
||
if (/^--.+=/.test(arg)) { | ||
// Using [\s\S] instead of . because js doesn't support the | ||
// 'dotall' regex modifier. See: | ||
// http://stackoverflow.com/a/1068308/13216 | ||
var m = arg.match(/^--([^=]+)=([\s\S]*)$/); | ||
var key = m[1]; | ||
var value = m[2]; | ||
if (flags.bools[key]) { | ||
value = value !== 'false'; | ||
} | ||
setArg(key, value, arg); | ||
} | ||
else if (/^--no-.+/.test(arg)) { | ||
var key = arg.match(/^--no-(.+)/)[1]; | ||
setArg(key, false, arg); | ||
} | ||
else if (/^--.+/.test(arg)) { | ||
var key = arg.match(/^--(.+)/)[1]; | ||
var next = args[i + 1]; | ||
if (next !== undefined && !/^-/.test(next) | ||
&& !flags.bools[key] | ||
&& !flags.allBools | ||
&& (aliases[key] ? !aliasIsBoolean(key) : true)) { | ||
setArg(key, next, arg); | ||
i++; | ||
} | ||
else if (/^(true|false)$/.test(next)) { | ||
setArg(key, next === 'true', arg); | ||
i++; | ||
} | ||
else { | ||
setArg(key, flags.strings[key] ? '' : true, arg); | ||
} | ||
} | ||
else if (/^-[^-]+/.test(arg)) { | ||
// 魔改部分: 保持行为和/^--.+/一致 | ||
// todo: 抽象成一个函数进行复用 | ||
var key = arg.match(/^-(.+)/)[1]; | ||
var next = args[i + 1]; | ||
if (next !== undefined && !/^-/.test(next) | ||
&& !flags.bools[key] | ||
&& !flags.allBools | ||
&& (aliases[key] ? !aliasIsBoolean(key) : true)) { | ||
setArg(key, next, arg); | ||
i++; | ||
} | ||
else if (/^(true|false)$/.test(next)) { | ||
setArg(key, next === 'true', arg); | ||
i++; | ||
} | ||
else { | ||
setArg(key, flags.strings[key] ? '' : true, arg); | ||
} | ||
} | ||
else { | ||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) { | ||
argv._.push( | ||
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) | ||
); | ||
} | ||
if (opts.stopEarly) { | ||
argv._.push.apply(argv._, args.slice(i + 1)); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
Object.keys(defaults).forEach(function (key) { | ||
if (!hasKey(argv, key.split('.'))) { | ||
setKey(argv, key.split('.'), defaults[key]); | ||
|
||
(aliases[key] || []).forEach(function (x) { | ||
setKey(argv, x.split('.'), defaults[key]); | ||
}); | ||
} | ||
}); | ||
|
||
if (opts['--']) { | ||
argv['--'] = new Array(); | ||
notFlags.forEach(function(key) { | ||
argv['--'].push(key); | ||
}); | ||
} | ||
else { | ||
notFlags.forEach(function(key) { | ||
argv._.push(key); | ||
}); | ||
} | ||
|
||
return argv; | ||
}; | ||
|
||
function hasKey (obj, keys) { | ||
var o = obj; | ||
keys.slice(0,-1).forEach(function (key) { | ||
o = (o[key] || {}); | ||
}); | ||
|
||
var key = keys[keys.length - 1]; | ||
return key in o; | ||
} | ||
|
||
function isNumber (x) { | ||
if (typeof x === 'number') return true; | ||
if (/^0x[0-9a-f]+$/i.test(x)) return true; | ||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"name": "samma", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/wushanchao/samma.git" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/wushanchao/samma/issues" | ||
}, | ||
"homepage": "https://github.com/wushanchao/samma#readme" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Samma | ||
`Samma`是一个命令行语法解析配置库。 | ||
目标是方便用户在Chrome控制台使用命令行语法进行页面交互。 | ||
也可用于Node环境。 | ||
|
||
### 命令行语法 | ||
`cmd x` | ||
解析成 | ||
``` | ||
{ | ||
_:["cmd","x"] | ||
} | ||
``` | ||
|
||
`cmd -x` | ||
解析成 | ||
``` | ||
{ | ||
_:["cmd"], | ||
x:true | ||
} | ||
``` | ||
|
||
`cmd -x hello` | ||
解析成 | ||
``` | ||
{ | ||
_:["cmd"], | ||
x:"hello" | ||
} | ||
``` | ||
|
||
|
||
`cmd --x=hello` | ||
解析成 | ||
``` | ||
{ | ||
_:["cmd"], | ||
x:"hello" | ||
} | ||
``` | ||
|
||
`cmd -x --y` | ||
解析成 | ||
``` | ||
{ | ||
_:["cmd"], | ||
x:true, | ||
y:true | ||
} | ||
``` | ||
|
||
### 使用方法 | ||
浏览器环境下: | ||
在页面JS中注入代码: | ||
```javascript | ||
const Samma = require('Samma'); | ||
|
||
Samma({ | ||
global:'samma', | ||
cmd:[ | ||
{ | ||
name:'Hello', | ||
callback: function(args, command){ | ||
console.log(command + ' ' + args['name']); | ||
} | ||
} | ||
] | ||
}); | ||
``` | ||
|
||
在Chrome的开发者工具中打开Console执行 | ||
``` | ||
samma('Hello -name world'); | ||
``` | ||
|
||
|
||
Node环境下: | ||
```javascript | ||
const Samma = require('Samma'); | ||
|
||
const samma = Samma({ | ||
cmd:[ | ||
{ | ||
name:'Hello', | ||
callback: function(args, command){ | ||
console.log(command + ' ' + args['name']); | ||
} | ||
} | ||
] | ||
}); | ||
|
||
|
||
samma('Hello -name world'); | ||
``` | ||
|
||
### 备注 | ||
基于`minimist`二次开发。 | ||
个人对`minimist`进行了小部分魔改。 | ||
修复其bug | ||
``` | ||
-x3=4解析不出来 | ||
-x3解析成{x:3} | ||
``` |
Oops, something went wrong.