"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/touch/node_modules/nopt/lib/nopt.js" (8 Mar 2017, 15345 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // info about each config option.
    2 
    3 var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
    4   ? function () { console.error.apply(console, arguments) }
    5   : function () {}
    6 
    7 var url = require("url")
    8   , path = require("path")
    9   , Stream = require("stream").Stream
   10   , abbrev = require("abbrev")
   11 
   12 module.exports = exports = nopt
   13 exports.clean = clean
   14 
   15 exports.typeDefs =
   16   { String  : { type: String,  validate: validateString  }
   17   , Boolean : { type: Boolean, validate: validateBoolean }
   18   , url     : { type: url,     validate: validateUrl     }
   19   , Number  : { type: Number,  validate: validateNumber  }
   20   , path    : { type: path,    validate: validatePath    }
   21   , Stream  : { type: Stream,  validate: validateStream  }
   22   , Date    : { type: Date,    validate: validateDate    }
   23   }
   24 
   25 function nopt (types, shorthands, args, slice) {
   26   args = args || process.argv
   27   types = types || {}
   28   shorthands = shorthands || {}
   29   if (typeof slice !== "number") slice = 2
   30 
   31   debug(types, shorthands, args, slice)
   32 
   33   args = args.slice(slice)
   34   var data = {}
   35     , key
   36     , remain = []
   37     , cooked = args
   38     , original = args.slice(0)
   39 
   40   parse(args, data, remain, types, shorthands)
   41   // now data is full
   42   clean(data, types, exports.typeDefs)
   43   data.argv = {remain:remain,cooked:cooked,original:original}
   44   data.argv.toString = function () {
   45     return this.original.map(JSON.stringify).join(" ")
   46   }
   47   return data
   48 }
   49 
   50 function clean (data, types, typeDefs) {
   51   typeDefs = typeDefs || exports.typeDefs
   52   var remove = {}
   53     , typeDefault = [false, true, null, String, Number]
   54 
   55   Object.keys(data).forEach(function (k) {
   56     if (k === "argv") return
   57     var val = data[k]
   58       , isArray = Array.isArray(val)
   59       , type = types[k]
   60     if (!isArray) val = [val]
   61     if (!type) type = typeDefault
   62     if (type === Array) type = typeDefault.concat(Array)
   63     if (!Array.isArray(type)) type = [type]
   64 
   65     debug("val=%j", val)
   66     debug("types=", type)
   67     val = val.map(function (val) {
   68       // if it's an unknown value, then parse false/true/null/numbers/dates
   69       if (typeof val === "string") {
   70         debug("string %j", val)
   71         val = val.trim()
   72         if ((val === "null" && ~type.indexOf(null))
   73             || (val === "true" &&
   74                (~type.indexOf(true) || ~type.indexOf(Boolean)))
   75             || (val === "false" &&
   76                (~type.indexOf(false) || ~type.indexOf(Boolean)))) {
   77           val = JSON.parse(val)
   78           debug("jsonable %j", val)
   79         } else if (~type.indexOf(Number) && !isNaN(val)) {
   80           debug("convert to number", val)
   81           val = +val
   82         } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
   83           debug("convert to date", val)
   84           val = new Date(val)
   85         }
   86       }
   87 
   88       if (!types.hasOwnProperty(k)) {
   89         return val
   90       }
   91 
   92       // allow `--no-blah` to set 'blah' to null if null is allowed
   93       if (val === false && ~type.indexOf(null) &&
   94           !(~type.indexOf(false) || ~type.indexOf(Boolean))) {
   95         val = null
   96       }
   97 
   98       var d = {}
   99       d[k] = val
  100       debug("prevalidated val", d, val, types[k])
  101       if (!validate(d, k, val, types[k], typeDefs)) {
  102         if (exports.invalidHandler) {
  103           exports.invalidHandler(k, val, types[k], data)
  104         } else if (exports.invalidHandler !== false) {
  105           debug("invalid: "+k+"="+val, types[k])
  106         }
  107         return remove
  108       }
  109       debug("validated val", d, val, types[k])
  110       return d[k]
  111     }).filter(function (val) { return val !== remove })
  112 
  113     if (!val.length) delete data[k]
  114     else if (isArray) {
  115       debug(isArray, data[k], val)
  116       data[k] = val
  117     } else data[k] = val[0]
  118 
  119     debug("k=%s val=%j", k, val, data[k])
  120   })
  121 }
  122 
  123 function validateString (data, k, val) {
  124   data[k] = String(val)
  125 }
  126 
  127 function validatePath (data, k, val) {
  128   data[k] = path.resolve(String(val))
  129   return true
  130 }
  131 
  132 function validateNumber (data, k, val) {
  133   debug("validate Number %j %j %j", k, val, isNaN(val))
  134   if (isNaN(val)) return false
  135   data[k] = +val
  136 }
  137 
  138 function validateDate (data, k, val) {
  139   debug("validate Date %j %j %j", k, val, Date.parse(val))
  140   var s = Date.parse(val)
  141   if (isNaN(s)) return false
  142   data[k] = new Date(val)
  143 }
  144 
  145 function validateBoolean (data, k, val) {
  146   if (val instanceof Boolean) val = val.valueOf()
  147   else if (typeof val === "string") {
  148     if (!isNaN(val)) val = !!(+val)
  149     else if (val === "null" || val === "false") val = false
  150     else val = true
  151   } else val = !!val
  152   data[k] = val
  153 }
  154 
  155 function validateUrl (data, k, val) {
  156   val = url.parse(String(val))
  157   if (!val.host) return false
  158   data[k] = val.href
  159 }
  160 
  161 function validateStream (data, k, val) {
  162   if (!(val instanceof Stream)) return false
  163   data[k] = val
  164 }
  165 
  166 function validate (data, k, val, type, typeDefs) {
  167   // arrays are lists of types.
  168   if (Array.isArray(type)) {
  169     for (var i = 0, l = type.length; i < l; i ++) {
  170       if (type[i] === Array) continue
  171       if (validate(data, k, val, type[i], typeDefs)) return true
  172     }
  173     delete data[k]
  174     return false
  175   }
  176 
  177   // an array of anything?
  178   if (type === Array) return true
  179 
  180   // NaN is poisonous.  Means that something is not allowed.
  181   if (type !== type) {
  182     debug("Poison NaN", k, val, type)
  183     delete data[k]
  184     return false
  185   }
  186 
  187   // explicit list of values
  188   if (val === type) {
  189     debug("Explicitly allowed %j", val)
  190     // if (isArray) (data[k] = data[k] || []).push(val)
  191     // else data[k] = val
  192     data[k] = val
  193     return true
  194   }
  195 
  196   // now go through the list of typeDefs, validate against each one.
  197   var ok = false
  198     , types = Object.keys(typeDefs)
  199   for (var i = 0, l = types.length; i < l; i ++) {
  200     debug("test type %j %j %j", k, val, types[i])
  201     var t = typeDefs[types[i]]
  202     if (t && type === t.type) {
  203       var d = {}
  204       ok = false !== t.validate(d, k, val)
  205       val = d[k]
  206       if (ok) {
  207         // if (isArray) (data[k] = data[k] || []).push(val)
  208         // else data[k] = val
  209         data[k] = val
  210         break
  211       }
  212     }
  213   }
  214   debug("OK? %j (%j %j %j)", ok, k, val, types[i])
  215 
  216   if (!ok) delete data[k]
  217   return ok
  218 }
  219 
  220 function parse (args, data, remain, types, shorthands) {
  221   debug("parse", args, data, remain)
  222 
  223   var key = null
  224     , abbrevs = abbrev(Object.keys(types))
  225     , shortAbbr = abbrev(Object.keys(shorthands))
  226 
  227   for (var i = 0; i < args.length; i ++) {
  228     var arg = args[i]
  229     debug("arg", arg)
  230 
  231     if (arg.match(/^-{2,}$/)) {
  232       // done with keys.
  233       // the rest are args.
  234       remain.push.apply(remain, args.slice(i + 1))
  235       args[i] = "--"
  236       break
  237     }
  238     if (arg.charAt(0) === "-") {
  239       if (arg.indexOf("=") !== -1) {
  240         var v = arg.split("=")
  241         arg = v.shift()
  242         v = v.join("=")
  243         args.splice.apply(args, [i, 1].concat([arg, v]))
  244       }
  245       // see if it's a shorthand
  246       // if so, splice and back up to re-parse it.
  247       var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
  248       debug("arg=%j shRes=%j", arg, shRes)
  249       if (shRes) {
  250         debug(arg, shRes)
  251         args.splice.apply(args, [i, 1].concat(shRes))
  252         if (arg !== shRes[0]) {
  253           i --
  254           continue
  255         }
  256       }
  257       arg = arg.replace(/^-+/, "")
  258       var no = false
  259       while (arg.toLowerCase().indexOf("no-") === 0) {
  260         no = !no
  261         arg = arg.substr(3)
  262       }
  263 
  264       if (abbrevs[arg]) arg = abbrevs[arg]
  265 
  266       var isArray = types[arg] === Array ||
  267         Array.isArray(types[arg]) && types[arg].indexOf(Array) !== -1
  268 
  269       var val
  270         , la = args[i + 1]
  271 
  272       var isBool = no ||
  273         types[arg] === Boolean ||
  274         Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 ||
  275         (la === "false" &&
  276          (types[arg] === null ||
  277           Array.isArray(types[arg]) && ~types[arg].indexOf(null)))
  278 
  279       if (isBool) {
  280         // just set and move along
  281         val = !no
  282         // however, also support --bool true or --bool false
  283         if (la === "true" || la === "false") {
  284           val = JSON.parse(la)
  285           la = null
  286           if (no) val = !val
  287           i ++
  288         }
  289 
  290         // also support "foo":[Boolean, "bar"] and "--foo bar"
  291         if (Array.isArray(types[arg]) && la) {
  292           if (~types[arg].indexOf(la)) {
  293             // an explicit type
  294             val = la
  295             i ++
  296           } else if ( la === "null" && ~types[arg].indexOf(null) ) {
  297             // null allowed
  298             val = null
  299             i ++
  300           } else if ( !la.match(/^-{2,}[^-]/) &&
  301                       !isNaN(la) &&
  302                       ~types[arg].indexOf(Number) ) {
  303             // number
  304             val = +la
  305             i ++
  306           } else if ( !la.match(/^-[^-]/) && ~types[arg].indexOf(String) ) {
  307             // string
  308             val = la
  309             i ++
  310           }
  311         }
  312 
  313         if (isArray) (data[arg] = data[arg] || []).push(val)
  314         else data[arg] = val
  315 
  316         continue
  317       }
  318 
  319       if (la && la.match(/^-{2,}$/)) {
  320         la = undefined
  321         i --
  322       }
  323 
  324       val = la === undefined ? true : la
  325       if (isArray) (data[arg] = data[arg] || []).push(val)
  326       else data[arg] = val
  327 
  328       i ++
  329       continue
  330     }
  331     remain.push(arg)
  332   }
  333 }
  334 
  335 function resolveShort (arg, shorthands, shortAbbr, abbrevs) {
  336   // handle single-char shorthands glommed together, like
  337   // npm ls -glp, but only if there is one dash, and only if
  338   // all of the chars are single-char shorthands, and it's
  339   // not a match to some other abbrev.
  340   arg = arg.replace(/^-+/, '')
  341   if (abbrevs[arg] && !shorthands[arg]) {
  342     return null
  343   }
  344   if (shortAbbr[arg]) {
  345     arg = shortAbbr[arg]
  346   } else {
  347     var singles = shorthands.___singles
  348     if (!singles) {
  349       singles = Object.keys(shorthands).filter(function (s) {
  350         return s.length === 1
  351       }).reduce(function (l,r) { l[r] = true ; return l }, {})
  352       shorthands.___singles = singles
  353     }
  354     var chrs = arg.split("").filter(function (c) {
  355       return singles[c]
  356     })
  357     if (chrs.join("") === arg) return chrs.map(function (c) {
  358       return shorthands[c]
  359     }).reduce(function (l, r) {
  360       return l.concat(r)
  361     }, [])
  362   }
  363 
  364   if (shorthands[arg] && !Array.isArray(shorthands[arg])) {
  365     shorthands[arg] = shorthands[arg].split(/\s+/)
  366   }
  367   return shorthands[arg]
  368 }
  369 
  370 if (module === require.main) {
  371 var assert = require("assert")
  372   , util = require("util")
  373 
  374   , shorthands =
  375     { s : ["--loglevel", "silent"]
  376     , d : ["--loglevel", "info"]
  377     , dd : ["--loglevel", "verbose"]
  378     , ddd : ["--loglevel", "silly"]
  379     , noreg : ["--no-registry"]
  380     , reg : ["--registry"]
  381     , "no-reg" : ["--no-registry"]
  382     , silent : ["--loglevel", "silent"]
  383     , verbose : ["--loglevel", "verbose"]
  384     , h : ["--usage"]
  385     , H : ["--usage"]
  386     , "?" : ["--usage"]
  387     , help : ["--usage"]
  388     , v : ["--version"]
  389     , f : ["--force"]
  390     , desc : ["--description"]
  391     , "no-desc" : ["--no-description"]
  392     , "local" : ["--no-global"]
  393     , l : ["--long"]
  394     , p : ["--parseable"]
  395     , porcelain : ["--parseable"]
  396     , g : ["--global"]
  397     }
  398 
  399   , types =
  400     { aoa: Array
  401     , nullstream: [null, Stream]
  402     , date: Date
  403     , str: String
  404     , browser : String
  405     , cache : path
  406     , color : ["always", Boolean]
  407     , depth : Number
  408     , description : Boolean
  409     , dev : Boolean
  410     , editor : path
  411     , force : Boolean
  412     , global : Boolean
  413     , globalconfig : path
  414     , group : [String, Number]
  415     , gzipbin : String
  416     , logfd : [Number, Stream]
  417     , loglevel : ["silent","win","error","warn","info","verbose","silly"]
  418     , long : Boolean
  419     , "node-version" : [false, String]
  420     , npaturl : url
  421     , npat : Boolean
  422     , "onload-script" : [false, String]
  423     , outfd : [Number, Stream]
  424     , parseable : Boolean
  425     , pre: Boolean
  426     , prefix: path
  427     , proxy : url
  428     , "rebuild-bundle" : Boolean
  429     , registry : url
  430     , searchopts : String
  431     , searchexclude: [null, String]
  432     , shell : path
  433     , t: [Array, String]
  434     , tag : String
  435     , tar : String
  436     , tmp : path
  437     , "unsafe-perm" : Boolean
  438     , usage : Boolean
  439     , user : String
  440     , username : String
  441     , userconfig : path
  442     , version : Boolean
  443     , viewer: path
  444     , _exit : Boolean
  445     }
  446 
  447 ; [["-v", {version:true}, []]
  448   ,["---v", {version:true}, []]
  449   ,["ls -s --no-reg connect -d",
  450     {loglevel:"info",registry:null},["ls","connect"]]
  451   ,["ls ---s foo",{loglevel:"silent"},["ls","foo"]]
  452   ,["ls --registry blargle", {}, ["ls"]]
  453   ,["--no-registry", {registry:null}, []]
  454   ,["--no-color true", {color:false}, []]
  455   ,["--no-color false", {color:true}, []]
  456   ,["--no-color", {color:false}, []]
  457   ,["--color false", {color:false}, []]
  458   ,["--color --logfd 7", {logfd:7,color:true}, []]
  459   ,["--color=true", {color:true}, []]
  460   ,["--logfd=10", {logfd:10}, []]
  461   ,["--tmp=/tmp -tar=gtar",{tmp:"/tmp",tar:"gtar"},[]]
  462   ,["--tmp=tmp -tar=gtar",
  463     {tmp:path.resolve(process.cwd(), "tmp"),tar:"gtar"},[]]
  464   ,["--logfd x", {}, []]
  465   ,["a -true -- -no-false", {true:true},["a","-no-false"]]
  466   ,["a -no-false", {false:false},["a"]]
  467   ,["a -no-no-true", {true:true}, ["a"]]
  468   ,["a -no-no-no-false", {false:false}, ["a"]]
  469   ,["---NO-no-No-no-no-no-nO-no-no"+
  470     "-No-no-no-no-no-no-no-no-no"+
  471     "-no-no-no-no-NO-NO-no-no-no-no-no-no"+
  472     "-no-body-can-do-the-boogaloo-like-I-do"
  473    ,{"body-can-do-the-boogaloo-like-I-do":false}, []]
  474   ,["we are -no-strangers-to-love "+
  475     "--you-know the-rules --and so-do-i "+
  476     "---im-thinking-of=a-full-commitment "+
  477     "--no-you-would-get-this-from-any-other-guy "+
  478     "--no-gonna-give-you-up "+
  479     "-no-gonna-let-you-down=true "+
  480     "--no-no-gonna-run-around false "+
  481     "--desert-you=false "+
  482     "--make-you-cry false "+
  483     "--no-tell-a-lie "+
  484     "--no-no-and-hurt-you false"
  485    ,{"strangers-to-love":false
  486     ,"you-know":"the-rules"
  487     ,"and":"so-do-i"
  488     ,"you-would-get-this-from-any-other-guy":false
  489     ,"gonna-give-you-up":false
  490     ,"gonna-let-you-down":false
  491     ,"gonna-run-around":false
  492     ,"desert-you":false
  493     ,"make-you-cry":false
  494     ,"tell-a-lie":false
  495     ,"and-hurt-you":false
  496     },["we", "are"]]
  497   ,["-t one -t two -t three"
  498    ,{t: ["one", "two", "three"]}
  499    ,[]]
  500   ,["-t one -t null -t three four five null"
  501    ,{t: ["one", "null", "three"]}
  502    ,["four", "five", "null"]]
  503   ,["-t foo"
  504    ,{t:["foo"]}
  505    ,[]]
  506   ,["--no-t"
  507    ,{t:["false"]}
  508    ,[]]
  509   ,["-no-no-t"
  510    ,{t:["true"]}
  511    ,[]]
  512   ,["-aoa one -aoa null -aoa 100"
  513    ,{aoa:["one", null, 100]}
  514    ,[]]
  515   ,["-str 100"
  516    ,{str:"100"}
  517    ,[]]
  518   ,["--color always"
  519    ,{color:"always"}
  520    ,[]]
  521   ,["--no-nullstream"
  522    ,{nullstream:null}
  523    ,[]]
  524   ,["--nullstream false"
  525    ,{nullstream:null}
  526    ,[]]
  527   ,["--notadate 2011-01-25"
  528    ,{notadate: "2011-01-25"}
  529    ,[]]
  530   ,["--date 2011-01-25"
  531    ,{date: new Date("2011-01-25")}
  532    ,[]]
  533   ].forEach(function (test) {
  534     var argv = test[0].split(/\s+/)
  535       , opts = test[1]
  536       , rem = test[2]
  537       , actual = nopt(types, shorthands, argv, 0)
  538       , parsed = actual.argv
  539     delete actual.argv
  540     console.log(util.inspect(actual, false, 2, true), parsed.remain)
  541     for (var i in opts) {
  542       var e = JSON.stringify(opts[i])
  543         , a = JSON.stringify(actual[i] === undefined ? null : actual[i])
  544       if (e && typeof e === "object") {
  545         assert.deepEqual(e, a)
  546       } else {
  547         assert.equal(e, a)
  548       }
  549     }
  550     assert.deepEqual(rem, parsed.remain)
  551   })
  552 }