Socket
Socket
Sign inDemoInstall

nopt

Package Overview
Dependencies
1
Maintainers
5
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.0 to 6.0.0

80

bin/nopt.js
#!/usr/bin/env node
var nopt = require("../lib/nopt")
, path = require("path")
, types = { num: Number
, bool: Boolean
, help: Boolean
, list: Array
, "num-list": [Number, Array]
, "str-list": [String, Array]
, "bool-list": [Boolean, Array]
, str: String
, clear: Boolean
, config: Boolean
, length: Number
, file: path
}
, shorthands = { s: [ "--str", "astring" ]
, b: [ "--bool" ]
, nb: [ "--no-bool" ]
, tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ]
, "?": ["--help"]
, h: ["--help"]
, H: ["--help"]
, n: [ "--num", "125" ]
, c: ["--config"]
, l: ["--length"]
, f: ["--file"]
}
, parsed = nopt( types
, shorthands
, process.argv
, 2 )
var nopt = require('../lib/nopt')
var path = require('path')
var types = { num: Number,
bool: Boolean,
help: Boolean,
list: Array,
'num-list': [Number, Array],
'str-list': [String, Array],
'bool-list': [Boolean, Array],
str: String,
clear: Boolean,
config: Boolean,
length: Number,
file: path,
}
var shorthands = { s: ['--str', 'astring'],
b: ['--bool'],
nb: ['--no-bool'],
tft: ['--bool-list', '--no-bool-list', '--bool-list', 'true'],
'?': ['--help'],
h: ['--help'],
H: ['--help'],
n: ['--num', '125'],
c: ['--config'],
l: ['--length'],
f: ['--file'],
}
var parsed = nopt(types
, shorthands
, process.argv
, 2)
console.log("parsed", parsed)
console.log('parsed', parsed)
if (parsed.help) {
console.log("")
console.log("nopt cli tester")
console.log("")
console.log("types")
console.log('')
console.log('nopt cli tester')
console.log('')
console.log('types')
console.log(Object.keys(types).map(function M (t) {
var type = types[t]
if (Array.isArray(type)) {
return [t, type.map(function (type) { return type.name })]
return [t, type.map(function (mappedType) {
return mappedType.name
})]
}

@@ -51,5 +53,5 @@ return [t, type && type.name]

}, {}))
console.log("")
console.log("shorthands")
console.log('')
console.log('shorthands')
console.log(shorthands)
}
// info about each config option.
var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
? function () { console.error.apply(console, arguments) }
? function () {
console.error.apply(console, arguments)
}
: function () {}
var url = require("url")
, path = require("path")
, Stream = require("stream").Stream
, abbrev = require("abbrev")
, os = require("os")
var url = require('url')
var path = require('path')
var Stream = require('stream').Stream
var abbrev = require('abbrev')
var os = require('os')

@@ -17,9 +19,9 @@ module.exports = exports = nopt

exports.typeDefs =
{ String : { type: String, validate: validateString }
, Boolean : { type: Boolean, validate: validateBoolean }
, url : { type: url, validate: validateUrl }
, Number : { type: Number, validate: validateNumber }
, path : { type: path, validate: validatePath }
, Stream : { type: Stream, validate: validateStream }
, Date : { type: Date, validate: validateDate }
{ String: { type: String, validate: validateString },
Boolean: { type: Boolean, validate: validateBoolean },
url: { type: url, validate: validateUrl },
Number: { type: Number, validate: validateNumber },
path: { type: path, validate: validatePath },
Stream: { type: Stream, validate: validateStream },
Date: { type: Date, validate: validateDate },
}

@@ -31,3 +33,5 @@

shorthands = shorthands || {}
if (typeof slice !== "number") slice = 2
if (typeof slice !== 'number') {
slice = 2
}

@@ -38,8 +42,7 @@ debug(types, shorthands, args, slice)

var data = {}
, key
, argv = {
remain: [],
cooked: args,
original: args.slice(0)
}
var argv = {
remain: [],
cooked: args,
original: args.slice(0),
}

@@ -51,4 +54,5 @@ parse(args, data, argv.remain, types, shorthands)

Object.defineProperty(data.argv, 'toString', { value: function () {
return this.original.map(JSON.stringify).join(" ")
}, enumerable: false })
return this.original.map(JSON.stringify).join(' ')
},
enumerable: false })
return data

@@ -60,61 +64,73 @@ }

var remove = {}
, typeDefault = [false, true, null, String, Array]
var typeDefault = [false, true, null, String, Array]
Object.keys(data).forEach(function (k) {
if (k === "argv") return
if (k === 'argv') {
return
}
var val = data[k]
, isArray = Array.isArray(val)
, type = types[k]
if (!isArray) val = [val]
if (!type) type = typeDefault
if (type === Array) type = typeDefault.concat(Array)
if (!Array.isArray(type)) type = [type]
var isArray = Array.isArray(val)
var type = types[k]
if (!isArray) {
val = [val]
}
if (!type) {
type = typeDefault
}
if (type === Array) {
type = typeDefault.concat(Array)
}
if (!Array.isArray(type)) {
type = [type]
}
debug("val=%j", val)
debug("types=", type)
val = val.map(function (val) {
debug('val=%j', val)
debug('types=', type)
val = val.map(function (v) {
// if it's an unknown value, then parse false/true/null/numbers/dates
if (typeof val === "string") {
debug("string %j", val)
val = val.trim()
if ((val === "null" && ~type.indexOf(null))
|| (val === "true" &&
if (typeof v === 'string') {
debug('string %j', v)
v = v.trim()
if ((v === 'null' && ~type.indexOf(null))
|| (v === 'true' &&
(~type.indexOf(true) || ~type.indexOf(Boolean)))
|| (val === "false" &&
|| (v === 'false' &&
(~type.indexOf(false) || ~type.indexOf(Boolean)))) {
val = JSON.parse(val)
debug("jsonable %j", val)
} else if (~type.indexOf(Number) && !isNaN(val)) {
debug("convert to number", val)
val = +val
} else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
debug("convert to date", val)
val = new Date(val)
v = JSON.parse(v)
debug('jsonable %j', v)
} else if (~type.indexOf(Number) && !isNaN(v)) {
debug('convert to number', v)
v = +v
} else if (~type.indexOf(Date) && !isNaN(Date.parse(v))) {
debug('convert to date', v)
v = new Date(v)
}
}
if (!types.hasOwnProperty(k)) {
return val
if (!Object.prototype.hasOwnProperty.call(types, k)) {
return v
}
// allow `--no-blah` to set 'blah' to null if null is allowed
if (val === false && ~type.indexOf(null) &&
if (v === false && ~type.indexOf(null) &&
!(~type.indexOf(false) || ~type.indexOf(Boolean))) {
val = null
v = null
}
var d = {}
d[k] = val
debug("prevalidated val", d, val, types[k])
if (!validate(d, k, val, types[k], typeDefs)) {
d[k] = v
debug('prevalidated val', d, v, types[k])
if (!validate(d, k, v, types[k], typeDefs)) {
if (exports.invalidHandler) {
exports.invalidHandler(k, val, types[k], data)
exports.invalidHandler(k, v, types[k], data)
} else if (exports.invalidHandler !== false) {
debug("invalid: "+k+"="+val, types[k])
debug('invalid: ' + k + '=' + v, types[k])
}
return remove
}
debug("validated val", d, val, types[k])
debug('validated v', d, v, types[k])
return d[k]
}).filter(function (val) { return val !== remove })
}).filter(function (v) {
return v !== remove
})

@@ -126,9 +142,10 @@ // if we allow Array specifically, then an empty array is how we

delete data[k]
}
else if (isArray) {
} else if (isArray) {
debug(isArray, data[k], val)
data[k] = val
} else data[k] = val[0]
} else {
data[k] = val[0]
}
debug("k=%s val=%j", k, val, data[k])
debug('k=%s val=%j', k, val, data[k])
})

@@ -142,13 +159,17 @@ }

function validatePath (data, k, val) {
if (val === true) return false
if (val === null) return true
if (val === true) {
return false
}
if (val === null) {
return true
}
val = String(val)
var isWin = process.platform === 'win32'
, homePattern = isWin ? /^~(\/|\\)/ : /^~\//
, home = os.homedir()
var isWin = process.platform === 'win32'
var homePattern = isWin ? /^~(\/|\\)/ : /^~\//
var home = os.homedir()
if (home && val.match(homePattern)) {
data[k] = path.resolve(home, val.substr(2))
data[k] = path.resolve(home, val.slice(2))
} else {

@@ -161,4 +182,6 @@ data[k] = path.resolve(val)

function validateNumber (data, k, val) {
debug("validate Number %j %j %j", k, val, isNaN(val))
if (isNaN(val)) return false
debug('validate Number %j %j %j', k, val, isNaN(val))
if (isNaN(val)) {
return false
}
data[k] = +val

@@ -169,4 +192,6 @@ }

var s = Date.parse(val)
debug("validate Date %j %j %j", k, val, s)
if (isNaN(s)) return false
debug('validate Date %j %j %j', k, val, s)
if (isNaN(s)) {
return false
}
data[k] = new Date(val)

@@ -176,8 +201,15 @@ }

function validateBoolean (data, k, val) {
if (val instanceof Boolean) val = val.valueOf()
else if (typeof val === "string") {
if (!isNaN(val)) val = !!(+val)
else if (val === "null" || val === "false") val = false
else val = true
} else val = !!val
if (val instanceof Boolean) {
val = val.valueOf()
} else if (typeof val === 'string') {
if (!isNaN(val)) {
val = !!(+val)
} else if (val === 'null' || val === 'false') {
val = false
} else {
val = true
}
} else {
val = !!val
}
data[k] = val

@@ -187,4 +219,8 @@ }

function validateUrl (data, k, val) {
// Changing this would be a breaking change in the npm cli
/* eslint-disable-next-line node/no-deprecated-api */
val = url.parse(String(val))
if (!val.host) return false
if (!val.host) {
return false
}
data[k] = val.href

@@ -194,3 +230,5 @@ }

function validateStream (data, k, val) {
if (!(val instanceof Stream)) return false
if (!(val instanceof Stream)) {
return false
}
data[k] = val

@@ -202,5 +240,9 @@ }

if (Array.isArray(type)) {
for (var i = 0, l = type.length; i < l; i ++) {
if (type[i] === Array) continue
if (validate(data, k, val, type[i], typeDefs)) return true
for (let i = 0, l = type.length; i < l; i++) {
if (type[i] === Array) {
continue
}
if (validate(data, k, val, type[i], typeDefs)) {
return true
}
}

@@ -212,7 +254,15 @@ delete data[k]

// an array of anything?
if (type === Array) return true
if (type === Array) {
return true
}
// Original comment:
// NaN is poisonous. Means that something is not allowed.
// New comment: Changing this to an isNaN check breaks a lot of tests.
// Something is being assumed here that is not actually what happens in
// practice. Fixing it is outside the scope of getting linting to pass in
// this repo. Leaving as-is for now.
/* eslint-disable-next-line no-self-compare */
if (type !== type) {
debug("Poison NaN", k, val, type)
debug('Poison NaN', k, val, type)
delete data[k]

@@ -224,3 +274,3 @@ return false

if (val === type) {
debug("Explicitly allowed %j", val)
debug('Explicitly allowed %j', val)
// if (isArray) (data[k] = data[k] || []).push(val)

@@ -234,10 +284,13 @@ // else data[k] = val

var ok = false
, types = Object.keys(typeDefs)
for (var i = 0, l = types.length; i < l; i ++) {
debug("test type %j %j %j", k, val, types[i])
var types = Object.keys(typeDefs)
for (let i = 0, l = types.length; i < l; i++) {
debug('test type %j %j %j', k, val, types[i])
var t = typeDefs[types[i]]
if (t &&
((type && type.name && t.type && t.type.name) ? (type.name === t.type.name) : (type === t.type))) {
if (t && (
(type && type.name && t.type && t.type.name) ?
(type.name === t.type.name) :
(type === t.type)
)) {
var d = {}
ok = false !== t.validate(d, k, val)
ok = t.validate(d, k, val) !== false
val = d[k]

@@ -252,5 +305,7 @@ if (ok) {

}
debug("OK? %j (%j %j %j)", ok, k, val, types[i])
debug('OK? %j (%j %j %j)', ok, k, val, types[types.length - 1])
if (!ok) delete data[k]
if (!ok) {
delete data[k]
}
return ok

@@ -260,11 +315,10 @@ }

function parse (args, data, remain, types, shorthands) {
debug("parse", args, data, remain)
debug('parse', args, data, remain)
var key = null
, abbrevs = abbrev(Object.keys(types))
, shortAbbr = abbrev(Object.keys(shorthands))
var abbrevs = abbrev(Object.keys(types))
var shortAbbr = abbrev(Object.keys(shorthands))
for (var i = 0; i < args.length; i ++) {
for (var i = 0; i < args.length; i++) {
var arg = args[i]
debug("arg", arg)
debug('arg', arg)

@@ -275,12 +329,12 @@ if (arg.match(/^-{2,}$/)) {

remain.push.apply(remain, args.slice(i + 1))
args[i] = "--"
args[i] = '--'
break
}
var hadEq = false
if (arg.charAt(0) === "-" && arg.length > 1) {
if (arg.charAt(0) === '-' && arg.length > 1) {
var at = arg.indexOf('=')
if (at > -1) {
hadEq = true
var v = arg.substr(at + 1)
arg = arg.substr(0, at)
var v = arg.slice(at + 1)
arg = arg.slice(0, at)
args.splice(i, 1, arg, v)

@@ -292,3 +346,3 @@ }

var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
debug("arg=%j shRes=%j", arg, shRes)
debug('arg=%j shRes=%j', arg, shRes)
if (shRes) {

@@ -298,14 +352,16 @@ debug(arg, shRes)

if (arg !== shRes[0]) {
i --
i--
continue
}
}
arg = arg.replace(/^-+/, "")
arg = arg.replace(/^-+/, '')
var no = null
while (arg.toLowerCase().indexOf("no-") === 0) {
while (arg.toLowerCase().indexOf('no-') === 0) {
no = !no
arg = arg.substr(3)
arg = arg.slice(3)
}
if (abbrevs[arg]) arg = abbrevs[arg]
if (abbrevs[arg]) {
arg = abbrevs[arg]
}

@@ -323,5 +379,9 @@ var argType = types[arg]

// allow unknown things to be arrays if specified multiple times.
if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) {
if (!Array.isArray(data[arg]))
if (
!Object.prototype.hasOwnProperty.call(types, arg) &&
Object.prototype.hasOwnProperty.call(data, arg)
) {
if (!Array.isArray(data[arg])) {
data[arg] = [data[arg]]
}
isArray = true

@@ -331,3 +391,3 @@ }

var val
, la = args[i + 1]
var la = args[i + 1]

@@ -338,3 +398,3 @@ var isBool = typeof no === 'boolean' ||

(typeof argType === 'undefined' && !hadEq) ||
(la === "false" &&
(la === 'false' &&
(argType === null ||

@@ -347,7 +407,9 @@ isTypeArray && ~argType.indexOf(null)))

// however, also support --bool true or --bool false
if (la === "true" || la === "false") {
if (la === 'true' || la === 'false') {
val = JSON.parse(la)
la = null
if (no) val = !val
i ++
if (no) {
val = !val
}
i++
}

@@ -360,22 +422,25 @@

val = la
i ++
} else if ( la === "null" && ~argType.indexOf(null) ) {
i++
} else if (la === 'null' && ~argType.indexOf(null)) {
// null allowed
val = null
i ++
} else if ( !la.match(/^-{2,}[^-]/) &&
i++
} else if (!la.match(/^-{2,}[^-]/) &&
!isNaN(la) &&
~argType.indexOf(Number) ) {
~argType.indexOf(Number)) {
// number
val = +la
i ++
} else if ( !la.match(/^-[^-]/) && ~argType.indexOf(String) ) {
i++
} else if (!la.match(/^-[^-]/) && ~argType.indexOf(String)) {
// string
val = la
i ++
i++
}
}
if (isArray) (data[arg] = data[arg] || []).push(val)
else data[arg] = val
if (isArray) {
(data[arg] = data[arg] || []).push(val)
} else {
data[arg] = val
}

@@ -387,6 +452,6 @@ continue

if (la === undefined) {
la = ""
la = ''
} else if (la.match(/^-{1,2}[^-]+/)) {
la = ""
i --
la = ''
i--
}

@@ -397,10 +462,13 @@ }

la = undefined
i --
i--
}
val = la === undefined ? true : la
if (isArray) (data[arg] = data[arg] || []).push(val)
else data[arg] = val
if (isArray) {
(data[arg] = data[arg] || []).push(val)
} else {
data[arg] = val
}
i ++
i++
continue

@@ -420,4 +488,5 @@ }

// if it's an exact known option, then don't go any further
if (abbrevs[arg] === arg)
if (abbrevs[arg] === arg) {
return null
}

@@ -427,4 +496,5 @@ // if it's an exact known shortopt, same deal

// make it an array, if it's a list of words
if (shorthands[arg] && !Array.isArray(shorthands[arg]))
if (shorthands[arg] && !Array.isArray(shorthands[arg])) {
shorthands[arg] = shorthands[arg].split(/\s+/)
}

@@ -439,3 +509,3 @@ return shorthands[arg]

return s.length === 1
}).reduce(function (l,r) {
}).reduce(function (l, r) {
l[r] = true

@@ -448,26 +518,30 @@ return l

var chrs = arg.split("").filter(function (c) {
var chrs = arg.split('').filter(function (c) {
return singles[c]
})
if (chrs.join("") === arg) return chrs.map(function (c) {
return shorthands[c]
}).reduce(function (l, r) {
return l.concat(r)
}, [])
if (chrs.join('') === arg) {
return chrs.map(function (c) {
return shorthands[c]
}).reduce(function (l, r) {
return l.concat(r)
}, [])
}
// if it's an arg abbrev, and not a literal shorthand, then prefer the arg
if (abbrevs[arg] && !shorthands[arg])
if (abbrevs[arg] && !shorthands[arg]) {
return null
}
// if it's an abbr for a shorthand, then use that
if (shortAbbr[arg])
if (shortAbbr[arg]) {
arg = shortAbbr[arg]
}
// make it an array, if it's a list of words
if (shorthands[arg] && !Array.isArray(shorthands[arg]))
if (shorthands[arg] && !Array.isArray(shorthands[arg])) {
shorthands[arg] = shorthands[arg].split(/\s+/)
}
return shorthands[arg]
}
{
"name": "nopt",
"version": "5.0.0",
"version": "6.0.0",
"description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"author": "GitHub Inc.",
"main": "lib/nopt.js",

@@ -11,3 +11,9 @@ "scripts": {

"prepublishOnly": "git push origin --follow-tags",
"test": "tap test/*.js"
"test": "tap",
"lint": "eslint \"**/*.js\"",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force",
"lintfix": "npm run lint -- --fix",
"snap": "tap",
"posttest": "npm run lint"
},

@@ -23,14 +29,27 @@ "repository": {

"dependencies": {
"abbrev": "1"
"abbrev": "^1.0.0"
},
"devDependencies": {
"tap": "^14.10.6"
"@npmcli/eslint-config": "^3.0.1",
"@npmcli/template-oss": "3.5.0",
"tap": "^16.3.0"
},
"tap": {
"lines": 87,
"functions": 91,
"branches": 81,
"statements": 87
},
"files": [
"bin",
"lib"
"bin/",
"lib/"
],
"engines": {
"node": ">=6"
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"windowsCI": false,
"version": "3.5.0"
}
}
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc