--- /dev/null
+// defaults, types, and shorthands.
+
+
+var path = require("path")
+ , url = require("url")
+ , Stream = require("stream").Stream
+ , semver = require("semver")
+ , stableFamily = semver.parse(process.version)
+ , nopt = require("nopt")
+ , os = require("os")
+ , osenv = require("osenv")
+ , umask = require("../utils/umask")
+
+var log
+try {
+ log = require("npmlog")
+} catch (er) {
+ var util = require("util")
+ log = { warn: function (m) {
+ console.warn(m + " " + util.format.apply(util, [].slice.call(arguments, 1)))
+ } }
+}
+
+exports.Umask = Umask
+function Umask () {}
+function validateUmask (data, k, val) {
+ return umask.validate(data, k, val)
+}
+
+function validateSemver (data, k, val) {
+ if (!semver.valid(val)) return false
+ data[k] = semver.valid(val)
+}
+
+function validateStream (data, k, val) {
+ if (!(val instanceof Stream)) return false
+ data[k] = val
+}
+
+nopt.typeDefs.semver = { type: semver, validate: validateSemver }
+nopt.typeDefs.Stream = { type: Stream, validate: validateStream }
+nopt.typeDefs.Umask = { type: Umask, validate: validateUmask }
+
+nopt.invalidHandler = function (k, val, type) {
+ log.warn("invalid config", k + "=" + JSON.stringify(val))
+
+ if (Array.isArray(type)) {
+ if (type.indexOf(url) !== -1) type = url
+ else if (type.indexOf(path) !== -1) type = path
+ }
+
+ switch (type) {
+ case Umask:
+ log.warn("invalid config", "Must be umask, octal number in range 0000..0777")
+ break
+ case url:
+ log.warn("invalid config", "Must be a full url with 'http://'")
+ break
+ case path:
+ log.warn("invalid config", "Must be a valid filesystem path")
+ break
+ case Number:
+ log.warn("invalid config", "Must be a numeric value")
+ break
+ case Stream:
+ log.warn("invalid config", "Must be an instance of the Stream class")
+ break
+ }
+}
+
+if (!stableFamily || (+stableFamily.minor % 2)) stableFamily = null
+else stableFamily = stableFamily.major + "." + stableFamily.minor
+
+var defaults
+
+var temp = osenv.tmpdir()
+var home = osenv.home()
+
+var uidOrPid = process.getuid ? process.getuid() : process.pid
+
+if (home) process.env.HOME = home
+else home = path.resolve(temp, "npm-" + uidOrPid)
+
+var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
+var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
+var cache = path.resolve(cacheRoot, cacheExtra)
+
+
+var globalPrefix
+Object.defineProperty(exports, "defaults", {get: function () {
+ if (defaults) return defaults
+
+ if (process.env.PREFIX) {
+ globalPrefix = process.env.PREFIX
+ } else if (process.platform === "win32") {
+ // c:\node\node.exe --> prefix=c:\node\
+ globalPrefix = path.dirname(process.execPath)
+ } else {
+ // /usr/local/bin/node --> prefix=/usr/local
+ globalPrefix = path.dirname(path.dirname(process.execPath))
+
+ // destdir only is respected on Unix
+ if (process.env.DESTDIR) {
+ globalPrefix = path.join(process.env.DESTDIR, globalPrefix)
+ }
+ }
+
+ defaults = {
+ access : null
+ , "always-auth" : false
+
+ , "bin-links" : true
+ , browser : null
+
+ , ca: null
+ , cafile: null
+
+ , cache : cache
+
+ , "cache-lock-stale": 60000
+ , "cache-lock-retries": 10
+ , "cache-lock-wait": 10000
+
+ , "cache-max": Infinity
+ , "cache-min": 10
+
+ , cert: null
+
+ , color : true
+ , depth: Infinity
+ , description : true
+ , dev : false
+ , editor : osenv.editor()
+ , "engine-strict": false
+ , force : false
+
+ , "fetch-retries": 2
+ , "fetch-retry-factor": 10
+ , "fetch-retry-mintimeout": 10000
+ , "fetch-retry-maxtimeout": 60000
+
+ , git: "git"
+ , "git-tag-version": true
+
+ , global : false
+ , globalconfig : path.resolve(globalPrefix, "etc", "npmrc")
+ , group : process.platform === "win32" ? 0
+ : process.env.SUDO_GID || (process.getgid && process.getgid())
+ , heading: "npm"
+ , "if-present": false
+ , "ignore-scripts": false
+ , "init-module": path.resolve(home, ".npm-init.js")
+ , "init-author-name" : ""
+ , "init-author-email" : ""
+ , "init-author-url" : ""
+ , "init-version": "1.0.0"
+ , "init-license": "ISC"
+ , json: false
+ , key: null
+ , link: false
+ , "local-address" : undefined
+ , loglevel : "warn"
+ , logstream : process.stderr
+ , long : false
+ , maxsockets : 50
+ , message : "%s"
+ , "node-version" : process.version
+ , npat : false
+ , "onload-script" : false
+ , optional: true
+ , parseable : false
+ , prefix : globalPrefix
+ , production: process.env.NODE_ENV === "production"
+ , "proprietary-attribs": true
+ , proxy : null
+ , "https-proxy" : null
+ , "user-agent" : "npm/{npm-version} "
+ + "node/{node-version} "
+ + "{platform} "
+ + "{arch}"
+ , "rebuild-bundle" : true
+ , registry : "https://registry.npmjs.org/"
+ , rollback : true
+ , save : false
+ , "save-bundle": false
+ , "save-dev" : false
+ , "save-exact" : false
+ , "save-optional" : false
+ , "save-prefix": "^"
+ , scope : ""
+ , searchopts: ""
+ , searchexclude: null
+ , searchsort: "name"
+ , shell : osenv.shell()
+ , shrinkwrap: true
+ , "sign-git-tag": false
+ , spin: true
+ , "strict-ssl": true
+ , tag : "latest"
+ , "tag-version-prefix" : "v"
+ , tmp : temp
+ , unicode : true
+ , "unsafe-perm" : process.platform === "win32"
+ || process.platform === "cygwin"
+ || !( process.getuid && process.setuid
+ && process.getgid && process.setgid )
+ || process.getuid() !== 0
+ , usage : false
+ , user : process.platform === "win32" ? 0 : "nobody"
+ , userconfig : path.resolve(home, ".npmrc")
+ , umask: process.umask ? process.umask() : umask.fromString("022")
+ , version : false
+ , versions : false
+ , viewer: process.platform === "win32" ? "browser" : "man"
+
+ , _exit : true
+ }
+
+ return defaults
+}})
+
+exports.types =
+ { access : [null, "restricted", "public"]
+ , "always-auth" : Boolean
+ , "bin-links": Boolean
+ , browser : [null, String]
+ , ca: [null, String, Array]
+ , cafile : path
+ , cache : path
+ , "cache-lock-stale": Number
+ , "cache-lock-retries": Number
+ , "cache-lock-wait": Number
+ , "cache-max": Number
+ , "cache-min": Number
+ , cert: [null, String]
+ , color : ["always", Boolean]
+ , depth : Number
+ , description : Boolean
+ , dev : Boolean
+ , editor : String
+ , "engine-strict": Boolean
+ , force : Boolean
+ , "fetch-retries": Number
+ , "fetch-retry-factor": Number
+ , "fetch-retry-mintimeout": Number
+ , "fetch-retry-maxtimeout": Number
+ , git: String
+ , "git-tag-version": Boolean
+ , global : Boolean
+ , globalconfig : path
+ , group : [Number, String]
+ , "https-proxy" : [null, url]
+ , "user-agent" : String
+ , "heading": String
+ , "if-present": Boolean
+ , "ignore-scripts": Boolean
+ , "init-module": path
+ , "init-author-name" : String
+ , "init-author-email" : String
+ , "init-author-url" : ["", url]
+ , "init-license": String
+ , "init-version": semver
+ , json: Boolean
+ , key: [null, String]
+ , link: Boolean
+ // local-address must be listed as an IP for a local network interface
+ // must be IPv4 due to node bug
+ , "local-address" : getLocalAddresses()
+ , loglevel : ["silent", "error", "warn", "http", "info", "verbose", "silly"]
+ , logstream : Stream
+ , long : Boolean
+ , maxsockets : Number
+ , message: String
+ , "node-version" : [null, semver]
+ , npat : Boolean
+ , "onload-script" : [null, String]
+ , optional: Boolean
+ , parseable : Boolean
+ , prefix: path
+ , production: Boolean
+ , "proprietary-attribs": Boolean
+ , proxy : [null, false, url] // allow proxy to be disabled explicitly
+ , "rebuild-bundle" : Boolean
+ , registry : [null, url]
+ , rollback : Boolean
+ , save : Boolean
+ , "save-bundle": Boolean
+ , "save-dev" : Boolean
+ , "save-exact" : Boolean
+ , "save-optional" : Boolean
+ , "save-prefix": String
+ , scope : String
+ , searchopts : String
+ , searchexclude: [null, String]
+ , searchsort: [ "name", "-name"
+ , "description", "-description"
+ , "author", "-author"
+ , "date", "-date"
+ , "keywords", "-keywords" ]
+ , shell : String
+ , shrinkwrap: Boolean
+ , "sign-git-tag": Boolean
+ , spin: ["always", Boolean]
+ , "strict-ssl": Boolean
+ , tag : String
+ , tmp : path
+ , unicode : Boolean
+ , "unsafe-perm" : Boolean
+ , usage : Boolean
+ , user : [Number, String]
+ , userconfig : path
+ , umask: Umask
+ , version : Boolean
+ , "tag-version-prefix" : String
+ , versions : Boolean
+ , viewer: String
+ , _exit : Boolean
+ }
+
+function getLocalAddresses () {
+ var interfaces
+ // #8094: some environments require elevated permissions to enumerate
+ // interfaces, and synchronously throw EPERM when run without
+ // elevated privileges
+ try {
+ interfaces = os.networkInterfaces()
+ } catch (e) {
+ interfaces = {}
+ }
+
+ return Object.keys(interfaces).map(function (nic) {
+ return interfaces[nic].filter(function (addr) {
+ return addr.family === 'IPv4'
+ })
+ .map(function (addr) {
+ return addr.address
+ })
+ }).reduce(function (curr, next) {
+ return curr.concat(next)
+ }, []).concat(undefined)
+}
+
+exports.shorthands =
+ { s : ["--loglevel", "silent"]
+ , d : ["--loglevel", "info"]
+ , dd : ["--loglevel", "verbose"]
+ , ddd : ["--loglevel", "silly"]
+ , noreg : ["--no-registry"]
+ , N : ["--no-registry"]
+ , reg : ["--registry"]
+ , "no-reg" : ["--no-registry"]
+ , silent : ["--loglevel", "silent"]
+ , verbose : ["--loglevel", "verbose"]
+ , quiet: ["--loglevel", "warn"]
+ , q: ["--loglevel", "warn"]
+ , h : ["--usage"]
+ , H : ["--usage"]
+ , "?" : ["--usage"]
+ , help : ["--usage"]
+ , v : ["--version"]
+ , f : ["--force"]
+ , gangster : ["--force"]
+ , gangsta : ["--force"]
+ , desc : ["--description"]
+ , "no-desc" : ["--no-description"]
+ , "local" : ["--no-global"]
+ , l : ["--long"]
+ , m : ["--message"]
+ , p : ["--parseable"]
+ , porcelain : ["--parseable"]
+ , g : ["--global"]
+ , S : ["--save"]
+ , D : ["--save-dev"]
+ , E : ["--save-exact"]
+ , O : ["--save-optional"]
+ , y : ["--yes"]
+ , n : ["--no-yes"]
+ , B : ["--save-bundle"]
+ , C : ["--prefix"]
+ }