1 // defaults, types, and shorthands.
4 var path = require("path")
6 , Stream = require("stream").Stream
7 , semver = require("semver")
8 , stableFamily = semver.parse(process.version)
9 , nopt = require("nopt")
11 , osenv = require("osenv")
14 var log = require("npmlog")
16 var util = require('util')
17 var log = { warn: function (m) {
18 console.warn(m + util.format.apply(util, [].slice.call(arguments, 1)))
24 function validateOctal (data, k, val) {
25 // must be either an integer or an octal string.
26 if (typeof val === "number") {
31 if (typeof val === "string") {
32 if (val.charAt(0) !== "0" || isNaN(val)) return false
33 data[k] = parseInt(val, 8).toString(8)
37 function validateSemver (data, k, val) {
38 if (!semver.valid(val)) return false
39 data[k] = semver.valid(val)
42 function validateStream (data, k, val) {
43 if (!(val instanceof Stream)) return false
47 nopt.typeDefs.semver = { type: semver, validate: validateSemver }
48 nopt.typeDefs.Octal = { type: Octal, validate: validateOctal }
49 nopt.typeDefs.Stream = { type: Stream, validate: validateStream }
51 nopt.invalidHandler = function (k, val, type, data) {
52 log.warn("invalid config", k + "=" + JSON.stringify(val))
54 if (Array.isArray(type)) {
55 if (type.indexOf(url) !== -1) type = url
56 else if (type.indexOf(path) !== -1) type = path
61 log.warn("invalid config", "Must be octal number, starting with 0")
64 log.warn("invalid config", "Must be a full url with 'http://'")
67 log.warn("invalid config", "Must be a valid filesystem path")
70 log.warn("invalid config", "Must be a numeric value")
73 log.warn("invalid config", "Must be an instance of the Stream class")
78 if (!stableFamily || (+stableFamily.minor % 2)) stableFamily = null
79 else stableFamily = stableFamily.major + "." + stableFamily.minor
83 var temp = osenv.tmpdir()
84 var home = osenv.home()
86 var uidOrPid = process.getuid ? process.getuid() : process.pid
88 if (home) process.env.HOME = home
89 else home = path.resolve(temp, "npm-" + uidOrPid)
91 var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
92 var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
93 var cache = path.resolve(cacheRoot, cacheExtra)
97 Object.defineProperty(exports, "defaults", {get: function () {
98 if (defaults) return defaults
100 if (process.env.PREFIX) {
101 globalPrefix = process.env.PREFIX
102 } else if (process.platform === "win32") {
103 // c:\node\node.exe --> prefix=c:\node\
104 globalPrefix = path.dirname(process.execPath)
106 // /usr/local/bin/node --> prefix=/usr/local
107 globalPrefix = path.dirname(path.dirname(process.execPath))
109 // destdir only is respected on Unix
110 if (process.env.DESTDIR) {
111 globalPrefix = path.join(process.env.DESTDIR, globalPrefix)
116 { "always-auth" : false
120 , ca: // the npm CA certificate.
121 [ "-----BEGIN CERTIFICATE-----\n"+
122 "MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC\n"+
123 "VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x\n"+
124 "IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w\n"+
125 "bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y\n"+
126 "MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV\n"+
127 "BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj\n"+
128 "YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA\n"+
129 "aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE\n"+
130 "OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz\n"+
131 "Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl\n"+
132 "y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC\n"+
133 "l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv\n"+
134 "yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl\n"+
135 "ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op\n"+
136 "-----END CERTIFICATE-----\n",
138 // "GlobalSign Root CA"
139 "-----BEGIN CERTIFICATE-----\n"+
140 "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\n"+
141 "GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\n"+
142 "b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\n"+
143 "BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\n"+
144 "VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\n"+
145 "DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\n"+
146 "THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\n"+
147 "Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\n"+
148 "c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\n"+
149 "gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"+
150 "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\n"+
151 "AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\n"+
152 "Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\n"+
153 "j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\n"+
154 "hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\n"+
155 "X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n"+
156 "-----END CERTIFICATE-----\n",
158 // "GlobalSign Root CA - R2"
159 "-----BEGIN CERTIFICATE-----\n"+
160 "MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv\n"+
161 "YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh\n"+
162 "bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT\n"+
163 "aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln\n"+
164 "bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6\n"+
165 "ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp\n"+
166 "s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN\n"+
167 "S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL\n"+
168 "TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C\n"+
169 "ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\n"+
170 "FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i\n"+
171 "YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN\n"+
172 "BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp\n"+
173 "9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu\n"+
174 "01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7\n"+
175 "9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\n"+
176 "TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n"+
177 "-----END CERTIFICATE-----\n",
179 // GlobalSign Organization Validation CA - G2
180 "-----BEGIN CERTIFICATE-----\n"+
181 "MIIEYDCCA0igAwIBAgILBAAAAAABL07hRQwwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n"+
182 "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n"+
183 "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw\n"+
184 "MDBaFw0yMjA0MTMxMDAwMDBaMF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n"+
185 "YWxTaWduIG52LXNhMTMwMQYDVQQDEypHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW\n"+
186 "YWxpZGF0aW9uIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n"+
187 "AQDdNR3yIFQmGtDvpW+Bdllw3Of01AMkHyQOnSKf1Ccyeit87ovjYWI4F6+0S3qf\n"+
188 "ZyEcLZVUunm6tsTyDSF0F2d04rFkCJlgePtnwkv3J41vNnbPMYzl8QbX3FcOW6zu\n"+
189 "zi2rqqlwLwKGyLHQCAeV6irs0Z7kNlw7pja1Q4ur944+ABv/hVlrYgGNguhKujiz\n"+
190 "4MP0bRmn6gXdhGfCZsckAnNate6kGdn8AM62pI3ffr1fsjqdhDFPyGMM5NgNUqN+\n"+
191 "ARvUZ6UYKOsBp4I82Y4d5UcNuotZFKMfH0vq4idGhs6dOcRmQafiFSNrVkfB7cVT\n"+
192 "5NSAH2v6gEaYsgmmD5W+ZoiTAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMCAQYw\n"+
193 "EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUXUayjcRLdBy77fVztjq3OI91\n"+
194 "nn4wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3\n"+
195 "Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSGImh0\n"+
196 "dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEEMTAv\n"+
197 "MC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEw\n"+
198 "HwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEFBQAD\n"+
199 "ggEBABvgiADHBREc/6stSEJSzSBo53xBjcEnxSxZZ6CaNduzUKcbYumlO/q2IQen\n"+
200 "fPMOK25+Lk2TnLryhj5jiBDYW2FQEtuHrhm70t8ylgCoXtwtI7yw07VKoI5lkS/Z\n"+
201 "9oL2dLLffCbvGSuXL+Ch7rkXIkg/pfcNYNUNUUflWP63n41edTzGQfDPgVRJEcYX\n"+
202 "pOBWYdw9P91nbHZF2krqrhqkYE/Ho9aqp9nNgSvBZnWygI/1h01fwlr1kMbawb30\n"+
203 "hag8IyrhFHvBN91i0ZJsumB9iOQct+R2UTjEqUdOqCsukNK1OFHrwZyKarXMsh3o\n"+
204 "wFZUTKiL8IkyhtyTMr5NGvo1dbU=\n"+
205 "-----END CERTIFICATE-----\n"
211 , "cache-lock-stale": 60000
212 , "cache-lock-retries": 10
213 , "cache-lock-wait": 10000
215 , "cache-max": Infinity
223 , editor : osenv.editor()
224 , "engine-strict": false
228 , "fetch-retry-factor": 10
229 , "fetch-retry-mintimeout": 10000
230 , "fetch-retry-maxtimeout": 60000
233 , "git-tag-version": true
236 , globalconfig : path.resolve(globalPrefix, "etc", "npmrc")
237 , globalignorefile : path.resolve( globalPrefix, "etc", "npmignore")
238 , group : process.platform === "win32" ? 0
239 : process.env.SUDO_GID || (process.getgid && process.getgid())
242 , "init-module": path.resolve(home, '.npm-init.js')
243 , "init.version" : "0.0.0"
244 , "init.author.name" : ""
245 , "init.author.email" : ""
246 , "init.author.url" : ""
249 , "local-address" : undefined
251 , logstream : process.stderr
254 , "node-version" : process.version
255 , npaturl : "http://npat.npmjs.org/"
257 , "onload-script" : false
261 , prefix : globalPrefix
262 , production: process.env.NODE_ENV === "production"
263 , "proprietary-attribs": true
264 , proxy : process.env.HTTP_PROXY || process.env.http_proxy || null
265 , "https-proxy" : process.env.HTTPS_PROXY || process.env.https_proxy ||
266 process.env.HTTP_PROXY || process.env.http_proxy || null
267 , "user-agent" : "node/" + process.version
268 + ' ' + process.platform
270 , "rebuild-bundle" : true
271 , registry : "https://registry.npmjs.org/"
274 , "save-bundle": false
276 , "save-optional" : false
278 , searchexclude: null
280 , shell : osenv.shell()
282 , "sign-git-tag": false
287 , "unsafe-perm" : process.platform === "win32"
288 || process.platform === "cygwin"
289 || !( process.getuid && process.setuid
290 && process.getgid && process.setgid )
291 || process.getuid() !== 0
293 , user : process.platform === "win32" ? 0 : "nobody"
295 , userconfig : path.resolve(home, ".npmrc")
296 , userignorefile : path.resolve(home, ".npmignore")
300 , viewer: process.platform === "win32" ? "browser" : "man"
308 { "always-auth" : Boolean
309 , "bin-links": Boolean
310 , browser : [null, String]
311 , ca: [null, String, Array]
313 , "cache-lock-stale": Number
314 , "cache-lock-retries": Number
315 , "cache-lock-wait": Number
316 , "cache-max": Number
317 , "cache-min": Number
318 , color : ["always", Boolean]
321 , description : Boolean
324 , "engine-strict": Boolean
326 , "fetch-retries": Number
327 , "fetch-retry-factor": Number
328 , "fetch-retry-mintimeout": Number
329 , "fetch-retry-maxtimeout": Number
331 , "git-tag-version": Boolean
333 , globalconfig : path
334 , globalignorefile: path
335 , group : [Number, String]
336 , "https-proxy" : [null, url]
337 , "user-agent" : String
340 , "init-module": path
341 , "init.version" : [null, semver]
342 , "init.author.name" : String
343 , "init.author.email" : String
344 , "init.author.url" : ["", url]
347 // local-address must be listed as an IP for a local network interface
348 // must be IPv4 due to node bug
349 , "local-address" : Object.keys(os.networkInterfaces()).map(function (nic) {
350 return os.networkInterfaces()[nic].filter(function (addr) {
351 return addr.family === "IPv4"
353 .map(function (addr) {
356 }).reduce(function (curr, next) {
357 return curr.concat(next)
359 , loglevel : ["silent","win","error","warn","http","info","verbose","silly"]
363 , "node-version" : [null, semver]
366 , "onload-script" : [null, String]
368 , parseable : Boolean
371 , production: Boolean
372 , "proprietary-attribs": Boolean
373 , proxy : [null, url]
374 , "rebuild-bundle" : Boolean
375 , registry : [null, url]
378 , "save-bundle": Boolean
379 , "save-dev" : Boolean
380 , "save-optional" : Boolean
381 , searchopts : String
382 , searchexclude: [null, String]
383 , searchsort: [ "name", "-name"
384 , "description", "-description"
385 , "author", "-author"
387 , "keywords", "-keywords" ]
389 , shrinkwrap: Boolean
390 , "sign-git-tag": Boolean
391 , "strict-ssl": Boolean
395 , "unsafe-perm" : Boolean
397 , user : [Number, String]
400 , userignorefile : path
405 , yes: [false, null, Boolean]
411 { s : ["--loglevel", "silent"]
412 , d : ["--loglevel", "info"]
413 , dd : ["--loglevel", "verbose"]
414 , ddd : ["--loglevel", "silly"]
415 , noreg : ["--no-registry"]
416 , N : ["--no-registry"]
417 , reg : ["--registry"]
418 , "no-reg" : ["--no-registry"]
419 , silent : ["--loglevel", "silent"]
420 , verbose : ["--loglevel", "verbose"]
421 , quiet: ["--loglevel", "warn"]
422 , q: ["--loglevel", "warn"]
429 , gangster : ["--force"]
430 , gangsta : ["--force"]
431 , desc : ["--description"]
432 , "no-desc" : ["--no-description"]
433 , "local" : ["--no-global"]
436 , p : ["--parseable"]
437 , porcelain : ["--parseable"]
441 , O : ["--save-optional"]
444 , B : ["--save-bundle"]