;(function(){ // windows: running "npm blah" in this folder will invoke WSH, not node. if (typeof WScript !== "undefined") { WScript.echo("npm does not work when run\n" +"with the Windows Scripting Host\n\n" +"'cd' to a different directory,\n" +"or type 'npm.cmd ',\n" +"or type 'node npm '.") WScript.quit(1) return } var EventEmitter = require("events").EventEmitter , npm = module.exports = new EventEmitter() , npmconf = require("./config/core.js") , log = require("npmlog") , gfs = require('graceful-fs') , fs = gfs.gracefulify(require('fs')) , path = require("path") , abbrev = require("abbrev") , which = require("which") , CachingRegClient = require("./cache/caching-client.js") , charSpin = require("char-spinner") npm.config = { loaded: false, get: function() { throw new Error('npm.load() required') }, set: function() { throw new Error('npm.load() required') } } npm.commands = {} npm.rollbacks = [] try { // startup, ok to do this synchronously var j = JSON.parse(fs.readFileSync( path.join(__dirname, "../package.json"))+"") npm.version = j.version } catch (ex) { try { log.info("error reading version", ex) } catch (er) {} npm.version = ex } var commandCache = {} // short names for common things , aliases = { "rm" : "uninstall" , "r" : "uninstall" , "un" : "uninstall" , "unlink" : "uninstall" , "remove" : "uninstall" , "rb" : "rebuild" , "list" : "ls" , "la" : "ls" , "ll" : "ls" , "ln" : "link" , "i" : "install" , "isntall" : "install" , "up" : "update" , "upgrade" : "update" , "c" : "config" , "dist-tags" : "dist-tag" , "info" : "view" , "show" : "view" , "find" : "search" , "s" : "search" , "se" : "search" , "author" : "owner" , "home" : "docs" , "issues": "bugs" , "unstar": "star" // same function , "apihelp" : "help" , "login": "adduser" , "add-user": "adduser" , "tst": "test" , "t": "test" , "find-dupes": "dedupe" , "ddp": "dedupe" , "v": "view" , "verison": "version" } , aliasNames = Object.keys(aliases) // these are filenames in . , cmdList = [ "install" , "uninstall" , "cache" , "config" , "set" , "get" , "update" , "outdated" , "prune" , "pack" , "dedupe" , "rebuild" , "link" , "publish" , "star" , "stars" , "tag" , "adduser" , "logout" , "unpublish" , "owner" , "access" , "team" , "deprecate" , "shrinkwrap" , "help" , "help-search" , "ls" , "search" , "view" , "init" , "version" , "edit" , "explore" , "docs" , "repo" , "bugs" , "faq" , "root" , "prefix" , "bin" , "whoami" , "dist-tag" , "ping" , "test" , "stop" , "start" , "restart" , "run-script" , "completion" ] , plumbing = [ "build" , "unbuild" , "xmas" , "substack" , "visnup" ] , littleGuys = [ "isntall" ] , fullList = cmdList.concat(aliasNames).filter(function (c) { return plumbing.indexOf(c) === -1 }) , abbrevs = abbrev(fullList) // we have our reasons fullList = npm.fullList = fullList.filter(function (c) { return littleGuys.indexOf(c) === -1 }) npm.spinner = { int: null , started: false , start: function () { if (npm.spinner.int) return var c = npm.config.get("spin") if (!c) return var stream = npm.config.get("logstream") var opt = { tty: c !== "always", stream: stream } opt.cleanup = !npm.spinner.started npm.spinner.int = charSpin(opt) npm.spinner.started = true } , stop: function () { clearInterval(npm.spinner.int) npm.spinner.int = null } } Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) { Object.defineProperty(npm.commands, c, { get : function () { if (!loaded) throw new Error( "Call npm.load(config, cb) before using this command.\n"+ "See the README.md or cli.js for example usage.") var a = npm.deref(c) if (c === "la" || c === "ll") { npm.config.set("long", true) } npm.command = c if (commandCache[a]) return commandCache[a] var cmd = require(__dirname+"/"+a+".js") commandCache[a] = function () { var args = Array.prototype.slice.call(arguments, 0) if (typeof args[args.length - 1] !== "function") { args.push(defaultCb) } if (args.length === 1) args.unshift([]) npm.registry.version = npm.version if (!npm.registry.refer) { npm.registry.refer = [a].concat(args[0]).map(function (arg) { // exclude anything that might be a URL, path, or private module // Those things will always have a slash in them somewhere if (arg && arg.match && arg.match(/\/|\\/)) { return "[REDACTED]" } else { return arg } }).filter(function (arg) { return arg && arg.match }).join(" ") } cmd.apply(npm, args) } Object.keys(cmd).forEach(function (k) { commandCache[a][k] = cmd[k] }) return commandCache[a] }, enumerable: fullList.indexOf(c) !== -1, configurable: true }) // make css-case commands callable via camelCase as well if (c.match(/\-([a-z])/)) { addCommand(c.replace(/\-([a-z])/g, function (a, b) { return b.toUpperCase() })) } }) function defaultCb (er, data) { if (er) console.error(er.stack || er.message) else console.log(data) } npm.deref = function (c) { if (!c) return "" if (c.match(/[A-Z]/)) c = c.replace(/([A-Z])/g, function (m) { return "-" + m.toLowerCase() }) if (plumbing.indexOf(c) !== -1) return c var a = abbrevs[c] if (aliases[a]) a = aliases[a] return a } var loaded = false , loading = false , loadErr = null , loadListeners = [] function loadCb (er) { loadListeners.forEach(function (cb) { process.nextTick(cb.bind(npm, er, npm)) }) loadListeners.length = 0 } npm.load = function (cli, cb_) { if (!cb_ && typeof cli === "function") cb_ = cli , cli = {} if (!cb_) cb_ = function () {} if (!cli) cli = {} loadListeners.push(cb_) if (loaded || loadErr) return cb(loadErr) if (loading) return loading = true var onload = true function cb (er) { if (loadErr) return loadErr = er if (er) return cb_(er) if (npm.config.get("force")) { log.warn("using --force", "I sure hope you know what you are doing.") } npm.config.loaded = true loaded = true loadCb(loadErr = er) if (onload = onload && npm.config.get("onload-script")) { require(onload) onload = false } } log.pause() load(npm, cli, cb) } function load (npm, cli, cb) { which(process.argv[0], function (er, node) { if (!er && node.toUpperCase() !== process.execPath.toUpperCase()) { log.verbose("node symlink", node) process.execPath = node process.installPrefix = path.resolve(node, "..", "..") } // look up configs //console.error("about to look up configs") var builtin = path.resolve(__dirname, "..", "npmrc") npmconf.load(cli, builtin, function (er, config) { if (er === config) er = null npm.config = config if (er) return cb(er) // if the "project" config is not a filename, and we're // not in global mode, then that means that it collided // with either the default or effective userland config if (!config.get("global") && config.sources.project && config.sources.project.type !== "ini") { log.verbose("config" , "Skipping project config: %s. " + "(matches userconfig)" , config.localPrefix + "/.npmrc") } // Include npm-version and node-version in user-agent var ua = config.get("user-agent") || "" ua = ua.replace(/\{node-version\}/gi, process.version) ua = ua.replace(/\{npm-version\}/gi, npm.version) ua = ua.replace(/\{platform\}/gi, process.platform) ua = ua.replace(/\{arch\}/gi, process.arch) config.set("user-agent", ua) var color = config.get("color") log.level = config.get("loglevel") log.heading = config.get("heading") || "npm" log.stream = config.get("logstream") switch (color) { case "always": log.enableColor() npm.color = true break case false: log.disableColor() npm.color = false break default: var tty = require("tty") if (process.stdout.isTTY) npm.color = true else if (!tty.isatty) npm.color = true else if (tty.isatty(1)) npm.color = true else npm.color = false break } log.resume() // at this point the configs are all set. // go ahead and spin up the registry client. npm.registry = new CachingRegClient(npm.config) var umask = npm.config.get("umask") npm.modes = { exec: 0777 & (~umask) , file: 0666 & (~umask) , umask: umask } var gp = Object.getOwnPropertyDescriptor(config, "globalPrefix") Object.defineProperty(npm, "globalPrefix", gp) var lp = Object.getOwnPropertyDescriptor(config, "localPrefix") Object.defineProperty(npm, "localPrefix", lp) return cb(null, npm) }) }) } Object.defineProperty(npm, "prefix", { get : function () { return npm.config.get("global") ? npm.globalPrefix : npm.localPrefix } , set : function (r) { var k = npm.config.get("global") ? "globalPrefix" : "localPrefix" return npm[k] = r } , enumerable : true }) Object.defineProperty(npm, "bin", { get : function () { if (npm.config.get("global")) return npm.globalBin return path.resolve(npm.root, ".bin") } , enumerable : true }) Object.defineProperty(npm, "globalBin", { get : function () { var b = npm.globalPrefix if (process.platform !== "win32") b = path.resolve(b, "bin") return b } }) Object.defineProperty(npm, "dir", { get : function () { if (npm.config.get("global")) return npm.globalDir return path.resolve(npm.prefix, "node_modules") } , enumerable : true }) Object.defineProperty(npm, "globalDir", { get : function () { return (process.platform !== "win32") ? path.resolve(npm.globalPrefix, "lib", "node_modules") : path.resolve(npm.globalPrefix, "node_modules") } , enumerable : true }) Object.defineProperty(npm, "root", { get : function () { return npm.dir } }) Object.defineProperty(npm, "cache", { get : function () { return npm.config.get("cache") } , set : function (r) { return npm.config.set("cache", r) } , enumerable : true }) var tmpFolder var rand = require("crypto").randomBytes(4).toString("hex") Object.defineProperty(npm, "tmp", { get : function () { if (!tmpFolder) tmpFolder = "npm-" + process.pid + "-" + rand return path.resolve(npm.config.get("tmp"), tmpFolder) } , enumerable : true }) // the better to repl you with Object.getOwnPropertyNames(npm.commands).forEach(function (n) { if (npm.hasOwnProperty(n) || n === "config") return Object.defineProperty(npm, n, { get: function () { return function () { var args = Array.prototype.slice.call(arguments, 0) , cb = defaultCb if (args.length === 1 && Array.isArray(args[0])) { args = args[0] } if (typeof args[args.length - 1] === "function") { cb = args.pop() } npm.commands[n](args, cb) } }, enumerable: false, configurable: true }) }) if (require.main === module) { require("../bin/npm-cli.js") } })()