+7
-43
| const abbrev = require('abbrev') | ||
| const debug = require('./debug') | ||
| const defaultTypeDefs = require('./type-defs') | ||
@@ -34,4 +33,2 @@ | ||
| } = {}) { | ||
| debug(types, shorthands, args, typeDefs) | ||
| const data = {} | ||
@@ -93,3 +90,2 @@ const argv = { | ||
| let val = data[k] | ||
| debug('val=%j', val) | ||
| const isArray = Array.isArray(val) | ||
@@ -111,8 +107,5 @@ let [hasType, rawType] = getType(k, { types, dynamicTypes }) | ||
| debug('val=%j', val) | ||
| debug('types=', type) | ||
| val = val.map((v) => { | ||
| // if it's an unknown value, then parse false/true/null/numbers/dates | ||
| if (typeof v === 'string') { | ||
| debug('string %j', v) | ||
| v = v.trim() | ||
@@ -125,8 +118,5 @@ if ((v === 'null' && ~type.indexOf(null)) | ||
| v = JSON.parse(v) | ||
| debug('jsonable %j', v) | ||
| } else if (hasTypeDef(type, NumberType) && !isNaN(v)) { | ||
| debug('convert to number', v) | ||
| v = +v | ||
| } else if (hasTypeDef(type, DateType) && !isNaN(Date.parse(v))) { | ||
| debug('convert to date', v) | ||
| v = new Date(v) | ||
@@ -155,12 +145,8 @@ } | ||
| d[k] = v | ||
| debug('prevalidated val', d, v, rawType) | ||
| if (!validate(d, k, v, rawType, { typeDefs })) { | ||
| if (invalidHandler) { | ||
| invalidHandler(k, v, rawType, data) | ||
| } else if (invalidHandler !== false) { | ||
| debug('invalid: ' + k + '=' + v, rawType) | ||
| } | ||
| return remove | ||
| } | ||
| debug('validated v', d, v, rawType) | ||
| return d[k] | ||
@@ -172,6 +158,4 @@ }).filter((v) => v !== remove) | ||
| if (!val.length && doesNotHaveTypeDef(type, ArrayType)) { | ||
| debug('VAL HAS NO LENGTH, DELETE IT', val, k, type.indexOf(ArrayType)) | ||
| delete data[k] | ||
| } else if (isArray) { | ||
| debug(isArray, data[k], val) | ||
| data[k] = val | ||
@@ -181,4 +165,2 @@ } else { | ||
| } | ||
| debug('k=%s val=%j', k, val, data[k]) | ||
| }) | ||
@@ -209,10 +191,11 @@ } | ||
| // 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. | ||
| // NaN is poisonous, it 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) | ||
| delete data[k] | ||
@@ -224,3 +207,2 @@ return false | ||
| if (val === type) { | ||
| debug('Explicitly allowed %j', val) | ||
| data[k] = val | ||
@@ -234,3 +216,2 @@ return true | ||
| for (let i = 0, l = types.length; i < l; i++) { | ||
| debug('test type %j %j %j', k, val, types[i]) | ||
| const t = typeDefs[types[i]] | ||
@@ -251,3 +232,2 @@ if (t && ( | ||
| } | ||
| debug('OK? %j (%j %j %j)', ok, k, val, types[types.length - 1]) | ||
@@ -272,7 +252,3 @@ if (!ok) { | ||
| const BooleanType = typeDefs.Boolean?.type | ||
| debug('parse', args, data, remain) | ||
| const abbrevs = abbrev(Object.keys(types)) | ||
| debug('abbrevs=%j', abbrevs) | ||
| const shortAbbr = abbrev(Object.keys(shorthands)) | ||
@@ -282,3 +258,2 @@ | ||
| let arg = args[i] | ||
| debug('arg', arg) | ||
@@ -305,3 +280,2 @@ if (arg.match(/^-{2,}$/)) { | ||
| const shRes = resolveShort(arg, shortAbbr, abbrevs, { shorthands, abbrevHandler }) | ||
| debug('arg=%j shRes=%j', arg, shRes) | ||
| if (shRes) { | ||
@@ -325,4 +299,2 @@ args.splice.apply(args, [i, 1].concat(shRes)) | ||
| abbrevHandler(arg, abbrevs[arg]) | ||
| } else if (abbrevHandler !== false) { | ||
| debug(`abbrev: ${arg} -> ${abbrevs[arg]}`) | ||
| } | ||
@@ -370,7 +342,2 @@ arg = abbrevs[arg] | ||
| } | ||
| } else if (unknownHandler !== false) { | ||
| debug(`unknown: ${arg}`) | ||
| if (hangingLa) { | ||
| debug(`unknown: ${la} parsed as normal opt`) | ||
| } | ||
| } | ||
@@ -461,3 +428,2 @@ } | ||
| shorthands[SINGLES] = singles | ||
| debug('shorthand singles', singles) | ||
| } | ||
@@ -510,4 +476,2 @@ const chrs = arg.split('').filter((c) => singles[c]) | ||
| abbrevHandler(arg, shortAbbr[arg]) | ||
| } else if (abbrevHandler !== false) { | ||
| debug(`abbrev: ${arg} -> ${shortAbbr[arg]}`) | ||
| } | ||
@@ -514,0 +478,0 @@ arg = shortAbbr[arg] |
+2
-4
| const lib = require('./nopt-lib') | ||
| const defaultTypeDefs = require('./type-defs') | ||
| // This is the version of nopt's API that requires setting typeDefs and invalidHandler | ||
| // on the required `nopt` object since it is a singleton. To not do a breaking change | ||
| // an API that requires all options be passed in is located in `nopt-lib.js` and | ||
| // exported here as lib. | ||
| // This is the version of nopt's API that requires setting typeDefs and invalidHandler on the required `nopt` object since it is a singleton. | ||
| // To not do a breaking change an API that requires all options be passed in is located in `nopt-lib.js` and exported here as lib. | ||
| // TODO(breaking): make API only work in non-singleton mode | ||
@@ -9,0 +7,0 @@ |
+8
-13
@@ -1,6 +0,5 @@ | ||
| const url = require('url') | ||
| const path = require('path') | ||
| const Stream = require('stream').Stream | ||
| const os = require('os') | ||
| const debug = require('./debug') | ||
| const os = require('node:os') | ||
| const path = require('node:path') | ||
| const { Stream } = require('node:stream') | ||
| const { URL } = require('node:url') | ||
@@ -34,3 +33,2 @@ function validateString (data, k, val) { | ||
| function validateNumber (data, k, val) { | ||
| debug('validate Number %j %j %j', k, val, isNaN(val)) | ||
| if (isNaN(val)) { | ||
@@ -44,3 +42,2 @@ return false | ||
| const s = Date.parse(val) | ||
| debug('validate Date %j %j %j', k, val, s) | ||
| if (isNaN(s)) { | ||
@@ -68,9 +65,7 @@ return false | ||
| 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) { | ||
| const parsed = URL.parse(String(val)) | ||
| if (!parsed) { | ||
| return false | ||
| } | ||
| data[k] = val.href | ||
| data[k] = parsed.href | ||
| } | ||
@@ -88,3 +83,3 @@ | ||
| Boolean: { type: Boolean, validate: validateBoolean }, | ||
| url: { type: url, validate: validateUrl }, | ||
| url: { type: URL, validate: validateUrl }, | ||
| Number: { type: Number, validate: validateNumber }, | ||
@@ -91,0 +86,0 @@ path: { type: path, validate: validatePath }, |
+15
-17
| { | ||
| "name": "nopt", | ||
| "version": "9.0.0", | ||
| "version": "10.0.0", | ||
| "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.", | ||
@@ -8,3 +8,3 @@ "author": "GitHub Inc.", | ||
| "scripts": { | ||
| "test": "tap", | ||
| "test": "node --test './test/**/*.js'", | ||
| "lint": "npm run eslint", | ||
@@ -14,5 +14,7 @@ "postlint": "template-oss-check", | ||
| "lintfix": "npm run eslint -- --fix", | ||
| "snap": "tap", | ||
| "snap": "node --test --test-update-snapshots './test/**/*.js'", | ||
| "posttest": "npm run lint", | ||
| "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" | ||
| "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", | ||
| "test:node20": "node --test test", | ||
| "test:cover": "node --test --experimental-test-coverage --test-timeout=3000 --test-coverage-lines=100 --test-coverage-functions=100 --test-coverage-branches=100 './test/**/*.js'" | ||
| }, | ||
@@ -28,15 +30,8 @@ "repository": { | ||
| "dependencies": { | ||
| "abbrev": "^4.0.0" | ||
| "abbrev": "^5.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@npmcli/eslint-config": "^5.0.0", | ||
| "@npmcli/template-oss": "4.27.1", | ||
| "tap": "^16.3.0" | ||
| "@npmcli/eslint-config": "^6.0.0", | ||
| "@npmcli/template-oss": "5.1.0" | ||
| }, | ||
| "tap": { | ||
| "nyc-arg": [ | ||
| "--exclude", | ||
| "tap-snapshots/**" | ||
| ] | ||
| }, | ||
| "files": [ | ||
@@ -47,3 +42,3 @@ "bin/", | ||
| "engines": { | ||
| "node": "^20.17.0 || >=22.9.0" | ||
| "node": "^22.22.2 || ^24.15.0 || >=26.0.0" | ||
| }, | ||
@@ -53,5 +48,8 @@ "templateOSS": { | ||
| "windowsCI": false, | ||
| "version": "4.27.1", | ||
| "publish": true | ||
| "version": "5.1.0", | ||
| "publish": true, | ||
| "testRunner": "node:test", | ||
| "latestCiVersion": 24, | ||
| "updateNpm": false | ||
| } | ||
| } |
| /* istanbul ignore next */ | ||
| module.exports = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG | ||
| // eslint-disable-next-line no-console | ||
| ? (...a) => console.error(...a) | ||
| : () => {} |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances
2
-33.33%0
-100%26636
-5.3%7
-12.5%555
-7.5%+ Added
- Removed
Updated