1 | ;(function () {
|
2 |
|
3 |
|
4 | if (typeof WScript !== 'undefined') {
|
5 | WScript.echo(
|
6 | 'npm does not work when run\n' +
|
7 | 'with the Windows Scripting Host\n\n' +
|
8 | '"cd" to a different directory,\n' +
|
9 | 'or type "npm.cmd <args>",\n' +
|
10 | 'or type "node npm <args>".'
|
11 | )
|
12 | WScript.quit(1)
|
13 | return
|
14 | }
|
15 |
|
16 | var unsupported = require('../lib/utils/unsupported.js')
|
17 | unsupported.checkForBrokenNode()
|
18 |
|
19 | var gfs = require('graceful-fs')
|
20 |
|
21 | var fs = gfs.gracefulify(require('fs'))
|
22 |
|
23 | var EventEmitter = require('events').EventEmitter
|
24 | var npm = module.exports = new EventEmitter()
|
25 | var npmconf = require('./config/core.js')
|
26 | var log = require('npmlog')
|
27 | var inspect = require('util').inspect
|
28 |
|
29 |
|
30 | process.on('log', function (level) {
|
31 | try {
|
32 | return log[level].apply(log, [].slice.call(arguments, 1))
|
33 | } catch (ex) {
|
34 | log.verbose('attempt to log ' + inspect(arguments) + ' crashed: ' + ex.message)
|
35 | }
|
36 | })
|
37 |
|
38 | var path = require('path')
|
39 | var abbrev = require('abbrev')
|
40 | var which = require('which')
|
41 | var glob = require('glob')
|
42 | var rimraf = require('rimraf')
|
43 | var lazyProperty = require('lazy-property')
|
44 | var parseJSON = require('./utils/parse-json.js')
|
45 | var clientConfig = require('./config/reg-client.js')
|
46 | var aliases = require('./config/cmd-list').aliases
|
47 | var cmdList = require('./config/cmd-list').cmdList
|
48 | var plumbing = require('./config/cmd-list').plumbing
|
49 | var output = require('./utils/output.js')
|
50 | var startMetrics = require('./utils/metrics.js').start
|
51 | var perf = require('./utils/perf.js')
|
52 |
|
53 | perf.emit('time', 'npm')
|
54 | perf.on('timing', function (name, finished) {
|
55 | log.timing(name, 'Completed in', finished + 'ms')
|
56 | })
|
57 |
|
58 | npm.config = {
|
59 | loaded: false,
|
60 | get: function () {
|
61 | throw new Error('npm.load() required')
|
62 | },
|
63 | set: function () {
|
64 | throw new Error('npm.load() required')
|
65 | }
|
66 | }
|
67 |
|
68 | npm.commands = {}
|
69 |
|
70 |
|
71 | npm.limit = {
|
72 | fetch: 10,
|
73 | action: 50
|
74 | }
|
75 |
|
76 |
|
77 | npm.lockfileVersion = 1
|
78 |
|
79 | npm.rollbacks = []
|
80 |
|
81 | try {
|
82 |
|
83 | var j = parseJSON(fs.readFileSync(
|
84 | path.join(__dirname, '../package.json')) + '')
|
85 | npm.name = j.name
|
86 | npm.version = j.version
|
87 | } catch (ex) {
|
88 | try {
|
89 | log.info('error reading version', ex)
|
90 | } catch (er) {}
|
91 | npm.version = ex
|
92 | }
|
93 |
|
94 | var commandCache = {}
|
95 | var aliasNames = Object.keys(aliases)
|
96 |
|
97 | var littleGuys = [ 'isntall', 'verison' ]
|
98 | var fullList = cmdList.concat(aliasNames).filter(function (c) {
|
99 | return plumbing.indexOf(c) === -1
|
100 | })
|
101 | var abbrevs = abbrev(fullList)
|
102 |
|
103 |
|
104 | fullList = npm.fullList = fullList.filter(function (c) {
|
105 | return littleGuys.indexOf(c) === -1
|
106 | })
|
107 |
|
108 | var registryRefer
|
109 | var registryLoaded
|
110 |
|
111 | Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
|
112 | Object.defineProperty(npm.commands, c, { get: function () {
|
113 | if (!loaded) {
|
114 | throw new Error(
|
115 | 'Call npm.load(config, cb) before using this command.\n' +
|
116 | 'See the README.md or bin/npm-cli.js for example usage.'
|
117 | )
|
118 | }
|
119 | var a = npm.deref(c)
|
120 | if (c === 'la' || c === 'll') {
|
121 | npm.config.set('long', true)
|
122 | }
|
123 |
|
124 | npm.command = c
|
125 | if (commandCache[a]) return commandCache[a]
|
126 |
|
127 | var cmd = require(path.join(__dirname, a + '.js'))
|
128 |
|
129 | commandCache[a] = function () {
|
130 | var args = Array.prototype.slice.call(arguments, 0)
|
131 | if (typeof args[args.length - 1] !== 'function') {
|
132 | args.push(defaultCb)
|
133 | }
|
134 | if (args.length === 1) args.unshift([])
|
135 |
|
136 |
|
137 |
|
138 | Array(args[0]).forEach(function (arg) {
|
139 | if (/^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(arg)) {
|
140 | log.error('arg', 'Argument starts with non-ascii dash, this is probably invalid:', arg)
|
141 | }
|
142 | })
|
143 |
|
144 | if (!registryRefer) {
|
145 | registryRefer = [a].concat(args[0]).map(function (arg) {
|
146 |
|
147 |
|
148 | if (arg && arg.match && arg.match(/\/|\\/)) {
|
149 | return '[REDACTED]'
|
150 | } else {
|
151 | return arg
|
152 | }
|
153 | }).filter(function (arg) {
|
154 | return arg && arg.match
|
155 | }).join(' ')
|
156 | if (registryLoaded) npm.registry.refer = registryRefer
|
157 | }
|
158 |
|
159 | cmd.apply(npm, args)
|
160 | }
|
161 |
|
162 | Object.keys(cmd).forEach(function (k) {
|
163 | commandCache[a][k] = cmd[k]
|
164 | })
|
165 |
|
166 | return commandCache[a]
|
167 | },
|
168 | enumerable: fullList.indexOf(c) !== -1,
|
169 | configurable: true })
|
170 |
|
171 |
|
172 | if (c.match(/-([a-z])/)) {
|
173 | addCommand(c.replace(/-([a-z])/g, function (a, b) {
|
174 | return b.toUpperCase()
|
175 | }))
|
176 | }
|
177 | })
|
178 |
|
179 | function defaultCb (er, data) {
|
180 | log.disableProgress()
|
181 | if (er) console.error(er.stack || er.message)
|
182 | else output(data)
|
183 | }
|
184 |
|
185 | npm.deref = function (c) {
|
186 | if (!c) return ''
|
187 | if (c.match(/[A-Z]/)) {
|
188 | c = c.replace(/([A-Z])/g, function (m) {
|
189 | return '-' + m.toLowerCase()
|
190 | })
|
191 | }
|
192 | if (plumbing.indexOf(c) !== -1) return c
|
193 | var a = abbrevs[c]
|
194 | while (aliases[a]) {
|
195 | a = aliases[a]
|
196 | }
|
197 | return a
|
198 | }
|
199 |
|
200 | var loaded = false
|
201 | var loading = false
|
202 | var loadErr = null
|
203 | var loadListeners = []
|
204 |
|
205 | function loadCb (er) {
|
206 | loadListeners.forEach(function (cb) {
|
207 | process.nextTick(cb.bind(npm, er, npm))
|
208 | })
|
209 | loadListeners.length = 0
|
210 | }
|
211 |
|
212 | npm.load = function (cli, cb_) {
|
213 | if (!cb_ && typeof cli === 'function') {
|
214 | cb_ = cli
|
215 | cli = {}
|
216 | }
|
217 | if (!cb_) cb_ = function () {}
|
218 | if (!cli) cli = {}
|
219 | loadListeners.push(cb_)
|
220 | if (loaded || loadErr) return cb(loadErr)
|
221 | if (loading) return
|
222 | loading = true
|
223 | var onload = true
|
224 |
|
225 | function cb (er) {
|
226 | if (loadErr) return
|
227 | loadErr = er
|
228 | if (er) return cb_(er)
|
229 | log.notice('CANARY', 'npmc is experimental software. If you find an issue, please file it in the main npm repository, and call out that you were using npmc.')
|
230 | if (npm.config.get('force')) {
|
231 | log.warn('using --force', 'I sure hope you know what you are doing.')
|
232 | }
|
233 | npm.config.loaded = true
|
234 | loaded = true
|
235 | loadCb(loadErr = er)
|
236 | onload = onload && npm.config.get('onload-script')
|
237 | if (onload) {
|
238 | try {
|
239 | require(onload)
|
240 | } catch (err) {
|
241 | log.warn('onload-script', 'failed to require onload script', onload)
|
242 | log.warn('onload-script', err)
|
243 | }
|
244 | onload = false
|
245 | }
|
246 | }
|
247 |
|
248 | log.pause()
|
249 |
|
250 | load(npm, cli, cb)
|
251 | }
|
252 |
|
253 | function load (npm, cli, cb) {
|
254 | which(process.argv[0], function (er, node) {
|
255 | if (!er && node.toUpperCase() !== process.execPath.toUpperCase()) {
|
256 | log.verbose('node symlink', node)
|
257 | process.execPath = node
|
258 | process.installPrefix = path.resolve(node, '..', '..')
|
259 | }
|
260 |
|
261 |
|
262 | var builtin = path.resolve(__dirname, '..', 'npmrc')
|
263 | npmconf.load(cli, builtin, function (er, config) {
|
264 | if (er === config) er = null
|
265 |
|
266 | npm.config = config
|
267 | if (er) return cb(er)
|
268 |
|
269 |
|
270 |
|
271 |
|
272 | if (!config.get('global') &&
|
273 | config.sources.project &&
|
274 | config.sources.project.type !== 'ini') {
|
275 | log.verbose(
|
276 | 'config',
|
277 | 'Skipping project config: %s. (matches userconfig)',
|
278 | config.localPrefix + '/.npmrc'
|
279 | )
|
280 | }
|
281 |
|
282 |
|
283 | var ua = config.get('user-agent') || ''
|
284 | ua = ua.replace(/\{node-version\}/gi, process.version)
|
285 | ua = ua.replace(/\{npm-version\}/gi, npm.version)
|
286 | ua = ua.replace(/\{platform\}/gi, process.platform)
|
287 | ua = ua.replace(/\{arch\}/gi, process.arch)
|
288 | config.set('user-agent', ua)
|
289 |
|
290 | if (config.get('metrics-registry') == null) {
|
291 | config.set('metrics-registry', config.get('registry'))
|
292 | }
|
293 |
|
294 | var color = config.get('color')
|
295 |
|
296 | if (npm.config.get('timing') && npm.config.get('loglevel') === 'notice') {
|
297 | log.level = 'timing'
|
298 | } else {
|
299 | log.level = config.get('loglevel')
|
300 | }
|
301 | log.heading = config.get('heading') || 'npm'
|
302 | log.stream = config.get('logstream')
|
303 |
|
304 | switch (color) {
|
305 | case 'always':
|
306 | npm.color = true
|
307 | break
|
308 | case false:
|
309 | npm.color = false
|
310 | break
|
311 | default:
|
312 | npm.color = process.stdout.isTTY && process.env['TERM'] !== 'dumb'
|
313 | break
|
314 | }
|
315 | if (npm.color) {
|
316 | log.enableColor()
|
317 | } else {
|
318 | log.disableColor()
|
319 | }
|
320 |
|
321 | if (config.get('unicode')) {
|
322 | log.enableUnicode()
|
323 | } else {
|
324 | log.disableUnicode()
|
325 | }
|
326 |
|
327 | if (config.get('progress') && process.stderr.isTTY && process.env['TERM'] !== 'dumb') {
|
328 | log.enableProgress()
|
329 | } else {
|
330 | log.disableProgress()
|
331 | }
|
332 |
|
333 | glob(path.resolve(npm.cache, '_logs', '*-debug.log'), function (er, files) {
|
334 | if (er) return cb(er)
|
335 |
|
336 | while (files.length >= npm.config.get('logs-max')) {
|
337 | rimraf.sync(files[0])
|
338 | files.splice(0, 1)
|
339 | }
|
340 | })
|
341 |
|
342 | log.resume()
|
343 |
|
344 | var umask = npm.config.get('umask')
|
345 | npm.modes = {
|
346 | exec: parseInt('0777', 8) & (~umask),
|
347 | file: parseInt('0666', 8) & (~umask),
|
348 | umask: umask
|
349 | }
|
350 |
|
351 | var gp = Object.getOwnPropertyDescriptor(config, 'globalPrefix')
|
352 | Object.defineProperty(npm, 'globalPrefix', gp)
|
353 |
|
354 | var lp = Object.getOwnPropertyDescriptor(config, 'localPrefix')
|
355 | Object.defineProperty(npm, 'localPrefix', lp)
|
356 |
|
357 | config.set('scope', scopeifyScope(config.get('scope')))
|
358 | npm.projectScope = config.get('scope') ||
|
359 | scopeifyScope(getProjectScope(npm.prefix))
|
360 |
|
361 |
|
362 |
|
363 | lazyProperty(npm, 'registry', function () {
|
364 | registryLoaded = true
|
365 | var RegClient = require('npm-registry-client')
|
366 | var registry = new RegClient(clientConfig(npm, log, npm.config))
|
367 | registry.version = npm.version
|
368 | registry.refer = registryRefer
|
369 | return registry
|
370 | })
|
371 |
|
372 | startMetrics()
|
373 |
|
374 | return cb(null, npm)
|
375 | })
|
376 | })
|
377 | }
|
378 |
|
379 | Object.defineProperty(npm, 'prefix',
|
380 | {
|
381 | get: function () {
|
382 | return npm.config.get('global') ? npm.globalPrefix : npm.localPrefix
|
383 | },
|
384 | set: function (r) {
|
385 | var k = npm.config.get('global') ? 'globalPrefix' : 'localPrefix'
|
386 | npm[k] = r
|
387 | return r
|
388 | },
|
389 | enumerable: true
|
390 | })
|
391 |
|
392 | Object.defineProperty(npm, 'bin',
|
393 | {
|
394 | get: function () {
|
395 | if (npm.config.get('global')) return npm.globalBin
|
396 | return path.resolve(npm.root, '.bin')
|
397 | },
|
398 | enumerable: true
|
399 | })
|
400 |
|
401 | Object.defineProperty(npm, 'globalBin',
|
402 | {
|
403 | get: function () {
|
404 | var b = npm.globalPrefix
|
405 | if (process.platform !== 'win32') b = path.resolve(b, 'bin')
|
406 | return b
|
407 | }
|
408 | })
|
409 |
|
410 | Object.defineProperty(npm, 'dir',
|
411 | {
|
412 | get: function () {
|
413 | if (npm.config.get('global')) return npm.globalDir
|
414 | return path.resolve(npm.prefix, 'node_modules')
|
415 | },
|
416 | enumerable: true
|
417 | })
|
418 |
|
419 | Object.defineProperty(npm, 'globalDir',
|
420 | {
|
421 | get: function () {
|
422 | return (process.platform !== 'win32')
|
423 | ? path.resolve(npm.globalPrefix, 'lib', 'node_modules')
|
424 | : path.resolve(npm.globalPrefix, 'node_modules')
|
425 | },
|
426 | enumerable: true
|
427 | })
|
428 |
|
429 | Object.defineProperty(npm, 'root',
|
430 | { get: function () { return npm.dir } })
|
431 |
|
432 | Object.defineProperty(npm, 'cache',
|
433 | { get: function () { return npm.config.get('cache') },
|
434 | set: function (r) { return npm.config.set('cache', r) },
|
435 | enumerable: true
|
436 | })
|
437 |
|
438 | var tmpFolder
|
439 | var rand = require('crypto').randomBytes(4).toString('hex')
|
440 | Object.defineProperty(npm, 'tmp',
|
441 | {
|
442 | get: function () {
|
443 | if (!tmpFolder) tmpFolder = 'npm-' + process.pid + '-' + rand
|
444 | return path.resolve(npm.config.get('tmp'), tmpFolder)
|
445 | },
|
446 | enumerable: true
|
447 | })
|
448 |
|
449 |
|
450 | Object.getOwnPropertyNames(npm.commands).forEach(function (n) {
|
451 | if (npm.hasOwnProperty(n) || n === 'config') return
|
452 |
|
453 | Object.defineProperty(npm, n, { get: function () {
|
454 | return function () {
|
455 | var args = Array.prototype.slice.call(arguments, 0)
|
456 | var cb = defaultCb
|
457 |
|
458 | if (args.length === 1 && Array.isArray(args[0])) {
|
459 | args = args[0]
|
460 | }
|
461 |
|
462 | if (typeof args[args.length - 1] === 'function') {
|
463 | cb = args.pop()
|
464 | }
|
465 | npm.commands[n](args, cb)
|
466 | }
|
467 | },
|
468 | enumerable: false,
|
469 | configurable: true })
|
470 | })
|
471 |
|
472 | if (require.main === module) {
|
473 | require('../bin/npm-cli.js')
|
474 | }
|
475 |
|
476 | function scopeifyScope (scope) {
|
477 | return (!scope || scope[0] === '@') ? scope : ('@' + scope)
|
478 | }
|
479 |
|
480 | function getProjectScope (prefix) {
|
481 | try {
|
482 | var pkg = JSON.parse(fs.readFileSync(path.join(prefix, 'package.json')))
|
483 | if (typeof pkg.name !== 'string') return ''
|
484 | var sep = pkg.name.indexOf('/')
|
485 | if (sep === -1) return ''
|
486 | return pkg.name.slice(0, sep)
|
487 | } catch (ex) {
|
488 | return ''
|
489 | }
|
490 | }
|
491 | })()
|