summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2017-06-25 14:45:17 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2017-06-25 14:45:17 +0000
commit4a81dec2f48191b5a2357b293c842723528ea0a2 (patch)
tree3d12349ce4caeef580085c3665c84b0ec3731ba9
parentInitial commit. (diff)
downloadnpm-4a81dec2f48191b5a2357b293c842723528ea0a2.zip
npm-4a81dec2f48191b5a2357b293c842723528ea0a2.tar.xz
Adding upstream version 1.4.21+ds.upstream/1.4.21+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.gitignore23
-rw-r--r--.npmignore27
-rw-r--r--.npmrc2
-rw-r--r--.travis.yml5
-rw-r--r--AUTHORS158
-rw-r--r--CONTRIBUTING.md9
-rw-r--r--LICENSE234
-rw-r--r--Makefile218
-rw-r--r--README.md245
-rwxr-xr-xbin/node-gyp-bin/node-gyp2
-rwxr-xr-xbin/node-gyp-bin/node-gyp.cmd1
-rwxr-xr-xbin/npm14
-rwxr-xr-xbin/npm-cli.js86
-rw-r--r--bin/npm.cmd6
-rwxr-xr-xbin/read-package-json.js22
-rwxr-xr-xcli.js2
-rwxr-xr-xconfigure33
-rw-r--r--doc/api/npm-bin.md13
-rw-r--r--doc/api/npm-bugs.md19
-rw-r--r--doc/api/npm-cache.md30
-rw-r--r--doc/api/npm-commands.md22
-rw-r--r--doc/api/npm-config.md45
-rw-r--r--doc/api/npm-deprecate.md34
-rw-r--r--doc/api/npm-docs.md19
-rw-r--r--doc/api/npm-edit.md24
-rw-r--r--doc/api/npm-explore.md18
-rw-r--r--doc/api/npm-help-search.md30
-rw-r--r--doc/api/npm-init.md29
-rw-r--r--doc/api/npm-install.md19
-rw-r--r--doc/api/npm-link.md33
-rw-r--r--doc/api/npm-load.md26
-rw-r--r--doc/api/npm-ls.md56
-rw-r--r--doc/api/npm-outdated.md13
-rw-r--r--doc/api/npm-owner.md31
-rw-r--r--doc/api/npm-pack.md19
-rw-r--r--doc/api/npm-prefix.md15
-rw-r--r--doc/api/npm-prune.md17
-rw-r--r--doc/api/npm-publish.md30
-rw-r--r--doc/api/npm-rebuild.md16
-rw-r--r--doc/api/npm-repo.md19
-rw-r--r--doc/api/npm-restart.md22
-rw-r--r--doc/api/npm-root.md15
-rw-r--r--doc/api/npm-run-script.md27
-rw-r--r--doc/api/npm-search.md35
-rw-r--r--doc/api/npm-shrinkwrap.md20
-rw-r--r--doc/api/npm-start.md13
-rw-r--r--doc/api/npm-stop.md13
-rw-r--r--doc/api/npm-submodule.md28
-rw-r--r--doc/api/npm-tag.md23
-rw-r--r--doc/api/npm-test.md16
-rw-r--r--doc/api/npm-uninstall.md16
-rw-r--r--doc/api/npm-unpublish.md20
-rw-r--r--doc/api/npm-update.md11
-rw-r--r--doc/api/npm-version.md18
-rw-r--r--doc/api/npm-view.md93
-rw-r--r--doc/api/npm-whoami.md15
-rw-r--r--doc/api/npm.md116
-rw-r--r--doc/cli/npm-adduser.md38
-rw-r--r--doc/cli/npm-bin.md19
-rw-r--r--doc/cli/npm-bugs.md42
-rw-r--r--doc/cli/npm-build.md22
-rw-r--r--doc/cli/npm-bundle.md14
-rw-r--r--doc/cli/npm-cache.md70
-rw-r--r--doc/cli/npm-completion.md29
-rw-r--r--doc/cli/npm-config.md71
-rw-r--r--doc/cli/npm-dedupe.md58
-rw-r--r--doc/cli/npm-deprecate.md26
-rw-r--r--doc/cli/npm-docs.md44
-rw-r--r--doc/cli/npm-edit.md37
-rw-r--r--doc/cli/npm-explore.md40
-rw-r--r--doc/cli/npm-help-search.md35
-rw-r--r--doc/cli/npm-help.md40
-rw-r--r--doc/cli/npm-init.md25
-rw-r--r--doc/cli/npm-install.md259
-rw-r--r--doc/cli/npm-link.md63
-rw-r--r--doc/cli/npm-ls.md80
-rw-r--r--doc/cli/npm-outdated.md58
-rw-r--r--doc/cli/npm-owner.md33
-rw-r--r--doc/cli/npm-pack.md27
-rw-r--r--doc/cli/npm-prefix.md19
-rw-r--r--doc/cli/npm-prune.md25
-rw-r--r--doc/cli/npm-publish.md39
-rw-r--r--doc/cli/npm-rebuild.md21
-rw-r--r--doc/cli/npm-repo.md28
-rw-r--r--doc/cli/npm-restart.md22
-rw-r--r--doc/cli/npm-rm.md23
-rw-r--r--doc/cli/npm-root.md19
-rw-r--r--doc/cli/npm-run-script.md25
-rw-r--r--doc/cli/npm-search.md36
-rw-r--r--doc/cli/npm-shrinkwrap.md176
-rw-r--r--doc/cli/npm-star.md22
-rw-r--r--doc/cli/npm-stars.md22
-rw-r--r--doc/cli/npm-start.md18
-rw-r--r--doc/cli/npm-stop.md18
-rw-r--r--doc/cli/npm-submodule.md28
-rw-r--r--doc/cli/npm-tag.md34
-rw-r--r--doc/cli/npm-test.md22
-rw-r--r--doc/cli/npm-uninstall.md43
-rw-r--r--doc/cli/npm-unpublish.md36
-rw-r--r--doc/cli/npm-update.md24
-rw-r--r--doc/cli/npm-version.md45
-rw-r--r--doc/cli/npm-view.md90
-rw-r--r--doc/cli/npm-whoami.md17
-rw-r--r--doc/cli/npm.md169
-rw-r--r--doc/files/npm-folders.md211
-rw-r--r--doc/files/npmrc.md71
-rw-r--r--doc/files/package.json.md607
-rw-r--r--doc/misc/npm-coding-style.md181
-rw-r--r--doc/misc/npm-config.md865
-rw-r--r--doc/misc/npm-developers.md207
-rw-r--r--doc/misc/npm-disputes.md99
-rw-r--r--doc/misc/npm-faq.md364
-rw-r--r--doc/misc/npm-registry.md69
-rw-r--r--doc/misc/npm-scripts.md245
-rw-r--r--doc/misc/removing-npm.md54
-rw-r--r--doc/misc/semver.md158
-rw-r--r--html/docfoot.html13
-rw-r--r--html/dochead.html11
-rw-r--r--html/favicon.icobin0 -> 7094 bytes
-rw-r--r--html/index.html95
-rw-r--r--html/n-64.pngbin0 -> 679 bytes
-rw-r--r--html/n-large.pngbin0 -> 699 bytes
-rw-r--r--html/npm-16.pngbin0 -> 145 bytes
-rw-r--r--html/npm-256-square.pngbin0 -> 3290 bytes
-rw-r--r--html/npm-256w.pngbin0 -> 3169 bytes
-rw-r--r--html/npm-64-square.pngbin0 -> 2908 bytes
-rw-r--r--html/npm-fin.pngbin0 -> 47789 bytes
-rw-r--r--html/npm-large-trans.pngbin0 -> 81961 bytes
-rw-r--r--html/npm-large.pngbin0 -> 483909 bytes
-rw-r--r--html/npm-logo-white-trans.pngbin0 -> 109429 bytes
-rw-r--r--html/npm.pngbin0 -> 1164 bytes
-rw-r--r--html/static/style.css336
-rw-r--r--html/static/toc.js29
-rw-r--r--lib/adduser.js149
-rw-r--r--lib/bin.js18
-rw-r--r--lib/bugs.js64
-rw-r--r--lib/build.js226
-rw-r--r--lib/cache.js371
-rw-r--r--lib/cache/add-local-tarball.js223
-rw-r--r--lib/cache/add-local.js146
-rw-r--r--lib/cache/add-named.js278
-rw-r--r--lib/cache/add-remote-git.js233
-rw-r--r--lib/cache/add-remote-tarball.js106
-rw-r--r--lib/cache/get-stat.js63
-rw-r--r--lib/cache/maybe-github.js35
-rw-r--r--lib/completion.js248
-rw-r--r--lib/config.js279
-rw-r--r--lib/dedupe.js352
-rw-r--r--lib/deprecate.js35
-rw-r--r--lib/docs.js68
-rw-r--r--lib/edit.js31
-rw-r--r--lib/explore.js37
-rw-r--r--lib/faq.js8
-rw-r--r--lib/get.js12
-rw-r--r--lib/help-search.js210
-rw-r--r--lib/help.js233
-rw-r--r--lib/init.js41
-rw-r--r--lib/install.js981
-rw-r--r--lib/link.js173
-rw-r--r--lib/ls.js352
-rw-r--r--lib/npm.js472
-rw-r--r--lib/outdated.js320
-rw-r--r--lib/owner.js211
-rw-r--r--lib/pack.js65
-rw-r--r--lib/prefix.js11
-rw-r--r--lib/prune.js56
-rw-r--r--lib/publish.js118
-rw-r--r--lib/rebuild.js72
-rw-r--r--lib/repo.js76
-rw-r--r--lib/restart.js1
-rw-r--r--lib/root.js11
-rw-r--r--lib/run-script.js130
-rw-r--r--lib/search.js271
-rw-r--r--lib/set.js13
-rw-r--r--lib/shrinkwrap.js79
-rw-r--r--lib/star.js36
-rw-r--r--lib/stars.js29
-rw-r--r--lib/start.js1
-rw-r--r--lib/stop.js1
-rw-r--r--lib/submodule.js91
-rw-r--r--lib/substack.js20
-rw-r--r--lib/tag.js20
-rw-r--r--lib/test.js13
-rw-r--r--lib/unbuild.js111
-rw-r--r--lib/uninstall.js128
-rw-r--r--lib/unpublish.js85
-rw-r--r--lib/update.js42
-rwxr-xr-xlib/utils/completion.sh54
-rw-r--r--lib/utils/completion/file-completion.js25
-rw-r--r--lib/utils/completion/installed-deep.js50
-rw-r--r--lib/utils/completion/installed-shallow.js79
-rw-r--r--lib/utils/depr-check.js13
-rw-r--r--lib/utils/error-handler.js353
-rw-r--r--lib/utils/fetch.js106
-rw-r--r--lib/utils/gently-rm.js61
-rw-r--r--lib/utils/git.js45
-rw-r--r--lib/utils/is-git-url.js13
-rw-r--r--lib/utils/lifecycle.js366
-rw-r--r--lib/utils/link.js39
-rw-r--r--lib/utils/locker.js52
-rw-r--r--lib/utils/tar.js323
-rw-r--r--lib/version.js117
-rw-r--r--lib/view.js262
-rw-r--r--lib/visnup.js42
-rw-r--r--lib/whoami.js13
-rw-r--r--lib/xmas.js55
-rw-r--r--make.bat3
-rw-r--r--node_modules/char-spinner/LICENSE15
-rw-r--r--node_modules/char-spinner/README.md31
-rw-r--r--node_modules/char-spinner/package.json54
-rw-r--r--node_modules/char-spinner/spin.js51
-rw-r--r--node_modules/char-spinner/test/basic.js35
-rw-r--r--node_modules/chmodr/LICENSE27
-rw-r--r--node_modules/chmodr/README.md3
-rw-r--r--node_modules/chmodr/chmodr.js54
-rw-r--r--node_modules/chmodr/package.json28
-rw-r--r--node_modules/chmodr/test/basic.js63
-rw-r--r--node_modules/chmodr/test/sync.js58
-rw-r--r--node_modules/chownr/LICENCE25
-rw-r--r--node_modules/chownr/README.md3
-rw-r--r--node_modules/chownr/chownr.js41
-rw-r--r--node_modules/chownr/package.json42
-rw-r--r--node_modules/columnify/LICENSE21
-rw-r--r--node_modules/columnify/Readme.md348
-rw-r--r--node_modules/columnify/index.js241
l---------node_modules/columnify/node_modules/.bin/strip-ansi1
-rwxr-xr-xnode_modules/columnify/node_modules/strip-ansi/cli.js39
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/index.js6
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/node_modules/ansi-regex/index.js2
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/node_modules/ansi-regex/package.json75
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/node_modules/ansi-regex/readme.md28
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/package.json84
-rw-r--r--node_modules/columnify/node_modules/strip-ansi/readme.md43
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/INSTALL.md12
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/LICENSE.md29
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/NEWS9
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/README.md65
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/package.json60
-rw-r--r--node_modules/columnify/node_modules/wcwidth.js/wcwidth.js262
-rw-r--r--node_modules/columnify/package.json62
-rw-r--r--node_modules/columnify/utils.js150
-rw-r--r--node_modules/columnify/width.js6
-rw-r--r--node_modules/editor/LICENSE21
-rw-r--r--node_modules/editor/README.markdown54
-rw-r--r--node_modules/editor/example/beep.json5
-rw-r--r--node_modules/editor/example/edit.js4
-rw-r--r--node_modules/editor/index.js20
-rw-r--r--node_modules/editor/package.json58
-rw-r--r--node_modules/fstream-npm/.npmignore2
-rw-r--r--node_modules/fstream-npm/LICENCE25
-rw-r--r--node_modules/fstream-npm/README.md18
-rw-r--r--node_modules/fstream-npm/example/bundle.js13
-rw-r--r--node_modules/fstream-npm/example/dir-tar.js19
-rw-r--r--node_modules/fstream-npm/example/dir.js25
-rw-r--r--node_modules/fstream-npm/example/example.js12
-rw-r--r--node_modules/fstream-npm/example/ig-tar.js19
-rw-r--r--node_modules/fstream-npm/example/tar.js25
-rw-r--r--node_modules/fstream-npm/fstream-npm.js323
-rw-r--r--node_modules/fstream-npm/package.json31
-rw-r--r--node_modules/github-url-from-username-repo/.npmignore13
-rw-r--r--node_modules/github-url-from-username-repo/.travis.yml4
-rw-r--r--node_modules/github-url-from-username-repo/LICENSE27
-rw-r--r--node_modules/github-url-from-username-repo/README.md14
-rw-r--r--node_modules/github-url-from-username-repo/index.js9
-rw-r--r--node_modules/github-url-from-username-repo/package.json50
-rw-r--r--node_modules/github-url-from-username-repo/test/index.js34
-rw-r--r--node_modules/inflight/LICENSE15
-rw-r--r--node_modules/inflight/README.md37
-rw-r--r--node_modules/inflight/inflight.js25
-rw-r--r--node_modules/inflight/package.json50
-rw-r--r--node_modules/inflight/test.js33
-rw-r--r--node_modules/init-package-json/LICENSE15
-rw-r--r--node_modules/init-package-json/README.md43
-rw-r--r--node_modules/init-package-json/default-input.js181
-rw-r--r--node_modules/init-package-json/example/example-basic.js8
-rw-r--r--node_modules/init-package-json/example/example-default.js7
-rw-r--r--node_modules/init-package-json/example/example-npm.js13
-rw-r--r--node_modules/init-package-json/example/init/basic-init.js1
-rw-r--r--node_modules/init-package-json/init-package-json.js129
-rw-r--r--node_modules/init-package-json/node_modules/promzard/.npmignore1
-rw-r--r--node_modules/init-package-json/node_modules/promzard/LICENSE15
-rw-r--r--node_modules/init-package-json/node_modules/promzard/README.md133
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/index.js11
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/npm-init/README.md8
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/npm-init/init-input.js191
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/npm-init/init.js37
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/npm-init/package.json10
-rw-r--r--node_modules/init-package-json/node_modules/promzard/example/substack-input.js61
-rw-r--r--node_modules/init-package-json/node_modules/promzard/package.json48
-rw-r--r--node_modules/init-package-json/node_modules/promzard/promzard.js216
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/basic.js91
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/exports.input5
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/exports.js48
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/fn.input18
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/fn.js56
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/simple.input8
-rw-r--r--node_modules/init-package-json/node_modules/promzard/test/simple.js30
-rw-r--r--node_modules/init-package-json/package.json50
-rw-r--r--node_modules/init-package-json/test/basic.input15
-rw-r--r--node_modules/init-package-json/test/basic.js35
-rw-r--r--node_modules/npm-cache-filename/LICENSE15
-rw-r--r--node_modules/npm-cache-filename/README.md21
-rw-r--r--node_modules/npm-cache-filename/index.js20
-rw-r--r--node_modules/npm-cache-filename/package.json33
-rw-r--r--node_modules/npm-cache-filename/test.js21
-rw-r--r--node_modules/npm-install-checks/LICENSE27
-rw-r--r--node_modules/npm-install-checks/README.md25
-rw-r--r--node_modules/npm-install-checks/index.js146
-rw-r--r--node_modules/npm-install-checks/package.json41
-rw-r--r--node_modules/npm-install-checks/test/check-engine.js35
-rw-r--r--node_modules/npm-install-checks/test/check-git.js31
-rw-r--r--node_modules/npm-install-checks/test/check-platform.js44
-rw-r--r--node_modules/npm-registry-client/.npmignore3
-rw-r--r--node_modules/npm-registry-client/LICENSE27
-rw-r--r--node_modules/npm-registry-client/README.md187
-rw-r--r--node_modules/npm-registry-client/index.js57
-rw-r--r--node_modules/npm-registry-client/lib/adduser.js132
-rw-r--r--node_modules/npm-registry-client/lib/bugs.js9
-rw-r--r--node_modules/npm-registry-client/lib/deprecate.js26
-rw-r--r--node_modules/npm-registry-client/lib/get.js203
-rw-r--r--node_modules/npm-registry-client/lib/publish.js155
-rw-r--r--node_modules/npm-registry-client/lib/request.js314
-rw-r--r--node_modules/npm-registry-client/lib/star.js27
-rw-r--r--node_modules/npm-registry-client/lib/stars.js9
-rw-r--r--node_modules/npm-registry-client/lib/tag.js5
-rw-r--r--node_modules/npm-registry-client/lib/unpublish.js105
-rw-r--r--node_modules/npm-registry-client/lib/upload.js22
-rw-r--r--node_modules/npm-registry-client/package.json46
-rw-r--r--node_modules/npm-registry-client/test/00-setup.js10
-rw-r--r--node_modules/npm-registry-client/test/adduser-new.js44
-rw-r--r--node_modules/npm-registry-client/test/adduser-update.js57
-rw-r--r--node_modules/npm-registry-client/test/bugs.js33
-rw-r--r--node_modules/npm-registry-client/test/deprecate.js66
-rw-r--r--node_modules/npm-registry-client/test/get-all.js16
-rw-r--r--node_modules/npm-registry-client/test/get-basic.js27
-rw-r--r--node_modules/npm-registry-client/test/lib/common.js17
-rw-r--r--node_modules/npm-registry-client/test/lib/server.js58
-rw-r--r--node_modules/npm-registry-client/test/publish-again.js79
-rw-r--r--node_modules/npm-registry-client/test/publish.js50
-rw-r--r--node_modules/npm-registry-client/test/redirects.js48
-rw-r--r--node_modules/npm-registry-client/test/request-gzip-content.js49
-rw-r--r--node_modules/npm-registry-client/test/retries.js49
-rw-r--r--node_modules/npm-registry-client/test/star.js60
-rw-r--r--node_modules/npm-registry-client/test/stars.js32
-rw-r--r--node_modules/npm-registry-client/test/tag.js39
-rw-r--r--node_modules/npm-registry-client/test/unpublish.js59
-rw-r--r--node_modules/npm-registry-client/test/upload.js37
-rw-r--r--node_modules/npm-registry-client/test/zz-cleanup.js10
-rw-r--r--node_modules/npm-user-validate/.npmignore13
-rw-r--r--node_modules/npm-user-validate/.travis.yml4
-rw-r--r--node_modules/npm-user-validate/LICENSE27
-rw-r--r--node_modules/npm-user-validate/README.md6
-rw-r--r--node_modules/npm-user-validate/npm-user-validate.js43
-rw-r--r--node_modules/npm-user-validate/package.json35
-rw-r--r--node_modules/npm-user-validate/test/email.test.js26
-rw-r--r--node_modules/npm-user-validate/test/pw.test.js32
-rw-r--r--node_modules/npm-user-validate/test/username.test.js26
-rw-r--r--node_modules/npmconf/.npmignore1
-rw-r--r--node_modules/npmconf/LICENSE27
-rw-r--r--node_modules/npmconf/README.md33
-rw-r--r--node_modules/npmconf/config-defs.js370
-rw-r--r--node_modules/npmconf/lib/find-prefix.js56
-rw-r--r--node_modules/npmconf/lib/load-cafile.js31
-rw-r--r--node_modules/npmconf/lib/load-prefix.js49
-rw-r--r--node_modules/npmconf/lib/load-uid.js15
-rw-r--r--node_modules/npmconf/lib/set-user.js26
-rw-r--r--node_modules/npmconf/node_modules/config-chain/.npmignore3
-rw-r--r--node_modules/npmconf/node_modules/config-chain/LICENCE22
-rwxr-xr-xnode_modules/npmconf/node_modules/config-chain/index.js282
-rw-r--r--node_modules/npmconf/node_modules/config-chain/node_modules/proto-list/LICENSE23
-rw-r--r--node_modules/npmconf/node_modules/config-chain/node_modules/proto-list/README.md3
-rw-r--r--node_modules/npmconf/node_modules/config-chain/node_modules/proto-list/package.json51
-rw-r--r--node_modules/npmconf/node_modules/config-chain/node_modules/proto-list/proto-list.js88
-rw-r--r--node_modules/npmconf/node_modules/config-chain/node_modules/proto-list/test/basic.js61
-rw-r--r--node_modules/npmconf/node_modules/config-chain/package.json54
-rw-r--r--node_modules/npmconf/node_modules/config-chain/readme.markdown228
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/broken.js10
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/broken.json21
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/chain-class.js100
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/env.js10
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/find-file.js13
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/get.js15
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/ignore-unfound-file.js5
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/ini.js18
-rw-r--r--node_modules/npmconf/node_modules/config-chain/test/save.js59
-rw-r--r--node_modules/npmconf/npmconf.js434
-rw-r--r--node_modules/npmconf/package.json53
-rw-r--r--node_modules/npmconf/test/00-setup.js40
-rw-r--r--node_modules/npmconf/test/basic.js83
-rw-r--r--node_modules/npmconf/test/builtin.js83
-rw-r--r--node_modules/npmconf/test/certfile.js17
-rw-r--r--node_modules/npmconf/test/fixtures/.npmrc1
-rw-r--r--node_modules/npmconf/test/fixtures/builtin1
-rw-r--r--node_modules/npmconf/test/fixtures/globalconfig1
-rw-r--r--node_modules/npmconf/test/fixtures/multi-ca32
-rw-r--r--node_modules/npmconf/test/fixtures/package.json0
-rw-r--r--node_modules/npmconf/test/fixtures/userconfig22
-rw-r--r--node_modules/npmconf/test/project.js85
-rw-r--r--node_modules/npmconf/test/save.js84
-rw-r--r--node_modules/opener/LICENSE.txt14
-rw-r--r--node_modules/opener/README.md44
-rwxr-xr-xnode_modules/opener/opener.js55
-rw-r--r--node_modules/opener/package.json34
-rw-r--r--node_modules/path-is-inside/LICENSE.txt19
-rw-r--r--node_modules/path-is-inside/README.md35
-rw-r--r--node_modules/path-is-inside/lib/path-is-inside.js28
-rw-r--r--node_modules/path-is-inside/package.json43
-rw-r--r--node_modules/read-installed/.npmignore13
-rw-r--r--node_modules/read-installed/LICENSE16
-rw-r--r--node_modules/read-installed/README.md27
-rw-r--r--node_modules/read-installed/node_modules/util-extend/README.md13
-rw-r--r--node_modules/read-installed/node_modules/util-extend/extend.js33
-rw-r--r--node_modules/read-installed/node_modules/util-extend/package.json40
-rw-r--r--node_modules/read-installed/node_modules/util-extend/test.js10
-rw-r--r--node_modules/read-installed/package.json42
-rw-r--r--node_modules/read-installed/read-installed.js369
-rw-r--r--node_modules/read-installed/test/basic.js47
-rw-r--r--node_modules/read-installed/test/depth-0.js27
-rw-r--r--node_modules/read-installed/test/depth-1.js23
-rw-r--r--node_modules/read-installed/test/dev.js23
-rw-r--r--node_modules/read-installed/test/extraneous.js17
-rw-r--r--node_modules/read-installed/test/fixtures/extraneous-detected/package.json7
-rw-r--r--node_modules/read-installed/test/fixtures/grandparent-peer/package.json8
-rw-r--r--node_modules/read-installed/test/fixtures/package.json27
-rw-r--r--node_modules/read-installed/test/grandparent-peer.js24
-rw-r--r--node_modules/read-installed/test/noargs.js21
-rw-r--r--node_modules/read-installed/test/peer-dep-at-latest.js14
-rw-r--r--node_modules/sorted-object/LICENSE.txt19
-rw-r--r--node_modules/sorted-object/README.md20
-rw-r--r--node_modules/sorted-object/lib/sorted-object.js11
-rw-r--r--node_modules/sorted-object/package.json37
-rw-r--r--node_modules/uid-number/LICENSE15
-rw-r--r--node_modules/uid-number/README.md17
-rwxr-xr-xnode_modules/uid-number/get-uid-gid.js24
-rw-r--r--node_modules/uid-number/package.json47
-rw-r--r--node_modules/uid-number/uid-number.js54
-rw-r--r--package.json162
-rwxr-xr-xscripts/clean-old.sh165
-rwxr-xr-xscripts/doc-build.sh111
-rwxr-xr-xscripts/index-build.js62
-rwxr-xr-xscripts/install.sh313
-rw-r--r--scripts/release.sh36
-rwxr-xr-xscripts/relocate.sh26
-rw-r--r--test/common-tap.js32
-rw-r--r--test/common.js7
-rw-r--r--test/disabled/bundlerecurs/package.json4
-rw-r--r--test/disabled/change-bin-1/bin/foo2
-rw-r--r--test/disabled/change-bin-1/package.json3
-rw-r--r--test/disabled/change-bin-2/bin/bar2
-rw-r--r--test/disabled/change-bin-2/package.json3
-rw-r--r--test/disabled/failer/package.json5
-rw-r--r--test/disabled/fast/package.json9
-rw-r--r--test/disabled/outdated-depth-integer.js52
-rw-r--r--test/disabled/outdated-depth-integer/README.md1
-rw-r--r--test/disabled/outdated-depth-integer/index.js1
-rw-r--r--test/disabled/outdated-depth-integer/package.json10
-rw-r--r--test/disabled/package-bar/package.json7
-rw-r--r--test/disabled/package-config/package.json4
-rwxr-xr-xtest/disabled/package-config/test.js17
-rw-r--r--test/disabled/package-foo/package.json4
-rw-r--r--test/disabled/slow/package.json9
-rw-r--r--test/packages/npm-test-array-bin/README1
-rw-r--r--test/packages/npm-test-array-bin/bin/array-bin2
-rw-r--r--test/packages/npm-test-array-bin/package.json4
-rw-r--r--test/packages/npm-test-array-bin/test.js4
-rw-r--r--test/packages/npm-test-blerg/README1
-rw-r--r--test/packages/npm-test-blerg/package.json5
-rw-r--r--test/packages/npm-test-blerg/test.js5
-rw-r--r--test/packages/npm-test-blerg3/README1
-rw-r--r--test/packages/npm-test-blerg3/package.json5
-rw-r--r--test/packages/npm-test-blerg3/test.js5
-rw-r--r--test/packages/npm-test-bundled-git/README1
-rw-r--r--test/packages/npm-test-bundled-git/minimatch-expected.json29
-rw-r--r--test/packages/npm-test-bundled-git/package.json5
-rw-r--r--test/packages/npm-test-bundled-git/test.js4
-rw-r--r--test/packages/npm-test-dir-bin/README1
-rw-r--r--test/packages/npm-test-dir-bin/bin/dir-bin2
-rw-r--r--test/packages/npm-test-dir-bin/package.json4
-rw-r--r--test/packages/npm-test-dir-bin/test.js4
-rw-r--r--test/packages/npm-test-env-reader/README1
-rw-r--r--test/packages/npm-test-env-reader/package.json14
-rwxr-xr-xtest/packages/npm-test-env-reader/test.js9
-rw-r--r--test/packages/npm-test-files/.npmignore7
-rw-r--r--test/packages/npm-test-files/README1
-rw-r--r--test/packages/npm-test-files/ignore30
-rw-r--r--test/packages/npm-test-files/ignoredir1/a0
-rw-r--r--test/packages/npm-test-files/ignoredir2/a0
-rw-r--r--test/packages/npm-test-files/include40
-rw-r--r--test/packages/npm-test-files/package.json10
-rw-r--r--test/packages/npm-test-files/sub/ignore10
-rw-r--r--test/packages/npm-test-files/sub/ignore30
-rw-r--r--test/packages/npm-test-files/sub/include0
-rw-r--r--test/packages/npm-test-files/sub/include20
-rw-r--r--test/packages/npm-test-files/sub/include41
-rw-r--r--test/packages/npm-test-files/test.sh27
-rw-r--r--test/packages/npm-test-ignore-nested-nm/README1
-rw-r--r--test/packages/npm-test-ignore-nested-nm/lib/node_modules/foo1
-rw-r--r--test/packages/npm-test-ignore-nested-nm/package.json3
-rw-r--r--test/packages/npm-test-ignore-nested-nm/test.js2
-rw-r--r--test/packages/npm-test-ignore/.npmignore7
-rw-r--r--test/packages/npm-test-ignore/README1
-rw-r--r--test/packages/npm-test-ignore/ignore30
-rw-r--r--test/packages/npm-test-ignore/ignoredir1/a0
-rw-r--r--test/packages/npm-test-ignore/ignoredir2/a0
-rw-r--r--test/packages/npm-test-ignore/include40
-rw-r--r--test/packages/npm-test-ignore/package.json3
-rw-r--r--test/packages/npm-test-ignore/sub/ignore10
-rw-r--r--test/packages/npm-test-ignore/sub/ignore30
-rw-r--r--test/packages/npm-test-ignore/sub/include0
-rw-r--r--test/packages/npm-test-ignore/sub/include20
-rw-r--r--test/packages/npm-test-ignore/sub/include41
-rw-r--r--test/packages/npm-test-ignore/test.sh29
-rw-r--r--test/packages/npm-test-missing-bindir/README1
-rw-r--r--test/packages/npm-test-missing-bindir/package.json4
-rw-r--r--test/packages/npm-test-missing-bindir/test.js5
-rw-r--r--test/packages/npm-test-optional-deps/README1
-rw-r--r--test/packages/npm-test-optional-deps/package.json12
-rw-r--r--test/packages/npm-test-optional-deps/test.js9
-rw-r--r--test/packages/npm-test-platform-all/README1
-rw-r--r--test/packages/npm-test-platform-all/package.json5
-rw-r--r--test/packages/npm-test-platform/README1
-rw-r--r--test/packages/npm-test-platform/package.json5
-rw-r--r--test/packages/npm-test-private/README1
-rw-r--r--test/packages/npm-test-private/package.json4
-rw-r--r--test/packages/npm-test-shrinkwrap/README1
-rw-r--r--test/packages/npm-test-shrinkwrap/npm-shrinkwrap.json48
-rw-r--r--test/packages/npm-test-shrinkwrap/package.json13
-rw-r--r--test/packages/npm-test-shrinkwrap/test.js35
-rw-r--r--test/packages/npm-test-test-package/README1
-rw-r--r--test/packages/npm-test-test-package/package.json5
-rw-r--r--test/packages/npm-test-url-dep/README1
-rw-r--r--test/packages/npm-test-url-dep/package.json7
-rw-r--r--test/run.js192
-rw-r--r--test/tap/00-check-mock-dep.js15
-rw-r--r--test/tap/00-verify-bundle-deps.js27
-rw-r--r--test/tap/404-parent.js53
-rw-r--r--test/tap/cache-add-unpublished.js61
-rw-r--r--test/tap/cache-shasum.js60
-rw-r--r--test/tap/circular-dep.js52
-rw-r--r--test/tap/circular-dep/minimist/package.json7
-rw-r--r--test/tap/config-meta.js125
-rw-r--r--test/tap/dedupe.js34
-rw-r--r--test/tap/dedupe/package.json9
-rw-r--r--test/tap/false_name.js51
-rw-r--r--test/tap/false_name/index.js1
-rw-r--r--test/tap/false_name/package.json8
-rw-r--r--test/tap/git-cache-locking.js52
-rw-r--r--test/tap/global-prefix-set-in-userconfig.js36
-rw-r--r--test/tap/ignore-install-link.js122
-rw-r--r--test/tap/ignore-scripts.js72
-rw-r--r--test/tap/ignore-scripts/binding.gyp1
-rw-r--r--test/tap/ignore-scripts/package.json30
-rw-r--r--test/tap/ignore-shrinkwrap.js77
-rw-r--r--test/tap/ignore-shrinkwrap/npm-shrinkwrap.json17
-rw-r--r--test/tap/ignore-shrinkwrap/package.json8
-rw-r--r--test/tap/install-at-locally.js43
-rw-r--r--test/tap/install-at-locally/package@1.2.3/package.json5
-rw-r--r--test/tap/install-cli-unicode.js38
-rw-r--r--test/tap/install-cli/README.md1
-rw-r--r--test/tap/install-cli/index.js1
-rw-r--r--test/tap/install-cli/package.json10
-rw-r--r--test/tap/install-save-exact.js92
-rw-r--r--test/tap/install-save-exact/README.md1
-rw-r--r--test/tap/install-save-exact/index.js1
-rw-r--r--test/tap/install-save-exact/package.json7
-rw-r--r--test/tap/install-save-prefix.js142
-rw-r--r--test/tap/install-save-prefix/README.md1
-rw-r--r--test/tap/install-save-prefix/index.js1
-rw-r--r--test/tap/install-save-prefix/package.json7
-rw-r--r--test/tap/invalid-cmd-exit-code.js29
-rw-r--r--test/tap/lifecycle-signal.js27
-rw-r--r--test/tap/lifecycle-signal/package.json3
-rw-r--r--test/tap/lifecycle.js12
-rw-r--r--test/tap/ls-depth-cli.js79
-rw-r--r--test/tap/ls-depth-unmet.js97
-rw-r--r--test/tap/ls-depth-unmet/package.json10
-rw-r--r--test/tap/ls-depth/package.json8
-rw-r--r--test/tap/ls-no-results.js12
-rw-r--r--test/tap/maybe-github.js76
-rw-r--r--test/tap/noargs-install-config-save.js84
-rw-r--r--test/tap/npm-api-not-loaded-error.js47
-rw-r--r--test/tap/outdated-color.js44
-rw-r--r--test/tap/outdated-depth.js51
-rw-r--r--test/tap/outdated-depth/README.md1
-rw-r--r--test/tap/outdated-depth/index.js1
-rw-r--r--test/tap/outdated-depth/package.json10
-rw-r--r--test/tap/outdated-git.js30
-rw-r--r--test/tap/outdated-git/README.md1
-rw-r--r--test/tap/outdated-git/package.json12
-rw-r--r--test/tap/outdated-include-devdependencies.js28
-rw-r--r--test/tap/outdated-include-devdependencies/package.json8
-rw-r--r--test/tap/outdated-json.js73
-rw-r--r--test/tap/outdated-new-versions.js36
-rw-r--r--test/tap/outdated-new-versions/package.json11
-rw-r--r--test/tap/outdated-notarget.js47
-rw-r--r--test/tap/outdated.js62
-rw-r--r--test/tap/outdated/README.md1
-rw-r--r--test/tap/outdated/index.js1
-rw-r--r--test/tap/outdated/package.json10
-rw-r--r--test/tap/package-with-peer-dep/package.json7
-rw-r--r--test/tap/peer-deps-invalid.js46
-rw-r--r--test/tap/peer-deps-invalid/file-fail.js10
-rw-r--r--test/tap/peer-deps-invalid/file-ok.js11
-rw-r--r--test/tap/peer-deps-invalid/package.json9
-rw-r--r--test/tap/peer-deps-without-package-json.js47
-rw-r--r--test/tap/peer-deps-without-package-json/.gitkeep0
-rw-r--r--test/tap/peer-deps-without-package-json/file-js.js11
-rw-r--r--test/tap/peer-deps.js57
-rw-r--r--test/tap/peer-deps/desired-ls-results.json17
-rw-r--r--test/tap/peer-deps/package.json8
-rw-r--r--test/tap/prepublish.js97
-rw-r--r--test/tap/prune.js115
-rw-r--r--test/tap/prune/package.json13
-rw-r--r--test/tap/publish-config.js51
-rw-r--r--test/tap/referer.js24
-rw-r--r--test/tap/registry.js55
-rw-r--r--test/tap/repo.js139
-rw-r--r--test/tap/scripts-whitespace-windows.js71
-rw-r--r--test/tap/scripts-whitespace-windows/README.md1
-rw-r--r--test/tap/scripts-whitespace-windows/dep/README.md1
-rw-r--r--test/tap/scripts-whitespace-windows/dep/bin/foo4
-rw-r--r--test/tap/scripts-whitespace-windows/dep/package.json6
-rw-r--r--test/tap/scripts-whitespace-windows/package.json11
-rw-r--r--test/tap/semver-doc.js12
-rw-r--r--test/tap/shrinkwrap-dev-dependency.js66
-rw-r--r--test/tap/shrinkwrap-dev-dependency/desired-shrinkwrap-results.json12
-rw-r--r--test/tap/shrinkwrap-dev-dependency/package.json12
-rw-r--r--test/tap/shrinkwrap-empty-deps.js47
-rw-r--r--test/tap/shrinkwrap-empty-deps/package.json7
-rw-r--r--test/tap/shrinkwrap-shared-dev-dependency.js58
-rw-r--r--test/tap/shrinkwrap-shared-dev-dependency/desired-shrinkwrap-results.json12
-rw-r--r--test/tap/shrinkwrap-shared-dev-dependency/package.json11
-rw-r--r--test/tap/sorted-package-json.js93
-rw-r--r--test/tap/startstop.js64
-rw-r--r--test/tap/startstop/package.json7
-rw-r--r--test/tap/test-run-ls.js33
-rw-r--r--test/tap/uninstall-package.js41
-rw-r--r--test/tap/uninstall-package/package.json11
-rw-r--r--test/tap/update-save.js160
-rw-r--r--test/tap/update-save/README.md1
-rw-r--r--test/tap/update-save/index.js1
-rw-r--r--test/tap/update-save/package.json10
-rw-r--r--test/tap/url-dependencies.js80
-rw-r--r--test/tap/url-dependencies/package.json8
-rw-r--r--test/tap/version-no-tags.js73
-rwxr-xr-xtest/update-test.sh59
-rw-r--r--wercker.yml22
647 files changed, 34254 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1d9fa90
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+*.swp
+npm-debug.log
+/test/bin
+/test/output.log
+/test/*/*/node_modules
+/test/packages/npm-test-depends-on-spark/which-spark.log
+/test/packages/test-package/random-data.txt
+/test/root
+/node_modules/ronn
+/node_modules/tap
+/node_modules/.bin
+/node_modules/npm-registry-mock
+/node_modules/marked
+/html/api/
+/html/doc/
+/man/
+/doc/*/npm-index.md
+/npmrc
+/release/
+/npm-*.tgz
+/node_modules/npm-registry-client/test/fixtures
+/node_modules/npm-registry-couchapp
+*.pyc
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..7232cea
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,27 @@
+*.swp
+.*.swp
+npm-debug.log
+/test/bin
+/test/output.log
+/test/packages/*/node_modules
+/test/packages/npm-test-depends-on-spark/which-spark.log
+/test/packages/test-package/random-data.txt
+/test/root
+node_modules/marked
+node_modules/ronn
+node_modules/tap
+node_modules/.bin
+node_modules/npm-registry-mock
+/npmrc
+/release/
+
+# don't need these in the npm package.
+html/*.png
+
+# don't ignore .npmignore files
+# these are used in some tests.
+!.npmignore
+
+/npm-*.tgz
+
+*.pyc
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..ca0bc48
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,2 @@
+save-prefix = ~
+proprietary-attribs = false
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0fbe8dc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+script: "npm run-script tap"
+node_js:
+ - "0.11"
+ - "0.10"
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..3c0c0b0
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,158 @@
+# Authors sorted by whether or not they're me
+Isaac Z. Schlueter <i@izs.me>
+Steve Steiner <ssteinerX@gmail.com>
+Mikeal Rogers <mikeal.rogers@gmail.com>
+Aaron Blohowiak <aaron.blohowiak@gmail.com>
+Martyn Smith <martyn@dollyfish.net.nz>
+Mathias Pettersson <mape@mape.me>
+Brian Hammond <brian@fictorial.com>
+Charlie Robbins <charlie.robbins@gmail.com>
+Francisco Treacy <francisco.treacy@gmail.com>
+Cliffano Subagio <cliffano@gmail.com>
+Christian Eager <christian.eager@nokia.com>
+Dav Glass <davglass@gmail.com>
+Alex K. Wolfe <alexkwolfe@gmail.com>
+James Sanders <jimmyjazz14@gmail.com>
+Reid Burke <me@reidburke.com>
+Arlo Breault <arlolra@gmail.com>
+Timo Derstappen <teemow@gmail.com>
+Bradley Meck <bradley.meck@gmail.com>
+Bart Teeuwisse <bart.teeuwisse@thecodemill.biz>
+Ben Noordhuis <info@bnoordhuis.nl>
+Tor Valamo <tor.valamo@gmail.com>
+Whyme.Lyu <5longluna@gmail.com>
+Olivier Melcher <olivier.melcher@gmail.com>
+Tomaž Muraus <kami@k5-storitve.net>
+Evan Meagher <evan.meagher@gmail.com>
+Orlando Vazquez <ovazquez@gmail.com>
+George Miroshnykov <gmiroshnykov@lohika.com>
+Geoff Flarity <geoff.flarity@gmail.com>
+Pete Kruckenberg <pete@kruckenberg.com>
+Laurie Harper <laurie@holoweb.net>
+Chris Wong <chris@chriswongstudio.com>
+Max Goodman <c@chromacode.com>
+Scott Bronson <brons_github@rinspin.com>
+Federico Romero <federomero@gmail.com>
+Visnu Pitiyanuvath <visnupx@gmail.com>
+Irakli Gozalishvili <rfobic@gmail.com>
+Mark Cahill <mark@tiemonster.info>
+Zearin <zearin@gonk.net>
+Iain Sproat <iainsproat@gmail.com>
+Trent Mick <trentm@gmail.com>
+Felix Geisendörfer <felix@debuggable.com>
+Conny Brunnkvist <cbrunnkvist@gmail.com>
+Will Elwood <w.elwood08@gmail.com>
+Oleg Efimov <efimovov@gmail.com>
+Martin Cooper <mfncooper@gmail.com>
+Jameson Little <t.jameson.little@gmail.com>
+cspotcode <cspotcode@gmail.com>
+Maciej Małecki <maciej.malecki@notimplemented.org>
+Stephen Sugden <glurgle@gmail.com>
+Gautham Pai <buzypi@gmail.com>
+David Trejo <david.daniel.trejo@gmail.com>
+Paul Vorbach <paul@vorb.de>
+George Ornbo <george@shapeshed.com>
+Tim Oxley <secoif@gmail.com>
+Tyler Green <tyler.green2@gmail.com>
+atomizer <danila.gerasimov@gmail.com>
+Rod Vagg <rod@vagg.org>
+Christian Howe <coderarity@gmail.com>
+Andrew Lunny <alunny@gmail.com>
+Henrik Hodne <dvyjones@binaryhex.com>
+Adam Blackburn <regality@gmail.com>
+Kris Windham <kriswindham@gmail.com>
+Jens Grunert <jens.grunert@gmail.com>
+Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
+Dalmais Maxence <github@maxired.fr>
+Marcus Ekwall <marcus.ekwall@gmail.com>
+Aaron Stacy <aaron.r.stacy@gmail.com>
+Phillip Howell <phowell@cothm.org>
+Domenic Denicola <domenic@domenicdenicola.com>
+James Halliday <mail@substack.net>
+Jeremy Cantrell <jmcantrell@gmail.com>
+Ribettes <patlogan29@gmail.com>
+Einar Otto Stangvik <einaros@gmail.com>
+Don Park <donpark@docuverse.com>
+Kei Son <heyacct@gmail.com>
+Nicolas Morel <marsup@gmail.com>
+Mark Dube <markisdee@gmail.com>
+Nathan Rajlich <nathan@tootallnate.net>
+Maxim Bogushevich <boga1@mail.ru>
+Justin Beckwith <justbe@microsoft.com>
+Meaglin <Meaglin.wasabi@gmail.com>
+Ben Evans <ben@bensbit.co.uk>
+Nathan Zadoks <nathan@nathan7.eu>
+Brian White <mscdex@gmail.com>
+Jed Schmidt <tr@nslator.jp>
+Ian Livingstone <ianl@cs.dal.ca>
+Patrick Pfeiffer <patrick@buzzle.at>
+Paul Miller <paul@paulmillr.com>
+seebees <seebees@gmail.com>
+Carl Lange <carl@flax.ie>
+Jan Lehnardt <jan@apache.org>
+Alexey Kreschuk <akrsch@gmail.com>
+Di Wu <dwu@palantir.com>
+Florian Margaine <florian@margaine.com>
+Forbes Lindesay <forbes@lindesay.co.uk>
+Ian Babrou <ibobrik@gmail.com>
+Jaakko Manninen <jaakko@rocketpack.fi>
+Johan Nordberg <its@johan-nordberg.com>
+Johan Sköld <johan@skold.cc>
+Larz Conwell <larz@larz-laptop.(none)>
+Luke Arduini <luke.arduini@gmail.com>
+Marcel Klehr <mklehr@gmx.net>
+Mathias Bynens <mathias@qiwi.be>
+Matt Lunn <matt@mattlunn.me.uk>
+Matt McClure <matt.mcclure@mapmyfitness.com>
+Nirk Niggler <nirk.niggler@gmail.com>
+Paolo Fragomeni <paolo@async.ly>
+Jake Verbaten (Raynos) <raynos2@gmail.com>
+Robert Kowalski <rok@kowalski.gd>
+Schabse Laks <Dev@SLaks.net>
+Stuart Knightley <stuart@stuartk.com>
+Stuart P. Bentley <stuart@testtrack4.com>
+Vaz Allen <vaz@tryptid.com>
+elisee <elisee@sparklin.org>
+Evan You <yyx990803@gmail.com>
+Wil Moore III <wil.moore@wilmoore.com>
+Dylan Greene <dylang@gmail.com>
+zeke <zeke@sikelianos.com>
+Andrew Horton <andrew.j.horton@gmail.com>
+Denis Gladkikh <outcoldman@gmail.com>
+Daniel Santiago <daniel.santiago@highlevelwebs.com>
+Alex Kocharin <alex@kocharin.ru>
+Evan Lucas <evanlucas@me.com>
+Steve Mason <stevem@brandwatch.com>
+Quinn Slack <qslack@qslack.com>
+Sébastien Santoro <dereckson@espace-win.org>
+CamilleM <camille.moulin@alterway.fr>
+Tom Huang <hzlhu.dargon@gmail.com>
+Sergey Belov <peimei@ya.ru>
+Younghoon Park <sola92@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
+Mikola Lysenko <mikolalysenko@gmail.com>
+Rafael de Oleza <rafa@spotify.com>
+Yeonghoon Park <sola92@gmail.com>
+Franck Cuny <franck.cuny@gmail.com>
+Alan Shaw <alan@freestyle-developments.co.uk>
+Alex Rodionov <p0deje@gmail.com>
+Alexej Yaroshevich <alex@qfox.ru>
+Elan Shanker <elan.shanker@gmail.com>
+François Frisch <francoisfrisch@gmail.com>
+Gabriel Falkenberg <gabriel.falkenberg@gmail.com>
+Jason Diamond <jason@diamond.name>
+Jess Martin <jessmartin@gmail.com>
+Jon Spencer <jon@jonspencer.ca>
+Matt Colyer <matt@colyer.name>
+Matt McClure <matt.mcclure@mapmyfitness.com>
+Maximilian Antoni <maximilian.antoni@juliusbaer.com>
+Nicholas Kinsey <pyro@feisty.io>
+Paulo Cesar <pauloc062@gmail.com>
+Quim Calpe <quim@kalpe.com>
+Robert Gieseke <robert.gieseke@gmail.com>
+Spain Train <michael.spainhower@opower.com>
+TJ Holowaychuk <tj@vision-media.ca>
+Thom Blake <tblake@brightroll.com>
+Trevor Burnham <tburnham@hubspot.com>
+bitspill <bitspill+github@bitspill.net>
+Neil Gentleman <ngentleman@gmail.com>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..0a5b53a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,9 @@
+## Before you submit a new issue
+
+* Check if there's a simple solution in the
+ [Troubleshooting](https://github.com/npm/npm/wiki/Troubleshooting)
+ wiki.
+* [Search for similar
+ issues](https://github.com/npm/npm/search?q=Similar%20issues&type=Issues).
+* Ensure your new issue conforms to the [Contributing
+ Guidelines](https://github.com/npm/npm/wiki/Contributing-Guidelines).
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9505fc1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,234 @@
+Copyright (c) npm, Inc. and Contributors
+All rights reserved.
+
+npm is released under the Artistic License 2.0.
+The text of the License follows:
+
+
+--------
+
+
+The Artistic License 2.0
+
+Copyright (c) 2000-2006, The Perl Foundation.
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+--------
+
+
+"Node.js" trademark Joyent, Inc. npm is not officially part of the Node.js
+project, and is neither owned by nor affiliated with Joyent, Inc.
+
+Packages published in the npm registry (other than the Software and
+its included dependencies) are not part of npm itself, are the sole
+property of their respective maintainers, and are not covered by
+this license.
+
+"npm Logo" created by Mathias Pettersson and Brian Hammond,
+used with permission.
+
+"Gubblebum Blocky" font
+Copyright (c) by Tjarda Koster, http://jelloween.deviantart.com
+included for use in the npm website and documentation,
+used with permission.
+
+This program uses several Node modules contained in the node_modules/
+subdirectory, according to the terms of their respective licenses.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..78014d5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,218 @@
+# vim: set softtabstop=2 shiftwidth=2:
+SHELL = bash
+
+markdowns = $(shell find doc -name '*.md' | grep -v 'index') README.md
+
+html_docdeps = html/dochead.html \
+ html/docfoot.html \
+ scripts/doc-build.sh \
+ package.json
+
+cli_mandocs = $(shell find doc/cli -name '*.md' \
+ |sed 's|.md|.1|g' \
+ |sed 's|doc/cli/|man/man1/|g' ) \
+ man/man1/npm-README.1
+
+api_mandocs = $(shell find doc/api -name '*.md' \
+ |sed 's|.md|.3|g' \
+ |sed 's|doc/api/|man/man3/|g' )
+
+files_mandocs = $(shell find doc/files -name '*.md' \
+ |sed 's|.md|.5|g' \
+ |sed 's|doc/files/|man/man5/|g' ) \
+ man/man5/npm-json.5 \
+ man/man5/npm-global.5
+
+misc_mandocs = $(shell find doc/misc -name '*.md' \
+ |sed 's|.md|.7|g' \
+ |sed 's|doc/misc/|man/man7/|g' ) \
+ man/man7/npm-index.7
+
+cli_htmldocs = $(shell find doc/cli -name '*.md' \
+ |sed 's|.md|.html|g' \
+ |sed 's|doc/cli/|html/doc/cli/|g' ) \
+ html/doc/README.html
+
+api_htmldocs = $(shell find doc/api -name '*.md' \
+ |sed 's|.md|.html|g' \
+ |sed 's|doc/api/|html/doc/api/|g' )
+
+files_htmldocs = $(shell find doc/files -name '*.md' \
+ |sed 's|.md|.html|g' \
+ |sed 's|doc/files/|html/doc/files/|g' ) \
+ html/doc/files/npm-json.html \
+ html/doc/files/npm-global.html
+
+misc_htmldocs = $(shell find doc/misc -name '*.md' \
+ |sed 's|.md|.html|g' \
+ |sed 's|doc/misc/|html/doc/misc/|g' ) \
+ html/doc/index.html
+
+mandocs = $(api_mandocs) $(cli_mandocs) $(files_mandocs) $(misc_mandocs)
+
+htmldocs = $(api_htmldocs) $(cli_htmldocs) $(files_htmldocs) $(misc_htmldocs)
+
+all: doc
+
+latest:
+ @echo "Installing latest published npm"
+ @echo "Use 'make install' or 'make link' to install the code"
+ @echo "in this folder that you're looking at right now."
+ node cli.js install -g -f npm
+
+install: docclean all
+ node cli.js install -g -f
+
+# backwards compat
+dev: install
+
+link: uninstall
+ node cli.js link -f
+
+clean: markedclean ronnclean doc-clean uninstall
+ rm -rf npmrc
+ node cli.js cache clean
+
+uninstall:
+ node cli.js rm npm -g -f
+
+doc: $(mandocs) $(htmldocs)
+
+markedclean:
+ rm -rf node_modules/marked node_modules/.bin/marked .building_marked
+
+ronnclean:
+ rm -rf node_modules/ronn node_modules/.bin/ronn .building_ronn
+
+docclean: doc-clean
+doc-clean:
+ rm -rf \
+ .building_marked \
+ .building_ronn \
+ html/doc \
+ html/api \
+ man
+
+# use `npm install ronn` for this to work.
+man/man1/npm-README.1: README.md scripts/doc-build.sh package.json
+ @[ -d man/man1 ] || mkdir -p man/man1
+ scripts/doc-build.sh $< $@
+
+man/man1/%.1: doc/cli/%.md scripts/doc-build.sh package.json
+ @[ -d man/man1 ] || mkdir -p man/man1
+ scripts/doc-build.sh $< $@
+
+man/man3/%.3: doc/api/%.md scripts/doc-build.sh package.json
+ @[ -d man/man3 ] || mkdir -p man/man3
+ scripts/doc-build.sh $< $@
+
+man/man5/npm-json.5: man/man5/package.json.5
+ cp $< $@
+
+man/man5/npm-global.5: man/man5/npm-folders.5
+ cp $< $@
+
+man/man5/%.5: doc/files/%.md scripts/doc-build.sh package.json
+ @[ -d man/man5 ] || mkdir -p man/man5
+ scripts/doc-build.sh $< $@
+
+doc/misc/npm-index.md: scripts/index-build.js package.json
+ node scripts/index-build.js > $@
+
+html/doc/index.html: doc/misc/npm-index.md $(html_docdeps)
+ @[ -d html/doc ] || mkdir -p html/doc
+ scripts/doc-build.sh $< $@
+
+man/man7/%.7: doc/misc/%.md scripts/doc-build.sh package.json
+ @[ -d man/man7 ] || mkdir -p man/man7
+ scripts/doc-build.sh $< $@
+
+html/doc/README.html: README.md $(html_docdeps)
+ @[ -d html/doc ] || mkdir -p html/doc
+ scripts/doc-build.sh $< $@
+
+html/doc/cli/%.html: doc/cli/%.md $(html_docdeps)
+ @[ -d html/doc/cli ] || mkdir -p html/doc/cli
+ scripts/doc-build.sh $< $@
+
+html/doc/api/%.html: doc/api/%.md $(html_docdeps)
+ @[ -d html/doc/api ] || mkdir -p html/doc/api
+ scripts/doc-build.sh $< $@
+
+html/doc/files/npm-json.html: html/doc/files/package.json.html
+ cp $< $@
+html/doc/files/npm-global.html: html/doc/files/npm-folders.html
+ cp $< $@
+
+html/doc/files/%.html: doc/files/%.md $(html_docdeps)
+ @[ -d html/doc/files ] || mkdir -p html/doc/files
+ scripts/doc-build.sh $< $@
+
+html/doc/misc/%.html: doc/misc/%.md $(html_docdeps)
+ @[ -d html/doc/misc ] || mkdir -p html/doc/misc
+ scripts/doc-build.sh $< $@
+
+
+marked: node_modules/.bin/marked
+
+node_modules/.bin/marked:
+ node cli.js install marked --no-global
+
+ronn: node_modules/.bin/ronn
+
+node_modules/.bin/ronn:
+ node cli.js install ronn --no-global
+
+doc: man
+
+man: $(cli_docs) $(api_docs)
+
+test: doc
+ node cli.js test
+
+publish: link doc
+ @git push origin :v$(shell npm -v) 2>&1 || true
+ @npm unpublish npm@$(shell npm -v) 2>&1 || true
+ git clean -fd &&\
+ git push origin &&\
+ git push origin --tags &&\
+ npm publish &&\
+ make doc-publish
+
+docpublish: doc-publish
+doc-publish: doc
+ # legacy urls
+ for f in $$(find html/doc/{cli,files,misc}/ -name '*.html'); do \
+ j=$$(basename $$f | sed 's|^npm-||g'); \
+ if ! [ -f html/doc/$$j ] && [ $$j != README.html ] && [ $$j != index.html ]; then \
+ perl -pi -e 's/ href="\.\.\// href="/g' <$$f >html/doc/$$j; \
+ fi; \
+ done
+ mkdir -p html/api
+ for f in $$(find html/doc/api/ -name '*.html'); do \
+ j=$$(basename $$f | sed 's|^npm-||g'); \
+ perl -pi -e 's/ href="\.\.\// href="/g' <$$f >html/api/$$j; \
+ done
+ rsync -vazu --stats --no-implied-dirs --delete \
+ html/doc/* \
+ ../npm-www/doc
+ rsync -vazu --stats --no-implied-dirs --delete \
+ html/static/style.css \
+ ../npm-www/static/
+ #cleanup
+ rm -rf html/api
+ for f in html/doc/*.html; do \
+ case $$f in \
+ html/doc/README.html) continue ;; \
+ html/doc/index.html) continue ;; \
+ *) rm $$f ;; \
+ esac; \
+ done
+
+release:
+ @bash scripts/release.sh
+
+sandwich:
+ @[ $$(whoami) = "root" ] && (echo "ok"; echo "ham" > sandwich) || (echo "make it yourself" && exit 13)
+
+.PHONY: all latest install dev link doc clean uninstall test man doc-publish doc-clean docclean docpublish release
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0c08862
--- /dev/null
+++ b/README.md
@@ -0,0 +1,245 @@
+npm(1) -- node package manager
+==============================
+[![Build Status](https://img.shields.io/travis/npm/npm/master.svg)](https://travis-ci.org/npm/npm)
+## SYNOPSIS
+
+This is just enough info to get you up and running.
+
+Much more info available via `npm help` once it's installed.
+
+## IMPORTANT
+
+**You need node v0.8 or higher to run this program.**
+
+To install an old **and unsupported** version of npm that works on node 0.3
+and prior, clone the git repo and dig through the old tags and branches.
+
+## Super Easy Install
+
+npm comes with node now.
+
+### Windows Computers
+
+Get the MSI. npm is in it.
+
+### Apple Macintosh Computers
+
+Get the pkg. npm is in it.
+
+### Other Sorts of Unices
+
+Run `make install`. npm will be installed with node.
+
+If you want a more fancy pants install (a different version, customized
+paths, etc.) then read on.
+
+## Fancy Install (Unix)
+
+There's a pretty robust install script at
+<https://www.npmjs.org/install.sh>. You can download that and run it.
+
+Here's an example using curl:
+
+ curl -L https://npmjs.org/install.sh | sh
+
+### Slightly Fancier
+
+You can set any npm configuration params with that script:
+
+ npm_config_prefix=/some/path sh install.sh
+
+Or, you can run it in uber-debuggery mode:
+
+ npm_debug=1 sh install.sh
+
+### Even Fancier
+
+Get the code with git. Use `make` to build the docs and do other stuff.
+If you plan on hacking on npm, `make link` is your friend.
+
+If you've got the npm source code, you can also semi-permanently set
+arbitrary config keys using the `./configure --key=val ...`, and then
+run npm commands by doing `node cli.js <cmd> <args>`. (This is helpful
+for testing, or running stuff without actually installing npm itself.)
+
+## Fancy Windows Install
+
+You can download a zip file from <https://npmjs.org/dist/>, and unpack it
+in the same folder where node.exe lives.
+
+If that's not fancy enough for you, then you can fetch the code with
+git, and mess with it directly.
+
+## Installing on Cygwin
+
+No.
+
+## Permissions when Using npm to Install Other Stuff
+
+**tl;dr**
+
+* Use `sudo` for greater safety. Or don't, if you prefer not to.
+* npm will downgrade permissions if it's root before running any build
+ scripts that package authors specified.
+
+### More details...
+
+As of version 0.3, it is recommended to run npm as root.
+This allows npm to change the user identifier to the `nobody` user prior
+to running any package build or test commands.
+
+If you are not the root user, or if you are on a platform that does not
+support uid switching, then npm will not attempt to change the userid.
+
+If you would like to ensure that npm **always** runs scripts as the
+"nobody" user, and have it fail if it cannot downgrade permissions, then
+set the following configuration param:
+
+ npm config set unsafe-perm false
+
+This will prevent running in unsafe mode, even as non-root users.
+
+## Uninstalling
+
+So sad to see you go.
+
+ sudo npm uninstall npm -g
+
+Or, if that fails,
+
+ sudo make uninstall
+
+## More Severe Uninstalling
+
+Usually, the above instructions are sufficient. That will remove
+npm, but leave behind anything you've installed.
+
+If you would like to remove all the packages that you have installed,
+then you can use the `npm ls` command to find them, and then `npm rm` to
+remove them.
+
+To remove cruft left behind by npm 0.x, you can use the included
+`clean-old.sh` script file. You can run it conveniently like this:
+
+ npm explore npm -g -- sh scripts/clean-old.sh
+
+npm uses two configuration files, one for per-user configs, and another
+for global (every-user) configs. You can view them by doing:
+
+ npm config get userconfig # defaults to ~/.npmrc
+ npm config get globalconfig # defaults to /usr/local/etc/npmrc
+
+Uninstalling npm does not remove configuration files by default. You
+must remove them yourself manually if you want them gone. Note that
+this means that future npm installs will not remember the settings that
+you have chosen.
+
+## Using npm Programmatically
+
+If you would like to use npm programmatically, you can do that.
+It's not very well documented, but it *is* rather simple.
+
+Most of the time, unless you actually want to do all the things that
+npm does, you should try using one of npm's dependencies rather than
+using npm itself, if possible.
+
+Eventually, npm will be just a thin cli wrapper around the modules
+that it depends on, but for now, there are some things that you must
+use npm itself to do.
+
+ var npm = require("npm")
+ npm.load(myConfigObject, function (er) {
+ if (er) return handlError(er)
+ npm.commands.install(["some", "args"], function (er, data) {
+ if (er) return commandFailed(er)
+ // command succeeded, and data might have some info
+ })
+ npm.on("log", function (message) { .... })
+ })
+
+The `load` function takes an object hash of the command-line configs.
+The various `npm.commands.<cmd>` functions take an **array** of
+positional argument **strings**. The last argument to any
+`npm.commands.<cmd>` function is a callback. Some commands take other
+optional arguments. Read the source.
+
+You cannot set configs individually for any single npm function at this
+time. Since `npm` is a singleton, any call to `npm.config.set` will
+change the value for *all* npm commands in that process.
+
+See `./bin/npm-cli.js` for an example of pulling config values off of the
+command line arguments using nopt. You may also want to check out `npm
+help config` to learn about all the options you can set there.
+
+## More Docs
+
+Check out the [docs](https://www.npmjs.org/doc/),
+especially the [faq](https://www.npmjs.org/doc/faq.html).
+
+You can use the `npm help` command to read any of them.
+
+If you're a developer, and you want to use npm to publish your program,
+you should [read this](https://www.npmjs.org/doc/developers.html)
+
+## Legal Stuff
+
+"npm" and "The npm Registry" are owned by npm, Inc.
+All rights reserved. See the included LICENSE file for more details.
+
+"Node.js" and "node" are trademarks owned by Joyent, Inc.
+
+Modules published on the npm registry are not officially endorsed by
+npm, Inc. or the Node.js project.
+
+Data published to the npm registry is not part of npm itself, and is
+the sole property of the publisher. While every effort is made to
+ensure accountability, there is absolutely no guarantee, warrantee, or
+assertion expressed or implied as to the quality, fitness for a
+specific purpose, or lack of malice in any given npm package.
+
+If you have a complaint about a package in the public npm registry,
+and cannot [resolve it with the package
+owner](https://www.npmjs.org/doc/misc/npm-disputes.html), please email
+<support@npmjs.com> and explain the situation.
+
+Any data published to The npm Registry (including user account
+information) may be removed or modified at the sole discretion of the
+npm server administrators.
+
+### In plainer english
+
+npm is the property of npm, Inc.
+
+If you publish something, it's yours, and you are solely accountable
+for it.
+
+If other people publish something, it's theirs.
+
+Users can publish Bad Stuff. It will be removed promptly if reported.
+But there is no vetting process for published modules, and you use
+them at your own risk. Please inspect the source.
+
+If you publish Bad Stuff, we may delete it from the registry, or even
+ban your account in extreme cases. So don't do that.
+
+## BUGS
+
+When you find issues, please report them:
+
+* web:
+ <https://github.com/npm/npm/issues>
+* email:
+ <npm-@googlegroups.com>
+
+Be sure to include *all* of the output from the npm command that didn't work
+as expected. The `npm-debug.log` file is also helpful to provide.
+
+You can also look for isaacs in #node.js on irc://irc.freenode.net. He
+will no doubt tell you to put the output in a gist or email.
+
+## SEE ALSO
+
+* npm(1)
+* npm-faq(7)
+* npm-help(1)
+* npm-index(7)
diff --git a/bin/node-gyp-bin/node-gyp b/bin/node-gyp-bin/node-gyp
new file mode 100755
index 0000000..345f07a
--- /dev/null
+++ b/bin/node-gyp-bin/node-gyp
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+node "`dirname "$0"`/../../node_modules/node-gyp/bin/node-gyp.js" "$@"
diff --git a/bin/node-gyp-bin/node-gyp.cmd b/bin/node-gyp-bin/node-gyp.cmd
new file mode 100755
index 0000000..c2563ea
--- /dev/null
+++ b/bin/node-gyp-bin/node-gyp.cmd
@@ -0,0 +1 @@
+node "%~dp0\..\..\node_modules\node-gyp\bin\node-gyp.js" %*
diff --git a/bin/npm b/bin/npm
new file mode 100755
index 0000000..d020ccf
--- /dev/null
+++ b/bin/npm
@@ -0,0 +1,14 @@
+#!/bin/sh
+(set -o igncr) 2>/dev/null && set -o igncr; # cygwin encoding fix
+
+basedir=`dirname "$0"`
+
+case `uname` in
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node.exe" ]; then
+ "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
+else
+ node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
+fi
diff --git a/bin/npm-cli.js b/bin/npm-cli.js
new file mode 100755
index 0000000..ef88735
--- /dev/null
+++ b/bin/npm-cli.js
@@ -0,0 +1,86 @@
+#!/usr/bin/env node
+;(function () { // wrapper in case we're in module_context mode
+
+// 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 <args>',\n"
+ +"or type 'node npm <args>'.")
+ WScript.quit(1)
+ return
+}
+
+
+process.title = "npm"
+
+var log = require("npmlog")
+log.pause() // will be unpaused when config is loaded.
+log.info("it worked if it ends with", "ok")
+
+var fs = require("graceful-fs")
+ , path = require("path")
+ , npm = require("../lib/npm.js")
+ , npmconf = require("npmconf")
+ , errorHandler = require("../lib/utils/error-handler.js")
+
+ , configDefs = npmconf.defs
+ , shorthands = configDefs.shorthands
+ , types = configDefs.types
+ , nopt = require("nopt")
+
+// if npm is called as "npmg" or "npm_g", then
+// run in global mode.
+if (path.basename(process.argv[1]).slice(-1) === "g") {
+ process.argv.splice(1, 1, "npm", "-g")
+}
+
+log.verbose("cli", process.argv)
+
+var conf = nopt(types, shorthands)
+npm.argv = conf.argv.remain
+if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift()
+else conf.usage = true
+
+
+if (conf.version) {
+ console.log(npm.version)
+ return
+}
+
+if (conf.versions) {
+ npm.command = "version"
+ conf.usage = false
+ npm.argv = []
+}
+
+log.info("using", "npm@%s", npm.version)
+log.info("using", "node@%s", process.version)
+
+// make sure that this version of node works with this version of npm.
+var semver = require("semver")
+ , nodeVer = process.version
+ , reqVer = npm.nodeVersionRequired
+if (reqVer && !semver.satisfies(nodeVer, reqVer)) {
+ return errorHandler(new Error(
+ "npm doesn't work with node " + nodeVer
+ + "\nRequired: node@" + reqVer), true)
+}
+
+process.on("uncaughtException", errorHandler)
+
+if (conf.usage && npm.command !== "help") {
+ npm.argv.unshift(npm.command)
+ npm.command = "help"
+}
+
+// now actually fire up npm and run the command.
+// this is how to use npm programmatically:
+conf._exit = true
+npm.load(conf, function (er) {
+ if (er) return errorHandler(er)
+ npm.commands[npm.command](npm.argv, errorHandler)
+})
+
+})()
diff --git a/bin/npm.cmd b/bin/npm.cmd
new file mode 100644
index 0000000..7720e20
--- /dev/null
+++ b/bin/npm.cmd
@@ -0,0 +1,6 @@
+:: Created by npm, please don't edit manually.
+@IF EXIST "%~dp0\node.exe" (
+ "%~dp0\node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
+) ELSE (
+ node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
+)
diff --git a/bin/read-package-json.js b/bin/read-package-json.js
new file mode 100755
index 0000000..3e5a0c7
--- /dev/null
+++ b/bin/read-package-json.js
@@ -0,0 +1,22 @@
+var argv = process.argv
+if (argv.length < 3) {
+ console.error("Usage: read-package.json <file> [<fields> ...]")
+ process.exit(1)
+}
+
+var fs = require("fs")
+ , file = argv[2]
+ , readJson = require("read-package-json")
+
+readJson(file, function (er, data) {
+ if (er) throw er
+ if (argv.length === 3) console.log(data)
+ else argv.slice(3).forEach(function (field) {
+ field = field.split(".")
+ var val = data
+ field.forEach(function (f) {
+ val = val[f]
+ })
+ console.log(val)
+ })
+})
diff --git a/cli.js b/cli.js
new file mode 100755
index 0000000..0df931e
--- /dev/null
+++ b/cli.js
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+require("./bin/npm-cli.js")
diff --git a/configure b/configure
new file mode 100755
index 0000000..b13c8d0
--- /dev/null
+++ b/configure
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# set configurations that will be "sticky" on this system,
+# surviving npm self-updates.
+
+CONFIGS=()
+i=0
+
+# get the location of this file.
+unset CDPATH
+CONFFILE=$(cd $(dirname "$0"); pwd -P)/npmrc
+
+while [ $# -gt 0 ]; do
+ conf="$1"
+ case $conf in
+ --help)
+ echo "./configure --param=value ..."
+ exit 0
+ ;;
+ --*)
+ CONFIGS[$i]="${conf:2}"
+ ;;
+ *)
+ CONFIGS[$i]="$conf"
+ ;;
+ esac
+ let i++
+ shift
+done
+
+for c in "${CONFIGS[@]}"; do
+ echo "$c" >> "$CONFFILE"
+done
diff --git a/doc/api/npm-bin.md b/doc/api/npm-bin.md
new file mode 100644
index 0000000..f3dc482
--- /dev/null
+++ b/doc/api/npm-bin.md
@@ -0,0 +1,13 @@
+npm-bin(3) -- Display npm bin folder
+====================================
+
+## SYNOPSIS
+
+ npm.commands.bin(args, cb)
+
+## DESCRIPTION
+
+Print the folder where npm will install executables.
+
+This function should not be used programmatically. Instead, just refer
+to the `npm.bin` member.
diff --git a/doc/api/npm-bugs.md b/doc/api/npm-bugs.md
new file mode 100644
index 0000000..cc4db8f
--- /dev/null
+++ b/doc/api/npm-bugs.md
@@ -0,0 +1,19 @@
+npm-bugs(3) -- Bugs for a package in a web browser maybe
+========================================================
+
+## SYNOPSIS
+
+ npm.commands.bugs(package, callback)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+bug tracker URL, and then tries to open it using the `--browser`
+config param.
+
+Like other commands, the first parameter is an array. This command only
+uses the first element, which is expected to be a package name with an
+optional version number.
+
+This command will launch a browser, so this command may not be the most
+friendly for programmatic use.
diff --git a/doc/api/npm-cache.md b/doc/api/npm-cache.md
new file mode 100644
index 0000000..e7079d8
--- /dev/null
+++ b/doc/api/npm-cache.md
@@ -0,0 +1,30 @@
+npm-cache(3) -- manage the npm cache programmatically
+=====================================================
+
+## SYNOPSIS
+
+ npm.commands.cache([args], callback)
+
+ // helpers
+ npm.commands.cache.clean([args], callback)
+ npm.commands.cache.add([args], callback)
+ npm.commands.cache.read(name, version, forceBypass, callback)
+
+## DESCRIPTION
+
+This acts much the same ways as the npm-cache(1) command line
+functionality.
+
+The callback is called with the package.json data of the thing that is
+eventually added to or read from the cache.
+
+The top level `npm.commands.cache(...)` functionality is a public
+interface, and like all commands on the `npm.commands` object, it will
+match the command line behavior exactly.
+
+However, the cache folder structure and the cache helper functions are
+considered **internal** API surface, and as such, may change in future
+releases of npm, potentially without warning or significant version
+incrementation.
+
+Use at your own risk.
diff --git a/doc/api/npm-commands.md b/doc/api/npm-commands.md
new file mode 100644
index 0000000..36dcfd8
--- /dev/null
+++ b/doc/api/npm-commands.md
@@ -0,0 +1,22 @@
+npm-commands(3) -- npm commands
+===============================
+
+## SYNOPSIS
+
+ npm.commands[<command>](args, callback)
+
+## DESCRIPTION
+
+npm comes with a full set of commands, and each of the commands takes a
+similar set of arguments.
+
+In general, all commands on the command object take an **array** of positional
+argument **strings**. The last argument to any function is a callback. Some
+commands are special and take other optional arguments.
+
+All commands have their own man page. See `man npm-<command>` for command-line
+usage, or `man 3 npm-<command>` for programmatic usage.
+
+## SEE ALSO
+
+* npm-index(7)
diff --git a/doc/api/npm-config.md b/doc/api/npm-config.md
new file mode 100644
index 0000000..7ae2274
--- /dev/null
+++ b/doc/api/npm-config.md
@@ -0,0 +1,45 @@
+npm-config(3) -- Manage the npm configuration files
+===================================================
+
+## SYNOPSIS
+
+ npm.commands.config(args, callback)
+ var val = npm.config.get(key)
+ npm.config.set(key, val)
+
+## DESCRIPTION
+
+This function acts much the same way as the command-line version. The first
+element in the array tells config what to do. Possible values are:
+
+* `set`
+
+ Sets a config parameter. The second element in `args` is interpreted as the
+ key, and the third element is interpreted as the value.
+
+* `get`
+
+ Gets the value of a config parameter. The second element in `args` is the
+ key to get the value of.
+
+* `delete` (`rm` or `del`)
+
+ Deletes a parameter from the config. The second element in `args` is the
+ key to delete.
+
+* `list` (`ls`)
+
+ Show all configs that aren't secret. No parameters necessary.
+
+* `edit`:
+
+ Opens the config file in the default editor. This command isn't very useful
+ programmatically, but it is made available.
+
+To programmatically access npm configuration settings, or set them for
+the duration of a program, use the `npm.config.set` and `npm.config.get`
+functions instead.
+
+## SEE ALSO
+
+* npm(3)
diff --git a/doc/api/npm-deprecate.md b/doc/api/npm-deprecate.md
new file mode 100644
index 0000000..200fb9c
--- /dev/null
+++ b/doc/api/npm-deprecate.md
@@ -0,0 +1,34 @@
+npm-deprecate(3) -- Deprecate a version of a package
+====================================================
+
+## SYNOPSIS
+
+ npm.commands.deprecate(args, callback)
+
+## DESCRIPTION
+
+This command will update the npm registry entry for a package, providing
+a deprecation warning to all who attempt to install it.
+
+The 'args' parameter must have exactly two elements:
+
+* `package[@version]`
+
+ The `version` portion is optional, and may be either a range, or a
+ specific version, or a tag.
+
+* `message`
+
+ The warning message that will be printed whenever a user attempts to
+ install the package.
+
+Note that you must be the package owner to deprecate something. See the
+`owner` and `adduser` help topics.
+
+To un-deprecate a package, specify an empty string (`""`) for the `message` argument.
+
+## SEE ALSO
+
+* npm-publish(3)
+* npm-unpublish(3)
+* npm-registry(7)
diff --git a/doc/api/npm-docs.md b/doc/api/npm-docs.md
new file mode 100644
index 0000000..2c5fc5e
--- /dev/null
+++ b/doc/api/npm-docs.md
@@ -0,0 +1,19 @@
+npm-docs(3) -- Docs for a package in a web browser maybe
+========================================================
+
+## SYNOPSIS
+
+ npm.commands.docs(package, callback)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+documentation URL, and then tries to open it using the `--browser`
+config param.
+
+Like other commands, the first parameter is an array. This command only
+uses the first element, which is expected to be a package name with an
+optional version number.
+
+This command will launch a browser, so this command may not be the most
+friendly for programmatic use.
diff --git a/doc/api/npm-edit.md b/doc/api/npm-edit.md
new file mode 100644
index 0000000..b13fbb8
--- /dev/null
+++ b/doc/api/npm-edit.md
@@ -0,0 +1,24 @@
+npm-edit(3) -- Edit an installed package
+========================================
+
+## SYNOPSIS
+
+ npm.commands.edit(package, callback)
+
+## DESCRIPTION
+
+Opens the package folder in the default editor (or whatever you've
+configured as the npm `editor` config -- see `npm help config`.)
+
+After it has been edited, the package is rebuilt so as to pick up any
+changes in compiled packages.
+
+For instance, you can do `npm install connect` to install connect
+into your package, and then `npm.commands.edit(["connect"], callback)`
+to make a few changes to your locally installed copy.
+
+The first parameter is a string array with a single element, the package
+to open. The package can optionally have a version number attached.
+
+Since this command opens an editor in a new process, be careful about where
+and how this is used.
diff --git a/doc/api/npm-explore.md b/doc/api/npm-explore.md
new file mode 100644
index 0000000..a239f3d
--- /dev/null
+++ b/doc/api/npm-explore.md
@@ -0,0 +1,18 @@
+npm-explore(3) -- Browse an installed package
+=============================================
+
+## SYNOPSIS
+
+ npm.commands.explore(args, callback)
+
+## DESCRIPTION
+
+Spawn a subshell in the directory of the installed package specified.
+
+If a command is specified, then it is run in the subshell, which then
+immediately terminates.
+
+Note that the package is *not* automatically rebuilt afterwards, so be
+sure to use `npm rebuild <pkg>` if you make any changes.
+
+The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.
diff --git a/doc/api/npm-help-search.md b/doc/api/npm-help-search.md
new file mode 100644
index 0000000..5c00cfc
--- /dev/null
+++ b/doc/api/npm-help-search.md
@@ -0,0 +1,30 @@
+npm-help-search(3) -- Search the help pages
+===========================================
+
+## SYNOPSIS
+
+ npm.commands.helpSearch(args, [silent,] callback)
+
+## DESCRIPTION
+
+This command is rarely useful, but it exists in the rare case that it is.
+
+This command takes an array of search terms and returns the help pages that
+match in order of best match.
+
+If there is only one match, then npm displays that help section. If there
+are multiple results, the results are printed to the screen formatted and the
+array of results is returned. Each result is an object with these properties:
+
+* hits:
+ A map of args to number of hits on that arg. For example, {"npm": 3}
+* found:
+ Total number of unique args that matched.
+* totalHits:
+ Total number of hits.
+* lines:
+ An array of all matching lines (and some adjacent lines).
+* file:
+ Name of the file that matched
+
+The silent parameter is not neccessary not used, but it may in the future.
diff --git a/doc/api/npm-init.md b/doc/api/npm-init.md
new file mode 100644
index 0000000..9b75bf7
--- /dev/null
+++ b/doc/api/npm-init.md
@@ -0,0 +1,29 @@
+npm init(3) -- Interactively create a package.json file
+=======================================================
+
+## SYNOPSIS
+
+ npm.commands.init(args, callback)
+
+## DESCRIPTION
+
+This will ask you a bunch of questions, and then write a package.json for you.
+
+It attempts to make reasonable guesses about what you want things to be set to,
+and then writes a package.json file with the options you've selected.
+
+If you already have a package.json file, it'll read that first, and default to
+the options in there.
+
+It is strictly additive, so it does not delete options from your package.json
+without a really good reason to do so.
+
+Since this function expects to be run on the command-line, it doesn't work very
+well as a programmatically. The best option is to roll your own, and since
+JavaScript makes it stupid simple to output formatted JSON, that is the
+preferred method. If you're sure you want to handle command-line prompting,
+then go ahead and use this programmatically.
+
+## SEE ALSO
+
+package.json(5)
diff --git a/doc/api/npm-install.md b/doc/api/npm-install.md
new file mode 100644
index 0000000..12f665a
--- /dev/null
+++ b/doc/api/npm-install.md
@@ -0,0 +1,19 @@
+npm-install(3) -- install a package programmatically
+====================================================
+
+## SYNOPSIS
+
+ npm.commands.install([where,] packages, callback)
+
+## DESCRIPTION
+
+This acts much the same ways as installing on the command-line.
+
+The 'where' parameter is optional and only used internally, and it specifies
+where the packages should be installed to.
+
+The 'packages' parameter is an array of strings. Each element in the array is
+the name of a package to be installed.
+
+Finally, 'callback' is a function that will be called when all packages have been
+installed or when an error has been encountered.
diff --git a/doc/api/npm-link.md b/doc/api/npm-link.md
new file mode 100644
index 0000000..fe875ec
--- /dev/null
+++ b/doc/api/npm-link.md
@@ -0,0 +1,33 @@
+npm-link(3) -- Symlink a package folder
+=======================================
+
+## SYNOPSIS
+
+ npm.commands.link(callback)
+ npm.commands.link(packages, callback)
+
+## DESCRIPTION
+
+Package linking is a two-step process.
+
+Without parameters, link will create a globally-installed
+symbolic link from `prefix/package-name` to the current folder.
+
+With a parameters, link will create a symlink from the local `node_modules`
+folder to the global symlink.
+
+When creating tarballs for `npm publish`, the linked packages are
+"snapshotted" to their current state by resolving the symbolic links.
+
+This is
+handy for installing your own stuff, so that you can work on it and test it
+iteratively without having to continually rebuild.
+
+For example:
+
+ npm.commands.link(cb) # creates global link from the cwd
+ # (say redis package)
+ npm.commands.link('redis', cb) # link-install the package
+
+Now, any changes to the redis package will be reflected in
+the package in the current working directory
diff --git a/doc/api/npm-load.md b/doc/api/npm-load.md
new file mode 100644
index 0000000..a95a6b2
--- /dev/null
+++ b/doc/api/npm-load.md
@@ -0,0 +1,26 @@
+npm-load(3) -- Load config settings
+===================================
+
+## SYNOPSIS
+
+ npm.load(conf, cb)
+
+## DESCRIPTION
+
+npm.load() must be called before any other function call. Both parameters are
+optional, but the second is recommended.
+
+The first parameter is an object hash of command-line config params, and the
+second parameter is a callback that will be called when npm is loaded and
+ready to serve.
+
+The first parameter should follow a similar structure as the package.json
+config object.
+
+For example, to emulate the --dev flag, pass an object that looks like this:
+
+ {
+ "dev": true
+ }
+
+For a list of all the available command-line configs, see `npm help config`
diff --git a/doc/api/npm-ls.md b/doc/api/npm-ls.md
new file mode 100644
index 0000000..ed890ff
--- /dev/null
+++ b/doc/api/npm-ls.md
@@ -0,0 +1,56 @@
+npm-ls(3) -- List installed packages
+======================================
+
+## SYNOPSIS
+
+ npm.commands.ls(args, [silent,] callback)
+
+## DESCRIPTION
+
+This command will print to stdout all the versions of packages that are
+installed, as well as their dependencies, in a tree-structure. It will also
+return that data using the callback.
+
+This command does not take any arguments, but args must be defined.
+Beyond that, if any arguments are passed in, npm will politely warn that it
+does not take positional arguments, though you may set config flags
+like with any other command, such as `global` to list global packages.
+
+It will print out extraneous, missing, and invalid packages.
+
+If the silent parameter is set to true, nothing will be output to the screen,
+but the data will still be returned.
+
+Callback is provided an error if one occurred, the full data about which
+packages are installed and which dependencies they will receive, and a
+"lite" data object which just shows which versions are installed where.
+Note that the full data object is a circular structure, so care must be
+taken if it is serialized to JSON.
+
+## CONFIGURATION
+
+### long
+
+* Default: false
+* Type: Boolean
+
+Show extended information.
+
+### parseable
+
+* Default: false
+* Type: Boolean
+
+Show parseable output instead of tree view.
+
+### global
+
+* Default: false
+* Type: Boolean
+
+List packages in the global install prefix instead of in the current
+project.
+
+Note, if parseable is set or long isn't set, then duplicates will be trimmed.
+This means that if a submodule a same dependency as a parent module, then the
+dependency will only be output once.
diff --git a/doc/api/npm-outdated.md b/doc/api/npm-outdated.md
new file mode 100644
index 0000000..89f4cf6
--- /dev/null
+++ b/doc/api/npm-outdated.md
@@ -0,0 +1,13 @@
+npm-outdated(3) -- Check for outdated packages
+==============================================
+
+## SYNOPSIS
+
+ npm.commands.outdated([packages,] callback)
+
+## DESCRIPTION
+
+This command will check the registry to see if the specified packages are
+currently outdated.
+
+If the 'packages' parameter is left out, npm will check all packages.
diff --git a/doc/api/npm-owner.md b/doc/api/npm-owner.md
new file mode 100644
index 0000000..71fcccf
--- /dev/null
+++ b/doc/api/npm-owner.md
@@ -0,0 +1,31 @@
+npm-owner(3) -- Manage package owners
+=====================================
+
+## SYNOPSIS
+
+ npm.commands.owner(args, callback)
+
+## DESCRIPTION
+
+The first element of the 'args' parameter defines what to do, and the subsequent
+elements depend on the action. Possible values for the action are (order of
+parameters are given in parenthesis):
+
+* ls (package):
+ List all the users who have access to modify a package and push new versions.
+ Handy when you need to know who to bug for help.
+* add (user, package):
+ Add a new user as a maintainer of a package. This user is enabled to modify
+ metadata, publish new versions, and add other owners.
+* rm (user, package):
+ Remove a user from the package owner list. This immediately revokes their
+ privileges.
+
+Note that there is only one level of access. Either you can modify a package,
+or you can't. Future versions may contain more fine-grained access levels, but
+that is not implemented at this time.
+
+## SEE ALSO
+
+* npm-publish(3)
+* npm-registry(7)
diff --git a/doc/api/npm-pack.md b/doc/api/npm-pack.md
new file mode 100644
index 0000000..cb339c0
--- /dev/null
+++ b/doc/api/npm-pack.md
@@ -0,0 +1,19 @@
+npm-pack(3) -- Create a tarball from a package
+==============================================
+
+## SYNOPSIS
+
+ npm.commands.pack([packages,] callback)
+
+## DESCRIPTION
+
+For anything that's installable (that is, a package folder, tarball,
+tarball url, name@tag, name@version, or name), this command will fetch
+it to the cache, and then copy the tarball to the current working
+directory as `<name>-<version>.tgz`, and then write the filenames out to
+stdout.
+
+If the same package is specified multiple times, then the file will be
+overwritten the second time.
+
+If no arguments are supplied, then npm packs the current package folder.
diff --git a/doc/api/npm-prefix.md b/doc/api/npm-prefix.md
new file mode 100644
index 0000000..806dd4b
--- /dev/null
+++ b/doc/api/npm-prefix.md
@@ -0,0 +1,15 @@
+npm-prefix(3) -- Display prefix
+===============================
+
+## SYNOPSIS
+
+ npm.commands.prefix(args, callback)
+
+## DESCRIPTION
+
+Print the prefix to standard out.
+
+'args' is never used and callback is never called with data.
+'args' must be present or things will break.
+
+This function is not useful programmatically
diff --git a/doc/api/npm-prune.md b/doc/api/npm-prune.md
new file mode 100644
index 0000000..2a4f177
--- /dev/null
+++ b/doc/api/npm-prune.md
@@ -0,0 +1,17 @@
+npm-prune(3) -- Remove extraneous packages
+==========================================
+
+## SYNOPSIS
+
+ npm.commands.prune([packages,] callback)
+
+## DESCRIPTION
+
+This command removes "extraneous" packages.
+
+The first parameter is optional, and it specifies packages to be removed.
+
+No packages are specified, then all packages will be checked.
+
+Extraneous packages are packages that are not listed on the parent
+package's dependencies list.
diff --git a/doc/api/npm-publish.md b/doc/api/npm-publish.md
new file mode 100644
index 0000000..6871daf
--- /dev/null
+++ b/doc/api/npm-publish.md
@@ -0,0 +1,30 @@
+npm-publish(3) -- Publish a package
+===================================
+
+## SYNOPSIS
+
+ npm.commands.publish([packages,] callback)
+
+## DESCRIPTION
+
+Publishes a package to the registry so that it can be installed by name.
+Possible values in the 'packages' array are:
+
+* `<folder>`:
+ A folder containing a package.json file
+
+* `<tarball>`:
+ A url or file path to a gzipped tar archive containing a single folder
+ with a package.json file inside.
+
+If the package array is empty, npm will try to publish something in the
+current working directory.
+
+This command could fails if one of the packages specified already exists in
+the registry. Overwrites when the "force" environment variable is set.
+
+## SEE ALSO
+
+* npm-registry(7)
+* npm-adduser(1)
+* npm-owner(3)
diff --git a/doc/api/npm-rebuild.md b/doc/api/npm-rebuild.md
new file mode 100644
index 0000000..8b89898
--- /dev/null
+++ b/doc/api/npm-rebuild.md
@@ -0,0 +1,16 @@
+npm-rebuild(3) -- Rebuild a package
+===================================
+
+## SYNOPSIS
+
+ npm.commands.rebuild([packages,] callback)
+
+## DESCRIPTION
+
+This command runs the `npm build` command on each of the matched packages. This is useful
+when you install a new version of node, and must recompile all your C++ addons with
+the new binary. If no 'packages' parameter is specify, every package will be rebuilt.
+
+## CONFIGURATION
+
+See `npm help build`
diff --git a/doc/api/npm-repo.md b/doc/api/npm-repo.md
new file mode 100644
index 0000000..af3c52f
--- /dev/null
+++ b/doc/api/npm-repo.md
@@ -0,0 +1,19 @@
+npm-repo(3) -- Open package repository page in the browser
+========================================================
+
+## SYNOPSIS
+
+ npm.commands.repo(package, callback)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+repository URL, and then tries to open it using the `--browser`
+config param.
+
+Like other commands, the first parameter is an array. This command only
+uses the first element, which is expected to be a package name with an
+optional version number.
+
+This command will launch a browser, so this command may not be the most
+friendly for programmatic use.
diff --git a/doc/api/npm-restart.md b/doc/api/npm-restart.md
new file mode 100644
index 0000000..c407044
--- /dev/null
+++ b/doc/api/npm-restart.md
@@ -0,0 +1,22 @@
+npm-restart(3) -- Start a package
+=================================
+
+## SYNOPSIS
+
+ npm.commands.restart(packages, callback)
+
+## DESCRIPTION
+
+This runs a package's "restart" script, if one was provided.
+Otherwise it runs package's "stop" script, if one was provided, and then
+the "start" script.
+
+If no version is specified, then it restarts the "active" version.
+
+npm can run tests on multiple packages. Just specify multiple packages
+in the `packages` parameter.
+
+## SEE ALSO
+
+* npm-start(3)
+* npm-stop(3)
diff --git a/doc/api/npm-root.md b/doc/api/npm-root.md
new file mode 100644
index 0000000..1c3ab56
--- /dev/null
+++ b/doc/api/npm-root.md
@@ -0,0 +1,15 @@
+npm-root(3) -- Display npm root
+===============================
+
+## SYNOPSIS
+
+ npm.commands.root(args, callback)
+
+## DESCRIPTION
+
+Print the effective `node_modules` folder to standard out.
+
+'args' is never used and callback is never called with data.
+'args' must be present or things will break.
+
+This function is not useful programmatically.
diff --git a/doc/api/npm-run-script.md b/doc/api/npm-run-script.md
new file mode 100644
index 0000000..91ad953
--- /dev/null
+++ b/doc/api/npm-run-script.md
@@ -0,0 +1,27 @@
+npm-run-script(3) -- Run arbitrary package scripts
+==================================================
+
+## SYNOPSIS
+
+ npm.commands.run-script(args, callback)
+
+## DESCRIPTION
+
+This runs an arbitrary command from a package's "scripts" object.
+
+It is used by the test, start, restart, and stop commands, but can be
+called directly, as well.
+
+The 'args' parameter is an array of strings. Behavior depends on the number
+of elements. If there is only one element, npm assumes that the element
+represents a command to be run on the local repository. If there is more than
+one element, then the first is assumed to be the package and the second is
+assumed to be the command to run. All other elements are ignored.
+
+## SEE ALSO
+
+* npm-scripts(7)
+* npm-test(3)
+* npm-start(3)
+* npm-restart(3)
+* npm-stop(3)
diff --git a/doc/api/npm-search.md b/doc/api/npm-search.md
new file mode 100644
index 0000000..30651d7
--- /dev/null
+++ b/doc/api/npm-search.md
@@ -0,0 +1,35 @@
+npm-search(3) -- Search for packages
+====================================
+
+## SYNOPSIS
+
+ npm.commands.search(searchTerms, [silent,] [staleness,] callback)
+
+## DESCRIPTION
+
+Search the registry for packages matching the search terms. The available parameters are:
+
+* searchTerms:
+ Array of search terms. These terms are case-insensitive.
+* silent:
+ If true, npm will not log anything to the console.
+* staleness:
+ This is the threshold for stale packages. "Fresh" packages are not refreshed
+ from the registry. This value is measured in seconds.
+* callback:
+ Returns an object where each key is the name of a package, and the value
+ is information about that package along with a 'words' property, which is
+ a space-delimited string of all of the interesting words in that package.
+ The only properties included are those that are searched, which generally include:
+
+ * name
+ * description
+ * maintainers
+ * url
+ * keywords
+
+A search on the registry excludes any result that does not match all of the
+search terms. It also removes any items from the results that contain an
+excluded term (the "searchexclude" config). The search is case insensitive
+and doesn't try to read your mind (it doesn't do any verb tense matching or the
+like).
diff --git a/doc/api/npm-shrinkwrap.md b/doc/api/npm-shrinkwrap.md
new file mode 100644
index 0000000..6584d6a
--- /dev/null
+++ b/doc/api/npm-shrinkwrap.md
@@ -0,0 +1,20 @@
+npm-shrinkwrap(3) -- programmatically generate package shrinkwrap file
+====================================================
+
+## SYNOPSIS
+
+ npm.commands.shrinkwrap(args, [silent,] callback)
+
+## DESCRIPTION
+
+This acts much the same ways as shrinkwrapping on the command-line.
+
+This command does not take any arguments, but 'args' must be defined.
+Beyond that, if any arguments are passed in, npm will politely warn that it
+does not take positional arguments.
+
+If the 'silent' parameter is set to true, nothing will be output to the screen,
+but the shrinkwrap file will still be written.
+
+Finally, 'callback' is a function that will be called when the shrinkwrap has
+been saved.
diff --git a/doc/api/npm-start.md b/doc/api/npm-start.md
new file mode 100644
index 0000000..7449114
--- /dev/null
+++ b/doc/api/npm-start.md
@@ -0,0 +1,13 @@
+npm-start(3) -- Start a package
+===============================
+
+## SYNOPSIS
+
+ npm.commands.start(packages, callback)
+
+## DESCRIPTION
+
+This runs a package's "start" script, if one was provided.
+
+npm can run tests on multiple packages. Just specify multiple packages
+in the `packages` parameter.
diff --git a/doc/api/npm-stop.md b/doc/api/npm-stop.md
new file mode 100644
index 0000000..0f8333d
--- /dev/null
+++ b/doc/api/npm-stop.md
@@ -0,0 +1,13 @@
+npm-stop(3) -- Stop a package
+=============================
+
+## SYNOPSIS
+
+ npm.commands.stop(packages, callback)
+
+## DESCRIPTION
+
+This runs a package's "stop" script, if one was provided.
+
+npm can run stop on multiple packages. Just specify multiple packages
+in the `packages` parameter.
diff --git a/doc/api/npm-submodule.md b/doc/api/npm-submodule.md
new file mode 100644
index 0000000..2d8bafa
--- /dev/null
+++ b/doc/api/npm-submodule.md
@@ -0,0 +1,28 @@
+npm-submodule(3) -- Add a package as a git submodule
+====================================================
+
+## SYNOPSIS
+
+ npm.commands.submodule(packages, callback)
+
+## DESCRIPTION
+
+For each package specified, npm will check if it has a git repository url
+in its package.json description then add it as a git submodule at
+`node_modules/<pkg name>`.
+
+This is a convenience only. From then on, it's up to you to manage
+updates by using the appropriate git commands. npm will stubbornly
+refuse to update, modify, or remove anything with a `.git` subfolder
+in it.
+
+This command also does not install missing dependencies, if the package
+does not include them in its git repository. If `npm ls` reports that
+things are missing, you can either install, link, or submodule them yourself,
+or you can do `npm explore <pkgname> -- npm install` to install the
+dependencies into the submodule folder.
+
+## SEE ALSO
+
+* npm help json
+* git help submodule
diff --git a/doc/api/npm-tag.md b/doc/api/npm-tag.md
new file mode 100644
index 0000000..b5a3d7f
--- /dev/null
+++ b/doc/api/npm-tag.md
@@ -0,0 +1,23 @@
+npm-tag(3) -- Tag a published version
+=====================================
+
+## SYNOPSIS
+
+ npm.commands.tag(package@version, tag, callback)
+
+## DESCRIPTION
+
+Tags the specified version of the package with the specified tag, or the
+`--tag` config if not specified.
+
+The 'package@version' is an array of strings, but only the first two elements are
+currently used.
+
+The first element must be in the form package@version, where package
+is the package name and version is the version number (much like installing a
+specific version).
+
+The second element is the name of the tag to tag this version with. If this
+parameter is missing or falsey (empty), the default froom the config will be
+used. For more information about how to set this config, check
+`man 3 npm-config` for programmatic usage or `man npm-config` for cli usage.
diff --git a/doc/api/npm-test.md b/doc/api/npm-test.md
new file mode 100644
index 0000000..bc48dcc
--- /dev/null
+++ b/doc/api/npm-test.md
@@ -0,0 +1,16 @@
+npm-test(3) -- Test a package
+=============================
+
+## SYNOPSIS
+
+ npm.commands.test(packages, callback)
+
+## DESCRIPTION
+
+This runs a package's "test" script, if one was provided.
+
+To run tests as a condition of installation, set the `npat` config to
+true.
+
+npm can run tests on multiple packages. Just specify multiple packages
+in the `packages` parameter.
diff --git a/doc/api/npm-uninstall.md b/doc/api/npm-uninstall.md
new file mode 100644
index 0000000..4505295
--- /dev/null
+++ b/doc/api/npm-uninstall.md
@@ -0,0 +1,16 @@
+npm-uninstall(3) -- uninstall a package programmatically
+========================================================
+
+## SYNOPSIS
+
+ npm.commands.uninstall(packages, callback)
+
+## DESCRIPTION
+
+This acts much the same ways as uninstalling on the command-line.
+
+The 'packages' parameter is an array of strings. Each element in the array is
+the name of a package to be uninstalled.
+
+Finally, 'callback' is a function that will be called when all packages have been
+uninstalled or when an error has been encountered.
diff --git a/doc/api/npm-unpublish.md b/doc/api/npm-unpublish.md
new file mode 100644
index 0000000..6cbc5c1
--- /dev/null
+++ b/doc/api/npm-unpublish.md
@@ -0,0 +1,20 @@
+npm-unpublish(3) -- Remove a package from the registry
+======================================================
+
+## SYNOPSIS
+
+ npm.commands.unpublish(package, callback)
+
+## DESCRIPTION
+
+This removes a package version from the registry, deleting its
+entry and removing the tarball.
+
+The package parameter must be defined.
+
+Only the first element in the package parameter is used. If there is no first
+element, then npm assumes that the package at the current working directory
+is what is meant.
+
+If no version is specified, or if all versions are removed then
+the root package entry is removed from the registry entirely.
diff --git a/doc/api/npm-update.md b/doc/api/npm-update.md
new file mode 100644
index 0000000..bf02fd3
--- /dev/null
+++ b/doc/api/npm-update.md
@@ -0,0 +1,11 @@
+npm-update(3) -- Update a package
+=================================
+
+## SYNOPSIS
+ npm.commands.update(packages, callback)
+
+# DESCRIPTION
+
+Updates a package, upgrading it to the latest version. It also installs any missing packages.
+
+The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.
diff --git a/doc/api/npm-version.md b/doc/api/npm-version.md
new file mode 100644
index 0000000..bd40102
--- /dev/null
+++ b/doc/api/npm-version.md
@@ -0,0 +1,18 @@
+npm-version(3) -- Bump a package version
+========================================
+
+## SYNOPSIS
+
+ npm.commands.version(newversion, callback)
+
+## DESCRIPTION
+
+Run this in a package directory to bump the version and write the new
+data back to the package.json file.
+
+If run in a git repo, it will also create a version commit and tag, and
+fail if the repo is not clean.
+
+Like all other commands, this function takes a string array as its first
+parameter. The difference, however, is this function will fail if it does
+not have exactly one element. The only element should be a version number.
diff --git a/doc/api/npm-view.md b/doc/api/npm-view.md
new file mode 100644
index 0000000..fd0076c
--- /dev/null
+++ b/doc/api/npm-view.md
@@ -0,0 +1,93 @@
+npm-view(3) -- View registry info
+=================================
+
+## SYNOPSIS
+
+ npm.commands.view(args, [silent,] callback)
+
+## DESCRIPTION
+
+This command shows data about a package and prints it to the stream
+referenced by the `outfd` config, which defaults to stdout.
+
+The "args" parameter is an ordered list that closely resembles the command-line
+usage. The elements should be ordered such that the first element is
+the package and version (package@version). The version is optional. After that,
+the rest of the parameters are fields with optional subfields ("field.subfield")
+which can be used to get only the information desired from the registry.
+
+The callback will be passed all of the data returned by the query.
+
+For example, to get the package registry entry for the `connect` package,
+you can do this:
+
+ npm.commands.view(["connect"], callback)
+
+If no version is specified, "latest" is assumed.
+
+Field names can be specified after the package descriptor.
+For example, to show the dependencies of the `ronn` package at version
+0.3.5, you could do the following:
+
+ npm.commands.view(["ronn@0.3.5", "dependencies"], callback)
+
+You can view child field by separating them with a period.
+To view the git repository URL for the latest version of npm, you could
+do this:
+
+ npm.commands.view(["npm", "repository.url"], callback)
+
+For fields that are arrays, requesting a non-numeric field will return
+all of the values from the objects in the list. For example, to get all
+the contributor names for the "express" project, you can do this:
+
+ npm.commands.view(["express", "contributors.email"], callback)
+
+You may also use numeric indices in square braces to specifically select
+an item in an array field. To just get the email address of the first
+contributor in the list, you can do this:
+
+ npm.commands.view(["express", "contributors[0].email"], callback)
+
+Multiple fields may be specified, and will be printed one after another.
+For exampls, to get all the contributor names and email addresses, you
+can do this:
+
+ npm.commands.view(["express", "contributors.name", "contributors.email"], callback)
+
+"Person" fields are shown as a string if they would be shown as an
+object. So, for example, this will show the list of npm contributors in
+the shortened string format. (See `npm help json` for more on this.)
+
+ npm.commands.view(["npm", "contributors"], callback)
+
+If a version range is provided, then data will be printed for every
+matching version of the package. This will show which version of jsdom
+was required by each matching version of yui3:
+
+ npm.commands.view(["yui3@'>0.5.4'", "dependencies.jsdom"], callback)
+
+## OUTPUT
+
+If only a single string field for a single version is output, then it
+will not be colorized or quoted, so as to enable piping the output to
+another command.
+
+If the version range matches multiple versions, than each printed value
+will be prefixed with the version it applies to.
+
+If multiple fields are requested, than each of them are prefixed with
+the field name.
+
+Console output can be disabled by setting the 'silent' parameter to true.
+
+## RETURN VALUE
+
+The data returned will be an object in this formation:
+
+ { <version>:
+ { <field>: <value>
+ , ... }
+ , ... }
+
+corresponding to the list of fields selected.
diff --git a/doc/api/npm-whoami.md b/doc/api/npm-whoami.md
new file mode 100644
index 0000000..598a1ab
--- /dev/null
+++ b/doc/api/npm-whoami.md
@@ -0,0 +1,15 @@
+npm-whoami(3) -- Display npm username
+=====================================
+
+## SYNOPSIS
+
+ npm.commands.whoami(args, callback)
+
+## DESCRIPTION
+
+Print the `username` config to standard output.
+
+'args' is never used and callback is never called with data.
+'args' must be present or things will break.
+
+This function is not useful programmatically
diff --git a/doc/api/npm.md b/doc/api/npm.md
new file mode 100644
index 0000000..d05684e
--- /dev/null
+++ b/doc/api/npm.md
@@ -0,0 +1,116 @@
+npm(3) -- node package manager
+==============================
+
+## SYNOPSIS
+
+ var npm = require("npm")
+ npm.load([configObject, ]function (er, npm) {
+ // use the npm object, now that it's loaded.
+
+ npm.config.set(key, val)
+ val = npm.config.get(key)
+
+ console.log("prefix = %s", npm.prefix)
+
+ npm.commands.install(["package"], cb)
+ })
+
+## VERSION
+
+@VERSION@
+
+## DESCRIPTION
+
+This is the API documentation for npm.
+To find documentation of the command line
+client, see `npm(1)`.
+
+Prior to using npm's commands, `npm.load()` must be called.
+If you provide `configObject` as an object hash of top-level
+configs, they override the values stored in the various config
+locations. In the npm command line client, this set of configs
+is parsed from the command line options. Additional configuration
+params are loaded from two configuration files. See `npm-config(1)`,
+`npm-config(7)`, and `npmrc(5)` for more information.
+
+After that, each of the functions are accessible in the
+commands object: `npm.commands.<cmd>`. See `npm-index(7)` for a list of
+all possible commands.
+
+All commands on the command object take an **array** of positional argument
+**strings**. The last argument to any function is a callback. Some
+commands take other optional arguments.
+
+Configs cannot currently be set on a per function basis, as each call to
+npm.config.set will change the value for *all* npm commands in that process.
+
+To find API documentation for a specific command, run the `npm apihelp`
+command.
+
+## METHODS AND PROPERTIES
+
+* `npm.load(configs, cb)`
+
+ Load the configuration params, and call the `cb` function once the
+ globalconfig and userconfig files have been loaded as well, or on
+ nextTick if they've already been loaded.
+
+* `npm.config`
+
+ An object for accessing npm configuration parameters.
+
+ * `npm.config.get(key)`
+ * `npm.config.set(key, val)`
+ * `npm.config.del(key)`
+
+* `npm.dir` or `npm.root`
+
+ The `node_modules` directory where npm will operate.
+
+* `npm.prefix`
+
+ The prefix where npm is operating. (Most often the current working
+ directory.)
+
+* `npm.cache`
+
+ The place where npm keeps JSON and tarballs it fetches from the
+ registry (or uploads to the registry).
+
+* `npm.tmp`
+
+ npm's temporary working directory.
+
+* `npm.deref`
+
+ Get the "real" name for a command that has either an alias or
+ abbreviation.
+
+## MAGIC
+
+For each of the methods in the `npm.commands` hash, a method is added to
+the npm object, which takes a set of positional string arguments rather
+than an array and a callback.
+
+If the last argument is a callback, then it will use the supplied
+callback. However, if no callback is provided, then it will print out
+the error or results.
+
+For example, this would work in a node repl:
+
+ > npm = require("npm")
+ > npm.load() // wait a sec...
+ > npm.install("dnode", "express")
+
+Note that that *won't* work in a node program, since the `install`
+method will get called before the configuration load is completed.
+
+## ABBREVS
+
+In order to support `npm ins foo` instead of `npm install foo`, the
+`npm.commands` object has a set of abbreviations as well as the full
+method names. Use the `npm.deref` method to find the real name.
+
+For example:
+
+ var cmd = npm.deref("unp") // cmd === "unpublish"
diff --git a/doc/cli/npm-adduser.md b/doc/cli/npm-adduser.md
new file mode 100644
index 0000000..68f3a3c
--- /dev/null
+++ b/doc/cli/npm-adduser.md
@@ -0,0 +1,38 @@
+npm-adduser(1) -- Add a registry user account
+=============================================
+
+## SYNOPSIS
+
+ npm adduser
+
+## DESCRIPTION
+
+Create or verify a user named `<username>` in the npm registry, and
+save the credentials to the `.npmrc` file.
+
+The username, password, and email are read in from prompts.
+
+You may use this command to change your email address, but not username
+or password.
+
+To reset your password, go to <https://npmjs.org/forgot>
+
+You may use this command multiple times with the same user account to
+authorize on a new machine.
+
+## CONFIGURATION
+
+### registry
+
+Default: http://registry.npmjs.org/
+
+The base URL of the npm package registry.
+
+## SEE ALSO
+
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-owner(1)
+* npm-whoami(1)
diff --git a/doc/cli/npm-bin.md b/doc/cli/npm-bin.md
new file mode 100644
index 0000000..33863b4
--- /dev/null
+++ b/doc/cli/npm-bin.md
@@ -0,0 +1,19 @@
+npm-bin(1) -- Display npm bin folder
+====================================
+
+## SYNOPSIS
+
+ npm bin
+
+## DESCRIPTION
+
+Print the folder where npm will install executables.
+
+## SEE ALSO
+
+* npm-prefix(1)
+* npm-root(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-bugs.md b/doc/cli/npm-bugs.md
new file mode 100644
index 0000000..002d9f7
--- /dev/null
+++ b/doc/cli/npm-bugs.md
@@ -0,0 +1,42 @@
+npm-bugs(1) -- Bugs for a package in a web browser maybe
+========================================================
+
+## SYNOPSIS
+
+ npm bugs <pkgname>
+ npm bugs (with no args in a package dir)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+bug tracker URL, and then tries to open it using the `--browser`
+config param. If no package name is provided, it will search for
+a `package.json` in the current folder and use the `name` property.
+
+## CONFIGURATION
+
+### browser
+
+* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"`
+* Type: String
+
+The browser that is called by the `npm bugs` command to open websites.
+
+### registry
+
+* Default: https://registry.npmjs.org/
+* Type: url
+
+The base URL of the npm package registry.
+
+
+## SEE ALSO
+
+* npm-docs(1)
+* npm-view(1)
+* npm-publish(1)
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* package.json(5)
diff --git a/doc/cli/npm-build.md b/doc/cli/npm-build.md
new file mode 100644
index 0000000..53813c1
--- /dev/null
+++ b/doc/cli/npm-build.md
@@ -0,0 +1,22 @@
+npm-build(1) -- Build a package
+===============================
+
+## SYNOPSIS
+
+ npm build <package-folder>
+
+* `<package-folder>`:
+ A folder containing a `package.json` file in its root.
+
+## DESCRIPTION
+
+This is the plumbing command called by `npm link` and `npm install`.
+
+It should generally not be called directly.
+
+## SEE ALSO
+
+* npm-install(1)
+* npm-link(1)
+* npm-scripts(7)
+* package.json(5)
diff --git a/doc/cli/npm-bundle.md b/doc/cli/npm-bundle.md
new file mode 100644
index 0000000..69b3d83
--- /dev/null
+++ b/doc/cli/npm-bundle.md
@@ -0,0 +1,14 @@
+npm-bundle(1) -- REMOVED
+========================
+
+## DESCRIPTION
+
+The `npm bundle` command has been removed in 1.0, for the simple reason
+that it is no longer necessary, as the default behavior is now to
+install packages into the local space.
+
+Just use `npm install` now to do what `npm bundle` used to do.
+
+## SEE ALSO
+
+* npm-install(1)
diff --git a/doc/cli/npm-cache.md b/doc/cli/npm-cache.md
new file mode 100644
index 0000000..03b5902
--- /dev/null
+++ b/doc/cli/npm-cache.md
@@ -0,0 +1,70 @@
+npm-cache(1) -- Manipulates packages cache
+==========================================
+
+## SYNOPSIS
+
+ npm cache add <tarball file>
+ npm cache add <folder>
+ npm cache add <tarball url>
+ npm cache add <name>@<version>
+
+ npm cache ls [<path>]
+
+ npm cache clean [<path>]
+
+## DESCRIPTION
+
+Used to add, list, or clear the npm cache folder.
+
+* add:
+ Add the specified package to the local cache. This command is primarily
+ intended to be used internally by npm, but it can provide a way to
+ add data to the local installation cache explicitly.
+
+* ls:
+ Show the data in the cache. Argument is a path to show in the cache
+ folder. Works a bit like the `find` program, but limited by the
+ `depth` config.
+
+* clean:
+ Delete data out of the cache folder. If an argument is provided, then
+ it specifies a subpath to delete. If no argument is provided, then
+ the entire cache is cleared.
+
+## DETAILS
+
+npm stores cache data in the directory specified in `npm config get cache`.
+For each package that is added to the cache, three pieces of information are
+stored in `{cache}/{name}/{version}`:
+
+* .../package/package.json:
+ The package.json file, as npm sees it.
+* .../package.tgz:
+ The tarball for that version.
+
+Additionally, whenever a registry request is made, a `.cache.json` file
+is placed at the corresponding URI, to store the ETag and the requested
+data. This is stored in `{cache}/{hostname}/{path}/.cache.json`.
+
+Commands that make non-essential registry requests (such as `search` and
+`view`, or the completion scripts) generally specify a minimum timeout.
+If the `.cache.json` file is younger than the specified timeout, then
+they do not make an HTTP request to the registry.
+
+## CONFIGURATION
+
+### cache
+
+Default: `~/.npm` on Posix, or `%AppData%/npm-cache` on Windows.
+
+The root cache folder.
+
+## SEE ALSO
+
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-install(1)
+* npm-publish(1)
+* npm-pack(1)
diff --git a/doc/cli/npm-completion.md b/doc/cli/npm-completion.md
new file mode 100644
index 0000000..bec0f60
--- /dev/null
+++ b/doc/cli/npm-completion.md
@@ -0,0 +1,29 @@
+npm-completion(1) -- Tab Completion for npm
+===========================================
+
+## SYNOPSIS
+
+ . <(npm completion)
+
+## DESCRIPTION
+
+Enables tab-completion in all npm commands.
+
+The synopsis above
+loads the completions into your current shell. Adding it to
+your ~/.bashrc or ~/.zshrc will make the completions available
+everywhere.
+
+You may of course also pipe the output of npm completion to a file
+such as `/usr/local/etc/bash_completion.d/npm` if you have a system
+that will read that file for you.
+
+When `COMP_CWORD`, `COMP_LINE`, and `COMP_POINT` are defined in the
+environment, `npm completion` acts in "plumbing mode", and outputs
+completions based on the arguments.
+
+## SEE ALSO
+
+* npm-developers(7)
+* npm-faq(7)
+* npm(1)
diff --git a/doc/cli/npm-config.md b/doc/cli/npm-config.md
new file mode 100644
index 0000000..1d978c9
--- /dev/null
+++ b/doc/cli/npm-config.md
@@ -0,0 +1,71 @@
+npm-config(1) -- Manage the npm configuration files
+===================================================
+
+## SYNOPSIS
+
+ npm config set <key> <value> [--global]
+ npm config get <key>
+ npm config delete <key>
+ npm config list
+ npm config edit
+ npm c [set|get|delete|list]
+ npm get <key>
+ npm set <key> <value> [--global]
+
+## DESCRIPTION
+
+npm gets its config settings from the command line, environment
+variables, `npmrc` files, and in some cases, the `package.json` file.
+
+See npmrc(5) for more information about the npmrc files.
+
+See `npm-config(7)` for a more thorough discussion of the mechanisms
+involved.
+
+The `npm config` command can be used to update and edit the contents
+of the user and global npmrc files.
+
+## Sub-commands
+
+Config supports the following sub-commands:
+
+### set
+
+ npm config set key value
+
+Sets the config key to the value.
+
+If value is omitted, then it sets it to "true".
+
+### get
+
+ npm config get key
+
+Echo the config value to stdout.
+
+### list
+
+ npm config list
+
+Show all the config settings.
+
+### delete
+
+ npm config delete key
+
+Deletes the key from all configuration files.
+
+### edit
+
+ npm config edit
+
+Opens the config file in an editor. Use the `--global` flag to edit the
+global config.
+
+## SEE ALSO
+
+* npm-folders(5)
+* npm-config(7)
+* package.json(5)
+* npmrc(5)
+* npm(1)
diff --git a/doc/cli/npm-dedupe.md b/doc/cli/npm-dedupe.md
new file mode 100644
index 0000000..d3be010
--- /dev/null
+++ b/doc/cli/npm-dedupe.md
@@ -0,0 +1,58 @@
+npm-dedupe(1) -- Reduce duplication
+===================================
+
+## SYNOPSIS
+
+ npm dedupe [package names...]
+ npm ddp [package names...]
+
+## DESCRIPTION
+
+Searches the local package tree and attempts to simplify the overall
+structure by moving dependencies further up the tree, where they can
+be more effectively shared by multiple dependent packages.
+
+For example, consider this dependency graph:
+
+ a
+ +-- b <-- depends on c@1.0.x
+ | `-- c@1.0.3
+ `-- d <-- depends on c@~1.0.9
+ `-- c@1.0.10
+
+In this case, `npm-dedupe(1)` will transform the tree to:
+
+ a
+ +-- b
+ +-- d
+ `-- c@1.0.10
+
+Because of the hierarchical nature of node's module lookup, b and d
+will both get their dependency met by the single c package at the root
+level of the tree.
+
+If a suitable version exists at the target location in the tree
+already, then it will be left untouched, but the other duplicates will
+be deleted.
+
+If no suitable version can be found, then a warning is printed, and
+nothing is done.
+
+If any arguments are supplied, then they are filters, and only the
+named packages will be touched.
+
+Note that this operation transforms the dependency tree, and may
+result in packages getting updated versions, perhaps from the npm
+registry.
+
+This feature is experimental, and may change in future versions.
+
+The `--tag` argument will apply to all of the affected dependencies. If a
+tag with the given name exists, the tagged version is preferred over newer
+versions.
+
+## SEE ALSO
+
+* npm-ls(1)
+* npm-update(1)
+* npm-install(1)
diff --git a/doc/cli/npm-deprecate.md b/doc/cli/npm-deprecate.md
new file mode 100644
index 0000000..e625793
--- /dev/null
+++ b/doc/cli/npm-deprecate.md
@@ -0,0 +1,26 @@
+npm-deprecate(1) -- Deprecate a version of a package
+====================================================
+
+## SYNOPSIS
+
+ npm deprecate <name>[@<version>] <message>
+
+## DESCRIPTION
+
+This command will update the npm registry entry for a package, providing
+a deprecation warning to all who attempt to install it.
+
+It works on version ranges as well as specific versions, so you can do
+something like this:
+
+ npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3"
+
+Note that you must be the package owner to deprecate something. See the
+`owner` and `adduser` help topics.
+
+To un-deprecate a package, specify an empty string (`""`) for the `message` argument.
+
+## SEE ALSO
+
+* npm-publish(1)
+* npm-registry(7)
diff --git a/doc/cli/npm-docs.md b/doc/cli/npm-docs.md
new file mode 100644
index 0000000..5db3d9f
--- /dev/null
+++ b/doc/cli/npm-docs.md
@@ -0,0 +1,44 @@
+npm-docs(1) -- Docs for a package in a web browser maybe
+========================================================
+
+## SYNOPSIS
+
+ npm docs [<pkgname> [<pkgname> ...]]
+ npm docs (with no args in a package dir)
+ npm home [<pkgname> [<pkgname> ...]]
+ npm home (with no args in a package dir)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+documentation URL, and then tries to open it using the `--browser`
+config param. You can pass multiple package names at once. If no
+package name is provided, it will search for a `package.json` in
+the current folder and use the `name` property.
+
+## CONFIGURATION
+
+### browser
+
+* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"`
+* Type: String
+
+The browser that is called by the `npm docs` command to open websites.
+
+### registry
+
+* Default: https://registry.npmjs.org/
+* Type: url
+
+The base URL of the npm package registry.
+
+
+## SEE ALSO
+
+* npm-view(1)
+* npm-publish(1)
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* package.json(5)
diff --git a/doc/cli/npm-edit.md b/doc/cli/npm-edit.md
new file mode 100644
index 0000000..6a73317
--- /dev/null
+++ b/doc/cli/npm-edit.md
@@ -0,0 +1,37 @@
+npm-edit(1) -- Edit an installed package
+========================================
+
+## SYNOPSIS
+
+ npm edit <name>[@<version>]
+
+## DESCRIPTION
+
+Opens the package folder in the default editor (or whatever you've
+configured as the npm `editor` config -- see `npm-config(7)`.)
+
+After it has been edited, the package is rebuilt so as to pick up any
+changes in compiled packages.
+
+For instance, you can do `npm install connect` to install connect
+into your package, and then `npm edit connect` to make a few
+changes to your locally installed copy.
+
+## CONFIGURATION
+
+### editor
+
+* Default: `EDITOR` environment variable if set, or `"vi"` on Posix,
+ or `"notepad"` on Windows.
+* Type: path
+
+The command to run for `npm edit` or `npm config edit`.
+
+## SEE ALSO
+
+* npm-folders(5)
+* npm-explore(1)
+* npm-install(1)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-explore.md b/doc/cli/npm-explore.md
new file mode 100644
index 0000000..3642d73
--- /dev/null
+++ b/doc/cli/npm-explore.md
@@ -0,0 +1,40 @@
+npm-explore(1) -- Browse an installed package
+=============================================
+
+## SYNOPSIS
+
+ npm explore <name> [ -- <cmd>]
+
+## DESCRIPTION
+
+Spawn a subshell in the directory of the installed package specified.
+
+If a command is specified, then it is run in the subshell, which then
+immediately terminates.
+
+This is particularly handy in the case of git submodules in the
+`node_modules` folder:
+
+ npm explore some-dependency -- git pull origin master
+
+Note that the package is *not* automatically rebuilt afterwards, so be
+sure to use `npm rebuild <pkg>` if you make any changes.
+
+## CONFIGURATION
+
+### shell
+
+* Default: SHELL environment variable, or "bash" on Posix, or "cmd" on
+ Windows
+* Type: path
+
+The shell to run for the `npm explore` command.
+
+## SEE ALSO
+
+* npm-submodule(1)
+* npm-folders(5)
+* npm-edit(1)
+* npm-rebuild(1)
+* npm-build(1)
+* npm-install(1)
diff --git a/doc/cli/npm-help-search.md b/doc/cli/npm-help-search.md
new file mode 100644
index 0000000..7bf7401
--- /dev/null
+++ b/doc/cli/npm-help-search.md
@@ -0,0 +1,35 @@
+npm-help-search(1) -- Search npm help documentation
+===================================================
+
+## SYNOPSIS
+
+ npm help-search some search terms
+
+## DESCRIPTION
+
+This command will search the npm markdown documentation files for the
+terms provided, and then list the results, sorted by relevance.
+
+If only one result is found, then it will show that help topic.
+
+If the argument to `npm help` is not a known help topic, then it will
+call `help-search`. It is rarely if ever necessary to call this
+command directly.
+
+## CONFIGURATION
+
+### long
+
+* Type: Boolean
+* Default false
+
+If true, the "long" flag will cause help-search to output context around
+where the terms were found in the documentation.
+
+If false, then help-search will just list out the help topics found.
+
+## SEE ALSO
+
+* npm(1)
+* npm-faq(7)
+* npm-help(1)
diff --git a/doc/cli/npm-help.md b/doc/cli/npm-help.md
new file mode 100644
index 0000000..7991b1d
--- /dev/null
+++ b/doc/cli/npm-help.md
@@ -0,0 +1,40 @@
+npm-help(1) -- Get help on npm
+==============================
+
+## SYNOPSIS
+
+ npm help <topic>
+ npm help some search terms
+
+## DESCRIPTION
+
+If supplied a topic, then show the appropriate documentation page.
+
+If the topic does not exist, or if multiple terms are provided, then run
+the `help-search` command to find a match. Note that, if `help-search`
+finds a single subject, then it will run `help` on that topic, so unique
+matches are equivalent to specifying a topic name.
+
+## CONFIGURATION
+
+### viewer
+
+* Default: "man" on Posix, "browser" on Windows
+* Type: path
+
+The program to use to view help content.
+
+Set to `"browser"` to view html help content in the default web browser.
+
+## SEE ALSO
+
+* npm(1)
+* README
+* npm-faq(7)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* package.json(5)
+* npm-help-search(1)
+* npm-index(7)
diff --git a/doc/cli/npm-init.md b/doc/cli/npm-init.md
new file mode 100644
index 0000000..bd63a88
--- /dev/null
+++ b/doc/cli/npm-init.md
@@ -0,0 +1,25 @@
+npm-init(1) -- Interactively create a package.json file
+=======================================================
+
+## SYNOPSIS
+
+ npm init
+
+## DESCRIPTION
+
+This will ask you a bunch of questions, and then write a package.json for you.
+
+It attempts to make reasonable guesses about what you want things to be set to,
+and then writes a package.json file with the options you've selected.
+
+If you already have a package.json file, it'll read that first, and default to
+the options in there.
+
+It is strictly additive, so it does not delete options from your package.json
+without a really good reason to do so.
+
+## SEE ALSO
+
+* <https://github.com/isaacs/init-package-json>
+* package.json(5)
+* npm-version(1)
diff --git a/doc/cli/npm-install.md b/doc/cli/npm-install.md
new file mode 100644
index 0000000..62eec2d
--- /dev/null
+++ b/doc/cli/npm-install.md
@@ -0,0 +1,259 @@
+npm-install(1) -- Install a package
+===================================
+
+## SYNOPSIS
+
+ npm install (with no args in a package dir)
+ npm install <tarball file>
+ npm install <tarball url>
+ npm install <folder>
+ npm install <name> [--save|--save-dev|--save-optional] [--save-exact]
+ npm install <name>@<tag>
+ npm install <name>@<version>
+ npm install <name>@<version range>
+ npm i (with any of the previous argument usage)
+
+## DESCRIPTION
+
+This command installs a package, and any packages that it depends on. If the
+package has a shrinkwrap file, the installation of dependencies will be driven
+by that. See npm-shrinkwrap(1).
+
+A `package` is:
+
+* a) a folder containing a program described by a package.json file
+* b) a gzipped tarball containing (a)
+* c) a url that resolves to (b)
+* d) a `<name>@<version>` that is published on the registry (see `npm-registry(7)`) with (c)
+* e) a `<name>@<tag>` that points to (d)
+* f) a `<name>` that has a "latest" tag satisfying (e)
+* g) a `<git remote url>` that resolves to (b)
+
+Even if you never publish your package, you can still get a lot of
+benefits of using npm if you just want to write a node program (a), and
+perhaps if you also want to be able to easily install it elsewhere
+after packing it up into a tarball (b).
+
+
+* `npm install` (in package directory, no arguments):
+
+ Install the dependencies in the local node_modules folder.
+
+ In global mode (ie, with `-g` or `--global` appended to the command),
+ it installs the current package context (ie, the current working
+ directory) as a global package.
+
+ By default, `npm install` will install all modules listed as
+ dependencies. With the `--production` flag,
+ npm will not install modules listed in `devDependencies`.
+
+* `npm install <folder>`:
+
+ Install a package that is sitting in a folder on the filesystem.
+
+* `npm install <tarball file>`:
+
+ Install a package that is sitting on the filesystem. Note: if you just want
+ to link a dev directory into your npm root, you can do this more easily by
+ using `npm link`.
+
+ Example:
+
+ npm install ./package.tgz
+
+* `npm install <tarball url>`:
+
+ Fetch the tarball url, and then install it. In order to distinguish between
+ this and other options, the argument must start with "http://" or "https://"
+
+ Example:
+
+ npm install https://github.com/indexzero/forever/tarball/v0.5.6
+
+* `npm install <name> [--save|--save-dev|--save-optional]`:
+
+ Do a `<name>@<tag>` install, where `<tag>` is the "tag" config. (See
+ `npm-config(7)`.)
+
+ In most cases, this will install the latest version
+ of the module published on npm.
+
+ Example:
+
+ npm install sax
+
+ `npm install` takes 3 exclusive, optional flags which save or update
+ the package version in your main package.json:
+
+ * `--save`: Package will appear in your `dependencies`.
+
+ * `--save-dev`: Package will appear in your `devDependencies`.
+
+ * `--save-optional`: Package will appear in your `optionalDependencies`.
+
+ When using any of the above options to save dependencies to your
+ package.json, there is an additional, optional flag:
+
+ * `--save-exact`: Saved dependencies will be configured with an
+ exact version rather than using npm's default semver range
+ operator.
+
+ Examples:
+
+ npm install sax --save
+ npm install node-tap --save-dev
+ npm install dtrace-provider --save-optional
+ npm install readable-stream --save --save-exact
+
+
+ **Note**: If there is a file or folder named `<name>` in the current
+ working directory, then it will try to install that, and only try to
+ fetch the package by name if it is not valid.
+
+* `npm install <name>@<tag>`:
+
+ Install the version of the package that is referenced by the specified tag.
+ If the tag does not exist in the registry data for that package, then this
+ will fail.
+
+ Example:
+
+ npm install sax@latest
+
+* `npm install <name>@<version>`:
+
+ Install the specified version of the package. This will fail if the version
+ has not been published to the registry.
+
+ Example:
+
+ npm install sax@0.1.1
+
+* `npm install <name>@<version range>`:
+
+ Install a version of the package matching the specified version range. This
+ will follow the same rules for resolving dependencies described in `package.json(5)`.
+
+ Note that most version ranges must be put in quotes so that your shell will
+ treat it as a single argument.
+
+ Example:
+
+ npm install sax@">=0.1.0 <0.2.0"
+
+* `npm install <git remote url>`:
+
+ Install a package by cloning a git remote url. The format of the git
+ url is:
+
+ <protocol>://[<user>@]<hostname><separator><path>[#<commit-ish>]
+
+ `<protocol>` is one of `git`, `git+ssh`, `git+http`, or
+ `git+https`. If no `<commit-ish>` is specified, then `master` is
+ used.
+
+ Examples:
+
+ git+ssh://git@github.com:npm/npm.git#v1.0.27
+ git+https://isaacs@github.com/npm/npm.git
+ git://github.com/npm/npm.git#v1.0.27
+
+You may combine multiple arguments, and even multiple types of arguments.
+For example:
+
+ npm install sax@">=0.1.0 <0.2.0" bench supervisor
+
+The `--tag` argument will apply to all of the specified install targets. If a
+tag with the given name exists, the tagged version is preferred over newer
+versions.
+
+The `--force` argument will force npm to fetch remote resources even if a
+local copy exists on disk.
+
+ npm install sax --force
+
+The `--global` argument will cause npm to install the package globally
+rather than locally. See `npm-folders(5)`.
+
+The `--link` argument will cause npm to link global installs into the
+local space in some cases.
+
+The `--no-bin-links` argument will prevent npm from creating symlinks for
+any binaries the package might contain.
+
+The `--no-optional` argument will prevent optional dependencies from
+being installed.
+
+The `--no-shrinkwrap` argument, which will ignore an available
+shrinkwrap file and use the package.json instead.
+
+The `--nodedir=/path/to/node/source` argument will allow npm to find the
+node source code so that npm can compile native modules.
+
+See `npm-config(7)`. Many of the configuration params have some
+effect on installation, since that's most of what npm does.
+
+## ALGORITHM
+
+To install a package, npm uses the following algorithm:
+
+ install(where, what, family, ancestors)
+ fetch what, unpack to <where>/node_modules/<what>
+ for each dep in what.dependencies
+ resolve dep to precise version
+ for each dep@version in what.dependencies
+ not in <where>/node_modules/<what>/node_modules/*
+ and not in <family>
+ add precise version deps to <family>
+ install(<where>/node_modules/<what>, dep, family)
+
+For this `package{dep}` structure: `A{B,C}, B{C}, C{D}`,
+this algorithm produces:
+
+ A
+ +-- B
+ `-- C
+ `-- D
+
+That is, the dependency from B to C is satisfied by the fact that A
+already caused C to be installed at a higher level.
+
+See npm-folders(5) for a more detailed description of the specific
+folder structures that npm creates.
+
+### Limitations of npm's Install Algorithm
+
+There are some very rare and pathological edge-cases where a cycle can
+cause npm to try to install a never-ending tree of packages. Here is
+the simplest case:
+
+ A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ...
+
+where `A` is some version of a package, and `A'` is a different version
+of the same package. Because `B` depends on a different version of `A`
+than the one that is already in the tree, it must install a separate
+copy. The same is true of `A'`, which must install `B'`. Because `B'`
+depends on the original version of `A`, which has been overridden, the
+cycle falls into infinite regress.
+
+To avoid this situation, npm flat-out refuses to install any
+`name@version` that is already present anywhere in the tree of package
+folder ancestors. A more correct, but more complex, solution would be
+to symlink the existing version into the new location. If this ever
+affects a real use-case, it will be investigated.
+
+## SEE ALSO
+
+* npm-folders(5)
+* npm-update(1)
+* npm-link(1)
+* npm-rebuild(1)
+* npm-scripts(7)
+* npm-build(1)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-registry(7)
+* npm-tag(1)
+* npm-rm(1)
+* npm-shrinkwrap(1)
diff --git a/doc/cli/npm-link.md b/doc/cli/npm-link.md
new file mode 100644
index 0000000..c0fc01e
--- /dev/null
+++ b/doc/cli/npm-link.md
@@ -0,0 +1,63 @@
+npm-link(1) -- Symlink a package folder
+=======================================
+
+## SYNOPSIS
+
+ npm link (in package folder)
+ npm link <pkgname>
+ npm ln (with any of the previous argument usage)
+
+## DESCRIPTION
+
+Package linking is a two-step process.
+
+First, `npm link` in a package folder will create a globally-installed
+symbolic link from `prefix/package-name` to the current folder.
+
+Next, in some other location, `npm link package-name` will create a
+symlink from the local `node_modules` folder to the global symlink.
+
+Note that `package-name` is taken from `package.json`,
+not from directory name.
+
+When creating tarballs for `npm publish`, the linked packages are
+"snapshotted" to their current state by resolving the symbolic links.
+
+This is
+handy for installing your own stuff, so that you can work on it and test it
+iteratively without having to continually rebuild.
+
+For example:
+
+ cd ~/projects/node-redis # go into the package directory
+ npm link # creates global link
+ cd ~/projects/node-bloggy # go into some other package directory.
+ npm link redis # link-install the package
+
+Now, any changes to ~/projects/node-redis will be reflected in
+~/projects/node-bloggy/node_modules/redis/
+
+You may also shortcut the two steps in one. For example, to do the
+above use-case in a shorter way:
+
+ cd ~/projects/node-bloggy # go into the dir of your main project
+ npm link ../node-redis # link the dir of your dependency
+
+The second line is the equivalent of doing:
+
+ (cd ../node-redis; npm link)
+ npm link redis
+
+That is, it first creates a global link, and then links the global
+installation target into your project's `node_modules` folder.
+
+## SEE ALSO
+
+* npm-developers(7)
+* npm-faq(7)
+* package.json(5)
+* npm-install(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-ls.md b/doc/cli/npm-ls.md
new file mode 100644
index 0000000..21f5426
--- /dev/null
+++ b/doc/cli/npm-ls.md
@@ -0,0 +1,80 @@
+npm-ls(1) -- List installed packages
+======================================
+
+## SYNOPSIS
+
+ npm list [<pkg> ...]
+ npm ls [<pkg> ...]
+ npm la [<pkg> ...]
+ npm ll [<pkg> ...]
+
+## DESCRIPTION
+
+This command will print to stdout all the versions of packages that are
+installed, as well as their dependencies, in a tree-structure.
+
+Positional arguments are `name@version-range` identifiers, which will
+limit the results to only the paths to the packages named. Note that
+nested packages will *also* show the paths to the specified packages.
+For example, running `npm ls promzard` in npm's source tree will show:
+
+ npm@@VERSION@ /path/to/npm
+ └─┬ init-package-json@0.0.4
+ └── promzard@0.1.5
+
+It will print out extraneous, missing, and invalid packages.
+
+If a project specifies git urls for dependencies these are shown
+in parentheses after the name@version to make it easier for users to
+recognize potential forks of a project.
+
+When run as `ll` or `la`, it shows extended information by default.
+
+## CONFIGURATION
+
+### json
+
+* Default: false
+* Type: Boolean
+
+Show information in JSON format.
+
+### long
+
+* Default: false
+* Type: Boolean
+
+Show extended information.
+
+### parseable
+
+* Default: false
+* Type: Boolean
+
+Show parseable output instead of tree view.
+
+### global
+
+* Default: false
+* Type: Boolean
+
+List packages in the global install prefix instead of in the current
+project.
+
+### depth
+
+* Type: Int
+
+Max display depth of the dependency tree.
+
+## SEE ALSO
+
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-folders(5)
+* npm-install(1)
+* npm-link(1)
+* npm-prune(1)
+* npm-outdated(1)
+* npm-update(1)
diff --git a/doc/cli/npm-outdated.md b/doc/cli/npm-outdated.md
new file mode 100644
index 0000000..aa2a7d5
--- /dev/null
+++ b/doc/cli/npm-outdated.md
@@ -0,0 +1,58 @@
+npm-outdated(1) -- Check for outdated packages
+==============================================
+
+## SYNOPSIS
+
+ npm outdated [<name> [<name> ...]]
+
+## DESCRIPTION
+
+This command will check the registry to see if any (or, specific) installed
+packages are currently outdated.
+
+The resulting field 'wanted' shows the latest version according to the
+version specified in the package.json, the field 'latest' the very latest
+version of the package.
+
+## CONFIGURATION
+
+### json
+
+* Default: false
+* Type: Boolean
+
+Show information in JSON format.
+
+### long
+
+* Default: false
+* Type: Boolean
+
+Show extended information.
+
+### parseable
+
+* Default: false
+* Type: Boolean
+
+Show parseable output instead of tree view.
+
+### global
+
+* Default: false
+* Type: Boolean
+
+Check packages in the global install prefix instead of in the current
+project.
+
+### depth
+
+* Type: Int
+
+Max depth for checking dependency tree.
+
+## SEE ALSO
+
+* npm-update(1)
+* npm-registry(7)
+* npm-folders(5)
diff --git a/doc/cli/npm-owner.md b/doc/cli/npm-owner.md
new file mode 100644
index 0000000..b400f76
--- /dev/null
+++ b/doc/cli/npm-owner.md
@@ -0,0 +1,33 @@
+npm-owner(1) -- Manage package owners
+=====================================
+
+## SYNOPSIS
+
+ npm owner ls <package name>
+ npm owner add <user> <package name>
+ npm owner rm <user> <package name>
+
+## DESCRIPTION
+
+Manage ownership of published packages.
+
+* ls:
+ List all the users who have access to modify a package and push new versions.
+ Handy when you need to know who to bug for help.
+* add:
+ Add a new user as a maintainer of a package. This user is enabled to modify
+ metadata, publish new versions, and add other owners.
+* rm:
+ Remove a user from the package owner list. This immediately revokes their
+ privileges.
+
+Note that there is only one level of access. Either you can modify a package,
+or you can't. Future versions may contain more fine-grained access levels, but
+that is not implemented at this time.
+
+## SEE ALSO
+
+* npm-publish(1)
+* npm-registry(7)
+* npm-adduser(1)
+* npm-disputes(7)
diff --git a/doc/cli/npm-pack.md b/doc/cli/npm-pack.md
new file mode 100644
index 0000000..42bc156
--- /dev/null
+++ b/doc/cli/npm-pack.md
@@ -0,0 +1,27 @@
+npm-pack(1) -- Create a tarball from a package
+==============================================
+
+## SYNOPSIS
+
+ npm pack [<pkg> [<pkg> ...]]
+
+## DESCRIPTION
+
+For anything that's installable (that is, a package folder, tarball,
+tarball url, name@tag, name@version, or name), this command will fetch
+it to the cache, and then copy the tarball to the current working
+directory as `<name>-<version>.tgz`, and then write the filenames out to
+stdout.
+
+If the same package is specified multiple times, then the file will be
+overwritten the second time.
+
+If no arguments are supplied, then npm packs the current package folder.
+
+## SEE ALSO
+
+* npm-cache(1)
+* npm-publish(1)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-prefix.md b/doc/cli/npm-prefix.md
new file mode 100644
index 0000000..f99a401
--- /dev/null
+++ b/doc/cli/npm-prefix.md
@@ -0,0 +1,19 @@
+npm-prefix(1) -- Display prefix
+===============================
+
+## SYNOPSIS
+
+ npm prefix
+
+## DESCRIPTION
+
+Print the prefix to standard out.
+
+## SEE ALSO
+
+* npm-root(1)
+* npm-bin(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-prune.md b/doc/cli/npm-prune.md
new file mode 100644
index 0000000..88c5475
--- /dev/null
+++ b/doc/cli/npm-prune.md
@@ -0,0 +1,25 @@
+npm-prune(1) -- Remove extraneous packages
+==========================================
+
+## SYNOPSIS
+
+ npm prune [<name> [<name ...]]
+ npm prune [<name> [<name ...]] [--production]
+
+## DESCRIPTION
+
+This command removes "extraneous" packages. If a package name is
+provided, then only packages matching one of the supplied names are
+removed.
+
+Extraneous packages are packages that are not listed on the parent
+package's dependencies list.
+
+If the `--production` flag is specified, this command will remove the
+packages specified in your `devDependencies`.
+
+## SEE ALSO
+
+* npm-rm(1)
+* npm-folders(5)
+* npm-ls(1)
diff --git a/doc/cli/npm-publish.md b/doc/cli/npm-publish.md
new file mode 100644
index 0000000..338728e
--- /dev/null
+++ b/doc/cli/npm-publish.md
@@ -0,0 +1,39 @@
+npm-publish(1) -- Publish a package
+===================================
+
+
+## SYNOPSIS
+
+ npm publish <tarball> [--tag <tag>]
+ npm publish <folder> [--tag <tag>]
+
+## DESCRIPTION
+
+Publishes a package to the registry so that it can be installed by name.
+
+* `<folder>`:
+ A folder containing a package.json file
+
+* `<tarball>`:
+ A url or file path to a gzipped tar archive containing a single folder
+ with a package.json file inside.
+
+* `[--tag <tag>]`
+ Registers the published package with the given tag, such that `npm install
+ <name>@<tag>` will install this version. By default, `npm publish` updates
+ and `npm install` installs the `latest` tag.
+
+Fails if the package name and version combination already exists in
+the registry.
+
+Once a package is published with a given name and version, that
+specific name and version combination can never be used again, even if
+it is removed with npm-unpublish(1).
+
+## SEE ALSO
+
+* npm-registry(7)
+* npm-adduser(1)
+* npm-owner(1)
+* npm-deprecate(1)
+* npm-tag(1)
diff --git a/doc/cli/npm-rebuild.md b/doc/cli/npm-rebuild.md
new file mode 100644
index 0000000..7287208
--- /dev/null
+++ b/doc/cli/npm-rebuild.md
@@ -0,0 +1,21 @@
+npm-rebuild(1) -- Rebuild a package
+===================================
+
+## SYNOPSIS
+
+ npm rebuild [<name> [<name> ...]]
+ npm rb [<name> [<name> ...]]
+
+* `<name>`:
+ The package to rebuild
+
+## DESCRIPTION
+
+This command runs the `npm build` command on the matched folders. This is useful
+when you install a new version of node, and must recompile all your C++ addons with
+the new binary.
+
+## SEE ALSO
+
+* npm-build(1)
+* npm-install(1)
diff --git a/doc/cli/npm-repo.md b/doc/cli/npm-repo.md
new file mode 100644
index 0000000..6bc6f3b
--- /dev/null
+++ b/doc/cli/npm-repo.md
@@ -0,0 +1,28 @@
+npm-repo(1) -- Open package repository page in the browser
+========================================================
+
+## SYNOPSIS
+
+ npm repo <pkgname>
+ npm repo (with no args in a package dir)
+
+## DESCRIPTION
+
+This command tries to guess at the likely location of a package's
+repository URL, and then tries to open it using the `--browser`
+config param. If no package name is provided, it will search for
+a `package.json` in the current folder and use the `name` property.
+
+## CONFIGURATION
+
+### browser
+
+* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"`
+* Type: String
+
+The browser that is called by the `npm repo` command to open websites.
+
+## SEE ALSO
+
+* npm-docs(1)
+* npm-config(1)
diff --git a/doc/cli/npm-restart.md b/doc/cli/npm-restart.md
new file mode 100644
index 0000000..4661d6b
--- /dev/null
+++ b/doc/cli/npm-restart.md
@@ -0,0 +1,22 @@
+npm-restart(1) -- Start a package
+=================================
+
+## SYNOPSIS
+
+ npm restart <name>
+
+## DESCRIPTION
+
+This runs a package's "restart" script, if one was provided.
+Otherwise it runs package's "stop" script, if one was provided, and then
+the "start" script.
+
+If no version is specified, then it restarts the "active" version.
+
+## SEE ALSO
+
+* npm-run-script(1)
+* npm-scripts(7)
+* npm-test(1)
+* npm-start(1)
+* npm-stop(1)
diff --git a/doc/cli/npm-rm.md b/doc/cli/npm-rm.md
new file mode 100644
index 0000000..6691265
--- /dev/null
+++ b/doc/cli/npm-rm.md
@@ -0,0 +1,23 @@
+npm-rm(1) -- Remove a package
+=============================
+
+## SYNOPSIS
+
+ npm rm <name>
+ npm r <name>
+ npm uninstall <name>
+ npm un <name>
+
+## DESCRIPTION
+
+This uninstalls a package, completely removing everything npm installed
+on its behalf.
+
+## SEE ALSO
+
+* npm-prune(1)
+* npm-install(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-root.md b/doc/cli/npm-root.md
new file mode 100644
index 0000000..ca99e12
--- /dev/null
+++ b/doc/cli/npm-root.md
@@ -0,0 +1,19 @@
+npm-root(1) -- Display npm root
+===============================
+
+## SYNOPSIS
+
+ npm root
+
+## DESCRIPTION
+
+Print the effective `node_modules` folder to standard out.
+
+## SEE ALSO
+
+* npm-prefix(1)
+* npm-bin(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-run-script.md b/doc/cli/npm-run-script.md
new file mode 100644
index 0000000..835dbf5
--- /dev/null
+++ b/doc/cli/npm-run-script.md
@@ -0,0 +1,25 @@
+npm-run-script(1) -- Run arbitrary package scripts
+==================================================
+
+## SYNOPSIS
+
+ npm run-script [<pkg>] [command]
+ npm run [<pkg>] [command]
+
+## DESCRIPTION
+
+This runs an arbitrary command from a package's `"scripts"` object.
+If no package name is provided, it will search for a `package.json`
+in the current folder and use its `"scripts"` object. If no `"command"`
+is provided, it will list the available top level scripts.
+
+It is used by the test, start, restart, and stop commands, but can be
+called directly, as well.
+
+## SEE ALSO
+
+* npm-scripts(7)
+* npm-test(1)
+* npm-start(1)
+* npm-restart(1)
+* npm-stop(1)
diff --git a/doc/cli/npm-search.md b/doc/cli/npm-search.md
new file mode 100644
index 0000000..4757ad3
--- /dev/null
+++ b/doc/cli/npm-search.md
@@ -0,0 +1,36 @@
+npm-search(1) -- Search for packages
+====================================
+
+## SYNOPSIS
+
+ npm search [--long] [search terms ...]
+ npm s [search terms ...]
+ npm se [search terms ...]
+
+## DESCRIPTION
+
+Search the registry for packages matching the search terms.
+
+If a term starts with `/`, then it's interpreted as a regular expression.
+A trailing `/` will be ignored in this case. (Note that many regular
+expression characters must be escaped or quoted in most shells.)
+
+## CONFIGURATION
+
+### long
+
+* Default: false
+* Type: Boolean
+
+Display full package descriptions and other long text across multiple
+lines. When disabled (default) search results are truncated to fit
+neatly on a single line. Modules with extremely long names will
+fall on multiple lines.
+
+## SEE ALSO
+
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-view(1)
diff --git a/doc/cli/npm-shrinkwrap.md b/doc/cli/npm-shrinkwrap.md
new file mode 100644
index 0000000..05637f2
--- /dev/null
+++ b/doc/cli/npm-shrinkwrap.md
@@ -0,0 +1,176 @@
+npm-shrinkwrap(1) -- Lock down dependency versions
+=====================================================
+
+## SYNOPSIS
+
+ npm shrinkwrap
+
+## DESCRIPTION
+
+This command locks down the versions of a package's dependencies so
+that you can control exactly which versions of each dependency will be
+used when your package is installed. The "package.json" file is still
+required if you want to use "npm install".
+
+By default, "npm install" recursively installs the target's
+dependencies (as specified in package.json), choosing the latest
+available version that satisfies the dependency's semver pattern. In
+some situations, particularly when shipping software where each change
+is tightly managed, it's desirable to fully specify each version of
+each dependency recursively so that subsequent builds and deploys do
+not inadvertently pick up newer versions of a dependency that satisfy
+the semver pattern. Specifying specific semver patterns in each
+dependency's package.json would facilitate this, but that's not always
+possible or desirable, as when another author owns the npm package.
+It's also possible to check dependencies directly into source control,
+but that may be undesirable for other reasons.
+
+As an example, consider package A:
+
+ {
+ "name": "A",
+ "version": "0.1.0",
+ "dependencies": {
+ "B": "<0.1.0"
+ }
+ }
+
+package B:
+
+ {
+ "name": "B",
+ "version": "0.0.1",
+ "dependencies": {
+ "C": "<0.1.0"
+ }
+ }
+
+and package C:
+
+ {
+ "name": "C,
+ "version": "0.0.1"
+ }
+
+If these are the only versions of A, B, and C available in the
+registry, then a normal "npm install A" will install:
+
+ A@0.1.0
+ `-- B@0.0.1
+ `-- C@0.0.1
+
+However, if B@0.0.2 is published, then a fresh "npm install A" will
+install:
+
+ A@0.1.0
+ `-- B@0.0.2
+ `-- C@0.0.1
+
+assuming the new version did not modify B's dependencies. Of course,
+the new version of B could include a new version of C and any number
+of new dependencies. If such changes are undesirable, the author of A
+could specify a dependency on B@0.0.1. However, if A's author and B's
+author are not the same person, there's no way for A's author to say
+that he or she does not want to pull in newly published versions of C
+when B hasn't changed at all.
+
+In this case, A's author can run
+
+ npm shrinkwrap
+
+This generates npm-shrinkwrap.json, which will look something like this:
+
+ {
+ "name": "A",
+ "version": "0.1.0",
+ "dependencies": {
+ "B": {
+ "version": "0.0.1",
+ "dependencies": {
+ "C": {
+ "version": "0.1.0"
+ }
+ }
+ }
+ }
+ }
+
+The shrinkwrap command has locked down the dependencies based on
+what's currently installed in node_modules. When "npm install"
+installs a package with a npm-shrinkwrap.json file in the package
+root, the shrinkwrap file (rather than package.json files) completely
+drives the installation of that package and all of its dependencies
+(recursively). So now the author publishes A@0.1.0, and subsequent
+installs of this package will use B@0.0.1 and C@0.1.0, regardless the
+dependencies and versions listed in A's, B's, and C's package.json
+files.
+
+
+### Using shrinkwrapped packages
+
+Using a shrinkwrapped package is no different than using any other
+package: you can "npm install" it by hand, or add a dependency to your
+package.json file and "npm install" it.
+
+### Building shrinkwrapped packages
+
+To shrinkwrap an existing package:
+
+1. Run "npm install" in the package root to install the current
+ versions of all dependencies.
+2. Validate that the package works as expected with these versions.
+3. Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish
+ your package.
+
+To add or update a dependency in a shrinkwrapped package:
+
+1. Run "npm install" in the package root to install the current
+ versions of all dependencies.
+2. Add or update dependencies. "npm install" each new or updated
+ package individually and then update package.json. Note that they
+ must be explicitly named in order to be installed: running `npm
+ install` with no arguments will merely reproduce the existing
+ shrinkwrap.
+3. Validate that the package works as expected with the new
+ dependencies.
+4. Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and
+ publish your package.
+
+You can use npm-outdated(1) to view dependencies with newer versions
+available.
+
+### Other Notes
+
+A shrinkwrap file must be consistent with the package's package.json
+file. "npm shrinkwrap" will fail if required dependencies are not
+already installed, since that would result in a shrinkwrap that
+wouldn't actually work. Similarly, the command will fail if there are
+extraneous packages (not referenced by package.json), since that would
+indicate that package.json is not correct.
+
+Since "npm shrinkwrap" is intended to lock down your dependencies for
+production use, `devDependencies` will not be included unless you
+explicitly set the `--dev` flag when you run `npm shrinkwrap`. If
+installed `devDependencies` are excluded, then npm will print a
+warning. If you want them to be installed with your module by
+default, please consider adding them to `dependencies` instead.
+
+If shrinkwrapped package A depends on shrinkwrapped package B, B's
+shrinkwrap will not be used as part of the installation of A. However,
+because A's shrinkwrap is constructed from a valid installation of B
+and recursively specifies all dependencies, the contents of B's
+shrinkwrap will implicitly be included in A's shrinkwrap.
+
+### Caveats
+
+If you wish to lock down the specific bytes included in a package, for
+example to have 100% confidence in being able to reproduce a
+deployment or build, then you ought to check your dependencies into
+source control, or pursue some other mechanism that can verify
+contents rather than versions.
+
+## SEE ALSO
+
+* npm-install(1)
+* package.json(5)
+* npm-ls(1)
diff --git a/doc/cli/npm-star.md b/doc/cli/npm-star.md
new file mode 100644
index 0000000..5c076b3
--- /dev/null
+++ b/doc/cli/npm-star.md
@@ -0,0 +1,22 @@
+npm-star(1) -- Mark your favorite packages
+==========================================
+
+## SYNOPSIS
+
+ npm star <pkgname> [<pkg>, ...]
+ npm unstar <pkgname> [<pkg>, ...]
+
+## DESCRIPTION
+
+"Starring" a package means that you have some interest in it. It's
+a vaguely positive way to show that you care.
+
+"Unstarring" is the same thing, but in reverse.
+
+It's a boolean thing. Starring repeatedly has no additional effect.
+
+## SEE ALSO
+
+* npm-view(1)
+* npm-whoami(1)
+* npm-adduser(1)
diff --git a/doc/cli/npm-stars.md b/doc/cli/npm-stars.md
new file mode 100644
index 0000000..7c28f5b
--- /dev/null
+++ b/doc/cli/npm-stars.md
@@ -0,0 +1,22 @@
+npm-stars(1) -- View packages marked as favorites
+=================================================
+
+## SYNOPSIS
+
+ npm stars
+ npm stars [username]
+
+## DESCRIPTION
+
+If you have starred a lot of neat things and want to find them again
+quickly this command lets you do just that.
+
+You may also want to see your friend's favorite packages, in this case
+you will most certainly enjoy this command.
+
+## SEE ALSO
+
+* npm-star(1)
+* npm-view(1)
+* npm-whoami(1)
+* npm-adduser(1)
diff --git a/doc/cli/npm-start.md b/doc/cli/npm-start.md
new file mode 100644
index 0000000..01347d2
--- /dev/null
+++ b/doc/cli/npm-start.md
@@ -0,0 +1,18 @@
+npm-start(1) -- Start a package
+===============================
+
+## SYNOPSIS
+
+ npm start <name>
+
+## DESCRIPTION
+
+This runs a package's "start" script, if one was provided.
+
+## SEE ALSO
+
+* npm-run-script(1)
+* npm-scripts(7)
+* npm-test(1)
+* npm-restart(1)
+* npm-stop(1)
diff --git a/doc/cli/npm-stop.md b/doc/cli/npm-stop.md
new file mode 100644
index 0000000..bda5cc8
--- /dev/null
+++ b/doc/cli/npm-stop.md
@@ -0,0 +1,18 @@
+npm-stop(1) -- Stop a package
+=============================
+
+## SYNOPSIS
+
+ npm stop <name>
+
+## DESCRIPTION
+
+This runs a package's "stop" script, if one was provided.
+
+## SEE ALSO
+
+* npm-run-script(1)
+* npm-scripts(7)
+* npm-test(1)
+* npm-start(1)
+* npm-restart(1)
diff --git a/doc/cli/npm-submodule.md b/doc/cli/npm-submodule.md
new file mode 100644
index 0000000..7f0fbfc
--- /dev/null
+++ b/doc/cli/npm-submodule.md
@@ -0,0 +1,28 @@
+npm-submodule(1) -- Add a package as a git submodule
+====================================================
+
+## SYNOPSIS
+
+ npm submodule <pkg>
+
+## DESCRIPTION
+
+If the specified package has a git repository url in its package.json
+description, then this command will add it as a git submodule at
+`node_modules/<pkg name>`.
+
+This is a convenience only. From then on, it's up to you to manage
+updates by using the appropriate git commands. npm will stubbornly
+refuse to update, modify, or remove anything with a `.git` subfolder
+in it.
+
+This command also does not install missing dependencies, if the package
+does not include them in its git repository. If `npm ls` reports that
+things are missing, you can either install, link, or submodule them yourself,
+or you can do `npm explore <pkgname> -- npm install` to install the
+dependencies into the submodule folder.
+
+## SEE ALSO
+
+* package.json(5)
+* git help submodule
diff --git a/doc/cli/npm-tag.md b/doc/cli/npm-tag.md
new file mode 100644
index 0000000..3e1d105
--- /dev/null
+++ b/doc/cli/npm-tag.md
@@ -0,0 +1,34 @@
+npm-tag(1) -- Tag a published version
+=====================================
+
+## SYNOPSIS
+
+ npm tag <name>@<version> [<tag>]
+
+## DESCRIPTION
+
+Tags the specified version of the package with the specified tag, or the
+`--tag` config if not specified.
+
+A tag can be used when installing packages as a reference to a version instead
+of using a specific version number:
+
+ npm install <name>@<tag>
+
+When installing dependencies, a preferred tagged version may be specified:
+
+ npm install --tag <tag>
+
+This also applies to `npm dedupe`.
+
+Publishing a package always sets the "latest" tag to the published version.
+
+## SEE ALSO
+
+* npm-publish(1)
+* npm-install(1)
+* npm-dedupe(1)
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-test.md b/doc/cli/npm-test.md
new file mode 100644
index 0000000..800f3ae
--- /dev/null
+++ b/doc/cli/npm-test.md
@@ -0,0 +1,22 @@
+npm-test(1) -- Test a package
+=============================
+
+## SYNOPSIS
+
+ npm test <name>
+ npm tst <name>
+
+## DESCRIPTION
+
+This runs a package's "test" script, if one was provided.
+
+To run tests as a condition of installation, set the `npat` config to
+true.
+
+## SEE ALSO
+
+* npm-run-script(1)
+* npm-scripts(7)
+* npm-start(1)
+* npm-restart(1)
+* npm-stop(1)
diff --git a/doc/cli/npm-uninstall.md b/doc/cli/npm-uninstall.md
new file mode 100644
index 0000000..e24815b
--- /dev/null
+++ b/doc/cli/npm-uninstall.md
@@ -0,0 +1,43 @@
+npm-rm(1) -- Remove a package
+=============================
+
+## SYNOPSIS
+
+ npm uninstall <name> [--save|--save-dev|--save-optional]
+ npm rm (with any of the previous argument usage)
+
+## DESCRIPTION
+
+This uninstalls a package, completely removing everything npm installed
+on its behalf.
+
+Example:
+
+ npm uninstall sax
+
+In global mode (ie, with `-g` or `--global` appended to the command),
+it uninstalls the current package context as a global package.
+
+`npm uninstall` takes 3 exclusive, optional flags which save or update
+the package version in your main package.json:
+
+* `--save`: Package will be removed from your `dependencies`.
+
+* `--save-dev`: Package will be removed from your `devDependencies`.
+
+* `--save-optional`: Package will be removed from your `optionalDependencies`.
+
+Examples:
+
+ npm uninstall sax --save
+ npm uninstall node-tap --save-dev
+ npm uninstall dtrace-provider --save-optional
+
+## SEE ALSO
+
+* npm-prune(1)
+* npm-install(1)
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
diff --git a/doc/cli/npm-unpublish.md b/doc/cli/npm-unpublish.md
new file mode 100644
index 0000000..4502619
--- /dev/null
+++ b/doc/cli/npm-unpublish.md
@@ -0,0 +1,36 @@
+npm-unpublish(1) -- Remove a package from the registry
+======================================================
+
+## SYNOPSIS
+
+ npm unpublish <name>[@<version>]
+
+## WARNING
+
+**It is generally considered bad behavior to remove versions of a library
+that others are depending on!**
+
+Consider using the `deprecate` command
+instead, if your intent is to encourage users to upgrade.
+
+There is plenty of room on the registry.
+
+## DESCRIPTION
+
+This removes a package version from the registry, deleting its
+entry and removing the tarball.
+
+If no version is specified, or if all versions are removed then
+the root package entry is removed from the registry entirely.
+
+Even if a package version is unpublished, that specific name and
+version combination can never be reused. In order to publish the
+package again, a new version number must be used.
+
+## SEE ALSO
+
+* npm-deprecate(1)
+* npm-publish(1)
+* npm-registry(7)
+* npm-adduser(1)
+* npm-owner(1)
diff --git a/doc/cli/npm-update.md b/doc/cli/npm-update.md
new file mode 100644
index 0000000..1ea6b62
--- /dev/null
+++ b/doc/cli/npm-update.md
@@ -0,0 +1,24 @@
+npm-update(1) -- Update a package
+=================================
+
+## SYNOPSIS
+
+ npm update [-g] [<name> [<name> ...]]
+
+## DESCRIPTION
+
+This command will update all the packages listed to the latest version
+(specified by the `tag` config).
+
+It will also install missing packages.
+
+If the `-g` flag is specified, this command will update globally installed packages.
+If no package name is specified, all packages in the specified location (global or local) will be updated.
+
+## SEE ALSO
+
+* npm-install(1)
+* npm-outdated(1)
+* npm-registry(7)
+* npm-folders(5)
+* npm-ls(1)
diff --git a/doc/cli/npm-version.md b/doc/cli/npm-version.md
new file mode 100644
index 0000000..870bd49
--- /dev/null
+++ b/doc/cli/npm-version.md
@@ -0,0 +1,45 @@
+npm-version(1) -- Bump a package version
+========================================
+
+## SYNOPSIS
+
+ npm version [<newversion> | major | minor | patch]
+
+## DESCRIPTION
+
+Run this in a package directory to bump the version and write the new
+data back to the package.json file.
+
+The `newversion` argument should be a valid semver string, *or* a valid
+second argument to semver.inc (one of "patch", "minor", or
+"major"). In the second case, the existing version will be incremented
+by 1 in the specified field.
+
+If run in a git repo, it will also create a version commit and tag, and
+fail if the repo is not clean.
+
+If supplied with `--message` (shorthand: `-m`) config option, npm will
+use it as a commit message when creating a version commit. If the
+`message` config contains `%s` then that will be replaced with the
+resulting version number. For example:
+
+ npm version patch -m "Upgrade to %s for reasons"
+
+If the `sign-git-tag` config is set, then the tag will be signed using
+the `-s` flag to git. Note that you must have a default GPG key set up
+in your git config for this to work properly. For example:
+
+ $ npm config set sign-git-tag true
+ $ npm version patch
+
+ You need a passphrase to unlock the secret key for
+ user: "isaacs (http://blog.izs.me/) <i@izs.me>"
+ 2048-bit RSA key, ID 6C481CF6, created 2010-08-31
+
+ Enter passphrase:
+
+## SEE ALSO
+
+* npm-init(1)
+* package.json(5)
+* semver(7)
diff --git a/doc/cli/npm-view.md b/doc/cli/npm-view.md
new file mode 100644
index 0000000..1d19fe8
--- /dev/null
+++ b/doc/cli/npm-view.md
@@ -0,0 +1,90 @@
+npm-view(1) -- View registry info
+=================================
+
+## SYNOPSIS
+
+ npm view <name>[@<version>] [<field>[.<subfield>]...]
+ npm v <name>[@<version>] [<field>[.<subfield>]...]
+
+## DESCRIPTION
+
+This command shows data about a package and prints it to the stream
+referenced by the `outfd` config, which defaults to stdout.
+
+To show the package registry entry for the `connect` package, you can do
+this:
+
+ npm view connect
+
+The default version is "latest" if unspecified.
+
+Field names can be specified after the package descriptor.
+For example, to show the dependencies of the `ronn` package at version
+0.3.5, you could do the following:
+
+ npm view ronn@0.3.5 dependencies
+
+You can view child field by separating them with a period.
+To view the git repository URL for the latest version of npm, you could
+do this:
+
+ npm view npm repository.url
+
+This makes it easy to view information about a dependency with a bit of
+shell scripting. For example, to view all the data about the version of
+opts that ronn depends on, you can do this:
+
+ npm view opts@$(npm view ronn dependencies.opts)
+
+For fields that are arrays, requesting a non-numeric field will return
+all of the values from the objects in the list. For example, to get all
+the contributor names for the "express" project, you can do this:
+
+ npm view express contributors.email
+
+You may also use numeric indices in square braces to specifically select
+an item in an array field. To just get the email address of the first
+contributor in the list, you can do this:
+
+ npm view express contributors[0].email
+
+Multiple fields may be specified, and will be printed one after another.
+For exampls, to get all the contributor names and email addresses, you
+can do this:
+
+ npm view express contributors.name contributors.email
+
+"Person" fields are shown as a string if they would be shown as an
+object. So, for example, this will show the list of npm contributors in
+the shortened string format. (See `package.json(5)` for more on this.)
+
+ npm view npm contributors
+
+If a version range is provided, then data will be printed for every
+matching version of the package. This will show which version of jsdom
+was required by each matching version of yui3:
+
+ npm view yui3@'>0.5.4' dependencies.jsdom
+
+## OUTPUT
+
+If only a single string field for a single version is output, then it
+will not be colorized or quoted, so as to enable piping the output to
+another command. If the field is an object, it will be output as a JavaScript object literal.
+
+If the --json flag is given, the outputted fields will be JSON.
+
+If the version range matches multiple versions, than each printed value
+will be prefixed with the version it applies to.
+
+If multiple fields are requested, than each of them are prefixed with
+the field name.
+
+## SEE ALSO
+
+* npm-search(1)
+* npm-registry(7)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-docs(1)
diff --git a/doc/cli/npm-whoami.md b/doc/cli/npm-whoami.md
new file mode 100644
index 0000000..3ff8837
--- /dev/null
+++ b/doc/cli/npm-whoami.md
@@ -0,0 +1,17 @@
+npm-whoami(1) -- Display npm username
+=====================================
+
+## SYNOPSIS
+
+ npm whoami
+
+## DESCRIPTION
+
+Print the `username` config to standard output.
+
+## SEE ALSO
+
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-adduser(1)
diff --git a/doc/cli/npm.md b/doc/cli/npm.md
new file mode 100644
index 0000000..ad16d41
--- /dev/null
+++ b/doc/cli/npm.md
@@ -0,0 +1,169 @@
+npm(1) -- node package manager
+==============================
+
+## SYNOPSIS
+
+ npm <command> [args]
+
+## VERSION
+
+@VERSION@
+
+## DESCRIPTION
+
+npm is the package manager for the Node JavaScript platform. It puts
+modules in place so that node can find them, and manages dependency
+conflicts intelligently.
+
+It is extremely configurable to support a wide variety of use cases.
+Most commonly, it is used to publish, discover, install, and develop node
+programs.
+
+Run `npm help` to get a list of available commands.
+
+## INTRODUCTION
+
+You probably got npm because you want to install stuff.
+
+Use `npm install blerg` to install the latest version of "blerg". Check out
+`npm-install(1)` for more info. It can do a lot of stuff.
+
+Use the `npm search` command to show everything that's available.
+Use `npm ls` to show everything you've installed.
+
+## DEPENDENCIES
+
+If a package references to another package with a git URL, npm depends
+on a preinstalled git.
+
+If one of the packages npm tries to install is a native node module and
+requires compiling of C++ Code, npm will use
+[node-gyp](https://github.com/TooTallNate/node-gyp) for that task.
+For a Unix system, [node-gyp](https://github.com/TooTallNate/node-gyp)
+needs Python, make and a buildchain like GCC. On Windows,
+Python and Microsoft Visual Studio C++ is needed. Python 3 is
+not supported by [node-gyp](https://github.com/TooTallNate/node-gyp).
+For more information visit
+[the node-gyp repository](https://github.com/TooTallNate/node-gyp) and
+the [node-gyp Wiki](https://github.com/TooTallNate/node-gyp/wiki).
+
+## DIRECTORIES
+
+See `npm-folders(5)` to learn about where npm puts stuff.
+
+In particular, npm has two modes of operation:
+
+* global mode:
+ npm installs packages into the install prefix at
+ `prefix/lib/node_modules` and bins are installed in `prefix/bin`.
+* local mode:
+ npm installs packages into the current project directory, which
+ defaults to the current working directory. Packages are installed to
+ `./node_modules`, and bins are installed to `./node_modules/.bin`.
+
+Local mode is the default. Use `--global` or `-g` on any command to
+operate in global mode instead.
+
+## DEVELOPER USAGE
+
+If you're using npm to develop and publish your code, check out the
+following help topics:
+
+* json:
+ Make a package.json file. See `package.json(5)`.
+* link:
+ For linking your current working code into Node's path, so that you
+ don't have to reinstall every time you make a change. Use
+ `npm link` to do this.
+* install:
+ It's a good idea to install things if you don't need the symbolic link.
+ Especially, installing other peoples code from the registry is done via
+ `npm install`
+* adduser:
+ Create an account or log in. Credentials are stored in the
+ user config file.
+* publish:
+ Use the `npm publish` command to upload your code to the registry.
+
+## CONFIGURATION
+
+npm is extremely configurable. It reads its configuration options from
+5 places.
+
+* Command line switches:
+ Set a config with `--key val`. All keys take a value, even if they
+ are booleans (the config parser doesn't know what the options are at
+ the time of parsing.) If no value is provided, then the option is set
+ to boolean `true`.
+* Environment Variables:
+ Set any config by prefixing the name in an environment variable with
+ `npm_config_`. For example, `export npm_config_key=val`.
+* User Configs:
+ The file at $HOME/.npmrc is an ini-formatted list of configs. If
+ present, it is parsed. If the `userconfig` option is set in the cli
+ or env, then that will be used instead.
+* Global Configs:
+ The file found at ../etc/npmrc (from the node executable, by default
+ this resolves to /usr/local/etc/npmrc) will be parsed if it is found.
+ If the `globalconfig` option is set in the cli, env, or user config,
+ then that file is parsed instead.
+* Defaults:
+ npm's default configuration options are defined in
+ lib/utils/config-defs.js. These must not be changed.
+
+See `npm-config(7)` for much much more information.
+
+## CONTRIBUTIONS
+
+Patches welcome!
+
+* code:
+ Read through `npm-coding-style(7)` if you plan to submit code.
+ You don't have to agree with it, but you do have to follow it.
+* docs:
+ If you find an error in the documentation, edit the appropriate markdown
+ file in the "doc" folder. (Don't worry about generating the man page.)
+
+Contributors are listed in npm's `package.json` file. You can view them
+easily by doing `npm view npm contributors`.
+
+If you would like to contribute, but don't know what to work on, check
+the issues list or ask on the mailing list.
+
+* <http://github.com/npm/npm/issues>
+* <npm-@googlegroups.com>
+
+## BUGS
+
+When you find issues, please report them:
+
+* web:
+ <http://github.com/npm/npm/issues>
+* email:
+ <npm-@googlegroups.com>
+
+Be sure to include *all* of the output from the npm command that didn't work
+as expected. The `npm-debug.log` file is also helpful to provide.
+
+You can also look for isaacs in #node.js on irc://irc.freenode.net. He
+will no doubt tell you to put the output in a gist or email.
+
+## AUTHOR
+
+[Isaac Z. Schlueter](http://blog.izs.me/) ::
+[isaacs](https://github.com/isaacs/) ::
+[@izs](http://twitter.com/izs) ::
+<i@izs.me>
+
+## SEE ALSO
+
+* npm-help(1)
+* npm-faq(7)
+* README
+* package.json(5)
+* npm-install(1)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-index(7)
+* npm(3)
diff --git a/doc/files/npm-folders.md b/doc/files/npm-folders.md
new file mode 100644
index 0000000..1b1485d
--- /dev/null
+++ b/doc/files/npm-folders.md
@@ -0,0 +1,211 @@
+npm-folders(5) -- Folder Structures Used by npm
+===============================================
+
+## DESCRIPTION
+
+npm puts various things on your computer. That's its job.
+
+This document will tell you what it puts where.
+
+### tl;dr
+
+* Local install (default): puts stuff in `./node_modules` of the current
+ package root.
+* Global install (with `-g`): puts stuff in /usr/local or wherever node
+ is installed.
+* Install it **locally** if you're going to `require()` it.
+* Install it **globally** if you're going to run it on the command line.
+* If you need both, then install it in both places, or use `npm link`.
+
+### prefix Configuration
+
+The `prefix` config defaults to the location where node is installed.
+On most systems, this is `/usr/local`, and most of the time is the same
+as node's `process.installPrefix`.
+
+On windows, this is the exact location of the node.exe binary. On Unix
+systems, it's one level up, since node is typically installed at
+`{prefix}/bin/node` rather than `{prefix}/node.exe`.
+
+When the `global` flag is set, npm installs things into this prefix.
+When it is not set, it uses the root of the current package, or the
+current working directory if not in a package already.
+
+### Node Modules
+
+Packages are dropped into the `node_modules` folder under the `prefix`.
+When installing locally, this means that you can
+`require("packagename")` to load its main module, or
+`require("packagename/lib/path/to/sub/module")` to load other modules.
+
+Global installs on Unix systems go to `{prefix}/lib/node_modules`.
+Global installs on Windows go to `{prefix}/node_modules` (that is, no
+`lib` folder.)
+
+If you wish to `require()` a package, then install it locally.
+
+### Executables
+
+When in global mode, executables are linked into `{prefix}/bin` on Unix,
+or directly into `{prefix}` on Windows.
+
+When in local mode, executables are linked into
+`./node_modules/.bin` so that they can be made available to scripts run
+through npm. (For example, so that a test runner will be in the path
+when you run `npm test`.)
+
+### Man Pages
+
+When in global mode, man pages are linked into `{prefix}/share/man`.
+
+When in local mode, man pages are not installed.
+
+Man pages are not installed on Windows systems.
+
+### Cache
+
+See `npm-cache(1)`. Cache files are stored in `~/.npm` on Posix, or
+`~/npm-cache` on Windows.
+
+This is controlled by the `cache` configuration param.
+
+### Temp Files
+
+Temporary files are stored by default in the folder specified by the
+`tmp` config, which defaults to the TMPDIR, TMP, or TEMP environment
+variables, or `/tmp` on Unix and `c:\windows\temp` on Windows.
+
+Temp files are given a unique folder under this root for each run of the
+program, and are deleted upon successful exit.
+
+## More Information
+
+When installing locally, npm first tries to find an appropriate
+`prefix` folder. This is so that `npm install foo@1.2.3` will install
+to the sensible root of your package, even if you happen to have `cd`ed
+into some other folder.
+
+Starting at the $PWD, npm will walk up the folder tree checking for a
+folder that contains either a `package.json` file, or a `node_modules`
+folder. If such a thing is found, then that is treated as the effective
+"current directory" for the purpose of running npm commands. (This
+behavior is inspired by and similar to git's .git-folder seeking
+logic when running git commands in a working dir.)
+
+If no package root is found, then the current folder is used.
+
+When you run `npm install foo@1.2.3`, then the package is loaded into
+the cache, and then unpacked into `./node_modules/foo`. Then, any of
+foo's dependencies are similarly unpacked into
+`./node_modules/foo/node_modules/...`.
+
+Any bin files are symlinked to `./node_modules/.bin/`, so that they may
+be found by npm scripts when necessary.
+
+### Global Installation
+
+If the `global` configuration is set to true, then npm will
+install packages "globally".
+
+For global installation, packages are installed roughly the same way,
+but using the folders described above.
+
+### Cycles, Conflicts, and Folder Parsimony
+
+Cycles are handled using the property of node's module system that it
+walks up the directories looking for `node_modules` folders. So, at every
+stage, if a package is already installed in an ancestor `node_modules`
+folder, then it is not installed at the current location.
+
+Consider the case above, where `foo -> bar -> baz`. Imagine if, in
+addition to that, baz depended on bar, so you'd have:
+`foo -> bar -> baz -> bar -> baz ...`. However, since the folder
+structure is: `foo/node_modules/bar/node_modules/baz`, there's no need to
+put another copy of bar into `.../baz/node_modules`, since when it calls
+require("bar"), it will get the copy that is installed in
+`foo/node_modules/bar`.
+
+This shortcut is only used if the exact same
+version would be installed in multiple nested `node_modules` folders. It
+is still possible to have `a/node_modules/b/node_modules/a` if the two
+"a" packages are different versions. However, without repeating the
+exact same package multiple times, an infinite regress will always be
+prevented.
+
+Another optimization can be made by installing dependencies at the
+highest level possible, below the localized "target" folder.
+
+#### Example
+
+Consider this dependency graph:
+
+ foo
+ +-- blerg@1.2.5
+ +-- bar@1.2.3
+ | +-- blerg@1.x (latest=1.3.7)
+ | +-- baz@2.x
+ | | `-- quux@3.x
+ | | `-- bar@1.2.3 (cycle)
+ | `-- asdf@*
+ `-- baz@1.2.3
+ `-- quux@3.x
+ `-- bar
+
+In this case, we might expect a folder structure like this:
+
+ foo
+ +-- node_modules
+ +-- blerg (1.2.5) <---[A]
+ +-- bar (1.2.3) <---[B]
+ | `-- node_modules
+ | +-- baz (2.0.2) <---[C]
+ | | `-- node_modules
+ | | `-- quux (3.2.0)
+ | `-- asdf (2.3.4)
+ `-- baz (1.2.3) <---[D]
+ `-- node_modules
+ `-- quux (3.2.0) <---[E]
+
+Since foo depends directly on `bar@1.2.3` and `baz@1.2.3`, those are
+installed in foo's `node_modules` folder.
+
+Even though the latest copy of blerg is 1.3.7, foo has a specific
+dependency on version 1.2.5. So, that gets installed at [A]. Since the
+parent installation of blerg satisfies bar's dependency on `blerg@1.x`,
+it does not install another copy under [B].
+
+Bar [B] also has dependencies on baz and asdf, so those are installed in
+bar's `node_modules` folder. Because it depends on `baz@2.x`, it cannot
+re-use the `baz@1.2.3` installed in the parent `node_modules` folder [D],
+and must install its own copy [C].
+
+Underneath bar, the `baz -> quux -> bar` dependency creates a cycle.
+However, because bar is already in quux's ancestry [B], it does not
+unpack another copy of bar into that folder.
+
+Underneath `foo -> baz` [D], quux's [E] folder tree is empty, because its
+dependency on bar is satisfied by the parent folder copy installed at [B].
+
+For a graphical breakdown of what is installed where, use `npm ls`.
+
+### Publishing
+
+Upon publishing, npm will look in the `node_modules` folder. If any of
+the items there are not in the `bundledDependencies` array, then they will
+not be included in the package tarball.
+
+This allows a package maintainer to install all of their dependencies
+(and dev dependencies) locally, but only re-publish those items that
+cannot be found elsewhere. See `package.json(5)` for more information.
+
+## SEE ALSO
+
+* npm-faq(7)
+* package.json(5)
+* npm-install(1)
+* npm-pack(1)
+* npm-cache(1)
+* npm-config(1)
+* npmrc(5)
+* npm-config(7)
+* npm-publish(1)
diff --git a/doc/files/npmrc.md b/doc/files/npmrc.md
new file mode 100644
index 0000000..ba57a6f
--- /dev/null
+++ b/doc/files/npmrc.md
@@ -0,0 +1,71 @@
+npmrc(5) -- The npm config files
+================================
+
+## DESCRIPTION
+
+npm gets its config settings from the command line, environment
+variables, and `npmrc` files.
+
+The `npm config` command can be used to update and edit the contents
+of the user and global npmrc files.
+
+For a list of available configuration options, see npm-config(7).
+
+## FILES
+
+The four relevant files are:
+
+* per-project config file (/path/to/my/project/.npmrc)
+* per-user config file (~/.npmrc)
+* global config file ($PREFIX/npmrc)
+* npm builtin config file (/path/to/npm/npmrc)
+
+All npm config files are an ini-formatted list of `key = value`
+parameters. Environment variables can be replaced using
+`${VARIABLE_NAME}`. For example:
+
+ prefix = ${HOME}/.npm-packages
+
+Each of these files is loaded, and config options are resolved in
+priority order. For example, a setting in the userconfig file would
+override the setting in the globalconfig file.
+
+### Per-project config file
+
+When working locally in a project, a `.npmrc` file in the root of the
+project (ie, a sibling of `node_modules` and `package.json`) will set
+config values specific to this project.
+
+Note that this only applies to the root of the project that you're
+running npm in. It has no effect when your module is published. For
+example, you can't publish a module that forces itself to install
+globally, or in a different location.
+
+### Per-user config file
+
+`$HOME/.npmrc` (or the `userconfig` param, if set in the environment
+or on the command line)
+
+### Global config file
+
+`$PREFIX/etc/npmrc` (or the `globalconfig` param, if set above):
+This file is an ini-file formatted list of `key = value` parameters.
+Environment variables can be replaced as above.
+
+### Built-in config file
+
+`path/to/npm/itself/npmrc`
+
+This is an unchangeable "builtin" configuration file that npm keeps
+consistent across updates. Set fields in here using the `./configure`
+script that comes with npm. This is primarily for distribution
+maintainers to override default configs in a standard and consistent
+manner.
+
+## SEE ALSO
+
+* npm-folders(5)
+* npm-config(1)
+* npm-config(7)
+* package.json(5)
+* npm(1)
diff --git a/doc/files/package.json.md b/doc/files/package.json.md
new file mode 100644
index 0000000..b9b05d4
--- /dev/null
+++ b/doc/files/package.json.md
@@ -0,0 +1,607 @@
+package.json(5) -- Specifics of npm's package.json handling
+===========================================================
+
+## DESCRIPTION
+
+This document is all you need to know about what's required in your package.json
+file. It must be actual JSON, not just a JavaScript object literal.
+
+A lot of the behavior described in this document is affected by the config
+settings described in `npm-config(7)`.
+
+## name
+
+The *most* important things in your package.json are the name and version fields.
+Those are actually required, and your package won't install without
+them. The name and version together form an identifier that is assumed
+to be completely unique. Changes to the package should come along with
+changes to the version.
+
+The name is what your thing is called. Some tips:
+
+* Don't put "js" or "node" in the name. It's assumed that it's js, since you're
+ writing a package.json file, and you can specify the engine using the "engines"
+ field. (See below.)
+* The name ends up being part of a URL, an argument on the command line, and a
+ folder name. Any name with non-url-safe characters will be rejected.
+ Also, it can't start with a dot or an underscore.
+* The name will probably be passed as an argument to require(), so it should
+ be something short, but also reasonably descriptive.
+* You may want to check the npm registry to see if there's something by that name
+ already, before you get too attached to it. http://registry.npmjs.org/
+
+## version
+
+The *most* important things in your package.json are the name and version fields.
+Those are actually required, and your package won't install without
+them. The name and version together form an identifier that is assumed
+to be completely unique. Changes to the package should come along with
+changes to the version.
+
+Version must be parseable by
+[node-semver](https://github.com/isaacs/node-semver), which is bundled
+with npm as a dependency. (`npm install semver` to use it yourself.)
+
+More on version numbers and ranges at semver(7).
+
+## description
+
+Put a description in it. It's a string. This helps people discover your
+package, as it's listed in `npm search`.
+
+## keywords
+
+Put keywords in it. It's an array of strings. This helps people
+discover your package as it's listed in `npm search`.
+
+## homepage
+
+The url to the project homepage.
+
+**NOTE**: This is *not* the same as "url". If you put a "url" field,
+then the registry will think it's a redirection to your package that has
+been published somewhere else, and spit at you.
+
+Literally. Spit. I'm so not kidding.
+
+## bugs
+
+The url to your project's issue tracker and / or the email address to which
+issues should be reported. These are helpful for people who encounter issues
+with your package.
+
+It should look like this:
+
+ { "url" : "http://github.com/owner/project/issues"
+ , "email" : "project@hostname.com"
+ }
+
+You can specify either one or both values. If you want to provide only a url,
+you can specify the value for "bugs" as a simple string instead of an object.
+
+If a url is provided, it will be used by the `npm bugs` command.
+
+## license
+
+You should specify a license for your package so that people know how they are
+permitted to use it, and any restrictions you're placing on it.
+
+The simplest way, assuming you're using a common license such as BSD-3-Clause
+or MIT, is to just specify the standard SPDX ID of the license you're using,
+like this:
+
+ { "license" : "BSD-3-Clause" }
+
+You can check [the full list of SPDX license IDs](https://spdx.org/licenses/).
+Ideally you should pick one that is
+[OSI](http://opensource.org/licenses/alphabetical) approved.
+
+It's also a good idea to include a LICENSE file at the top level in
+your package.
+
+## people fields: author, contributors
+
+The "author" is one person. "contributors" is an array of people. A "person"
+is an object with a "name" field and optionally "url" and "email", like this:
+
+ { "name" : "Barney Rubble"
+ , "email" : "b@rubble.com"
+ , "url" : "http://barnyrubble.tumblr.com/"
+ }
+
+Or you can shorten that all into a single string, and npm will parse it for you:
+
+ "Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)
+
+Both email and url are optional either way.
+
+npm also sets a top-level "maintainers" field with your npm user info.
+
+## files
+
+The "files" field is an array of files to include in your project. If
+you name a folder in the array, then it will also include the files
+inside that folder. (Unless they would be ignored by another rule.)
+
+You can also provide a ".npmignore" file in the root of your package,
+which will keep files from being included, even if they would be picked
+up by the files array. The ".npmignore" file works just like a
+".gitignore".
+
+## main
+
+The main field is a module ID that is the primary entry point to your program.
+That is, if your package is named `foo`, and a user installs it, and then does
+`require("foo")`, then your main module's exports object will be returned.
+
+This should be a module ID relative to the root of your package folder.
+
+For most modules, it makes the most sense to have a main script and often not
+much else.
+
+## bin
+
+A lot of packages have one or more executable files that they'd like to
+install into the PATH. npm makes this pretty easy (in fact, it uses this
+feature to install the "npm" executable.)
+
+To use this, supply a `bin` field in your package.json which is a map of
+command name to local file name. On install, npm will symlink that file into
+`prefix/bin` for global installs, or `./node_modules/.bin/` for local
+installs.
+
+
+For example, npm has this:
+
+ { "bin" : { "npm" : "./cli.js" } }
+
+So, when you install npm, it'll create a symlink from the `cli.js` script to
+`/usr/local/bin/npm`.
+
+If you have a single executable, and its name should be the name
+of the package, then you can just supply it as a string. For example:
+
+ { "name": "my-program"
+ , "version": "1.2.5"
+ , "bin": "./path/to/program" }
+
+would be the same as this:
+
+ { "name": "my-program"
+ , "version": "1.2.5"
+ , "bin" : { "my-program" : "./path/to/program" } }
+
+## man
+
+Specify either a single file or an array of filenames to put in place for the
+`man` program to find.
+
+If only a single file is provided, then it's installed such that it is the
+result from `man <pkgname>`, regardless of its actual filename. For example:
+
+ { "name" : "foo"
+ , "version" : "1.2.3"
+ , "description" : "A packaged foo fooer for fooing foos"
+ , "main" : "foo.js"
+ , "man" : "./man/doc.1"
+ }
+
+would link the `./man/doc.1` file in such that it is the target for `man foo`
+
+If the filename doesn't start with the package name, then it's prefixed.
+So, this:
+
+ { "name" : "foo"
+ , "version" : "1.2.3"
+ , "description" : "A packaged foo fooer for fooing foos"
+ , "main" : "foo.js"
+ , "man" : [ "./man/foo.1", "./man/bar.1" ]
+ }
+
+will create files to do `man foo` and `man foo-bar`.
+
+Man files must end with a number, and optionally a `.gz` suffix if they are
+compressed. The number dictates which man section the file is installed into.
+
+ { "name" : "foo"
+ , "version" : "1.2.3"
+ , "description" : "A packaged foo fooer for fooing foos"
+ , "main" : "foo.js"
+ , "man" : [ "./man/foo.1", "./man/foo.2" ]
+ }
+
+will create entries for `man foo` and `man 2 foo`
+
+## directories
+
+The CommonJS [Packages](http://wiki.commonjs.org/wiki/Packages/1.0) spec details a
+few ways that you can indicate the structure of your package using a `directories`
+hash. If you look at [npm's package.json](http://registry.npmjs.org/npm/latest),
+you'll see that it has directories for doc, lib, and man.
+
+In the future, this information may be used in other creative ways.
+
+### directories.lib
+
+Tell people where the bulk of your library is. Nothing special is done
+with the lib folder in any way, but it's useful meta info.
+
+### directories.bin
+
+If you specify a "bin" directory, then all the files in that folder will
+be used as the "bin" hash.
+
+If you have a "bin" hash already, then this has no effect.
+
+### directories.man
+
+A folder that is full of man pages. Sugar to generate a "man" array by
+walking the folder.
+
+### directories.doc
+
+Put markdown files in here. Eventually, these will be displayed nicely,
+maybe, someday.
+
+### directories.example
+
+Put example scripts in here. Someday, it might be exposed in some clever way.
+
+## repository
+
+Specify the place where your code lives. This is helpful for people who
+want to contribute. If the git repo is on github, then the `npm docs`
+command will be able to find you.
+
+Do it like this:
+
+ "repository" :
+ { "type" : "git"
+ , "url" : "http://github.com/npm/npm.git"
+ }
+
+ "repository" :
+ { "type" : "svn"
+ , "url" : "http://v8.googlecode.com/svn/trunk/"
+ }
+
+The URL should be a publicly available (perhaps read-only) url that can be handed
+directly to a VCS program without any modification. It should not be a url to an
+html project page that you put in your browser. It's for computers.
+
+## scripts
+
+The "scripts" member is an object hash of script commands that are run
+at various times in the lifecycle of your package. The key is the lifecycle
+event, and the value is the command to run at that point.
+
+See `npm-scripts(7)` to find out more about writing package scripts.
+
+## config
+
+A "config" hash can be used to set configuration
+parameters used in package scripts that persist across upgrades. For
+instance, if a package had the following:
+
+ { "name" : "foo"
+ , "config" : { "port" : "8080" } }
+
+and then had a "start" command that then referenced the
+`npm_package_config_port` environment variable, then the user could
+override that by doing `npm config set foo:port 8001`.
+
+See `npm-config(7)` and `npm-scripts(7)` for more on package
+configs.
+
+## dependencies
+
+Dependencies are specified with a simple hash of package name to
+version range. The version range is a string which has one or more
+space-separated descriptors. Dependencies can also be identified with
+a tarball or git URL.
+
+**Please do not put test harnesses or transpilers in your
+`dependencies` hash.** See `devDependencies`, below.
+
+See semver(7) for more details about specifying version ranges.
+
+* `version` Must match `version` exactly
+* `>version` Must be greater than `version`
+* `>=version` etc
+* `<version`
+* `<=version`
+* `~version` "Approximately equivalent to version" See semver(7)
+* `^version` "Compatible with version" See semver(7)
+* `1.2.x` 1.2.0, 1.2.1, etc., but not 1.3.0
+* `http://...` See 'URLs as Dependencies' below
+* `*` Matches any version
+* `""` (just an empty string) Same as `*`
+* `version1 - version2` Same as `>=version1 <=version2`.
+* `range1 || range2` Passes if either range1 or range2 are satisfied.
+* `git...` See 'Git URLs as Dependencies' below
+* `user/repo` See 'GitHub URLs' below
+
+For example, these are all valid:
+
+ { "dependencies" :
+ { "foo" : "1.0.0 - 2.9999.9999"
+ , "bar" : ">=1.0.2 <2.1.2"
+ , "baz" : ">1.0.2 <=2.3.4"
+ , "boo" : "2.0.1"
+ , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
+ , "asd" : "http://asdf.com/asdf.tar.gz"
+ , "til" : "~1.2"
+ , "elf" : "~1.2.3"
+ , "two" : "2.x"
+ , "thr" : "3.3.x"
+ }
+ }
+
+### URLs as Dependencies
+
+You may specify a tarball URL in place of a version range.
+
+This tarball will be downloaded and installed locally to your package at
+install time.
+
+### Git URLs as Dependencies
+
+Git urls can be of the form:
+
+ git://github.com/user/project.git#commit-ish
+ git+ssh://user@hostname:project.git#commit-ish
+ git+ssh://user@hostname/project.git#commit-ish
+ git+http://user@hostname/project/blah.git#commit-ish
+ git+https://user@hostname/project/blah.git#commit-ish
+
+The `commit-ish` can be any tag, sha, or branch which can be supplied as
+an argument to `git checkout`. The default is `master`.
+
+## GitHub URLs
+
+As of version 1.1.65, you can refer to GitHub urls as just "foo": "user/foo-project". For example:
+
+ {
+ "name": "foo",
+ "version": "0.0.0",
+ "dependencies": {
+ "express": "visionmedia/express"
+ }
+ }
+
+## devDependencies
+
+If someone is planning on downloading and using your module in their
+program, then they probably don't want or need to download and build
+the external test or documentation framework that you use.
+
+In this case, it's best to list these additional items in a
+`devDependencies` hash.
+
+These things will be installed when doing `npm link` or `npm install`
+from the root of a package, and can be managed like any other npm
+configuration param. See `npm-config(7)` for more on the topic.
+
+For build steps that are not platform-specific, such as compiling
+CoffeeScript or other languages to JavaScript, use the `prepublish`
+script to do this, and make the required package a devDependency.
+
+For example:
+
+ { "name": "ethopia-waza",
+ "description": "a delightfully fruity coffee varietal",
+ "version": "1.2.3",
+ "devDependencies": {
+ "coffee-script": "~1.6.3"
+ },
+ "scripts": {
+ "prepublish": "coffee -o lib/ -c src/waza.coffee"
+ },
+ "main": "lib/waza.js"
+ }
+
+The `prepublish` script will be run before publishing, so that users
+can consume the functionality without requiring them to compile it
+themselves. In dev mode (ie, locally running `npm install`), it'll
+run this script as well, so that you can test it easily.
+
+## peerDependencies
+
+In some cases, you want to express the compatibility of your package with an
+host tool or library, while not necessarily doing a `require` of this host.
+This is usually refered to as a *plugin*. Notably, your module may be exposing
+a specific interface, expected and specified by the host documentation.
+
+For example:
+
+ {
+ "name": "tea-latte",
+ "version": "1.3.5"
+ "peerDependencies": {
+ "tea": "2.x"
+ }
+ }
+
+This ensures your package `tea-latte` can be installed *along* with the second
+major version of the host package `tea` only. The host package is automatically
+installed if needed. `npm install tea-latte` could possibly yield the following
+dependency graph:
+
+ ├── tea-latte@1.3.5
+ └── tea@2.2.0
+
+Trying to install another plugin with a conflicting requirement will cause an
+error. For this reason, make sure your plugin requirement is as broad as
+possible, and not to lock it down to specific patch versions.
+
+Assuming the host complies with [semver](http://semver.org/), only changes in
+the host package's major version will break your plugin. Thus, if you've worked
+with every 1.x version of the host package, use `"^1.0"` or `"1.x"` to express
+this. If you depend on features introduced in 1.5.2, use `">= 1.5.2 < 2"`.
+
+## bundledDependencies
+
+Array of package names that will be bundled when publishing the package.
+
+If this is spelled `"bundleDependencies"`, then that is also honorable.
+
+## optionalDependencies
+
+If a dependency can be used, but you would like npm to proceed if it
+cannot be found or fails to install, then you may put it in the
+`optionalDependencies` hash. This is a map of package name to version
+or url, just like the `dependencies` hash. The difference is that
+failure is tolerated.
+
+It is still your program's responsibility to handle the lack of the
+dependency. For example, something like this:
+
+ try {
+ var foo = require('foo')
+ var fooVersion = require('foo/package.json').version
+ } catch (er) {
+ foo = null
+ }
+ if ( notGoodFooVersion(fooVersion) ) {
+ foo = null
+ }
+
+ // .. then later in your program ..
+
+ if (foo) {
+ foo.doFooThings()
+ }
+
+Entries in `optionalDependencies` will override entries of the same name in
+`dependencies`, so it's usually best to only put in one place.
+
+## engines
+
+You can specify the version of node that your stuff works on:
+
+ { "engines" : { "node" : ">=0.10.3 <0.12" } }
+
+And, like with dependencies, if you don't specify the version (or if you
+specify "\*" as the version), then any version of node will do.
+
+If you specify an "engines" field, then npm will require that "node" be
+somewhere on that list. If "engines" is omitted, then npm will just assume
+that it works on node.
+
+You can also use the "engines" field to specify which versions of npm
+are capable of properly installing your program. For example:
+
+ { "engines" : { "npm" : "~1.0.20" } }
+
+Note that, unless the user has set the `engine-strict` config flag, this
+field is advisory only.
+
+## engineStrict
+
+If you are sure that your module will *definitely not* run properly on
+versions of Node/npm other than those specified in the `engines` hash,
+then you can set `"engineStrict": true` in your package.json file.
+This will override the user's `engine-strict` config setting.
+
+Please do not do this unless you are really very very sure. If your
+engines hash is something overly restrictive, you can quite easily and
+inadvertently lock yourself into obscurity and prevent your users from
+updating to new versions of Node. Consider this choice carefully. If
+people abuse it, it will be removed in a future version of npm.
+
+## os
+
+You can specify which operating systems your
+module will run on:
+
+ "os" : [ "darwin", "linux" ]
+
+You can also blacklist instead of whitelist operating systems,
+just prepend the blacklisted os with a '!':
+
+ "os" : [ "!win32" ]
+
+The host operating system is determined by `process.platform`
+
+It is allowed to both blacklist, and whitelist, although there isn't any
+good reason to do this.
+
+## cpu
+
+If your code only runs on certain cpu architectures,
+you can specify which ones.
+
+ "cpu" : [ "x64", "ia32" ]
+
+Like the `os` option, you can also blacklist architectures:
+
+ "cpu" : [ "!arm", "!mips" ]
+
+The host architecture is determined by `process.arch`
+
+## preferGlobal
+
+If your package is primarily a command-line application that should be
+installed globally, then set this value to `true` to provide a warning
+if it is installed locally.
+
+It doesn't actually prevent users from installing it locally, but it
+does help prevent some confusion if it doesn't work as expected.
+
+## private
+
+If you set `"private": true` in your package.json, then npm will refuse
+to publish it.
+
+This is a way to prevent accidental publication of private repositories.
+If you would like to ensure that a given package is only ever published
+to a specific registry (for example, an internal registry),
+then use the `publishConfig` hash described below
+to override the `registry` config param at publish-time.
+
+## publishConfig
+
+This is a set of config values that will be used at publish-time. It's
+especially handy if you want to set the tag or registry, so that you can
+ensure that a given package is not tagged with "latest" or published to
+the global public registry by default.
+
+Any config values can be overridden, but of course only "tag" and
+"registry" probably matter for the purposes of publishing.
+
+See `npm-config(7)` to see the list of config options that can be
+overridden.
+
+## DEFAULT VALUES
+
+npm will default some values based on package contents.
+
+* `"scripts": {"start": "node server.js"}`
+
+ If there is a `server.js` file in the root of your package, then npm
+ will default the `start` command to `node server.js`.
+
+* `"scripts":{"preinstall": "node-gyp rebuild"}`
+
+ If there is a `binding.gyp` file in the root of your package, npm will
+ default the `preinstall` command to compile using node-gyp.
+
+* `"contributors": [...]`
+
+ If there is an `AUTHORS` file in the root of your package, npm will
+ treat each line as a `Name <email> (url)` format, where email and url
+ are optional. Lines which start with a `#` or are blank, will be
+ ignored.
+
+## SEE ALSO
+
+* semver(7)
+* npm-init(1)
+* npm-version(1)
+* npm-config(1)
+* npm-config(7)
+* npm-help(1)
+* npm-faq(7)
+* npm-install(1)
+* npm-publish(1)
+* npm-rm(1)
diff --git a/doc/misc/npm-coding-style.md b/doc/misc/npm-coding-style.md
new file mode 100644
index 0000000..b6a4a62
--- /dev/null
+++ b/doc/misc/npm-coding-style.md
@@ -0,0 +1,181 @@
+npm-coding-style(7) -- npm's "funny" coding style
+=================================================
+
+## DESCRIPTION
+
+npm's coding style is a bit unconventional. It is not different for
+difference's sake, but rather a carefully crafted style that is
+designed to reduce visual clutter and make bugs more apparent.
+
+If you want to contribute to npm (which is very encouraged), you should
+make your code conform to npm's style.
+
+Note: this concerns npm's code not the specific packages at npmjs.org
+
+## Line Length
+
+Keep lines shorter than 80 characters. It's better for lines to be
+too short than to be too long. Break up long lists, objects, and other
+statements onto multiple lines.
+
+## Indentation
+
+Two-spaces. Tabs are better, but they look like hell in web browsers
+(and on github), and node uses 2 spaces, so that's that.
+
+Configure your editor appropriately.
+
+## Curly braces
+
+Curly braces belong on the same line as the thing that necessitates them.
+
+Bad:
+
+ function ()
+ {
+
+Good:
+
+ function () {
+
+If a block needs to wrap to the next line, use a curly brace. Don't
+use it if it doesn't.
+
+Bad:
+
+ if (foo) { bar() }
+ while (foo)
+ bar()
+
+Good:
+
+ if (foo) bar()
+ while (foo) {
+ bar()
+ }
+
+## Semicolons
+
+Don't use them except in four situations:
+
+* `for (;;)` loops. They're actually required.
+* null loops like: `while (something) ;` (But you'd better have a good
+ reason for doing that.)
+* `case "foo": doSomething(); break`
+* In front of a leading `(` or `[` at the start of the line.
+ This prevents the expression from being interpreted
+ as a function call or property access, respectively.
+
+Some examples of good semicolon usage:
+
+ ;(x || y).doSomething()
+ ;[a, b, c].forEach(doSomething)
+ for (var i = 0; i < 10; i ++) {
+ switch (state) {
+ case "begin": start(); continue
+ case "end": finish(); break
+ default: throw new Error("unknown state")
+ }
+ end()
+ }
+
+Note that starting lines with `-` and `+` also should be prefixed
+with a semicolon, but this is much less common.
+
+## Comma First
+
+If there is a list of things separated by commas, and it wraps
+across multiple lines, put the comma at the start of the next
+line, directly below the token that starts the list. Put the
+final token in the list on a line by itself. For example:
+
+ var magicWords = [ "abracadabra"
+ , "gesundheit"
+ , "ventrilo"
+ ]
+ , spells = { "fireball" : function () { setOnFire() }
+ , "water" : function () { putOut() }
+ }
+ , a = 1
+ , b = "abc"
+ , etc
+ , somethingElse
+
+## Whitespace
+
+Put a single space in front of ( for anything other than a function call.
+Also use a single space wherever it makes things more readable.
+
+Don't leave trailing whitespace at the end of lines. Don't indent empty
+lines. Don't use more spaces than are helpful.
+
+## Functions
+
+Use named functions. They make stack traces a lot easier to read.
+
+## Callbacks, Sync/async Style
+
+Use the asynchronous/non-blocking versions of things as much as possible.
+It might make more sense for npm to use the synchronous fs APIs, but this
+way, the fs and http and child process stuff all uses the same callback-passing
+methodology.
+
+The callback should always be the last argument in the list. Its first
+argument is the Error or null.
+
+Be very careful never to ever ever throw anything. It's worse than useless.
+Just send the error message back as the first argument to the callback.
+
+## Errors
+
+Always create a new Error object with your message. Don't just return a
+string message to the callback. Stack traces are handy.
+
+## Logging
+
+Logging is done using the [npmlog](https://github.com/npm/npmlog)
+utility.
+
+Please clean up logs when they are no longer helpful. In particular,
+logging the same object over and over again is not helpful. Logs should
+report what's happening so that it's easier to track down where a fault
+occurs.
+
+Use appropriate log levels. See `npm-config(7)` and search for
+"loglevel".
+
+## Case, naming, etc.
+
+Use `lowerCamelCase` for multiword identifiers when they refer to objects,
+functions, methods, members, or anything not specified in this section.
+
+Use `UpperCamelCase` for class names (things that you'd pass to "new").
+
+Use `all-lower-hyphen-css-case` for multiword filenames and config keys.
+
+Use named functions. They make stack traces easier to follow.
+
+Use `CAPS_SNAKE_CASE` for constants, things that should never change
+and are rarely used.
+
+Use a single uppercase letter for function names where the function
+would normally be anonymous, but needs to call itself recursively. It
+makes it clear that it's a "throwaway" function.
+
+## null, undefined, false, 0
+
+Boolean variables and functions should always be either `true` or
+`false`. Don't set it to 0 unless it's supposed to be a number.
+
+When something is intentionally missing or removed, set it to `null`.
+
+Don't set things to `undefined`. Reserve that value to mean "not yet
+set to anything."
+
+Boolean objects are verboten.
+
+## SEE ALSO
+
+* npm-developers(7)
+* npm-faq(7)
+* npm(1)
diff --git a/doc/misc/npm-config.md b/doc/misc/npm-config.md
new file mode 100644
index 0000000..035923f
--- /dev/null
+++ b/doc/misc/npm-config.md
@@ -0,0 +1,865 @@
+npm-config(7) -- More than you probably want to know about npm configuration
+============================================================================
+
+## DESCRIPTION
+
+npm gets its configuration values from 6 sources, in this priority:
+
+### Command Line Flags
+
+Putting `--foo bar` on the command line sets the `foo` configuration
+parameter to `"bar"`. A `--` argument tells the cli parser to stop
+reading flags. A `--flag` parameter that is at the *end* of the
+command will be given the value of `true`.
+
+### Environment Variables
+
+Any environment variables that start with `npm_config_` will be
+interpreted as a configuration parameter. For example, putting
+`npm_config_foo=bar` in your environment will set the `foo`
+configuration parameter to `bar`. Any environment configurations that
+are not given a value will be given the value of `true`. Config
+values are case-insensitive, so `NPM_CONFIG_FOO=bar` will work the
+same.
+
+### npmrc Files
+
+The four relevant files are:
+
+* per-project config file (/path/to/my/project/.npmrc)
+* per-user config file (~/.npmrc)
+* global config file ($PREFIX/npmrc)
+* npm builtin config file (/path/to/npm/npmrc)
+
+See npmrc(5) for more details.
+
+### Default Configs
+
+A set of configuration parameters that are internal to npm, and are
+defaults if nothing else is specified.
+
+## Shorthands and Other CLI Niceties
+
+The following shorthands are parsed on the command-line:
+
+* `-v`: `--version`
+* `-h`, `-?`, `--help`, `-H`: `--usage`
+* `-s`, `--silent`: `--loglevel silent`
+* `-q`, `--quiet`: `--loglevel warn`
+* `-d`: `--loglevel info`
+* `-dd`, `--verbose`: `--loglevel verbose`
+* `-ddd`: `--loglevel silly`
+* `-g`: `--global`
+* `-l`: `--long`
+* `-m`: `--message`
+* `-p`, `--porcelain`: `--parseable`
+* `-reg`: `--registry`
+* `-v`: `--version`
+* `-f`: `--force`
+* `-desc`: `--description`
+* `-S`: `--save`
+* `-D`: `--save-dev`
+* `-O`: `--save-optional`
+* `-B`: `--save-bundle`
+* `-E`: `--save-exact`
+* `-y`: `--yes`
+* `-n`: `--yes false`
+* `ll` and `la` commands: `ls --long`
+
+If the specified configuration param resolves unambiguously to a known
+configuration parameter, then it is expanded to that configuration
+parameter. For example:
+
+ npm ls --par
+ # same as:
+ npm ls --parseable
+
+If multiple single-character shorthands are strung together, and the
+resulting combination is unambiguously not some other configuration
+param, then it is expanded to its various component pieces. For
+example:
+
+ npm ls -gpld
+ # same as:
+ npm ls --global --parseable --long --loglevel info
+
+## Per-Package Config Settings
+
+When running scripts (see `npm-scripts(7)`) the package.json "config"
+keys are overwritten in the environment if there is a config param of
+`<name>[@<version>]:<key>`. For example, if the package.json has
+this:
+
+ { "name" : "foo"
+ , "config" : { "port" : "8080" }
+ , "scripts" : { "start" : "node server.js" } }
+
+and the server.js is this:
+
+ http.createServer(...).listen(process.env.npm_package_config_port)
+
+then the user could change the behavior by doing:
+
+ npm config set foo:port 80
+
+See package.json(5) for more information.
+
+## Config Settings
+
+### always-auth
+
+* Default: false
+* Type: Boolean
+
+Force npm to always require authentication when accessing the registry,
+even for `GET` requests.
+
+### bin-links
+
+* Default: `true`
+* Type: Boolean
+
+Tells npm to create symlinks (or `.cmd` shims on Windows) for package
+executables.
+
+Set to false to have it not do this. This can be used to work around
+the fact that some file systems don't support symlinks, even on
+ostensibly Unix systems.
+
+### browser
+
+* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"`
+* Type: String
+
+The browser that is called by the `npm docs` command to open websites.
+
+### ca
+
+* Default: The npm CA certificate
+* Type: String or null
+
+The Certificate Authority signing certificate that is trusted for SSL
+connections to the registry.
+
+Set to `null` to only allow "known" registrars, or to a specific CA cert
+to trust only that specific signing authority.
+
+See also the `strict-ssl` config.
+
+### cafile
+
+* Default: `null`
+* Type: path
+
+A path to a file containing one or multiple Certificate Authority signing
+certificates. Similar to the `ca` setting, but allows for multiple CA's, as
+well as for the CA information to be stored in a file on disk.
+
+### cache
+
+* Default: Windows: `%AppData%\npm-cache`, Posix: `~/.npm`
+* Type: path
+
+The location of npm's cache directory. See `npm-cache(1)`
+
+### cache-lock-stale
+
+* Default: 60000 (1 minute)
+* Type: Number
+
+The number of ms before cache folder lockfiles are considered stale.
+
+### cache-lock-retries
+
+* Default: 10
+* Type: Number
+
+Number of times to retry to acquire a lock on cache folder lockfiles.
+
+### cache-lock-wait
+
+* Default: 10000 (10 seconds)
+* Type: Number
+
+Number of ms to wait for cache lock files to expire.
+
+### cache-max
+
+* Default: Infinity
+* Type: Number
+
+The maximum time (in seconds) to keep items in the registry cache before
+re-checking against the registry.
+
+Note that no purging is done unless the `npm cache clean` command is
+explicitly used, and that only GET requests use the cache.
+
+### cache-min
+
+* Default: 10
+* Type: Number
+
+The minimum time (in seconds) to keep items in the registry cache before
+re-checking against the registry.
+
+Note that no purging is done unless the `npm cache clean` command is
+explicitly used, and that only GET requests use the cache.
+
+### cert
+
+* Default: `null`
+* Type: String
+
+A client certificate to pass when accessing the registry.
+
+### color
+
+* Default: true on Posix, false on Windows
+* Type: Boolean or `"always"`
+
+If false, never shows colors. If `"always"` then always shows colors.
+If true, then only prints color codes for tty file descriptors.
+
+### depth
+
+* Default: Infinity
+* Type: Number
+
+The depth to go when recursing directories for `npm ls` and
+`npm cache ls`.
+
+### description
+
+* Default: true
+* Type: Boolean
+
+Show the description in `npm search`
+
+### dev
+
+* Default: false
+* Type: Boolean
+
+Install `dev-dependencies` along with packages.
+
+Note that `dev-dependencies` are also installed if the `npat` flag is
+set.
+
+### editor
+
+* Default: `EDITOR` environment variable if set, or `"vi"` on Posix,
+ or `"notepad"` on Windows.
+* Type: path
+
+The command to run for `npm edit` or `npm config edit`.
+
+### email
+
+The email of the logged-in user.
+
+Set by the `npm adduser` command. Should not be set explicitly.
+
+### engine-strict
+
+* Default: false
+* Type: Boolean
+
+If set to true, then npm will stubbornly refuse to install (or even
+consider installing) any package that claims to not be compatible with
+the current Node.js version.
+
+### force
+
+* Default: false
+* Type: Boolean
+
+Makes various commands more forceful.
+
+* lifecycle script failure does not block progress.
+* publishing clobbers previously published versions.
+* skips cache when requesting from the registry.
+* prevents checks against clobbering non-npm files.
+
+### fetch-retries
+
+* Default: 2
+* Type: Number
+
+The "retries" config for the `retry` module to use when fetching
+packages from the registry.
+
+### fetch-retry-factor
+
+* Default: 10
+* Type: Number
+
+The "factor" config for the `retry` module to use when fetching
+packages.
+
+### fetch-retry-mintimeout
+
+* Default: 10000 (10 seconds)
+* Type: Number
+
+The "minTimeout" config for the `retry` module to use when fetching
+packages.
+
+### fetch-retry-maxtimeout
+
+* Default: 60000 (1 minute)
+* Type: Number
+
+The "maxTimeout" config for the `retry` module to use when fetching
+packages.
+
+### git
+
+* Default: `"git"`
+* Type: String
+
+The command to use for git commands. If git is installed on the
+computer, but is not in the `PATH`, then set this to the full path to
+the git binary.
+
+### git-tag-version
+
+* Default: `true`
+* Type: Boolean
+
+Tag the commit when using the `npm version` command.
+
+### global
+
+* Default: false
+* Type: Boolean
+
+Operates in "global" mode, so that packages are installed into the
+`prefix` folder instead of the current working directory. See
+`npm-folders(5)` for more on the differences in behavior.
+
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead of the
+ current working directory.
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
+
+### globalconfig
+
+* Default: {prefix}/etc/npmrc
+* Type: path
+
+The config file to read for global config options.
+
+### group
+
+* Default: GID of the current process
+* Type: String or Number
+
+The group to use when running package scripts in global mode as the root
+user.
+
+### heading
+
+* Default: `"npm"`
+* Type: String
+
+The string that starts all the debugging log output.
+
+### https-proxy
+
+* Default: the `HTTPS_PROXY` or `https_proxy` or `HTTP_PROXY` or
+ `http_proxy` environment variables.
+* Type: url
+
+A proxy to use for outgoing https requests.
+
+### ignore-scripts
+
+* Default: false
+* Type: Boolean
+
+If true, npm does not run scripts specified in package.json files.
+
+### init-module
+
+* Default: ~/.npm-init.js
+* Type: path
+
+A module that will be loaded by the `npm init` command. See the
+documentation for the
+[init-package-json](https://github.com/isaacs/init-package-json) module
+for more information, or npm-init(1).
+
+### init.author.name
+
+* Default: ""
+* Type: String
+
+The value `npm init` should use by default for the package author's name.
+
+### init.author.email
+
+* Default: ""
+* Type: String
+
+The value `npm init` should use by default for the package author's email.
+
+### init.author.url
+
+* Default: ""
+* Type: String
+
+The value `npm init` should use by default for the package author's homepage.
+
+### init.license
+
+* Default: "ISC"
+* Type: String
+
+The value `npm init` should use by default for the package license.
+
+### json
+
+* Default: false
+* Type: Boolean
+
+Whether or not to output JSON data, rather than the normal output.
+
+This feature is currently experimental, and the output data structures
+for many commands is either not implemented in JSON yet, or subject to
+change. Only the output from `npm ls --json` is currently valid.
+
+### key
+
+* Default: `null`
+* Type: String
+
+A client key to pass when accessing the registry.
+
+### link
+
+* Default: false
+* Type: Boolean
+
+If true, then local installs will link if there is a suitable globally
+installed package.
+
+Note that this means that local installs can cause things to be
+installed into the global space at the same time. The link is only done
+if one of the two conditions are met:
+
+* The package is not already installed globally, or
+* the globally installed version is identical to the version that is
+ being installed locally.
+
+### local-address
+
+* Default: undefined
+* Type: IP Address
+
+The IP address of the local interface to use when making connections
+to the npm registry. Must be IPv4 in versions of Node prior to 0.12.
+
+### loglevel
+
+* Default: "http"
+* Type: String
+* Values: "silent", "win", "error", "warn", "http", "info", "verbose", "silly"
+
+What level of logs to report. On failure, *all* logs are written to
+`npm-debug.log` in the current working directory.
+
+Any logs of a higher level than the setting are shown.
+The default is "http", which shows http, warn, and error output.
+
+### logstream
+
+* Default: process.stderr
+* Type: Stream
+
+This is the stream that is passed to the
+[npmlog](https://github.com/npm/npmlog) module at run time.
+
+It cannot be set from the command line, but if you are using npm
+programmatically, you may wish to send logs to somewhere other than
+stderr.
+
+If the `color` config is set to true, then this stream will receive
+colored output if it is a TTY.
+
+### long
+
+* Default: false
+* Type: Boolean
+
+Show extended information in `npm ls` and `npm search`.
+
+### message
+
+* Default: "%s"
+* Type: String
+
+Commit message which is used by `npm version` when creating version commit.
+
+Any "%s" in the message will be replaced with the version number.
+
+### node-version
+
+* Default: process.version
+* Type: semver or false
+
+The node version to use when checking package's "engines" hash.
+
+### npat
+
+* Default: false
+* Type: Boolean
+
+Run tests on installation.
+
+### onload-script
+
+* Default: false
+* Type: path
+
+A node module to `require()` when npm loads. Useful for programmatic
+usage.
+
+### optional
+
+* Default: true
+* Type: Boolean
+
+Attempt to install packages in the `optionalDependencies` hash. Note
+that if these packages fail to install, the overall installation
+process is not aborted.
+
+### parseable
+
+* Default: false
+* Type: Boolean
+
+Output parseable results from commands that write to
+standard output.
+
+### prefix
+
+* Default: see npm-folders(5)
+* Type: path
+
+The location to install global items. If set on the command line, then
+it forces non-global commands to run in the specified folder.
+
+### production
+
+* Default: false
+* Type: Boolean
+
+Set to true to run in "production" mode.
+
+1. devDependencies are not installed at the topmost level when running
+ local `npm install` without any arguments.
+2. Set the NODE_ENV="production" for lifecycle scripts.
+
+### proprietary-attribs
+
+* Default: true
+* Type: Boolean
+
+Whether or not to include proprietary extended attributes in the
+tarballs created by npm.
+
+Unless you are expecting to unpack package tarballs with something other
+than npm -- particularly a very outdated tar implementation -- leave
+this as true.
+
+### proxy
+
+* Default: `HTTP_PROXY` or `http_proxy` environment variable, or null
+* Type: url
+
+A proxy to use for outgoing http requests.
+
+### rebuild-bundle
+
+* Default: true
+* Type: Boolean
+
+Rebuild bundled dependencies after installation.
+
+### registry
+
+* Default: https://registry.npmjs.org/
+* Type: url
+
+The base URL of the npm package registry.
+
+### rollback
+
+* Default: true
+* Type: Boolean
+
+Remove failed installs.
+
+### save
+
+* Default: false
+* Type: Boolean
+
+Save installed packages to a package.json file as dependencies.
+
+When used with the `npm rm` command, it removes it from the dependencies
+hash.
+
+Only works if there is already a package.json file present.
+
+### save-bundle
+
+* Default: false
+* Type: Boolean
+
+If a package would be saved at install time by the use of `--save`,
+`--save-dev`, or `--save-optional`, then also put it in the
+`bundleDependencies` list.
+
+When used with the `npm rm` command, it removes it from the
+bundledDependencies list.
+
+### save-dev
+
+* Default: false
+* Type: Boolean
+
+Save installed packages to a package.json file as devDependencies.
+
+When used with the `npm rm` command, it removes it from the
+devDependencies hash.
+
+Only works if there is already a package.json file present.
+
+### save-exact
+
+* Default: false
+* Type: Boolean
+
+Dependencies saved to package.json using `--save`, `--save-dev` or
+`--save-optional` will be configured with an exact version rather than
+using npm's default semver range operator.
+
+### save-optional
+
+* Default: false
+* Type: Boolean
+
+Save installed packages to a package.json file as
+optionalDependencies.
+
+When used with the `npm rm` command, it removes it from the
+devDependencies hash.
+
+Only works if there is already a package.json file present.
+
+### save-prefix
+
+* Default: '^'
+* Type: String
+
+Configure how versions of packages installed to a package.json file via
+`--save` or `--save-dev` get prefixed.
+
+For example if a package has version `1.2.3`, by default it's version is
+set to `^1.2.3` which allows minor upgrades for that package, but after
+`npm config set save-prefix='~'` it would be set to `~1.2.3` which only allows
+patch upgrades.
+
+### searchopts
+
+* Default: ""
+* Type: String
+
+Space-separated options that are always passed to search.
+
+### searchexclude
+
+* Default: ""
+* Type: String
+
+Space-separated options that limit the results from search.
+
+### searchsort
+
+* Default: "name"
+* Type: String
+* Values: "name", "-name", "date", "-date", "description",
+ "-description", "keywords", "-keywords"
+
+Indication of which field to sort search results by. Prefix with a `-`
+character to indicate reverse sort.
+
+### shell
+
+* Default: SHELL environment variable, or "bash" on Posix, or "cmd" on
+ Windows
+* Type: path
+
+The shell to run for the `npm explore` command.
+
+### shrinkwrap
+
+* Default: true
+* Type: Boolean
+
+If set to false, then ignore `npm-shrinkwrap.json` files when
+installing.
+
+### sign-git-tag
+
+* Default: false
+* Type: Boolean
+
+If set to true, then the `npm version` command will tag the version
+using `-s` to add a signature.
+
+Note that git requires you to have set up GPG keys in your git configs
+for this to work properly.
+
+### spin
+
+* Default: true
+* Type: Boolean or `"always"`
+
+When set to `true`, npm will display an ascii spinner while it is doing
+things, if `process.stderr` is a TTY.
+
+Set to `false` to suppress the spinner, or set to `always` to output
+the spinner even for non-TTY outputs.
+
+### strict-ssl
+
+* Default: true
+* Type: Boolean
+
+Whether or not to do SSL key validation when making requests to the
+registry via https.
+
+See also the `ca` config.
+
+### tag
+
+* Default: latest
+* Type: String
+
+If you ask npm to install a package and don't tell it a specific version, then
+it will install the specified tag.
+
+Also the tag that is added to the package@version specified by the `npm
+tag` command, if no explicit tag is given.
+
+### tmp
+
+* Default: TMPDIR environment variable, or "/tmp"
+* Type: path
+
+Where to store temporary files and folders. All temp files are deleted
+on success, but left behind on failure for forensic purposes.
+
+### unicode
+
+* Default: true
+* Type: Boolean
+
+When set to true, npm uses unicode characters in the tree output. When
+false, it uses ascii characters to draw trees.
+
+### unsafe-perm
+
+* Default: false if running as root, true otherwise
+* Type: Boolean
+
+Set to true to suppress the UID/GID switching when running package
+scripts. If set explicitly to false, then installing as a non-root user
+will fail.
+
+### usage
+
+* Default: false
+* Type: Boolean
+
+Set to show short usage output (like the -H output)
+instead of complete help when doing `npm-help(1)`.
+
+### user
+
+* Default: "nobody"
+* Type: String or Number
+
+The UID to set to when running package scripts as root.
+
+### username
+
+* Default: null
+* Type: String
+
+The username on the npm registry. Set with `npm adduser`
+
+### userconfig
+
+* Default: ~/.npmrc
+* Type: path
+
+The location of user-level configuration settings.
+
+### umask
+
+* Default: 022
+* Type: Octal numeric string
+
+The "umask" value to use when setting the file creation mode on files
+and folders.
+
+Folders and executables are given a mode which is `0777` masked against
+this value. Other files are given a mode which is `0666` masked against
+this value. Thus, the defaults are `0755` and `0644` respectively.
+
+### user-agent
+
+* Default: node/{process.version} {process.platform} {process.arch}
+* Type: String
+
+Sets a User-Agent to the request header
+
+### version
+
+* Default: false
+* Type: boolean
+
+If true, output the npm version and exit successfully.
+
+Only relevant when specified explicitly on the command line.
+
+### versions
+
+* Default: false
+* Type: boolean
+
+If true, output the npm version as well as node's `process.versions`
+hash, and exit successfully.
+
+Only relevant when specified explicitly on the command line.
+
+### viewer
+
+* Default: "man" on Posix, "browser" on Windows
+* Type: path
+
+The program to use to view help content.
+
+Set to `"browser"` to view html help content in the default web browser.
+
+## SEE ALSO
+
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-scripts(7)
+* npm-folders(5)
+* npm(1)
diff --git a/doc/misc/npm-developers.md b/doc/misc/npm-developers.md
new file mode 100644
index 0000000..5e53301
--- /dev/null
+++ b/doc/misc/npm-developers.md
@@ -0,0 +1,207 @@
+npm-developers(7) -- Developer Guide
+====================================
+
+## DESCRIPTION
+
+So, you've decided to use npm to develop (and maybe publish/deploy)
+your project.
+
+Fantastic!
+
+There are a few things that you need to do above the simple steps
+that your users will do to install your program.
+
+## About These Documents
+
+These are man pages. If you install npm, you should be able to
+then do `man npm-thing` to get the documentation on a particular
+topic, or `npm help thing` to see the same information.
+
+## What is a `package`
+
+A package is:
+
+* a) a folder containing a program described by a package.json file
+* b) a gzipped tarball containing (a)
+* c) a url that resolves to (b)
+* d) a `<name>@<version>` that is published on the registry with (c)
+* e) a `<name>@<tag>` that points to (d)
+* f) a `<name>` that has a "latest" tag satisfying (e)
+* g) a `git` url that, when cloned, results in (a).
+
+Even if you never publish your package, you can still get a lot of
+benefits of using npm if you just want to write a node program (a), and
+perhaps if you also want to be able to easily install it elsewhere
+after packing it up into a tarball (b).
+
+Git urls can be of the form:
+
+ git://github.com/user/project.git#commit-ish
+ git+ssh://user@hostname:project.git#commit-ish
+ git+http://user@hostname/project/blah.git#commit-ish
+ git+https://user@hostname/project/blah.git#commit-ish
+
+The `commit-ish` can be any tag, sha, or branch which can be supplied as
+an argument to `git checkout`. The default is `master`.
+
+## The package.json File
+
+You need to have a `package.json` file in the root of your project to do
+much of anything with npm. That is basically the whole interface.
+
+See `package.json(5)` for details about what goes in that file. At the very
+least, you need:
+
+* name:
+ This should be a string that identifies your project. Please do not
+ use the name to specify that it runs on node, or is in JavaScript.
+ You can use the "engines" field to explicitly state the versions of
+ node (or whatever else) that your program requires, and it's pretty
+ well assumed that it's javascript.
+
+ It does not necessarily need to match your github repository name.
+
+ So, `node-foo` and `bar-js` are bad names. `foo` or `bar` are better.
+
+* version:
+ A semver-compatible version.
+
+* engines:
+ Specify the versions of node (or whatever else) that your program
+ runs on. The node API changes a lot, and there may be bugs or new
+ functionality that you depend on. Be explicit.
+
+* author:
+ Take some credit.
+
+* scripts:
+ If you have a special compilation or installation script, then you
+ should put it in the `scripts` hash. You should definitely have at
+ least a basic smoke-test command as the "scripts.test" field.
+ See npm-scripts(7).
+
+* main:
+ If you have a single module that serves as the entry point to your
+ program (like what the "foo" package gives you at require("foo")),
+ then you need to specify that in the "main" field.
+
+* directories:
+ This is a hash of folders. The best ones to include are "lib" and
+ "doc", but if you specify a folder full of man pages in "man", then
+ they'll get installed just like these ones.
+
+You can use `npm init` in the root of your package in order to get you
+started with a pretty basic package.json file. See `npm-init(1)` for
+more info.
+
+## Keeping files *out* of your package
+
+Use a `.npmignore` file to keep stuff out of your package. If there's
+no `.npmignore` file, but there *is* a `.gitignore` file, then npm will
+ignore the stuff matched by the `.gitignore` file. If you *want* to
+include something that is excluded by your `.gitignore` file, you can
+create an empty `.npmignore` file to override it.
+
+By default, the following paths and files are ignored, so there's no
+need to add them to `.npmignore` explicitly:
+
+* `.*.swp`
+* `._*`
+* `.DS_Store`
+* `.git`
+* `.hg`
+* `.lock-wscript`
+* `.svn`
+* `.wafpickle-*`
+* `CVS`
+* `npm-debug.log`
+
+Additionally, everything in `node_modules` is ignored, except for
+bundled dependencies. npm automatically handles this for you, so don't
+bother adding `node_modules` to `.npmignore`.
+
+The following paths and files are never ignored, so adding them to
+`.npmignore` is pointless:
+
+* `package.json`
+* `README.*`
+
+## Link Packages
+
+`npm link` is designed to install a development package and see the
+changes in real time without having to keep re-installing it. (You do
+need to either re-link or `npm rebuild -g` to update compiled packages,
+of course.)
+
+More info at `npm-link(1)`.
+
+## Before Publishing: Make Sure Your Package Installs and Works
+
+**This is important.**
+
+If you can not install it locally, you'll have
+problems trying to publish it. Or, worse yet, you'll be able to
+publish it, but you'll be publishing a broken or pointless package.
+So don't do that.
+
+In the root of your package, do this:
+
+ npm install . -g
+
+That'll show you that it's working. If you'd rather just create a symlink
+package that points to your working directory, then do this:
+
+ npm link
+
+Use `npm ls -g` to see if it's there.
+
+To test a local install, go into some other folder, and then do:
+
+ cd ../some-other-folder
+ npm install ../my-package
+
+to install it locally into the node_modules folder in that other place.
+
+Then go into the node-repl, and try using require("my-thing") to
+bring in your module's main module.
+
+## Create a User Account
+
+Create a user with the adduser command. It works like this:
+
+ npm adduser
+
+and then follow the prompts.
+
+This is documented better in npm-adduser(1).
+
+## Publish your package
+
+This part's easy. IN the root of your folder, do this:
+
+ npm publish
+
+You can give publish a url to a tarball, or a filename of a tarball,
+or a path to a folder.
+
+Note that pretty much **everything in that folder will be exposed**
+by default. So, if you have secret stuff in there, use a
+`.npmignore` file to list out the globs to ignore, or publish
+from a fresh checkout.
+
+## Brag about it
+
+Send emails, write blogs, blab in IRC.
+
+Tell the world how easy it is to install your program!
+
+## SEE ALSO
+
+* npm-faq(7)
+* npm(1)
+* npm-init(1)
+* package.json(5)
+* npm-scripts(7)
+* npm-publish(1)
+* npm-adduser(1)
+* npm-registry(7)
diff --git a/doc/misc/npm-disputes.md b/doc/misc/npm-disputes.md
new file mode 100644
index 0000000..9fb1eaa
--- /dev/null
+++ b/doc/misc/npm-disputes.md
@@ -0,0 +1,99 @@
+npm-disputes(7) -- Handling Module Name Disputes
+================================================
+
+## SYNOPSIS
+
+1. Get the author email with `npm owner ls <pkgname>`
+2. Email the author, CC <support@npmjs.com>
+3. After a few weeks, if there's no resolution, we'll sort it out.
+
+Don't squat on package names. Publish code or move out of the way.
+
+## DESCRIPTION
+
+There sometimes arise cases where a user publishes a module, and then
+later, some other user wants to use that name. Here are some common
+ways that happens (each of these is based on actual events.)
+
+1. Joe writes a JavaScript module `foo`, which is not node-specific.
+ Joe doesn't use node at all. Bob wants to use `foo` in node, so he
+ wraps it in an npm module. Some time later, Joe starts using node,
+ and wants to take over management of his program.
+2. Bob writes an npm module `foo`, and publishes it. Perhaps much
+ later, Joe finds a bug in `foo`, and fixes it. He sends a pull
+ request to Bob, but Bob doesn't have the time to deal with it,
+ because he has a new job and a new baby and is focused on his new
+ erlang project, and kind of not involved with node any more. Joe
+ would like to publish a new `foo`, but can't, because the name is
+ taken.
+3. Bob writes a 10-line flow-control library, and calls it `foo`, and
+ publishes it to the npm registry. Being a simple little thing, it
+ never really has to be updated. Joe works for Foo Inc, the makers
+ of the critically acclaimed and widely-marketed `foo` JavaScript
+ toolkit framework. They publish it to npm as `foojs`, but people are
+ routinely confused when `npm install foo` is some different thing.
+4. Bob writes a parser for the widely-known `foo` file format, because
+ he needs it for work. Then, he gets a new job, and never updates the
+ prototype. Later on, Joe writes a much more complete `foo` parser,
+ but can't publish, because Bob's `foo` is in the way.
+
+The validity of Joe's claim in each situation can be debated. However,
+Joe's appropriate course of action in each case is the same.
+
+1. `npm owner ls foo`. This will tell Joe the email address of the
+ owner (Bob).
+2. Joe emails Bob, explaining the situation **as respectfully as
+ possible**, and what he would like to do with the module name. He
+ adds the npm support staff <support@npmjs.com> to the CC list of
+ the email. Mention in the email that Bob can run `npm owner add
+ joe foo` to add Joe as an owner of the `foo` package.
+3. After a reasonable amount of time, if Bob has not responded, or if
+ Bob and Joe can't come to any sort of resolution, email support
+ <support@npmjs.com> and we'll sort it out. ("Reasonable" is
+ usually at least 4 weeks, but extra time is allowed around common
+ holidays.)
+
+## REASONING
+
+In almost every case so far, the parties involved have been able to reach
+an amicable resolution without any major intervention. Most people
+really do want to be reasonable, and are probably not even aware that
+they're in your way.
+
+Module ecosystems are most vibrant and powerful when they are as
+self-directed as possible. If an admin one day deletes something you
+had worked on, then that is going to make most people quite upset,
+regardless of the justification. When humans solve their problems by
+talking to other humans with respect, everyone has the chance to end up
+feeling good about the interaction.
+
+## EXCEPTIONS
+
+Some things are not allowed, and will be removed without discussion if
+they are brought to the attention of the npm registry admins, including
+but not limited to:
+
+1. Malware (that is, a package designed to exploit or harm the machine on
+ which it is installed).
+2. Violations of copyright or licenses (for example, cloning an
+ MIT-licensed program, and then removing or changing the copyright and
+ license statement).
+3. Illegal content.
+4. "Squatting" on a package name that you *plan* to use, but aren't
+ actually using. Sorry, I don't care how great the name is, or how
+ perfect a fit it is for the thing that someday might happen. If
+ someone wants to use it today, and you're just taking up space with
+ an empty tarball, you're going to be evicted.
+5. Putting empty packages in the registry. Packages must have SOME
+ functionality. It can be silly, but it can't be *nothing*. (See
+ also: squatting.)
+6. Doing weird things with the registry, like using it as your own
+ personal application database or otherwise putting non-packagey
+ things into it.
+
+If you see bad behavior like this, please report it right away.
+
+## SEE ALSO
+
+* npm-registry(7)
+* npm-owner(1)
diff --git a/doc/misc/npm-faq.md b/doc/misc/npm-faq.md
new file mode 100644
index 0000000..53fa03d
--- /dev/null
+++ b/doc/misc/npm-faq.md
@@ -0,0 +1,364 @@
+npm-faq(7) -- Frequently Asked Questions
+========================================
+
+## Where can I find these docs in HTML?
+
+<https://www.npmjs.org/doc/>, or run:
+
+ npm config set viewer browser
+
+to open these documents in your default web browser rather than `man`.
+
+## It didn't work.
+
+That's not really a question.
+
+## Why didn't it work?
+
+I don't know yet.
+
+Read the error output, and if you can't figure out what it means,
+do what it says and post a bug with all the information it asks for.
+
+## Where does npm put stuff?
+
+See `npm-folders(5)`
+
+tl;dr:
+
+* Use the `npm root` command to see where modules go, and the `npm bin`
+ command to see where executables go
+* Global installs are different from local installs. If you install
+ something with the `-g` flag, then its executables go in `npm bin -g`
+ and its modules go in `npm root -g`.
+
+## How do I install something on my computer in a central location?
+
+Install it globally by tacking `-g` or `--global` to the command. (This
+is especially important for command line utilities that need to add
+their bins to the global system `PATH`.)
+
+## I installed something globally, but I can't `require()` it
+
+Install it locally.
+
+The global install location is a place for command-line utilities
+to put their bins in the system `PATH`. It's not for use with `require()`.
+
+If you `require()` a module in your code, then that means it's a
+dependency, and a part of your program. You need to install it locally
+in your program.
+
+## Why can't npm just put everything in one place, like other package managers?
+
+Not every change is an improvement, but every improvement is a change.
+This would be like asking git to do network IO for every commit. It's
+not going to happen, because it's a terrible idea that causes more
+problems than it solves.
+
+It is much harder to avoid dependency conflicts without nesting
+dependencies. This is fundamental to the way that npm works, and has
+proven to be an extremely successful approach. See `npm-folders(5)` for
+more details.
+
+If you want a package to be installed in one place, and have all your
+programs reference the same copy of it, then use the `npm link` command.
+That's what it's for. Install it globally, then link it into each
+program that uses it.
+
+## Whatever, I really want the old style 'everything global' style.
+
+Write your own package manager. You could probably even wrap up `npm`
+in a shell script if you really wanted to.
+
+npm will not help you do something that is known to be a bad idea.
+
+## Should I check my `node_modules` folder into git?
+
+Mikeal Rogers answered this question very well:
+
+<http://www.futurealoof.com/posts/nodemodules-in-git.html>
+
+tl;dr
+
+* Check `node_modules` into git for things you **deploy**, such as
+ websites and apps.
+* Do not check `node_modules` into git for libraries and modules
+ intended to be reused.
+* Use npm to manage dependencies in your dev environment, but not in
+ your deployment scripts.
+
+## Is it 'npm' or 'NPM' or 'Npm'?
+
+npm should never be capitalized unless it is being displayed in a
+location that is customarily all-caps (such as the title of man pages.)
+
+## If 'npm' is an acronym, why is it never capitalized?
+
+Contrary to the belief of many, "npm" is not in fact an abbreviation for
+"Node Package Manager". It is a recursive bacronymic abbreviation for
+"npm is not an acronym". (If it was "ninaa", then it would be an
+acronym, and thus incorrectly named.)
+
+"NPM", however, *is* an acronym (more precisely, a capitonym) for the
+National Association of Pastoral Musicians. You can learn more
+about them at <http://npm.org/>.
+
+In software, "NPM" is a Non-Parametric Mapping utility written by
+Chris Rorden. You can analyze pictures of brains with it. Learn more
+about the (capitalized) NPM program at <http://www.cabiatl.com/mricro/npm/>.
+
+The first seed that eventually grew into this flower was a bash utility
+named "pm", which was a shortened descendent of "pkgmakeinst", a
+bash function that was used to install various different things on different
+platforms, most often using Yahoo's `yinst`. If `npm` was ever an
+acronym for anything, it was `node pm` or maybe `new pm`.
+
+So, in all seriousness, the "npm" project is named after its command-line
+utility, which was organically selected to be easily typed by a right-handed
+programmer using a US QWERTY keyboard layout, ending with the
+right-ring-finger in a postition to type the `-` key for flags and
+other command-line arguments. That command-line utility is always
+lower-case, though it starts most sentences it is a part of.
+
+## How do I list installed packages?
+
+`npm ls`
+
+## How do I search for packages?
+
+`npm search`
+
+Arguments are greps. `npm search jsdom` shows jsdom packages.
+
+## How do I update npm?
+
+ npm update npm -g
+
+You can also update all outdated local packages by doing `npm update` without
+any arguments, or global packages by doing `npm update -g`.
+
+Occasionally, the version of npm will progress such that the current
+version cannot be properly installed with the version that you have
+installed already. (Consider, if there is ever a bug in the `update`
+command.)
+
+In those cases, you can do this:
+
+ curl https://www.npmjs.org/install.sh | sh
+
+## What is a `package`?
+
+A package is:
+
+* a) a folder containing a program described by a package.json file
+* b) a gzipped tarball containing (a)
+* c) a url that resolves to (b)
+* d) a `<name>@<version>` that is published on the registry with (c)
+* e) a `<name>@<tag>` that points to (d)
+* f) a `<name>` that has a "latest" tag satisfying (e)
+* g) a `git` url that, when cloned, results in (a).
+
+Even if you never publish your package, you can still get a lot of
+benefits of using npm if you just want to write a node program (a), and
+perhaps if you also want to be able to easily install it elsewhere
+after packing it up into a tarball (b).
+
+Git urls can be of the form:
+
+ git://github.com/user/project.git#commit-ish
+ git+ssh://user@hostname:project.git#commit-ish
+ git+http://user@hostname/project/blah.git#commit-ish
+ git+https://user@hostname/project/blah.git#commit-ish
+
+The `commit-ish` can be any tag, sha, or branch which can be supplied as
+an argument to `git checkout`. The default is `master`.
+
+## What is a `module`?
+
+A module is anything that can be loaded with `require()` in a Node.js
+program. The following things are all examples of things that can be
+loaded as modules:
+
+* A folder with a `package.json` file containing a `main` field.
+* A folder with an `index.js` file in it.
+* A JavaScript file.
+
+Most npm packages are modules, because they are libraries that you
+load with `require`. However, there's no requirement that an npm
+package be a module! Some only contain an executable command-line
+interface, and don't provide a `main` field for use in Node programs.
+
+Almost all npm packages (at least, those that are Node programs)
+*contain* many modules within them (because every file they load with
+`require()` is a module).
+
+In the context of a Node program, the `module` is also the thing that
+was loaded *from* a file. For example, in the following program:
+
+ var req = require('request')
+
+we might say that "The variable `req` refers to the `request` module".
+
+## So, why is it the "`node_modules`" folder, but "`package.json`" file? Why not `node_packages` or `module.json`?
+
+The `package.json` file defines the package. (See "What is a
+package?" above.)
+
+The `node_modules` folder is the place Node.js looks for modules.
+(See "What is a module?" above.)
+
+For example, if you create a file at `node_modules/foo.js` and then
+had a program that did `var f = require('foo.js')` then it would load
+the module. However, `foo.js` is not a "package" in this case,
+because it does not have a package.json.
+
+Alternatively, if you create a package which does not have an
+`index.js` or a `"main"` field in the `package.json` file, then it is
+not a module. Even if it's installed in `node_modules`, it can't be
+an argument to `require()`.
+
+## `"node_modules"` is the name of my deity's arch-rival, and a Forbidden Word in my religion. Can I configure npm to use a different folder?
+
+No. This will never happen. This question comes up sometimes,
+because it seems silly from the outside that npm couldn't just be
+configured to put stuff somewhere else, and then npm could load them
+from there. It's an arbitrary spelling choice, right? What's the big
+deal?
+
+At the time of this writing, the string `'node_modules'` appears 151
+times in 53 separate files in npm and node core (excluding tests and
+documentation).
+
+Some of these references are in node's built-in module loader. Since
+npm is not involved **at all** at run-time, node itself would have to
+be configured to know where you've decided to stick stuff. Complexity
+hurdle #1. Since the Node module system is locked, this cannot be
+changed, and is enough to kill this request. But I'll continue, in
+deference to your deity's delicate feelings regarding spelling.
+
+Many of the others are in dependencies that npm uses, which are not
+necessarily tightly coupled to npm (in the sense that they do not read
+npm's configuration files, etc.) Each of these would have to be
+configured to take the name of the `node_modules` folder as a
+parameter. Complexity hurdle #2.
+
+Furthermore, npm has the ability to "bundle" dependencies by adding
+the dep names to the `"bundledDependencies"` list in package.json,
+which causes the folder to be included in the package tarball. What
+if the author of a module bundles its dependencies, and they use a
+different spelling for `node_modules`? npm would have to rename the
+folder at publish time, and then be smart enough to unpack it using
+your locally configured name. Complexity hurdle #3.
+
+Furthermore, what happens when you *change* this name? Fine, it's
+easy enough the first time, just rename the `node_modules` folders to
+`./blergyblerp/` or whatever name you choose. But what about when you
+change it again? npm doesn't currently track any state about past
+configuration settings, so this would be rather difficult to do
+properly. It would have to track every previous value for this
+config, and always accept any of them, or else yesterday's install may
+be broken tomorrow. Complexity hurdle #4.
+
+Never going to happen. The folder is named `node_modules`. It is
+written indelibly in the Node Way, handed down from the ancient times
+of Node 0.3.
+
+## How do I install node with npm?
+
+You don't. Try one of these node version managers:
+
+Unix:
+
+* <http://github.com/isaacs/nave>
+* <http://github.com/visionmedia/n>
+* <http://github.com/creationix/nvm>
+
+Windows:
+
+* <http://github.com/marcelklehr/nodist>
+* <https://github.com/hakobera/nvmw>
+* <https://github.com/nanjingboy/nvmw>
+
+## How can I use npm for development?
+
+See `npm-developers(7)` and `package.json(5)`.
+
+You'll most likely want to `npm link` your development folder. That's
+awesomely handy.
+
+To set up your own private registry, check out `npm-registry(7)`.
+
+## Can I list a url as a dependency?
+
+Yes. It should be a url to a gzipped tarball containing a single folder
+that has a package.json in its root, or a git url.
+(See "what is a package?" above.)
+
+## How do I symlink to a dev folder so I don't have to keep re-installing?
+
+See `npm-link(1)`
+
+## The package registry website. What is that exactly?
+
+See `npm-registry(7)`.
+
+## I forgot my password, and can't publish. How do I reset it?
+
+Go to <https://npmjs.org/forgot>.
+
+## I get ECONNREFUSED a lot. What's up?
+
+Either the registry is down, or node's DNS isn't able to reach out.
+
+To check if the registry is down, open up
+<https://registry.npmjs.org/> in a web browser. This will also tell
+you if you are just unable to access the internet for some reason.
+
+If the registry IS down, let us know by emailing <support@npmjs.com>
+or posting an issue at <https://github.com/npm/npm/issues>. If it's
+down for the world (and not just on your local network) then we're
+probably already being pinged about it.
+
+You can also often get a faster response by visiting the #npm channel
+on Freenode IRC.
+
+## Why no namespaces?
+
+Please see this discussion: <https://github.com/npm/npm/issues/798>
+
+tl;dr - It doesn't actually make things better, and can make them worse.
+
+If you want to namespace your own packages, you may: simply use the
+`-` character to separate the names. npm is a mostly anarchic system.
+There is not sufficient need to impose namespace rules on everyone.
+
+## Who does npm?
+
+npm was originally written by Isaac Z. Schlueter, and many others have
+contributed to it, some of them quite substantially.
+
+The npm open source project, The npm Registry, and [the community
+website](https://www.npmjs.org) are maintained and operated by the
+good folks at [npm, Inc.](http://www.npmjs.com)
+
+## I have a question or request not addressed here. Where should I put it?
+
+Post an issue on the github project:
+
+* <https://github.com/npm/npm/issues>
+
+## Why does npm hate me?
+
+npm is not capable of hatred. It loves everyone, especially you.
+
+## SEE ALSO
+
+* npm(1)
+* npm-developers(7)
+* package.json(5)
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-config(7)
+* npm-folders(5)
diff --git a/doc/misc/npm-registry.md b/doc/misc/npm-registry.md
new file mode 100644
index 0000000..a8c4b02
--- /dev/null
+++ b/doc/misc/npm-registry.md
@@ -0,0 +1,69 @@
+npm-registry(7) -- The JavaScript Package Registry
+==================================================
+
+## DESCRIPTION
+
+To resolve packages by name and version, npm talks to a registry website
+that implements the CommonJS Package Registry specification for reading
+package info.
+
+Additionally, npm's package registry implementation supports several
+write APIs as well, to allow for publishing packages and managing user
+account information.
+
+The official public npm registry is at <http://registry.npmjs.org/>. It
+is powered by a CouchDB database at
+<http://isaacs.iriscouch.com/registry>. The code for the couchapp is
+available at <http://github.com/npm/npmjs.org>. npm user accounts
+are CouchDB users, stored in the <http://isaacs.iriscouch.com/_users>
+database.
+
+The registry URL is supplied by the `registry` config parameter. See
+`npm-config(1)`, `npmrc(5)`, and `npm-config(7)` for more on managing
+npm's configuration.
+
+## Can I run my own private registry?
+
+Yes!
+
+The easiest way is to replicate the couch database, and use the same (or
+similar) design doc to implement the APIs.
+
+If you set up continuous replication from the official CouchDB, and then
+set your internal CouchDB as the registry config, then you'll be able
+to read any published packages, in addition to your private ones, and by
+default will only publish internally. If you then want to publish a
+package for the whole world to see, you can simply override the
+`--registry` config for that command.
+
+## I don't want my package published in the official registry. It's private.
+
+Set `"private": true` in your package.json to prevent it from being
+published at all, or
+`"publishConfig":{"registry":"http://my-internal-registry.local"}`
+to force it to be published only to your internal registry.
+
+See `package.json(5)` for more info on what goes in the package.json file.
+
+## Will you replicate from my registry into the public one?
+
+No. If you want things to be public, then publish them into the public
+registry using npm. What little security there is would be for nought
+otherwise.
+
+## Do I have to use couchdb to build a registry that npm can talk to?
+
+No, but it's way easier. Basically, yes, you do, or you have to
+effectively implement the entire CouchDB API anyway.
+
+## Is there a website or something to see package docs and such?
+
+Yes, head over to <https://npmjs.org/>
+
+## SEE ALSO
+
+* npm-config(1)
+* npm-config(7)
+* npmrc(5)
+* npm-developers(7)
+* npm-disputes(7)
diff --git a/doc/misc/npm-scripts.md b/doc/misc/npm-scripts.md
new file mode 100644
index 0000000..b49d9e2
--- /dev/null
+++ b/doc/misc/npm-scripts.md
@@ -0,0 +1,245 @@
+npm-scripts(7) -- How npm handles the "scripts" field
+=====================================================
+
+## DESCRIPTION
+
+npm supports the "scripts" member of the package.json script, for the
+following scripts:
+
+* prepublish:
+ Run BEFORE the package is published. (Also run on local `npm
+ install` without any arguments.)
+* publish, postpublish:
+ Run AFTER the package is published.
+* preinstall:
+ Run BEFORE the package is installed
+* install, postinstall:
+ Run AFTER the package is installed.
+* preuninstall, uninstall:
+ Run BEFORE the package is uninstalled.
+* postuninstall:
+ Run AFTER the package is uninstalled.
+* preupdate:
+ Run BEFORE the package is updated with the update command.
+* update, postupdate:
+ Run AFTER the package is updated with the update command.
+* pretest, test, posttest:
+ Run by the `npm test` command.
+* prestop, stop, poststop:
+ Run by the `npm stop` command.
+* prestart, start, poststart:
+ Run by the `npm start` command.
+* prerestart, restart, postrestart:
+ Run by the `npm restart` command. Note: `npm restart` will run the
+ stop and start scripts if no `restart` script is provided.
+
+Additionally, arbitrary scripts can be run by doing
+`npm run-script <pkg> <stage>`.
+
+## NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN
+
+**tl;dr** Don't use `install`. Use a `.gyp` file for compilation, and
+`prepublish` for anything else.
+
+You should almost never have to explicitly set a `preinstall` or
+`install` script. If you are doing this, please consider if there is
+another option.
+
+The only valid use of `install` or `preinstall` scripts is for
+compilation which must be done on the target architecture. In early
+versions of node, this was often done using the `node-waf` scripts, or
+a standalone `Makefile`, and early versions of npm required that it be
+explicitly set in package.json. This was not portable, and harder to
+do properly.
+
+In the current version of node, the standard way to do this is using a
+`.gyp` file. If you have a file with a `.gyp` extension in the root
+of your package, then npm will run the appropriate `node-gyp` commands
+automatically at install time. This is the only officially supported
+method for compiling binary addons, and does not require that you add
+anything to your package.json file.
+
+If you have to do other things before your package is used, in a way
+that is not dependent on the operating system or architecture of the
+target system, then use a `prepublish` script instead. This includes
+tasks such as:
+
+* Compile CoffeeScript source code into JavaScript.
+* Create minified versions of JavaScript source code.
+* Fetching remote resources that your package will use.
+
+The advantage of doing these things at `prepublish` time instead of
+`preinstall` or `install` time is that they can be done once, in a
+single place, and thus greatly reduce complexity and variability.
+Additionally, this means that:
+
+* You can depend on `coffee-script` as a `devDependency`, and thus
+ your users don't need to have it installed.
+* You don't need to include the minifiers in your package, reducing
+ the size for your users.
+* You don't need to rely on your users having `curl` or `wget` or
+ other system tools on the target machines.
+
+## DEFAULT VALUES
+
+npm will default some script values based on package contents.
+
+* `"start": "node server.js"`:
+
+ If there is a `server.js` file in the root of your package, then npm
+ will default the `start` command to `node server.js`.
+
+* `"preinstall": "node-waf clean || true; node-waf configure build"`:
+
+ If there is a `wscript` file in the root of your package, npm will
+ default the `preinstall` command to compile using node-waf.
+
+## USER
+
+If npm was invoked with root privileges, then it will change the uid
+to the user account or uid specified by the `user` config, which
+defaults to `nobody`. Set the `unsafe-perm` flag to run scripts with
+root privileges.
+
+## ENVIRONMENT
+
+Package scripts run in an environment where many pieces of information
+are made available regarding the setup of npm and the current state of
+the process.
+
+
+### path
+
+If you depend on modules that define executable scripts, like test
+suites, then those executables will be added to the `PATH` for
+executing the scripts. So, if your package.json has this:
+
+ { "name" : "foo"
+ , "dependencies" : { "bar" : "0.1.x" }
+ , "scripts": { "start" : "bar ./test" } }
+
+then you could run `npm start` to execute the `bar` script, which is
+exported into the `node_modules/.bin` directory on `npm install`.
+
+### package.json vars
+
+The package.json fields are tacked onto the `npm_package_` prefix. So,
+for instance, if you had `{"name":"foo", "version":"1.2.5"}` in your
+package.json file, then your package scripts would have the
+`npm_package_name` environment variable set to "foo", and the
+`npm_package_version` set to "1.2.5"
+
+### configuration
+
+Configuration parameters are put in the environment with the
+`npm_config_` prefix. For instance, you can view the effective `root`
+config by checking the `npm_config_root` environment variable.
+
+### Special: package.json "config" hash
+
+The package.json "config" keys are overwritten in the environment if
+there is a config param of `<name>[@<version>]:<key>`. For example,
+if the package.json has this:
+
+ { "name" : "foo"
+ , "config" : { "port" : "8080" }
+ , "scripts" : { "start" : "node server.js" } }
+
+and the server.js is this:
+
+ http.createServer(...).listen(process.env.npm_package_config_port)
+
+then the user could change the behavior by doing:
+
+ npm config set foo:port 80
+
+### current lifecycle event
+
+Lastly, the `npm_lifecycle_event` environment variable is set to
+whichever stage of the cycle is being executed. So, you could have a
+single script used for different parts of the process which switches
+based on what's currently happening.
+
+Objects are flattened following this format, so if you had
+`{"scripts":{"install":"foo.js"}}` in your package.json, then you'd
+see this in the script:
+
+ process.env.npm_package_scripts_install === "foo.js"
+
+## EXAMPLES
+
+For example, if your package.json contains this:
+
+ { "scripts" :
+ { "install" : "scripts/install.js"
+ , "postinstall" : "scripts/install.js"
+ , "uninstall" : "scripts/uninstall.js"
+ }
+ }
+
+then the `scripts/install.js` will be called for the install,
+post-install, stages of the lifecycle, and the `scripts/uninstall.js`
+would be called when the package is uninstalled. Since
+`scripts/install.js` is running for three different phases, it would
+be wise in this case to look at the `npm_lifecycle_event` environment
+variable.
+
+If you want to run a make command, you can do so. This works just
+fine:
+
+ { "scripts" :
+ { "preinstall" : "./configure"
+ , "install" : "make && make install"
+ , "test" : "make test"
+ }
+ }
+
+## EXITING
+
+Scripts are run by passing the line as a script argument to `sh`.
+
+If the script exits with a code other than 0, then this will abort the
+process.
+
+Note that these script files don't have to be nodejs or even
+javascript programs. They just have to be some kind of executable
+file.
+
+## HOOK SCRIPTS
+
+If you want to run a specific script at a specific lifecycle event for
+ALL packages, then you can use a hook script.
+
+Place an executable file at `node_modules/.hooks/{eventname}`, and
+it'll get run for all packages when they are going through that point
+in the package lifecycle for any packages installed in that root.
+
+Hook scripts are run exactly the same way as package.json scripts.
+That is, they are in a separate child process, with the env described
+above.
+
+## BEST PRACTICES
+
+* Don't exit with a non-zero error code unless you *really* mean it.
+ Except for uninstall scripts, this will cause the npm action to
+ fail, and potentially be rolled back. If the failure is minor or
+ only will prevent some optional features, then it's better to just
+ print a warning and exit successfully.
+* Try not to use scripts to do what npm can do for you. Read through
+ `package.json(5)` to see all the things that you can specify and enable
+ by simply describing your package appropriately. In general, this
+ will lead to a more robust and consistent state.
+* Inspect the env to determine where to put things. For instance, if
+ the `npm_config_binroot` environ is set to `/home/user/bin`, then
+ don't try to install executables into `/usr/local/bin`. The user
+ probably set it up that way for a reason.
+* Don't prefix your script commands with "sudo". If root permissions
+ are required for some reason, then it'll fail with that error, and
+ the user will sudo the npm command in question.
+
+## SEE ALSO
+
+* npm-run-script(1)
+* package.json(5)
+* npm-developers(7)
+* npm-install(1)
diff --git a/doc/misc/removing-npm.md b/doc/misc/removing-npm.md
new file mode 100644
index 0000000..bedd28a
--- /dev/null
+++ b/doc/misc/removing-npm.md
@@ -0,0 +1,54 @@
+npm-removal(1) -- Cleaning the Slate
+====================================
+
+## SYNOPSIS
+
+So sad to see you go.
+
+ sudo npm uninstall npm -g
+
+Or, if that fails, get the npm source code, and do:
+
+ sudo make uninstall
+
+## More Severe Uninstalling
+
+Usually, the above instructions are sufficient. That will remove
+npm, but leave behind anything you've installed.
+
+If that doesn't work, or if you require more drastic measures,
+continue reading.
+
+Note that this is only necessary for globally-installed packages. Local
+installs are completely contained within a project's `node_modules`
+folder. Delete that folder, and everything is gone (unless a package's
+install script is particularly ill-behaved).
+
+This assumes that you installed node and npm in the default place. If
+you configured node with a different `--prefix`, or installed npm with a
+different prefix setting, then adjust the paths accordingly, replacing
+`/usr/local` with your install prefix.
+
+To remove everything npm-related manually:
+
+ rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm*
+
+If you installed things *with* npm, then your best bet is to uninstall
+them with npm first, and then install them again once you have a
+proper install. This can help find any symlinks that are lying
+around:
+
+ ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm
+
+Prior to version 0.3, npm used shim files for executables and node
+modules. To track those down, you can do the following:
+
+ find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ;
+
+(This is also in the README file.)
+
+## SEE ALSO
+
+* README
+* npm-rm(1)
+* npm-prune(1)
diff --git a/doc/misc/semver.md b/doc/misc/semver.md
new file mode 100644
index 0000000..6c7d280
--- /dev/null
+++ b/doc/misc/semver.md
@@ -0,0 +1,158 @@
+semver(7) -- The semantic versioner for npm
+===========================================
+
+## Usage
+
+ $ npm install semver
+
+ semver.valid('1.2.3') // '1.2.3'
+ semver.valid('a.b.c') // null
+ semver.clean(' =v1.2.3 ') // '1.2.3'
+ semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
+ semver.gt('1.2.3', '9.8.7') // false
+ semver.lt('1.2.3', '9.8.7') // true
+
+As a command-line utility:
+
+ $ semver -h
+
+ Usage: semver <version> [<version> [...]] [-r <range> | -i <inc> | -d <dec>]
+ Test if version(s) satisfy the supplied range(s), and sort them.
+
+ Multiple versions or ranges may be supplied, unless increment
+ or decrement options are specified. In that case, only a single
+ version may be used, and it is incremented by the specified level
+
+ Program exits successfully if any valid version satisfies
+ all supplied ranges, and prints all satisfying versions.
+
+ If no versions are valid, or ranges are not satisfied,
+ then exits failure.
+
+ Versions are printed in ascending order, so supplying
+ multiple versions to the utility will just sort them.
+
+## Versions
+
+A "version" is described by the `v2.0.0` specification found at
+<http://semver.org/>.
+
+A leading `"="` or `"v"` character is stripped off and ignored.
+
+## Ranges
+
+The following range styles are supported:
+
+* `1.2.3` A specific version. When nothing else will do. Must be a full
+ version number, with major, minor, and patch versions specified.
+ Note that build metadata is still ignored, so `1.2.3+build2012` will
+ satisfy this range.
+* `>1.2.3` Greater than a specific version.
+* `<1.2.3` Less than a specific version. If there is no prerelease
+ tag on the version range, then no prerelease version will be allowed
+ either, even though these are technically "less than".
+* `>=1.2.3` Greater than or equal to. Note that prerelease versions
+ are NOT equal to their "normal" equivalents, so `1.2.3-beta` will
+ not satisfy this range, but `2.3.0-beta` will.
+* `<=1.2.3` Less than or equal to. In this case, prerelease versions
+ ARE allowed, so `1.2.3-beta` would satisfy.
+* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
+* `~1.2.3` := `>=1.2.3-0 <1.3.0-0` "Reasonably close to `1.2.3`". When
+ using tilde operators, prerelease versions are supported as well,
+ but a prerelease of the next significant digit will NOT be
+ satisfactory, so `1.3.0-beta` will not satisfy `~1.2.3`.
+* `^1.2.3` := `>=1.2.3-0 <2.0.0-0` "Compatible with `1.2.3`". When
+ using caret operators, anything from the specified version (including
+ prerelease) will be supported up to, but not including, the next
+ major version (or its prereleases). `1.5.1` will satisfy `^1.2.3`,
+ while `1.2.2` and `2.0.0-beta` will not.
+* `^0.1.3` := `>=0.1.3-0 <0.2.0-0` "Compatible with `0.1.3`". `0.x.x` versions are
+ special: the first non-zero component indicates potentially breaking changes,
+ meaning the caret operator matches any version with the same first non-zero
+ component starting at the specified version.
+* `^0.0.2` := `=0.0.2` "Only the version `0.0.2` is considered compatible"
+* `~1.2` := `>=1.2.0-0 <1.3.0-0` "Any version starting with `1.2`"
+* `^1.2` := `>=1.2.0-0 <2.0.0-0` "Any version compatible with `1.2`"
+* `1.2.x` := `>=1.2.0-0 <1.3.0-0` "Any version starting with `1.2`"
+* `1.2.*` Same as `1.2.x`.
+* `1.2` Same as `1.2.x`.
+* `~1` := `>=1.0.0-0 <2.0.0-0` "Any version starting with `1`"
+* `^1` := `>=1.0.0-0 <2.0.0-0` "Any version compatible with `1`"
+* `1.x` := `>=1.0.0-0 <2.0.0-0` "Any version starting with `1`"
+* `1.*` Same as `1.x`.
+* `1` Same as `1.x`.
+* `*` Any version whatsoever.
+* `x` Same as `*`.
+* `""` (just an empty string) Same as `*`.
+
+
+Ranges can be joined with either a space (which implies "and") or a
+`||` (which implies "or").
+
+## Functions
+
+All methods and classes take a final `loose` boolean argument that, if
+true, will be more forgiving about not-quite-valid semver strings.
+The resulting output will always be 100% strict, of course.
+
+Strict-mode Comparators and Ranges will be strict about the SemVer
+strings that they parse.
+
+* `valid(v)`: Return the parsed version, or null if it's not valid.
+* `inc(v, release)`: Return the version incremented by the release
+ type (`major`, `premajor`, `minor`, `preminor`, `patch`,
+ `prepatch`, or `prerelease`), or null if it's not valid
+ * `premajor` in one call will bump the version up to the next major
+ version and down to a prerelease of that major version.
+ `preminor`, and `prepatch` work the same way.
+ * If called from a non-prerelease version, the `prerelease` will work the
+ same as `prepatch`. It increments the patch version, then makes a
+ prerelease. If the input version is already a prerelease it simply
+ increments it.
+
+### Comparison
+
+* `gt(v1, v2)`: `v1 > v2`
+* `gte(v1, v2)`: `v1 >= v2`
+* `lt(v1, v2)`: `v1 < v2`
+* `lte(v1, v2)`: `v1 <= v2`
+* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent,
+ even if they're not the exact same string. You already know how to
+ compare strings.
+* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`.
+* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call
+ the corresponding function above. `"==="` and `"!=="` do simple
+ string comparison, but are included for completeness. Throws if an
+ invalid comparison string is provided.
+* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if
+ `v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
+* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions
+ in descending order when passed to `Array.sort()`.
+
+
+### Ranges
+
+* `validRange(range)`: Return the valid range or null if it's not valid
+* `satisfies(version, range)`: Return true if the version satisfies the
+ range.
+* `maxSatisfying(versions, range)`: Return the highest version in the list
+ that satisfies the range, or `null` if none of them do.
+* `gtr(version, range)`: Return `true` if version is greater than all the
+ versions possible in the range.
+* `ltr(version, range)`: Return `true` if version is less than all the
+ versions possible in the range.
+* `outside(version, range, hilo)`: Return true if the version is outside
+ the bounds of the range in either the high or low direction. The
+ `hilo` argument must be either the string `'>'` or `'<'`. (This is
+ the function called by `gtr` and `ltr`.)
+
+Note that, since ranges may be non-contiguous, a version might not be
+greater than a range, less than a range, *or* satisfy a range! For
+example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9`
+until `2.0.0`, so the version `1.2.10` would not be greater than the
+range (because `2.0.1` satisfies, which is higher), nor less than the
+range (since `1.2.8` satisfies, which is lower), and it also does not
+satisfy the range.
+
+If you want to know if a version satisfies or does not satisfy a
+range, use the `satisfies(version, range)` function.
diff --git a/html/docfoot.html b/html/docfoot.html
new file mode 100644
index 0000000..11a6794
--- /dev/null
+++ b/html/docfoot.html
@@ -0,0 +1,13 @@
+</div>
+
+<table border=0 cellspacing=0 cellpadding=0 id=npmlogo>
+<tr><td style="width:180px;height:10px;background:rgb(237,127,127)" colspan=18>&nbsp;</td></tr>
+<tr><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td><td style="width:40px;height:10px;background:#fff" colspan=4>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4>&nbsp;</td><td style="width:40px;height:10px;background:#fff" colspan=4>&nbsp;</td><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td><td colspan=6 style="width:60px;height:10px;background:#fff">&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4>&nbsp;</td></tr>
+<tr><td colspan=2 style="width:20px;height:30px;background:#fff" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:20px;height:10px;background:#fff" rowspan=4 colspan=2>&nbsp;</td><td style="width:10px;height:20px;background:rgb(237,127,127)" rowspan=2>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:20px;height:10px;background:#fff" rowspan=3 colspan=2>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td></tr>
+<tr><td style="width:10px;height:10px;background:#fff" rowspan=2>&nbsp;</td></tr>
+<tr><td style="width:10px;height:10px;background:#fff">&nbsp;</td></tr>
+<tr><td style="width:60px;height:10px;background:rgb(237,127,127)" colspan=6>&nbsp;</td><td colspan=10 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td></tr>
+<tr><td colspan=5 style="width:50px;height:10px;background:#fff">&nbsp;</td><td style="width:40px;height:10px;background:rgb(237,127,127)" colspan=4>&nbsp;</td><td style="width:90px;height:10px;background:#fff" colspan=9>&nbsp;</td></tr>
+</table>
+<p id="footer">@NAME@ &mdash; npm@@VERSION@</p>
+
diff --git a/html/dochead.html b/html/dochead.html
new file mode 100644
index 0000000..e2f0e83
--- /dev/null
+++ b/html/dochead.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+ <title>@NAME@</title>
+ <meta http-equiv="content-type" value="text/html;utf-8">
+ <link rel="stylesheet" type="text/css" href="../../static/style.css">
+ <link rel="canonical" href="https://www.npmjs.org/@URL@">
+ <script async=true src="../../static/toc.js"></script>
+
+ <body>
+ <div id="wrapper">
+
diff --git a/html/favicon.ico b/html/favicon.ico
new file mode 100644
index 0000000..9e0d4ee
--- /dev/null
+++ b/html/favicon.ico
Binary files differ
diff --git a/html/index.html b/html/index.html
new file mode 100644
index 0000000..bf0a3f0
--- /dev/null
+++ b/html/index.html
@@ -0,0 +1,95 @@
+<!doctype html>
+
+<html>
+<head>
+<style>
+ html { background:#202050;
+ font-family:CentSchbook Mono BT, Bitstream Vera Sans Mono, monofont, monospace;
+ }
+body { background:#ddd; width:600px; border:10px solid #fff; margin:2em auto; padding:2em }
+h1 {
+ font-size:200px;
+ line-height:1;
+ font-family:"gubblebum-blocky", monospace;
+ color:#f00;
+ text-align:center;
+ padding:0;
+ margin:0 auto;
+ text-indent:-999em;
+ height:202px;
+ width:519px;
+ background:url(npm.png) center;
+}
+h2 {
+ color:#202050;
+ font-size:100%;
+}
+p, ul, ol { margin:1em 0 0; padding:0 }
+li { list-style-position:inside }
+a { color:#f00; text-decoration:none; }
+a:hover { text-decoration:underline; }
+code { background:#fff ; outline: 1px solid #ccc; padding:0 2px; }
+
+@font-face {
+ font-family:monofont;
+ src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMono.ttf) format("truetype");
+}
+@font-face {
+ font-family:monofont;
+ font-style:italic;
+ src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoIt.ttf) format("truetype");
+}
+@font-face {
+ font-family:monofont;
+ font-weight:bold;
+ src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoBd.ttf) format("truetype");
+}
+@font-face {
+ font-family:monofont;
+ font-style:italic;
+ font-weight:bold;
+ src: url(http://foohack.com/tpl/fonts/Bitstream-Vera-Sans-Mono/VeraMoBI.ttf) format("truetype");
+}
+
+</style>
+ <title>npm - Node Package Manager</title>
+</head>
+<h1>npm</h1>
+
+<p>npm is a package manager for <a href="http://nodejs.org/">node</a>. You can use it to install
+ and publish your node programs. It manages dependencies and does other cool stuff.</p>
+
+<h2>Easy Zero Line Install</h2>
+
+<p><a href="http://nodejs.org/#download">Install Node.js</a> <br>
+(npm comes with it.)</p>
+
+<p>Because a one-line install is one too many.</p>
+
+<h2>Fancy Install</h2>
+
+<ol>
+ <li><a href="https://github.com/npm/npm">Get the code.</a>
+ <li>Do what <a href="https://npmjs.org/doc/README.html">the README</a>
+ says to do.
+</ol>
+
+<p>There's a pretty thorough install script at
+<a href="https://npmjs.org/install.sh">https://npmjs.org/install.sh</a></p>
+
+<p>For maximum security, make sure to thorougly inspect every
+program that you run on your computer!</p>
+
+<h2>Other Cool Stuff</h2>
+
+<ul>
+ <li><a href="https://npmjs.org/doc/README.html">README</a>
+ <li><a href="doc/">Help Documentation</a>
+ <li><a href="doc/faq.html">FAQ</a>
+ <li><a href="https://search.npmjs.org/">Search for Packages</a>
+ <li><a href="https://groups.google.com/group/npm-">Mailing List</a>
+ <li><a href="https://github.com/npm/npm/issues">Bugs</a>
+</ul>
+
+</body>
+</html>
diff --git a/html/n-64.png b/html/n-64.png
new file mode 100644
index 0000000..d4145ef
--- /dev/null
+++ b/html/n-64.png
Binary files differ
diff --git a/html/n-large.png b/html/n-large.png
new file mode 100644
index 0000000..9e1525f
--- /dev/null
+++ b/html/n-large.png
Binary files differ
diff --git a/html/npm-16.png b/html/npm-16.png
new file mode 100644
index 0000000..c3c9d05
--- /dev/null
+++ b/html/npm-16.png
Binary files differ
diff --git a/html/npm-256-square.png b/html/npm-256-square.png
new file mode 100644
index 0000000..f7f18b5
--- /dev/null
+++ b/html/npm-256-square.png
Binary files differ
diff --git a/html/npm-256w.png b/html/npm-256w.png
new file mode 100644
index 0000000..dac32c8
--- /dev/null
+++ b/html/npm-256w.png
Binary files differ
diff --git a/html/npm-64-square.png b/html/npm-64-square.png
new file mode 100644
index 0000000..eef2629
--- /dev/null
+++ b/html/npm-64-square.png
Binary files differ
diff --git a/html/npm-fin.png b/html/npm-fin.png
new file mode 100644
index 0000000..7efbef6
--- /dev/null
+++ b/html/npm-fin.png
Binary files differ
diff --git a/html/npm-large-trans.png b/html/npm-large-trans.png
new file mode 100644
index 0000000..7f6c738
--- /dev/null
+++ b/html/npm-large-trans.png
Binary files differ
diff --git a/html/npm-large.png b/html/npm-large.png
new file mode 100644
index 0000000..27d8317
--- /dev/null
+++ b/html/npm-large.png
Binary files differ
diff --git a/html/npm-logo-white-trans.png b/html/npm-logo-white-trans.png
new file mode 100644
index 0000000..0af8ad7
--- /dev/null
+++ b/html/npm-logo-white-trans.png
Binary files differ
diff --git a/html/npm.png b/html/npm.png
new file mode 100644
index 0000000..d78ff53
--- /dev/null
+++ b/html/npm.png
Binary files differ
diff --git a/html/static/style.css b/html/static/style.css
new file mode 100644
index 0000000..7a7f6ea
--- /dev/null
+++ b/html/static/style.css
@@ -0,0 +1,336 @@
+/* reset */
+* {
+ margin:0;
+ padding:0;
+ border:none;
+ font-family:inherit;
+ font-size:inherit;
+ font-weight:inherit;
+}
+:target::before {
+ content:" >>> ";
+ position:absolute;
+ display:block;
+ opacity:0.5;
+ color:#f00;
+ margin:0 0 0 -2em;
+}
+abbr, acronym {
+ border-bottom:1px dotted #aaa;
+}
+kbd, code, pre {
+ font-family:monospace;
+ margin:0;
+ font-size:18px;
+ line-height:24px;
+ background:#eee;
+ outline:1px solid #ccc;
+}
+kbd code, kbd pre, kbd kbd,
+pre code, pre pre, pre kbd,
+code code, code pre, code kbd { outline: none }
+.dollar::before {
+ content:"$ ";
+ display:inline;
+}
+p, ul, ol, dl, pre {
+ margin:30px 0;
+ line-height:30px;
+}
+hr {
+ margin:30px auto 29px;
+ width:66%;
+ height:1px;
+ background:#aaa;
+}
+pre {
+ display:block;
+}
+dd :first-child {
+ margin-top:0;
+}
+
+body {
+ quotes:"“" "”" "‘" "’";
+ width:666px;
+ margin:30px auto 120px;
+ font-family:Times New Roman, serif;
+ font-size:20px;
+ background:#fff;
+ line-height:30px;
+ color:#111;
+}
+
+blockquote {
+ position:relative;
+ font-size:16px;
+ line-height:30px;
+ font-weight:bold;
+ width:85%;
+ margin:0 auto;
+}
+blockquote::before {
+ font-size:90px;
+ display:block;
+ position:absolute;
+ top:20px;
+ right:100%;
+ content:"“";
+ padding-right:10px;
+ color:#ccc;
+}
+.source cite::before {
+ content:"— ";
+}
+.source {
+ padding-left:20%;
+ margin-top:30px;
+}
+.source cite span {
+ font-style:normal;
+}
+blockquote p {
+ margin-bottom:0;
+}
+.quote blockquote {
+ font-weight:normal;
+}
+
+h1, h2, h3, h4, h5, h6, dt, #header {
+ font-family:serif;
+ font-size:20px;
+ font-weight:bold;
+}
+h2 {
+ background:#eee;
+}
+h1, h2 {
+ line-height:40px;
+}
+
+i, em, cite {
+ font-style:italic;
+}
+b, strong {
+ font-weight:bold;
+}
+i, em, cite, b, strong, small {
+ line-height:28px;
+}
+small, .small, .small *, aside {
+ font-style:italic;
+ color:#669;
+ font-size:18px;
+}
+small a, .small a {
+ text-decoration:underline;
+}
+del {
+ text-decoration:line-through;
+}
+ins {
+ text-decoration:underline;
+}
+.alignright { display:block; float:right; margin-left:1em; }
+.alignleft { display:block; float:left; margin-right:1em; }
+
+q:before, q q q:before, q q q q q:before, q q q q q q q:before { content:"“"; }
+q q:before, q q q q:before, q q q q q q:before, q q q q q q q q:before { content:"‘"; }
+q:after, q q q:after, q q q q q:after, q q q q q q q:after { content:"”"; }
+q q:after, q q q q:after, q q q q q q:after, q q q q q q q q:after { content:"’"; }
+
+a { color:#00f; text-decoration:none; }
+a:visited { color:#636; }
+a:hover, a:active { color:#c00!important; text-decoration:underline; }
+
+h1 {
+ font-weight:bold;
+ background:#fff;
+}
+h1 a, h1 a:visited {
+ font-family:monospace;
+ font-size:60px;
+ color:#c00;
+ display:block;
+}
+h1 a:focus, h1 a:hover, h1 a:active {
+ color:#f00!important;
+ text-decoration:none;
+}
+
+.navigation {
+ display:table;
+ width:100%;
+ margin:0 0 30px 0;
+ position:relative;
+}
+#nav-above {
+ margin-bottom:0;
+}
+.navigation .nav-previous {
+ display:table-cell;
+ text-align:left;
+ width:50%;
+}
+/* hang the » and « off into the margins */
+.navigation .nav-previous a:before, .navigation .nav-next a:after {
+ content: "«";
+ display:block;
+ height:30px;
+ margin-bottom:-30px;
+ text-decoration:none;
+ margin-left:-15px;
+}
+.navigation .nav-next a:after {
+ content: "»";
+ text-align:right;
+ margin-left:0;
+ margin-top:-30px;
+ margin-right:-15px;
+}
+
+
+.navigation .nav-next {
+ display:table-cell;
+ text-align:right;
+ width:50%;
+}
+.navigation a {
+ display:block;
+ width:100%;
+ height:100%;
+}
+
+input, button, textarea {
+ border:0;
+ line-height:30px;
+}
+textarea {
+ height:300px;
+}
+input {
+ height:30px;
+ line-height:30px;
+}
+input.submit, input#submit, input.button, button, input[type=submit] {
+ cursor:hand; cursor:pointer;
+ outline:1px solid #ccc;
+}
+
+#wrapper {
+ margin-bottom:90px;
+ position:relative;
+ z-index:1;
+ *zoom:1;
+ background:#fff;
+}
+#wrapper:after {
+ display:block;
+ content:".";
+ visibility:hidden;
+ width:0;
+ height:0;
+ clear:both;
+}
+
+.sidebar .xoxo > li {
+ float:left;
+ width:50%;
+}
+.sidebar li {
+ list-style:none;
+}
+.sidebar #elsewhere {
+ margin-left:-10%;
+ margin-right:-10%;
+}
+.sidebar #rss-links, .sidebar #twitter-feeds {
+ float:right;
+ clear:right;
+ width:20%;
+}
+.sidebar #comment {
+ clear:both;
+ float:none;
+ width:100%;
+}
+.sidebar #search {
+ clear:both;
+ float:none;
+ width:100%;
+}
+.sidebar #search h2 {
+ margin-left:40%;
+}
+.sidebar #search #s {
+ width:90%;
+ float:left;
+}
+.sidebar #search #searchsubmit {
+ width:10%;
+ float:right;
+}
+.sidebar * {
+ font-size:15px;
+ line-height:30px;
+}
+
+#footer, #footer * {
+ text-align:center;
+ font-size:16px;
+ color:#ccc;
+ font-style:italic;
+ word-spacing:1em;
+ margin-top:0;
+}
+
+#toc {
+ position:absolute;
+ top:0;
+ right:0;
+ padding:40px 0 40px 20px;
+ margin:0;
+ width:200px;
+ opacity:0.2;
+ z-index:-1;
+}
+#toc:hover {
+ opacity:1;
+ background:#fff;
+ z-index:999;
+}
+#toc ul {
+ padding:0;
+ margin:0;
+}
+#toc, #toc li {
+ list-style-type:none;
+ font-size:15px;
+ line-height:15px;
+}
+#toc li {
+ padding:0 0 0 10px;
+}
+#toc li a {
+ position:relative;
+ display:block;
+}
+
+table#npmlogo {
+ line-height:10px;
+ width:180px;
+ margin:0 auto;
+}
+
+@media print {
+ a[href] {
+ color:inherit;
+ }
+ a[href]:after {
+ white-space:nowrap;
+ content:" " attr(href);
+ }
+ a[href^=\#], .navigation {
+ display:none;
+ }
+}
diff --git a/html/static/toc.js b/html/static/toc.js
new file mode 100644
index 0000000..2cfebd0
--- /dev/null
+++ b/html/static/toc.js
@@ -0,0 +1,29 @@
+;(function () {
+var wrapper = document.getElementById("wrapper")
+var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
+ .filter(function (el) {
+ return el.parentNode === wrapper
+ && el.tagName.match(/H[1-6]/)
+ && el.id
+ })
+var l = 2
+ , toc = document.createElement("ul")
+toc.innerHTML = els.map(function (el) {
+ var i = el.tagName.charAt(1)
+ , out = ""
+ while (i > l) {
+ out += "<ul>"
+ l ++
+ }
+ while (i < l) {
+ out += "</ul>"
+ l --
+ }
+ out += "<li><a href='#" + el.id + "'>" +
+ ( el.innerText || el.text || el.innerHTML)
+ + "</a>"
+ return out
+}).join("\n")
+toc.id = "toc"
+document.body.appendChild(toc)
+})();
diff --git a/lib/adduser.js b/lib/adduser.js
new file mode 100644
index 0000000..579ecb0
--- /dev/null
+++ b/lib/adduser.js
@@ -0,0 +1,149 @@
+
+module.exports = adduser
+
+var log = require("npmlog")
+ , npm = require("./npm.js")
+ , registry = npm.registry
+ , read = require("read")
+ , userValidate = require("npm-user-validate")
+ , crypto
+
+try {
+ crypto = process.binding("crypto") && require("crypto")
+} catch (ex) {}
+
+adduser.usage = "npm adduser\nThen enter stuff at the prompts"
+
+function adduser (args, cb) {
+ npm.spinner.stop()
+ if (!crypto) return cb(new Error(
+ "You must compile node with ssl support to use the adduser feature"))
+
+ var c = { u : npm.config.get("username") || ""
+ , p : npm.config.get("_password") || ""
+ , e : npm.config.get("email") || ""
+ }
+ , u = {}
+ , fns = [readUsername, readPassword, readEmail, save]
+
+ loop()
+ function loop (er) {
+ if (er) return cb(er)
+ var fn = fns.shift()
+ if (fn) return fn(c, u, loop)
+ cb()
+ }
+}
+
+function readUsername (c, u, cb) {
+ var v = userValidate.username
+ read({prompt: "Username: ", default: c.u || ""}, function (er, un) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ // make sure it's valid. we have to do this here, because
+ // couchdb will only ever say "bad password" with a 401 when
+ // you try to PUT a _users record that the validate_doc_update
+ // rejects for *any* reason.
+
+ if (!un) {
+ return readUsername(c, u, cb)
+ }
+
+ var error = v(un)
+ if (error) {
+ log.warn(error.message)
+ return readUsername(c, u, cb)
+ }
+
+ c.changed = c.u !== un
+ u.u = un
+ cb(er)
+ })
+}
+
+function readPassword (c, u, cb) {
+ var v = userValidate.pw
+
+ var prompt
+ if (c.p && !c.changed) {
+ prompt = "Password: (or leave unchanged) "
+ } else {
+ prompt = "Password: "
+ }
+
+ read({prompt: prompt, silent: true}, function (er, pw) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ if (!c.changed && pw === "") {
+ // when the username was not changed,
+ // empty response means "use the old value"
+ pw = c.p
+ }
+
+ if (!pw) {
+ return readPassword(c, u, cb)
+ }
+
+ var error = v(pw)
+ if (error) {
+ log.warn(error.message)
+ return readPassword(c, u, cb)
+ }
+
+ c.changed = c.changed || c.p != pw
+ u.p = pw
+ cb(er)
+ })
+}
+
+function readEmail (c, u, cb) {
+ var v = userValidate.email
+ var r = { prompt: "Email: (this IS public) ", default: c.e || "" }
+ read(r, function (er, em) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ if (!em) {
+ return readEmail(c, u, cb)
+ }
+
+ var error = v(em)
+ if (error) {
+ log.warn(error.message)
+ return readEmail(c, u, cb)
+ }
+
+ u.e = em
+ cb(er)
+ })
+}
+
+function save (c, u, cb) {
+ if (c.changed) {
+ delete registry.auth
+ delete registry.username
+ delete registry.password
+ registry.username = u.u
+ registry.password = u.p
+ }
+ npm.spinner.start()
+ // save existing configs, but yank off for this PUT
+ registry.adduser(npm.config.get("registry"), u.u, u.p, u.e, function (er) {
+ npm.spinner.stop()
+ if (er) return cb(er)
+ registry.username = u.u
+ registry.password = u.p
+ registry.email = u.e
+ npm.config.set("username", u.u, "user")
+ npm.config.set("_password", u.p, "user")
+ npm.config.set("email", u.e, "user")
+ npm.config.del("_token", "user")
+ log.info("adduser", "Authorized user %s", u.u)
+ npm.config.save("user", cb)
+ })
+}
diff --git a/lib/bin.js b/lib/bin.js
new file mode 100644
index 0000000..719e887
--- /dev/null
+++ b/lib/bin.js
@@ -0,0 +1,18 @@
+module.exports = bin
+
+var npm = require("./npm.js")
+
+bin.usage = "npm bin\nnpm bin -g\n(just prints the bin folder)"
+
+function bin (args, silent, cb) {
+ if (typeof cb !== "function") cb = silent, silent = false
+ var b = npm.bin
+ , PATH = (process.env.PATH || "").split(":")
+
+ if (!silent) console.log(b)
+ process.nextTick(cb.bind(this, null, b))
+
+ if (npm.config.get("global") && PATH.indexOf(b) === -1) {
+ npm.config.get("logstream").write("(not in PATH env variable)\n")
+ }
+}
diff --git a/lib/bugs.js b/lib/bugs.js
new file mode 100644
index 0000000..b3022bf
--- /dev/null
+++ b/lib/bugs.js
@@ -0,0 +1,64 @@
+
+module.exports = bugs
+
+bugs.usage = "npm bugs <pkgname>"
+
+var npm = require("./npm.js")
+ , registry = npm.registry
+ , log = require("npmlog")
+ , opener = require("opener")
+ , path = require("path")
+ , readJson = require("read-package-json")
+ , fs = require("fs")
+ , url = require("url")
+
+bugs.completion = function (opts, cb) {
+ if (opts.conf.argv.remain.length > 2) return cb()
+ var uri = url.resolve(npm.config.get("registry"), "-/short")
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
+}
+
+function bugs (args, cb) {
+ var n = args.length && args[0].split("@").shift() || '.'
+ fs.stat(n, function (er, s) {
+ if (er && er.code === "ENOENT") return callRegistry(n, cb)
+ else if (er) return cb (er)
+ if (!s.isDirectory()) return callRegistry(n, cb)
+ readJson(path.resolve(n, "package.json"), function(er, d) {
+ if (er) return cb(er)
+ getUrlAndOpen(d, cb)
+ })
+ })
+}
+
+function getUrlAndOpen (d, cb) {
+ var bugs = d.bugs
+ , repo = d.repository || d.repositories
+ , url
+ if (bugs) {
+ url = (typeof url === "string") ? bugs : bugs.url
+ } else if (repo) {
+ if (Array.isArray(repo)) repo = repo.shift()
+ if (repo.hasOwnProperty("url")) repo = repo.url
+ log.verbose("repository", repo)
+ if (bugs && bugs.match(/^(https?:\/\/|git(:\/\/|@))github.com/)) {
+ url = bugs.replace(/^git(@|:\/\/)/, "https://")
+ .replace(/^https?:\/\/github.com:/, "https://github.com/")
+ .replace(/\.git$/, '')+"/issues"
+ }
+ }
+ if (!url) {
+ url = "https://npmjs.org/package/" + d.name
+ }
+ opener(url, { command: npm.config.get("browser") }, cb)
+}
+
+function callRegistry (n, cb) {
+ var uri = url.resolve(npm.config.get("registry"), n + "/latest")
+ registry.get(uri, { timeout : 3600 }, function (er, d) {
+ if (er) return cb(er)
+ getUrlAndOpen (d, cb)
+ })
+}
diff --git a/lib/build.js b/lib/build.js
new file mode 100644
index 0000000..350774a
--- /dev/null
+++ b/lib/build.js
@@ -0,0 +1,226 @@
+// npm build command
+
+// everything about the installation after the creation of
+// the .npm/{name}/{version}/package folder.
+// linking the modules into the npm.root,
+// resolving dependencies, etc.
+
+// This runs AFTER install or link are completed.
+
+var npm = require("./npm.js")
+ , log = require("npmlog")
+ , chain = require("slide").chain
+ , fs = require("graceful-fs")
+ , path = require("path")
+ , lifecycle = require("./utils/lifecycle.js")
+ , readJson = require("read-package-json")
+ , link = require("./utils/link.js")
+ , linkIfExists = link.ifExists
+ , cmdShim = require("cmd-shim")
+ , cmdShimIfExists = cmdShim.ifExists
+ , asyncMap = require("slide").asyncMap
+
+module.exports = build
+build.usage = "npm build <folder>\n(this is plumbing)"
+
+build._didBuild = {}
+build._noLC = {}
+function build (args, global, didPre, didRB, cb) {
+ if (typeof cb !== "function") cb = didRB, didRB = false
+ if (typeof cb !== "function") cb = didPre, didPre = false
+ if (typeof cb !== "function") {
+ cb = global, global = npm.config.get("global")
+ }
+ // it'd be nice to asyncMap these, but actually, doing them
+ // in parallel generally munges up the output from node-waf
+ var builder = build_(global, didPre, didRB)
+ chain(args.map(function (arg) { return function (cb) {
+ builder(arg, cb)
+ }}), cb)
+}
+
+function build_ (global, didPre, didRB) { return function (folder, cb) {
+ folder = path.resolve(folder)
+ build._didBuild[folder] = true
+ log.info("build", folder)
+ readJson(path.resolve(folder, "package.json"), function (er, pkg) {
+ if (er) return cb(er)
+ chain
+ ( [ !didPre && [lifecycle, pkg, "preinstall", folder]
+ , [linkStuff, pkg, folder, global, didRB]
+ , pkg.name === "npm" && [writeBuiltinConf, folder]
+ , didPre !== build._noLC && [lifecycle, pkg, "install", folder]
+ , didPre !== build._noLC && [lifecycle, pkg, "postinstall", folder]
+ , didPre !== build._noLC
+ && npm.config.get("npat")
+ && [lifecycle, pkg, "test", folder] ]
+ , cb )
+ })
+}}
+
+function writeBuiltinConf (folder, cb) {
+ // the builtin config is "sticky". Any time npm installs itself,
+ // it puts its builtin config file there, as well.
+ if (!npm.config.usingBuiltin
+ || folder !== path.dirname(__dirname)) {
+ return cb()
+ }
+ npm.config.save("builtin", cb)
+}
+
+function linkStuff (pkg, folder, global, didRB, cb) {
+ // allow to opt out of linking binaries.
+ if (npm.config.get("bin-links") === false) return cb()
+
+ // if it's global, and folder is in {prefix}/node_modules,
+ // then bins are in {prefix}/bin
+ // otherwise, then bins are in folder/../.bin
+ var parent = path.dirname(folder)
+ , gnm = global && npm.globalDir
+ , gtop = parent === gnm
+
+ log.verbose("linkStuff", [global, gnm, gtop, parent])
+ log.info("linkStuff", pkg._id)
+
+ shouldWarn(pkg, folder, global, function() {
+ asyncMap( [linkBins, linkMans, !didRB && rebuildBundles]
+ , function (fn, cb) {
+ if (!fn) return cb()
+ log.verbose(fn.name, pkg._id)
+ fn(pkg, folder, parent, gtop, cb)
+ }, cb)
+ })
+}
+
+function shouldWarn(pkg, folder, global, cb) {
+ var parent = path.dirname(folder)
+ , top = parent === npm.dir
+ , cwd = process.cwd()
+
+ readJson(path.resolve(cwd, "package.json"), function(er, topPkg) {
+ if (er) return cb(er)
+
+ var linkedPkg = path.basename(cwd)
+ , currentPkg = path.basename(folder)
+
+ // current searched package is the linked package on first call
+ if (linkedPkg !== currentPkg) {
+
+ if (!topPkg.dependencies) return cb()
+
+ // don't generate a warning if it's listed in dependencies
+ if (Object.keys(topPkg.dependencies).indexOf(currentPkg) === -1) {
+
+ if (top && pkg.preferGlobal && !global) {
+ log.warn("prefer global", pkg._id + " should be installed with -g")
+ }
+ }
+ }
+
+ cb()
+ })
+}
+
+function rebuildBundles (pkg, folder, parent, gtop, cb) {
+ if (!npm.config.get("rebuild-bundle")) return cb()
+
+ var deps = Object.keys(pkg.dependencies || {})
+ .concat(Object.keys(pkg.devDependencies || {}))
+ , bundles = pkg.bundleDependencies || pkg.bundledDependencies || []
+
+ fs.readdir(path.resolve(folder, "node_modules"), function (er, files) {
+ // error means no bundles
+ if (er) return cb()
+
+ log.verbose("rebuildBundles", files)
+ // don't asyncMap these, because otherwise build script output
+ // gets interleaved and is impossible to read
+ chain(files.filter(function (file) {
+ // rebuild if:
+ // not a .folder, like .bin or .hooks
+ return !file.match(/^[\._-]/)
+ // not some old 0.x style bundle
+ && file.indexOf("@") === -1
+ // either not a dep, or explicitly bundled
+ && (deps.indexOf(file) === -1 || bundles.indexOf(file) !== -1)
+ }).map(function (file) {
+ file = path.resolve(folder, "node_modules", file)
+ return function (cb) {
+ if (build._didBuild[file]) return cb()
+ log.verbose("rebuild bundle", file)
+ // if file is not a package dir, then don't do it.
+ fs.lstat(path.resolve(file, "package.json"), function (er) {
+ if (er) return cb()
+ build_(false)(file, cb)
+ })
+ }}), cb)
+ })
+}
+
+function linkBins (pkg, folder, parent, gtop, cb) {
+ if (!pkg.bin || !gtop && path.basename(parent) !== "node_modules") {
+ return cb()
+ }
+ var binRoot = gtop ? npm.globalBin
+ : path.resolve(parent, ".bin")
+ log.verbose("link bins", [pkg.bin, binRoot, gtop])
+
+ asyncMap(Object.keys(pkg.bin), function (b, cb) {
+ linkBin( path.resolve(folder, pkg.bin[b])
+ , path.resolve(binRoot, b)
+ , gtop && folder
+ , function (er) {
+ if (er) return cb(er)
+ // bins should always be executable.
+ // XXX skip chmod on windows?
+ var src = path.resolve(folder, pkg.bin[b])
+ fs.chmod(src, npm.modes.exec, function (er) {
+ if (er && er.code === "ENOENT" && npm.config.get("ignore-scripts")) {
+ return cb()
+ }
+ if (er || !gtop) return cb(er)
+ var dest = path.resolve(binRoot, b)
+ , out = npm.config.get("parseable")
+ ? dest + "::" + src + ":BINFILE"
+ : dest + " -> " + src
+ console.log(out)
+ cb()
+ })
+ })
+ }, cb)
+}
+
+function linkBin (from, to, gently, cb) {
+ if (process.platform !== "win32") {
+ return linkIfExists(from, to, gently, cb)
+ } else {
+ return cmdShimIfExists(from, to, cb)
+ }
+}
+
+function linkMans (pkg, folder, parent, gtop, cb) {
+ if (!pkg.man || !gtop || process.platform === "win32") return cb()
+
+ var manRoot = path.resolve(npm.config.get("prefix"), "share", "man")
+
+ // make sure that the mans are unique.
+ // otherwise, if there are dupes, it'll fail with EEXIST
+ var set = pkg.man.reduce(function (acc, man) {
+ acc[path.basename(man)] = man
+ return acc
+ }, {})
+ pkg.man = pkg.man.filter(function (man) {
+ return set[path.basename(man)] === man
+ })
+
+ asyncMap(pkg.man, function (man, cb) {
+ if (typeof man !== "string") return cb()
+ var parseMan = man.match(/(.*\.([0-9]+)(\.gz)?)$/)
+ , stem = parseMan[1]
+ , sxn = parseMan[2]
+ , bn = path.basename(stem)
+ , manDest = path.join(manRoot, "man" + sxn, bn)
+
+ linkIfExists(man, manDest, gtop && folder, cb)
+ }, cb)
+}
diff --git a/lib/cache.js b/lib/cache.js
new file mode 100644
index 0000000..37bba5a
--- /dev/null
+++ b/lib/cache.js
@@ -0,0 +1,371 @@
+// XXX lib/utils/tar.js and this file need to be rewritten.
+
+// URL-to-cache folder mapping:
+// : -> !
+// @ -> _
+// http://registry.npmjs.org/foo/version -> cache/http!/...
+//
+
+/*
+fetching a URL:
+1. Check for URL in inflight URLs. If present, add cb, and return.
+2. Acquire lock at {cache}/{sha(url)}.lock
+ retries = {cache-lock-retries, def=3}
+ stale = {cache-lock-stale, def=30000}
+ wait = {cache-lock-wait, def=100}
+3. if lock can't be acquired, then fail
+4. fetch url, clear lock, call cbs
+
+cache folders:
+1. urls: http!/server.com/path/to/thing
+2. c:\path\to\thing: file!/c!/path/to/thing
+3. /path/to/thing: file!/path/to/thing
+4. git@ private: git_github.com!npm/npm
+5. git://public: git!/github.com/npm/npm
+6. git+blah:// git-blah!/server.com/foo/bar
+
+adding a folder:
+1. tar into tmp/random/package.tgz
+2. untar into tmp/random/contents/package, stripping one dir piece
+3. tar tmp/random/contents/package to cache/n/v/package.tgz
+4. untar cache/n/v/package.tgz into cache/n/v/package
+5. rm tmp/random
+
+Adding a url:
+1. fetch to tmp/random/package.tgz
+2. goto folder(2)
+
+adding a name@version:
+1. registry.get(name/version)
+2. if response isn't 304, add url(dist.tarball)
+
+adding a name@range:
+1. registry.get(name)
+2. Find a version that satisfies
+3. add name@version
+
+adding a local tarball:
+1. untar to tmp/random/{blah}
+2. goto folder(2)
+*/
+
+exports = module.exports = cache
+cache.unpack = unpack
+cache.clean = clean
+cache.read = read
+
+var npm = require("./npm.js")
+ , fs = require("graceful-fs")
+ , assert = require("assert")
+ , rm = require("./utils/gently-rm.js")
+ , readJson = require("read-package-json")
+ , log = require("npmlog")
+ , path = require("path")
+ , url = require("url")
+ , asyncMap = require("slide").asyncMap
+ , tar = require("./utils/tar.js")
+ , fileCompletion = require("./utils/completion/file-completion.js")
+ , isGitUrl = require("./utils/is-git-url.js")
+ , deprCheck = require("./utils/depr-check.js")
+ , addNamed = require("./cache/add-named.js")
+ , addLocal = require("./cache/add-local.js")
+ , addRemoteTarball = require("./cache/add-remote-tarball.js")
+ , addRemoteGit = require("./cache/add-remote-git.js")
+ , inflight = require("inflight")
+
+cache.usage = "npm cache add <tarball file>"
+ + "\nnpm cache add <folder>"
+ + "\nnpm cache add <tarball url>"
+ + "\nnpm cache add <git url>"
+ + "\nnpm cache add <name>@<version>"
+ + "\nnpm cache ls [<path>]"
+ + "\nnpm cache clean [<pkg>[@<version>]]"
+
+cache.completion = function (opts, cb) {
+
+ var argv = opts.conf.argv.remain
+ if (argv.length === 2) {
+ return cb(null, ["add", "ls", "clean"])
+ }
+
+ switch (argv[2]) {
+ case "clean":
+ case "ls":
+ // cache and ls are easy, because the completion is
+ // what ls_ returns anyway.
+ // just get the partial words, minus the last path part
+ var p = path.dirname(opts.partialWords.slice(3).join("/"))
+ if (p === ".") p = ""
+ return ls_(p, 2, cb)
+ case "add":
+ // Same semantics as install and publish.
+ return npm.commands.install.completion(opts, cb)
+ }
+}
+
+function cache (args, cb) {
+ var cmd = args.shift()
+ switch (cmd) {
+ case "rm": case "clear": case "clean": return clean(args, cb)
+ case "list": case "sl": case "ls": return ls(args, cb)
+ case "add": return add(args, cb)
+ default: return cb(new Error(
+ "Invalid cache action: "+cmd))
+ }
+}
+
+// if the pkg and ver are in the cache, then
+// just do a readJson and return.
+// if they're not, then fetch them from the registry.
+function read (name, ver, forceBypass, cb) {
+ assert(typeof name === "string", "must include name of module to install")
+ assert(typeof cb === "function", "must include callback")
+
+ if (forceBypass === undefined || forceBypass === null) forceBypass = true
+
+ var jsonFile = path.join(npm.cache, name, ver, "package", "package.json")
+ function c (er, data) {
+ if (data) deprCheck(data)
+
+ return cb(er, data)
+ }
+
+ if (forceBypass && npm.config.get("force")) {
+ log.verbose("using force", "skipping cache")
+ return addNamed(name, ver, null, c)
+ }
+
+ readJson(jsonFile, function (er, data) {
+ er = needName(er, data)
+ er = needVersion(er, data)
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
+ if (er) return addNamed(name, ver, null, c)
+
+ deprCheck(data)
+
+ c(er, data)
+ })
+}
+
+// npm cache ls [<path>]
+function ls (args, cb) {
+ args = args.join("/").split("@").join("/")
+ if (args.substr(-1) === "/") args = args.substr(0, args.length - 1)
+ var prefix = npm.config.get("cache")
+ if (0 === prefix.indexOf(process.env.HOME)) {
+ prefix = "~" + prefix.substr(process.env.HOME.length)
+ }
+ ls_(args, npm.config.get("depth"), function (er, files) {
+ console.log(files.map(function (f) {
+ return path.join(prefix, f)
+ }).join("\n").trim())
+ cb(er, files)
+ })
+}
+
+// Calls cb with list of cached pkgs matching show.
+function ls_ (req, depth, cb) {
+ return fileCompletion(npm.cache, req, depth, cb)
+}
+
+// npm cache clean [<path>]
+function clean (args, cb) {
+ assert(typeof cb === "function", "must include callback")
+
+ if (!args) args = []
+
+ args = args.join("/").split("@").join("/")
+ if (args.substr(-1) === "/") args = args.substr(0, args.length - 1)
+ var f = path.join(npm.cache, path.normalize(args))
+ if (f === npm.cache) {
+ fs.readdir(npm.cache, function (er, files) {
+ if (er) return cb()
+ asyncMap( files.filter(function (f) {
+ return npm.config.get("force") || f !== "-"
+ }).map(function (f) {
+ return path.join(npm.cache, f)
+ })
+ , rm, cb )
+ })
+ } else rm(path.join(npm.cache, path.normalize(args)), cb)
+}
+
+// npm cache add <tarball-url>
+// npm cache add <pkg> <ver>
+// npm cache add <tarball>
+// npm cache add <folder>
+cache.add = function (pkg, ver, scrub, cb) {
+ assert(typeof pkg === "string", "must include name of package to install")
+ assert(typeof cb === "function", "must include callback")
+
+ if (scrub) {
+ return clean([], function (er) {
+ if (er) return cb(er)
+ add([pkg, ver], cb)
+ })
+ }
+ log.verbose("cache add", [pkg, ver])
+ return add([pkg, ver], cb)
+}
+
+
+var adding = 0
+function add (args, cb) {
+ // this is hot code. almost everything passes through here.
+ // the args can be any of:
+ // ["url"]
+ // ["pkg", "version"]
+ // ["pkg@version"]
+ // ["pkg", "url"]
+ // This is tricky, because urls can contain @
+ // Also, in some cases we get [name, null] rather
+ // that just a single argument.
+
+ var usage = "Usage:\n"
+ + " npm cache add <tarball-url>\n"
+ + " npm cache add <pkg>@<ver>\n"
+ + " npm cache add <tarball>\n"
+ + " npm cache add <folder>\n"
+ , name
+ , spec
+
+ if (args[1] === undefined) args[1] = null
+
+ // at this point the args length must ==2
+ if (args[1] !== null) {
+ name = args[0]
+ spec = args[1]
+ } else if (args.length === 2) {
+ spec = args[0]
+ }
+
+ log.verbose("cache add", "name=%j spec=%j args=%j", name, spec, args)
+
+ if (!name && !spec) return cb(usage)
+
+ if (adding <= 0) {
+ npm.spinner.start()
+ }
+ adding ++
+ cb = afterAdd([name, spec], cb)
+
+ // see if the spec is a url
+ // otherwise, treat as name@version
+ var p = url.parse(spec) || {}
+ log.verbose("parsed url", p)
+
+ // If there's a /, and it's a path, then install the path.
+ // If not, and there's a @, it could be that we got name@http://blah
+ // in that case, we will not have a protocol now, but if we
+ // split and check, we will.
+ if (!name && !p.protocol) {
+ return maybeFile(spec, cb)
+ }
+ else {
+ switch (p.protocol) {
+ case "http:":
+ case "https:":
+ return addRemoteTarball(spec, { name: name }, null, cb)
+
+ default:
+ if (isGitUrl(p)) return addRemoteGit(spec, p, false, cb)
+
+ // if we have a name and a spec, then try name@spec
+ if (name) {
+ addNamed(name, spec, null, cb)
+ }
+ // if not, then try just spec (which may try name@"" if not found)
+ else {
+ addLocal(spec, {}, cb)
+ }
+ }
+ }
+}
+
+function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb) {
+ if (typeof cb !== "function") cb = gid, gid = null
+ if (typeof cb !== "function") cb = uid, uid = null
+ if (typeof cb !== "function") cb = fMode, fMode = null
+ if (typeof cb !== "function") cb = dMode, dMode = null
+
+ read(pkg, ver, false, function (er) {
+ if (er) {
+ log.error("unpack", "Could not read data for %s", pkg + "@" + ver)
+ return cb(er)
+ }
+ npm.commands.unbuild([unpackTarget], true, function (er) {
+ if (er) return cb(er)
+ tar.unpack( path.join(npm.cache, pkg, ver, "package.tgz")
+ , unpackTarget
+ , dMode, fMode
+ , uid, gid
+ , cb )
+ })
+ })
+}
+
+function afterAdd (arg, cb) { return function (er, data) {
+ adding --
+ if (adding <= 0) {
+ npm.spinner.stop()
+ }
+ if (er || !data || !data.name || !data.version) {
+ return cb(er, data)
+ }
+
+ // Save the resolved, shasum, etc. into the data so that the next
+ // time we load from this cached data, we have all the same info.
+ var name = data.name
+ var ver = data.version
+ var pj = path.join(npm.cache, name, ver, "package", "package.json")
+ var tmp = pj + "." + process.pid
+
+ var done = inflight(pj, cb)
+
+ if (!done) return
+
+ fs.writeFile(tmp, JSON.stringify(data), "utf8", function (er) {
+ if (er) return done(er)
+ fs.rename(tmp, pj, function (er) {
+ done(er, data)
+ })
+ })
+}}
+
+function maybeFile (spec, cb) {
+ // split name@2.3.4 only if name is a valid package name,
+ // don't split in case of "./test@example.com/" (local path)
+ fs.stat(spec, function (er) {
+ if (!er) {
+ // definitely a local thing
+ return addLocal(spec, {}, cb)
+ }
+
+ maybeAt(spec, cb)
+ })
+}
+
+function maybeAt (spec, cb) {
+ if (spec.indexOf("@") !== -1) {
+ var tmp = spec.split("@")
+
+ var name = tmp.shift()
+ spec = tmp.join("@")
+ add([name, spec], cb)
+ } else {
+ // already know it's not a url, so must be local
+ addLocal(spec, {}, cb)
+ }
+}
+
+function needName(er, data) {
+ return er ? er
+ : (data && !data.name) ? new Error("No name provided")
+ : null
+}
+
+function needVersion(er, data) {
+ return er ? er
+ : (data && !data.version) ? new Error("No version provided")
+ : null
+}
diff --git a/lib/cache/add-local-tarball.js b/lib/cache/add-local-tarball.js
new file mode 100644
index 0000000..bcb938f
--- /dev/null
+++ b/lib/cache/add-local-tarball.js
@@ -0,0 +1,223 @@
+var mkdir = require("mkdirp")
+ , assert = require("assert")
+ , fs = require("graceful-fs")
+ , readJson = require("read-package-json")
+ , log = require("npmlog")
+ , path = require("path")
+ , sha = require("sha")
+ , npm = require("../npm.js")
+ , tar = require("../utils/tar.js")
+ , pathIsInside = require("path-is-inside")
+ , locker = require("../utils/locker.js")
+ , lock = locker.lock
+ , unlock = locker.unlock
+ , getCacheStat = require("./get-stat.js")
+ , chownr = require("chownr")
+ , inflight = require("inflight")
+ , once = require("once")
+
+module.exports = addLocalTarball
+
+function addLocalTarball (p, pkgData, shasum, cb_) {
+ assert(typeof p === "string", "must have path")
+ assert(typeof cb_ === "function", "must have callback")
+
+ if (!pkgData) pkgData = {}
+ var name = pkgData.name || ""
+
+ // If we don't have a shasum yet, then get the shasum now.
+ if (!shasum) {
+ return sha.get(p, function (er, shasum) {
+ if (er) return cb_(er)
+ addLocalTarball(p, pkgData, shasum, cb_)
+ })
+ }
+
+ // if it's a tar, and not in place,
+ // then unzip to .tmp, add the tmp folder, and clean up tmp
+ if (pathIsInside(p, npm.tmp))
+ return addTmpTarball(p, pkgData, shasum, cb_)
+
+ if (pathIsInside(p, npm.cache)) {
+ if (path.basename(p) !== "package.tgz") return cb_(new Error(
+ "Not a valid cache tarball name: "+p))
+ return addPlacedTarball(p, pkgData, shasum, cb_)
+ }
+
+ function cb (er, data) {
+ if (data) {
+ data._resolved = p
+ data._shasum = data._shasum || shasum
+ }
+ return cb_(er, data)
+ }
+
+ // just copy it over and then add the temp tarball file.
+ var tmp = path.join(npm.tmp, name + Date.now()
+ + "-" + Math.random(), "tmp.tgz")
+ mkdir(path.dirname(tmp), function (er) {
+ if (er) return cb(er)
+ var from = fs.createReadStream(p)
+ , to = fs.createWriteStream(tmp)
+ , errState = null
+ function errHandler (er) {
+ if (errState) return
+ return cb(errState = er)
+ }
+ from.on("error", errHandler)
+ to.on("error", errHandler)
+ to.on("close", function () {
+ if (errState) return
+ log.verbose("chmod", tmp, npm.modes.file.toString(8))
+ fs.chmod(tmp, npm.modes.file, function (er) {
+ if (er) return cb(er)
+ addTmpTarball(tmp, pkgData, shasum, cb)
+ })
+ })
+ from.pipe(to)
+ })
+}
+
+function addPlacedTarball (p, pkgData, shasum, cb) {
+ assert(pkgData, "should have package data by now")
+ assert(typeof cb === "function", "cb function required")
+
+ getCacheStat(function (er, cs) {
+ if (er) return cb(er)
+ return addPlacedTarball_(p, pkgData, cs.uid, cs.gid, shasum, cb)
+ })
+}
+
+function addPlacedTarball_ (p, pkgData, uid, gid, resolvedSum, cb) {
+ // now we know it's in place already as .cache/name/ver/package.tgz
+ var name = pkgData.name
+ , version = pkgData.version
+ , folder = path.join(npm.cache, name, version, "package")
+
+ // First, make sure we have the shasum, if we don't already.
+ if (!resolvedSum) {
+ sha.get(p, function (er, shasum) {
+ if (er) return cb(er)
+ addPlacedTarball_(p, pkgData, uid, gid, shasum, cb)
+ })
+ return
+ }
+
+ lock(folder, function (er) {
+ if (er) return cb(er)
+
+ // async try/finally
+ var originalCb = cb
+ cb = function (er, data) {
+ unlock(folder, function (er2) {
+ return originalCb(er || er2, data)
+ })
+ }
+
+ mkdir(folder, function (er) {
+ if (er) return cb(er)
+ var pj = path.join(folder, "package.json")
+ var json = JSON.stringify(pkgData, null, 2)
+ fs.writeFile(pj, json, "utf8", function (er) {
+ cb(er, pkgData)
+ })
+ })
+ })
+}
+
+function addTmpTarball (tgz, pkgData, shasum, cb) {
+ assert(typeof cb === "function", "must have callback function")
+ assert(shasum, "should have shasum by now")
+
+ cb = inflight("addTmpTarball:" + tgz, cb)
+ if (!cb) return
+
+ // we already have the package info, so just move into place
+ if (pkgData && pkgData.name && pkgData.version) {
+ return addTmpTarball_(tgz, pkgData, shasum, cb)
+ }
+
+ // This is a tarball we probably downloaded from the internet.
+ // The shasum's already been checked, but we haven't ever had
+ // a peek inside, so we unpack it here just to make sure it is
+ // what it says it is.
+ // Note: we might not have any clue what we think it is, for
+ // example if the user just did `npm install ./foo.tgz`
+
+ var target = tgz + "-unpack"
+ getCacheStat(function (er, cs) {
+ tar.unpack(tgz, target, null, null, cs.uid, cs.gid, next)
+ })
+
+ function next (er) {
+ if (er) return cb(er)
+ var pj = path.join(target, "package.json")
+ readJson(pj, function (er, data) {
+ // XXX dry with similar stanza in add-local.js
+ er = needName(er, data)
+ er = needVersion(er, data)
+ // check that this is what we expected.
+ if (!er && pkgData.name && pkgData.name !== data.name) {
+ er = new Error( "Invalid Package: expected "
+ + pkgData.name + " but found "
+ + data.name )
+ }
+
+ if (!er && pkgData.version && pkgData.version !== data.version) {
+ er = new Error( "Invalid Package: expected "
+ + pkgData.name + "@" + pkgData.version
+ + " but found "
+ + data.name + "@" + data.version )
+ }
+
+ if (er) return cb(er)
+
+ addTmpTarball_(tgz, data, shasum, cb)
+ })
+ }
+}
+
+function addTmpTarball_ (tgz, data, shasum, cb) {
+ assert(typeof cb === "function", "must have callback function")
+ cb = once(cb)
+
+ var name = data.name
+ var version = data.version
+ assert(name, "should have package name by now")
+ assert(version, "should have package version by now")
+
+ var root = path.resolve(npm.cache, name, version)
+ var pkg = path.resolve(root, "package")
+ var target = path.resolve(root, "package.tgz")
+ getCacheStat(function (er, cs) {
+ if (er) return cb(er)
+ mkdir(pkg, function (er) {
+ if (er) return cb(er)
+ var read = fs.createReadStream(tgz)
+ var write = fs.createWriteStream(target)
+ var fin = cs.uid && cs.gid ? chown : done
+ read.on("error", cb).pipe(write).on("error", cb).on("close", fin)
+ })
+
+ function chown () {
+ chownr(root, cs.uid, cs.gid, done)
+ }
+ })
+
+ function done() {
+ data._shasum = data._shasum || shasum
+ cb(null, data)
+ }
+}
+
+function needName(er, data) {
+ return er ? er
+ : (data && !data.name) ? new Error("No name provided")
+ : null
+}
+
+function needVersion(er, data) {
+ return er ? er
+ : (data && !data.version) ? new Error("No version provided")
+ : null
+}
diff --git a/lib/cache/add-local.js b/lib/cache/add-local.js
new file mode 100644
index 0000000..2a6d8cf
--- /dev/null
+++ b/lib/cache/add-local.js
@@ -0,0 +1,146 @@
+var fs = require("graceful-fs")
+ , assert = require("assert")
+ , path = require("path")
+ , mkdir = require("mkdirp")
+ , chownr = require("chownr")
+ , pathIsInside = require("path-is-inside")
+ , readJson = require("read-package-json")
+ , log = require("npmlog")
+ , npm = require("../npm.js")
+ , tar = require("../utils/tar.js")
+ , deprCheck = require("../utils/depr-check.js")
+ , locker = require("../utils/locker.js")
+ , lock = locker.lock
+ , unlock = locker.unlock
+ , getCacheStat = require("./get-stat.js")
+ , addNamed = require("./add-named.js")
+ , addLocalTarball = require("./add-local-tarball.js")
+ , maybeGithub = require("./maybe-github.js")
+ , sha = require("sha")
+
+module.exports = addLocal
+
+function addLocal (p, pkgData, cb_) {
+ assert(typeof p === "string", "must have path")
+ assert(typeof cb === "function", "must have callback")
+
+ pkgData = pkgData || {}
+
+ function cb (er, data) {
+ unlock(p, function () {
+ if (er) {
+ // if it doesn't have a / in it, it might be a
+ // remote thing.
+ if (p.indexOf("/") === -1 && p.charAt(0) !== "."
+ && (process.platform !== "win32" || p.indexOf("\\") === -1)) {
+ return addNamed(p, "", null, cb_)
+ }
+ log.error("addLocal", "Could not install %s", p)
+ return cb_(er)
+ }
+ if (data && !data._fromGithub) data._from = p
+ return cb_(er, data)
+ })
+ }
+
+ lock(p, function (er) {
+ if (er) return cb(er)
+ // figure out if this is a folder or file.
+ fs.stat(p, function (er, s) {
+ if (er) {
+ // might be username/project
+ // in that case, try it as a github url.
+ if (p.split("/").length === 2) {
+ return maybeGithub(p, er, cb)
+ }
+ return cb(er)
+ }
+ if (s.isDirectory()) addLocalDirectory(p, pkgData, null, cb)
+ else addLocalTarball(p, pkgData, null, cb)
+ })
+ })
+}
+
+// At this point, if shasum is set, it's something that we've already
+// read and checked. Just stashing it in the data at this point.
+function addLocalDirectory (p, pkgData, shasum, cb) {
+ assert(pkgData, "must pass package data")
+ assert(typeof cb === "function", "must have callback")
+
+ // if it's a folder, then read the package.json,
+ // tar it to the proper place, and add the cache tar
+ if (pathIsInside(p, npm.cache)) return cb(new Error(
+ "Adding a cache directory to the cache will make the world implode."))
+
+ readJson(path.join(p, "package.json"), false, function (er, data) {
+ er = needName(er, data)
+ er = needVersion(er, data)
+
+ // check that this is what we expected.
+ if (!er && pkgData.name && pkgData.name !== data.name) {
+ er = new Error( "Invalid Package: expected "
+ + pkgData.name + " but found "
+ + data.name )
+ }
+
+ if (!er && pkgData.version && pkgData.version !== data.version) {
+ er = new Error( "Invalid Package: expected "
+ + pkgData.name + "@" + pkgData.version
+ + " but found "
+ + data.name + "@" + data.version )
+ }
+
+ if (er) return cb(er)
+ deprCheck(data)
+
+ // pack to {cache}/name/ver/package.tgz
+ var croot = path.resolve(npm.cache, data.name, data.version)
+ var tgz = path.resolve(croot, "package.tgz")
+ var pj = path.resolve(croot, "package/package.json")
+ getCacheStat(function (er, cs) {
+ mkdir(path.dirname(pj), function (er, made) {
+ if (er) return cb(er)
+ var fancy = !pathIsInside(p, npm.tmp)
+ tar.pack(tgz, p, data, fancy, function (er) {
+ if (er) {
+ log.error( "addLocalDirectory", "Could not pack %j to %j"
+ , p, tgz )
+ return cb(er)
+ }
+
+ if (!cs || isNaN(cs.uid) || isNaN(cs.gid)) next()
+
+ chownr(made || tgz, cs.uid, cs.gid, next)
+ })
+ })
+ })
+
+ function next (er) {
+ if (er) return cb(er)
+ // if we have the shasum already, just add it
+ if (shasum) {
+ return addLocalTarball(tgz, data, shasum, cb)
+ } else {
+ sha.get(tgz, function (er, shasum) {
+ if (er) {
+ return cb(er)
+ }
+ data._shasum = shasum
+ return addLocalTarball(tgz, data, shasum, cb)
+ })
+ }
+ }
+ })
+}
+
+function needName(er, data) {
+ return er ? er
+ : (data && !data.name) ? new Error("No name provided")
+ : null
+}
+
+function needVersion(er, data) {
+ return er ? er
+ : (data && !data.version) ? new Error("No version provided")
+ : null
+}
diff --git a/lib/cache/add-named.js b/lib/cache/add-named.js
new file mode 100644
index 0000000..7137cc9
--- /dev/null
+++ b/lib/cache/add-named.js
@@ -0,0 +1,278 @@
+var path = require("path")
+ , assert = require("assert")
+ , fs = require("graceful-fs")
+ , http = require("http")
+ , log = require("npmlog")
+ , semver = require("semver")
+ , readJson = require("read-package-json")
+ , url = require("url")
+ , npm = require("../npm.js")
+ , registry = npm.registry
+ , deprCheck = require("../utils/depr-check.js")
+ , inflight = require("inflight")
+ , locker = require("../utils/locker.js")
+ , lock = locker.lock
+ , unlock = locker.unlock
+ , maybeGithub = require("./maybe-github.js")
+ , addRemoteTarball = require("./add-remote-tarball.js")
+
+
+module.exports = addNamed
+
+var NAME_PREFIX = "addName:"
+function addNamed (name, version, data, cb_) {
+ assert(typeof name === "string", "must have module name")
+ assert(typeof cb_ === "function", "must have callback")
+
+ log.verbose("addNamed", [name, version])
+
+ var key = name + "@" + version
+ function cb (er, data) {
+ if (data && !data._fromGithub) data._from = key
+ unlock(key, function () { cb_(er, data) })
+ }
+
+ cb_ = inflight(NAME_PREFIX + key, cb_)
+
+ if (!cb_) return
+
+ log.verbose("addNamed", [semver.valid(version), semver.validRange(version)])
+ lock(key, function (er) {
+ if (er) return cb(er)
+
+ var fn = ( semver.valid(version, true) ? addNameVersion
+ : semver.validRange(version, true) ? addNameRange
+ : addNameTag
+ )
+ fn(name, version, data, cb)
+ })
+}
+
+function addNameTag (name, tag, data, cb_) {
+ log.info("addNameTag", [name, tag])
+ var explicit = true
+ if (!tag) {
+ explicit = false
+ tag = npm.config.get("tag")
+ }
+
+ function cb(er, data) {
+ // might be username/project
+ // in that case, try it as a github url.
+ if (er && tag.split("/").length === 2) {
+ return maybeGithub(tag, er, cb_)
+ }
+ return cb_(er, data)
+ }
+
+ var uri = url.resolve(npm.config.get("registry"), name)
+ registry.get(uri, null, function (er, data, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
+ if (er) return cb(er)
+ engineFilter(data)
+ if (data["dist-tags"] && data["dist-tags"][tag]
+ && data.versions[data["dist-tags"][tag]]) {
+ var ver = data["dist-tags"][tag]
+ return addNamed(name, ver, data.versions[ver], cb)
+ }
+ if (!explicit && Object.keys(data.versions).length) {
+ return addNamed(name, "*", data, cb)
+ }
+
+ er = installTargetsError(tag, data)
+ return cb(er)
+ })
+}
+
+function engineFilter (data) {
+ var npmv = npm.version
+ , nodev = npm.config.get("node-version")
+ , strict = npm.config.get("engine-strict")
+
+ if (!nodev || npm.config.get("force")) return data
+
+ Object.keys(data.versions || {}).forEach(function (v) {
+ var eng = data.versions[v].engines
+ if (!eng) return
+ if (!strict && !data.versions[v].engineStrict) return
+ if (eng.node && !semver.satisfies(nodev, eng.node, true)
+ || eng.npm && !semver.satisfies(npmv, eng.npm, true)) {
+ delete data.versions[v]
+ }
+ })
+}
+
+function addNameVersion (name, v, data, cb) {
+ var ver = semver.valid(v, true)
+ if (!ver) return cb(new Error("Invalid version: "+v))
+
+ var response
+
+ if (data) {
+ response = null
+ return next()
+ }
+ var uri = url.resolve(npm.config.get("registry"), name)
+ registry.get(uri, null, function (er, d, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
+ if (er) return cb(er)
+ data = d && d.versions[ver]
+ if (!data) {
+ er = new Error('version not found: ' + name + '@' + ver)
+ er.package = name
+ er.statusCode = 404
+ return cb(er)
+ }
+ response = resp
+ next()
+ })
+
+ function next () {
+ deprCheck(data)
+ var dist = data.dist
+
+ if (!dist) return cb(new Error("No dist in "+data._id+" package"))
+
+ if (!dist.tarball) return cb(new Error(
+ "No dist.tarball in " + data._id + " package"))
+
+ if ((response && response.statusCode !== 304) || npm.config.get("force")) {
+ return fetchit()
+ }
+
+ // we got cached data, so let's see if we have a tarball.
+ var pkgroot = path.join(npm.cache, name, ver)
+ var pkgtgz = path.join(pkgroot, "package.tgz")
+ var pkgjson = path.join(pkgroot, "package", "package.json")
+ fs.stat(pkgtgz, function (er) {
+ if (!er) {
+ readJson(pkgjson, function (er, data) {
+ er = needName(er, data)
+ er = needVersion(er, data)
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR")
+ return cb(er)
+ if (er) return fetchit()
+ return cb(null, data)
+ })
+ } else return fetchit()
+ })
+
+ function fetchit () {
+ if (!npm.config.get("registry")) {
+ return cb(new Error("Cannot fetch: "+dist.tarball))
+ }
+
+ // use the same protocol as the registry.
+ // https registry --> https tarballs, but
+ // only if they're the same hostname, or else
+ // detached tarballs may not work.
+ var tb = url.parse(dist.tarball)
+ var rp = url.parse(npm.config.get("registry"))
+ if (tb.hostname === rp.hostname
+ && tb.protocol !== rp.protocol) {
+ tb.protocol = url.parse(npm.config.get("registry")).protocol
+ delete tb.href
+ }
+ tb = url.format(tb)
+
+ // only add non-shasum'ed packages if --forced.
+ // only ancient things would lack this for good reasons nowadays.
+ if (!dist.shasum && !npm.config.get("force")) {
+ return cb(new Error("package lacks shasum: " + data._id))
+ }
+ return addRemoteTarball(tb, data, dist.shasum, cb)
+ }
+ }
+}
+
+function addNameRange (name, range, data, cb) {
+ range = semver.validRange(range, true)
+ if (range === null) return cb(new Error(
+ "Invalid version range: "+range))
+
+ log.silly("addNameRange", {name:name, range:range, hasData:!!data})
+
+ if (data) return next()
+ var uri = url.resolve(npm.config.get("registry"), name)
+ registry.get(uri, null, function (er, d, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
+ if (er) return cb(er)
+ data = d
+ next()
+ })
+
+ function next () {
+ log.silly( "addNameRange", "number 2"
+ , {name:name, range:range, hasData:!!data})
+ engineFilter(data)
+
+ log.silly("addNameRange", "versions"
+ , [data.name, Object.keys(data.versions || {})])
+
+ // if the tagged version satisfies, then use that.
+ var tagged = data["dist-tags"][npm.config.get("tag")]
+ if (tagged
+ && data.versions[tagged]
+ && semver.satisfies(tagged, range, true)) {
+ return addNamed(name, tagged, data.versions[tagged], cb)
+ }
+
+ // find the max satisfying version.
+ var versions = Object.keys(data.versions || {})
+ var ms = semver.maxSatisfying(versions, range, true)
+ if (!ms) {
+ return cb(installTargetsError(range, data))
+ }
+
+ // if we don't have a registry connection, try to see if
+ // there's a cached copy that will be ok.
+ addNamed(name, ms, data.versions[ms], cb)
+ }
+}
+
+function installTargetsError (requested, data) {
+ var targets = Object.keys(data["dist-tags"]).filter(function (f) {
+ return (data.versions || {}).hasOwnProperty(f)
+ }).concat(Object.keys(data.versions || {}))
+
+ requested = data.name + (requested ? "@'" + requested + "'" : "")
+
+ targets = targets.length
+ ? "Valid install targets:\n" + JSON.stringify(targets) + "\n"
+ : "No valid targets found.\n"
+ + "Perhaps not compatible with your version of node?"
+
+ var er = new Error( "No compatible version found: "
+ + requested + "\n" + targets)
+ er.code = "ETARGET"
+ return er
+}
+
+function errorResponse (name, response) {
+ var er
+ if (response.statusCode >= 400) {
+ er = new Error(http.STATUS_CODES[response.statusCode])
+ er.statusCode = response.statusCode
+ er.code = "E" + er.statusCode
+ er.pkgid = name
+ }
+ return er
+}
+
+function needName(er, data) {
+ return er ? er
+ : (data && !data.name) ? new Error("No name provided")
+ : null
+}
+
+function needVersion(er, data) {
+ return er ? er
+ : (data && !data.version) ? new Error("No version provided")
+ : null
+}
diff --git a/lib/cache/add-remote-git.js b/lib/cache/add-remote-git.js
new file mode 100644
index 0000000..7743aa4
--- /dev/null
+++ b/lib/cache/add-remote-git.js
@@ -0,0 +1,233 @@
+var mkdir = require("mkdirp")
+ , assert = require("assert")
+ , git = require("../utils/git.js")
+ , once = require("once")
+ , fs = require("graceful-fs")
+ , log = require("npmlog")
+ , path = require("path")
+ , url = require("url")
+ , chownr = require("chownr")
+ , zlib = require("zlib")
+ , which = require("which")
+ , crypto = require("crypto")
+ , chmodr = require("chmodr")
+ , npm = require("../npm.js")
+ , rm = require("../utils/gently-rm.js")
+ , inflight = require("inflight")
+ , locker = require("../utils/locker.js")
+ , lock = locker.lock
+ , unlock = locker.unlock
+ , getCacheStat = require("./get-stat.js")
+ , addLocalTarball = require("./add-local-tarball.js")
+
+
+// 1. cacheDir = path.join(cache,'_git-remotes',sha1(u))
+// 2. checkGitDir(cacheDir) ? 4. : 3. (rm cacheDir if necessary)
+// 3. git clone --mirror u cacheDir
+// 4. cd cacheDir && git fetch -a origin
+// 5. git archive /tmp/random.tgz
+// 6. addLocalTarball(/tmp/random.tgz) <gitref> --format=tar --prefix=package/
+// silent flag is used if this should error quietly
+module.exports = function addRemoteGit (u, parsed, silent, cb_) {
+ assert(typeof u === "string", "must have git URL")
+ assert(typeof parsed === "object", "must have parsed query")
+ assert(typeof cb_ === "function", "must have callback")
+
+ function cb (er, data) {
+ unlock(u, function () { cb_(er, data) })
+ }
+
+ cb_ = inflight(u, cb_)
+
+ if (!cb_) return
+
+ // git is so tricky!
+ // if the path is like ssh://foo:22/some/path then it works, but
+ // it needs the ssh://
+ // If the path is like ssh://foo:some/path then it works, but
+ // only if you remove the ssh://
+ var origUrl = u
+ u = u.replace(/^git\+/, "")
+ .replace(/#.*$/, "")
+
+ // ssh paths that are scp-style urls don't need the ssh://
+ if (parsed.pathname.match(/^\/?:/)) {
+ u = u.replace(/^ssh:\/\//, "")
+ }
+
+ lock(u, function (er) {
+ if (er) return cb(er)
+
+ // figure out what we should check out.
+ var co = parsed.hash && parsed.hash.substr(1) || "master"
+
+ var v = crypto.createHash("sha1").update(u).digest("hex").slice(0, 8)
+ v = u.replace(/[^a-zA-Z0-9]+/g, '-') + '-' + v
+
+ log.verbose("addRemoteGit", [u, co])
+
+ var p = path.join(npm.config.get("cache"), "_git-remotes", v)
+
+ checkGitDir(p, u, co, origUrl, silent, function(er, data) {
+ chmodr(p, npm.modes.file, function(erChmod) {
+ if (er) return cb(er, data)
+ return cb(erChmod, data)
+ })
+ })
+ })
+}
+
+function checkGitDir (p, u, co, origUrl, silent, cb) {
+ fs.stat(p, function (er, s) {
+ if (er) return cloneGitRemote(p, u, co, origUrl, silent, cb)
+ if (!s.isDirectory()) return rm(p, function (er){
+ if (er) return cb(er)
+ cloneGitRemote(p, u, co, origUrl, silent, cb)
+ })
+
+ var args = [ "config", "--get", "remote.origin.url" ]
+ var env = gitEnv()
+
+ // check for git
+ git.whichAndExec(args, {cwd: p, env: env}, function (er, stdout, stderr) {
+ var stdoutTrimmed = (stdout + "\n" + stderr).trim()
+ if (er || u !== stdout.trim()) {
+ log.warn( "`git config --get remote.origin.url` returned "
+ + "wrong result ("+u+")", stdoutTrimmed )
+ return rm(p, function (er){
+ if (er) return cb(er)
+ cloneGitRemote(p, u, co, origUrl, silent, cb)
+ })
+ }
+ log.verbose("git remote.origin.url", stdoutTrimmed)
+ archiveGitRemote(p, u, co, origUrl, cb)
+ })
+ })
+}
+
+function cloneGitRemote (p, u, co, origUrl, silent, cb) {
+ mkdir(p, function (er) {
+ if (er) return cb(er)
+
+ var args = [ "clone", "--mirror", u, p ]
+ var env = gitEnv()
+
+ // check for git
+ git.whichAndExec(args, {cwd: p, env: env}, function (er, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ if (silent) {
+ log.verbose("git clone " + u, stdout)
+ } else {
+ log.error("git clone " + u, stdout)
+ }
+ return cb(er)
+ }
+ log.verbose("git clone " + u, stdout)
+ archiveGitRemote(p, u, co, origUrl, cb)
+ })
+ })
+}
+
+function archiveGitRemote (p, u, co, origUrl, cb) {
+ var archive = [ "fetch", "-a", "origin" ]
+ var resolve = [ "rev-list", "-n1", co ]
+ var env = gitEnv()
+
+ var resolved = null
+ var tmp
+
+ git.whichAndExec(archive, {cwd: p, env: env}, function (er, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ log.error("git fetch -a origin ("+u+")", stdout)
+ return cb(er)
+ }
+ log.verbose("git fetch -a origin ("+u+")", stdout)
+ tmp = path.join(npm.tmp, Date.now()+"-"+Math.random(), "tmp.tgz")
+ verifyOwnership()
+ })
+
+ function verifyOwnership() {
+ if (process.platform === "win32") {
+ log.silly("verifyOwnership", "skipping for windows")
+ resolveHead()
+ } else {
+ getCacheStat(function(er, cs) {
+ if (er) {
+ log.error("Could not get cache stat")
+ return cb(er)
+ }
+ chownr(p, cs.uid, cs.gid, function(er) {
+ if (er) {
+ log.error("Failed to change folder ownership under npm cache for %s", p)
+ return cb(er)
+ }
+ resolveHead()
+ })
+ })
+ }
+ }
+
+ function resolveHead () {
+ git.whichAndExec(resolve, {cwd: p, env: env}, function (er, stdout, stderr) {
+ stdout = (stdout + "\n" + stderr).trim()
+ if (er) {
+ log.error("Failed resolving git HEAD (" + u + ")", stderr)
+ return cb(er)
+ }
+ log.verbose("git rev-list -n1 " + co, stdout)
+ var parsed = url.parse(origUrl)
+ parsed.hash = stdout
+ resolved = url.format(parsed)
+
+ // https://github.com/npm/npm/issues/3224
+ // node incorrectly sticks a / at the start of the path
+ // We know that the host won't change, so split and detect this
+ var spo = origUrl.split(parsed.host)
+ var spr = resolved.split(parsed.host)
+ if (spo[1].charAt(0) === ':' && spr[1].charAt(0) === '/')
+ spr[1] = spr[1].slice(1)
+ resolved = spr.join(parsed.host)
+
+ log.verbose('resolved git url', resolved)
+ next()
+ })
+ }
+
+ function next () {
+ mkdir(path.dirname(tmp), function (er) {
+ if (er) return cb(er)
+ var gzip = zlib.createGzip({ level: 9 })
+ var args = ["archive", co, "--format=tar", "--prefix=package/"]
+ var out = fs.createWriteStream(tmp)
+ var env = gitEnv()
+ cb = once(cb)
+ var cp = git.spawn(args, { env: env, cwd: p })
+ cp.on("error", cb)
+ cp.stderr.on("data", function(chunk) {
+ log.silly(chunk.toString(), "git archive")
+ })
+
+ cp.stdout.pipe(gzip).pipe(out).on("close", function() {
+ addLocalTarball(tmp, null, null, function(er, data) {
+ if (data) data._resolved = resolved
+ cb(er, data)
+ })
+ })
+ })
+ }
+}
+
+var gitEnv_
+function gitEnv () {
+ // git responds to env vars in some weird ways in post-receive hooks
+ // so don't carry those along.
+ if (gitEnv_) return gitEnv_
+ gitEnv_ = {}
+ for (var k in process.env) {
+ if (!~['GIT_PROXY_COMMAND','GIT_SSH','GIT_SSL_NO_VERIFY'].indexOf(k) && k.match(/^GIT/)) continue
+ gitEnv_[k] = process.env[k]
+ }
+ return gitEnv_
+}
diff --git a/lib/cache/add-remote-tarball.js b/lib/cache/add-remote-tarball.js
new file mode 100644
index 0000000..db9a05d
--- /dev/null
+++ b/lib/cache/add-remote-tarball.js
@@ -0,0 +1,106 @@
+var mkdir = require("mkdirp")
+ , assert = require("assert")
+ , log = require("npmlog")
+ , path = require("path")
+ , sha = require("sha")
+ , retry = require("retry")
+ , npm = require("../npm.js")
+ , fetch = require("../utils/fetch.js")
+ , inflight = require("inflight")
+ , locker = require("../utils/locker.js")
+ , lock = locker.lock
+ , unlock = locker.unlock
+ , addLocalTarball = require("./add-local-tarball.js")
+ , cacheFile = require("npm-cache-filename")
+
+module.exports = addRemoteTarball
+
+function addRemoteTarball (u, pkgData, shasum, cb_) {
+ assert(typeof u === "string", "must have module URL")
+ assert(typeof cb_ === "function", "must have callback")
+
+ function cb (er, data) {
+ if (data) {
+ data._from = u
+ data._shasum = data._shasum || shasum
+ data._resolved = u
+ }
+ unlock(u, function () {
+ cb_(er, data)
+ })
+ }
+
+ cb_ = inflight(u, cb_)
+
+ if (!cb_) return
+
+ // XXX Fetch direct to cache location, store tarballs under
+ // ${cache}/registry.npmjs.org/pkg/-/pkg-1.2.3.tgz
+ var tmp = cacheFile(npm.tmp, u)
+
+ function next (er, resp, shasum) {
+ if (er) return cb(er)
+ addLocalTarball(tmp, pkgData, shasum, cb)
+ }
+
+ lock(u, function (er) {
+ if (er) return cb(er)
+
+ log.verbose("addRemoteTarball", [u, shasum])
+ mkdir(path.dirname(tmp), function (er) {
+ if (er) return cb(er)
+ addRemoteTarball_(u, tmp, shasum, next)
+ })
+ })
+}
+
+function addRemoteTarball_(u, tmp, shasum, cb) {
+ // Tuned to spread 3 attempts over about a minute.
+ // See formula at <https://github.com/tim-kos/node-retry>.
+ var operation = retry.operation
+ ( { retries: npm.config.get("fetch-retries")
+ , factor: npm.config.get("fetch-retry-factor")
+ , minTimeout: npm.config.get("fetch-retry-mintimeout")
+ , maxTimeout: npm.config.get("fetch-retry-maxtimeout") })
+
+ operation.attempt(function (currentAttempt) {
+ log.info("retry", "fetch attempt " + currentAttempt
+ + " at " + (new Date()).toLocaleTimeString())
+ fetchAndShaCheck(u, tmp, shasum, function (er, response, shasum) {
+ // Only retry on 408, 5xx or no `response`.
+ var sc = response && response.statusCode
+ var statusRetry = !sc || (sc === 408 || sc >= 500)
+ if (er && statusRetry && operation.retry(er)) {
+ log.info("retry", "will retry, error on last attempt: " + er)
+ return
+ }
+ cb(er, response, shasum)
+ })
+ })
+}
+
+function fetchAndShaCheck (u, tmp, shasum, cb) {
+ fetch(u, tmp, function (er, response) {
+ if (er) {
+ log.error("fetch failed", u)
+ return cb(er, response)
+ }
+
+ if (!shasum) {
+ // Well, we weren't given a shasum, so at least sha what we have
+ // in case we want to compare it to something else later
+ return sha.get(tmp, function (er, shasum) {
+ cb(er, response, shasum)
+ })
+ }
+
+ // validate that the url we just downloaded matches the expected shasum.
+ sha.check(tmp, shasum, function (er) {
+ if (er && er.message) {
+ // add original filename for better debuggability
+ er.message = er.message + '\n' + 'From: ' + u
+ }
+ return cb(er, response, shasum)
+ })
+ })
+}
diff --git a/lib/cache/get-stat.js b/lib/cache/get-stat.js
new file mode 100644
index 0000000..913f5af
--- /dev/null
+++ b/lib/cache/get-stat.js
@@ -0,0 +1,63 @@
+var mkdir = require("mkdirp")
+ , fs = require("graceful-fs")
+ , log = require("npmlog")
+ , chownr = require("chownr")
+ , npm = require("../npm.js")
+ , inflight = require("inflight")
+
+// to maintain the cache dir's permissions consistently.
+var cacheStat = null
+module.exports = function getCacheStat (cb) {
+ if (cacheStat) return cb(null, cacheStat)
+
+ cb = inflight("getCacheStat", cb)
+ if (!cb) return
+
+ fs.stat(npm.cache, function (er, st) {
+ if (er) return makeCacheDir(cb)
+ if (!st.isDirectory()) {
+ log.error("getCacheStat", "invalid cache dir %j", npm.cache)
+ return cb(er)
+ }
+ return cb(null, cacheStat = st)
+ })
+}
+
+function makeCacheDir (cb) {
+ if (!process.getuid) return mkdir(npm.cache, cb)
+
+ var uid = +process.getuid()
+ , gid = +process.getgid()
+
+ if (uid === 0) {
+ if (process.env.SUDO_UID) uid = +process.env.SUDO_UID
+ if (process.env.SUDO_GID) gid = +process.env.SUDO_GID
+ }
+ if (uid !== 0 || !process.env.HOME) {
+ cacheStat = {uid: uid, gid: gid}
+ return mkdir(npm.cache, afterMkdir)
+ }
+
+ fs.stat(process.env.HOME, function (er, st) {
+ if (er) {
+ log.error("makeCacheDir", "homeless?")
+ return cb(er)
+ }
+ cacheStat = st
+ log.silly("makeCacheDir", "cache dir uid, gid", [st.uid, st.gid])
+ return mkdir(npm.cache, afterMkdir)
+ })
+
+ function afterMkdir (er, made) {
+ if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) {
+ return cb(er, cacheStat)
+ }
+
+ if (!made) return cb(er, cacheStat)
+
+ // ensure that the ownership is correct.
+ chownr(made, cacheStat.uid, cacheStat.gid, function (er) {
+ return cb(er, cacheStat)
+ })
+ }
+}
diff --git a/lib/cache/maybe-github.js b/lib/cache/maybe-github.js
new file mode 100644
index 0000000..fee64c5
--- /dev/null
+++ b/lib/cache/maybe-github.js
@@ -0,0 +1,35 @@
+var url = require("url")
+ , assert = require("assert")
+ , log = require("npmlog")
+ , addRemoteGit = require("./add-remote-git.js")
+
+module.exports = function maybeGithub (p, er, cb) {
+ assert(typeof p === "string", "must pass package name")
+ assert(er instanceof Error, "must include error")
+ assert(typeof cb === "function", "must pass callback")
+
+ var u = "git://github.com/" + p
+ , up = url.parse(u)
+ log.info("maybeGithub", "Attempting %s from %s", p, u)
+
+ return addRemoteGit(u, up, true, function (er2, data) {
+ if (er2) {
+ var upriv = "git+ssh://git@github.com:" + p
+ , uppriv = url.parse(upriv)
+
+ log.info("maybeGithub", "Attempting %s from %s", p, upriv)
+
+ return addRemoteGit(upriv, uppriv, false, function (er3, data) {
+ if (er3) return cb(er)
+ success(upriv, data)
+ })
+ }
+ success(u, data)
+ })
+
+ function success (u, data) {
+ data._from = u
+ data._fromGithub = true
+ return cb(null, data)
+ }
+}
diff --git a/lib/completion.js b/lib/completion.js
new file mode 100644
index 0000000..5c1098a
--- /dev/null
+++ b/lib/completion.js
@@ -0,0 +1,248 @@
+
+module.exports = completion
+
+completion.usage = "npm completion >> ~/.bashrc\n"
+ + "npm completion >> ~/.zshrc\n"
+ + "source <(npm completion)"
+
+var npm = require("./npm.js")
+ , npmconf = require("npmconf")
+ , configDefs = npmconf.defs
+ , configTypes = configDefs.types
+ , shorthands = configDefs.shorthands
+ , nopt = require("nopt")
+ , configNames = Object.keys(configTypes).filter(function (e) {
+ return e.charAt(0) !== "_"
+ })
+ , shorthandNames = Object.keys(shorthands)
+ , allConfs = configNames.concat(shorthandNames)
+ , once = require("once")
+
+
+completion.completion = function (opts, cb) {
+ if (opts.w > 3) return cb()
+
+ var fs = require("graceful-fs")
+ , path = require("path")
+ , bashExists = null
+ , zshExists = null
+ fs.stat(path.resolve(process.env.HOME, ".bashrc"), function (er) {
+ bashExists = !er
+ next()
+ })
+ fs.stat(path.resolve(process.env.HOME, ".zshrc"), function (er) {
+ zshExists = !er
+ next()
+ })
+ function next () {
+ if (zshExists === null || bashExists === null) return
+ var out = []
+ if (zshExists) out.push("~/.zshrc")
+ if (bashExists) out.push("~/.bashrc")
+ if (opts.w === 2) out = out.map(function (m) {
+ return [">>", m]
+ })
+ cb(null, out)
+ }
+}
+
+function completion (args, cb) {
+ if (process.platform === "win32") {
+ var e = new Error("npm completion not supported on windows")
+ e.code = "ENOTSUP"
+ e.errno = require("constants").ENOTSUP
+ return cb(e)
+ }
+
+ // if the COMP_* isn't in the env, then just dump the script.
+ if (process.env.COMP_CWORD === undefined
+ ||process.env.COMP_LINE === undefined
+ ||process.env.COMP_POINT === undefined
+ ) return dumpScript(cb)
+
+ console.error(process.env.COMP_CWORD)
+ console.error(process.env.COMP_LINE)
+ console.error(process.env.COMP_POINT)
+
+ //console.log("abracadabrasauce\nabracad cat monger")
+ //if (Math.random() * 3 < 1) console.log("man\\ bear\\ pig")
+ //else if (Math.random() * 3 < 1)
+ // console.log("porkchop\\ sandwiches\nporkman")
+ //else console.log("encephylophagy")
+
+ // get the partial line and partial word,
+ // if the point isn't at the end.
+ // ie, tabbing at: npm foo b|ar
+ var w = +process.env.COMP_CWORD
+ , words = args.map(unescape)
+ , word = words[w]
+ , line = process.env.COMP_LINE
+ , point = +process.env.COMP_POINT
+ , partialLine = line.substr(0, point)
+ , partialWords = words.slice(0, w)
+
+ // figure out where in that last word the point is.
+ var partialWord = args[w]
+ , i = partialWord.length
+ while (partialWord.substr(0, i) !== partialLine.substr(-1*i) && i > 0) {
+ i --
+ }
+ partialWord = unescape(partialWord.substr(0, i))
+ partialWords.push(partialWord)
+
+ var opts = { words : words
+ , w : w
+ , word : word
+ , line : line
+ , lineLength : line.length
+ , point : point
+ , partialLine : partialLine
+ , partialWords : partialWords
+ , partialWord : partialWord
+ , raw: args
+ }
+
+ cb = wrapCb(cb, opts)
+
+ console.error(opts)
+
+ if (partialWords.slice(0, -1).indexOf("--") === -1) {
+ if (word.charAt(0) === "-") return configCompl(opts, cb)
+ if (words[w - 1]
+ && words[w - 1].charAt(0) === "-"
+ && !isFlag(words[w - 1])) {
+ // awaiting a value for a non-bool config.
+ // don't even try to do this for now
+ console.error("configValueCompl")
+ return configValueCompl(opts, cb)
+ }
+ }
+
+ // try to find the npm command.
+ // it's the first thing after all the configs.
+ // take a little shortcut and use npm's arg parsing logic.
+ // don't have to worry about the last arg being implicitly
+ // boolean'ed, since the last block will catch that.
+ var parsed = opts.conf =
+ nopt(configTypes, shorthands, partialWords.slice(0, -1), 0)
+ // check if there's a command already.
+ console.error(parsed)
+ var cmd = parsed.argv.remain[1]
+ if (!cmd) return cmdCompl(opts, cb)
+
+ Object.keys(parsed).forEach(function (k) {
+ npm.config.set(k, parsed[k])
+ })
+
+ // at this point, if words[1] is some kind of npm command,
+ // then complete on it.
+ // otherwise, do nothing
+ cmd = npm.commands[cmd]
+ if (cmd && cmd.completion) return cmd.completion(opts, cb)
+
+ // nothing to do.
+ cb()
+}
+
+function dumpScript (cb) {
+ var fs = require("graceful-fs")
+ , path = require("path")
+ , p = path.resolve(__dirname, "utils/completion.sh")
+
+ // The Darwin patch below results in callbacks first for the write and then
+ // for the error handler, so make sure we only call our callback once.
+ cb = once(cb)
+
+ fs.readFile(p, "utf8", function (er, d) {
+ if (er) return cb(er)
+ d = d.replace(/^\#\!.*?\n/, "")
+
+ process.stdout.write(d, function () { cb() })
+ process.stdout.on("error", function (er) {
+ // Darwin is a real dick sometimes.
+ //
+ // This is necessary because the "source" or "." program in
+ // bash on OS X closes its file argument before reading
+ // from it, meaning that you get exactly 1 write, which will
+ // work most of the time, and will always raise an EPIPE.
+ //
+ // Really, one should not be tossing away EPIPE errors, or any
+ // errors, so casually. But, without this, `. <(npm completion)`
+ // can never ever work on OS X.
+ if (er.errno === "EPIPE") er = null
+ cb(er)
+ })
+
+ })
+}
+
+function unescape (w) {
+ if (w.charAt(0) === "\"") return w.replace(/^"|"$/g, "")
+ else return w.replace(/\\ /g, " ")
+}
+
+function escape (w) {
+ if (!w.match(/\s+/)) return w
+ return "\"" + w + "\""
+}
+
+// The command should respond with an array. Loop over that,
+// wrapping quotes around any that have spaces, and writing
+// them to stdout. Use console.log, not the outfd config.
+// If any of the items are arrays, then join them with a space.
+// Ie, returning ["a", "b c", ["d", "e"]] would allow it to expand
+// to: "a", "b c", or "d" "e"
+function wrapCb (cb, opts) { return function (er, compls) {
+ if (!Array.isArray(compls)) compls = compls ? [compls] : []
+ compls = compls.map(function (c) {
+ if (Array.isArray(c)) c = c.map(escape).join(" ")
+ else c = escape(c)
+ return c
+ })
+ if (opts.partialWord) compls = compls.filter(function (c) {
+ return c.indexOf(opts.partialWord) === 0
+ })
+ console.error([er && er.stack, compls, opts.partialWord])
+ if (er || compls.length === 0) return cb(er)
+
+ console.log(compls.join("\n"))
+ cb()
+}}
+
+// the current word has a dash. Return the config names,
+// with the same number of dashes as the current word has.
+function configCompl (opts, cb) {
+ var word = opts.word
+ , split = word.match(/^(-+)((?:no-)*)(.*)$/)
+ , dashes = split[1]
+ , no = split[2]
+ , flags = configNames.filter(isFlag)
+ console.error(flags)
+
+ return cb(null, allConfs.map(function (c) {
+ return dashes + c
+ }).concat(flags.map(function (f) {
+ return dashes + (no || "no-") + f
+ })))
+}
+
+// expand with the valid values of various config values.
+// not yet implemented.
+function configValueCompl (opts, cb) {
+ console.error('configValue', opts)
+ return cb(null, [])
+}
+
+// check if the thing is a flag or not.
+function isFlag (word) {
+ // shorthands never take args.
+ var split = word.match(/^(-*)((?:no-)+)?(.*)$/)
+ , no = split[2]
+ , conf = split[3]
+ return no || configTypes[conf] === Boolean || shorthands[conf]
+}
+
+// complete against the npm commands
+function cmdCompl (opts, cb) {
+ return cb(null, npm.fullList)
+}
diff --git a/lib/config.js b/lib/config.js
new file mode 100644
index 0000000..8dc814a
--- /dev/null
+++ b/lib/config.js
@@ -0,0 +1,279 @@
+
+module.exports = config
+
+config.usage = "npm config set <key> <value>"
+ + "\nnpm config get [<key>]"
+ + "\nnpm config delete <key>"
+ + "\nnpm config list"
+ + "\nnpm config edit"
+ + "\nnpm set <key> <value>"
+ + "\nnpm get [<key>]"
+
+var log = require("npmlog")
+ , npm = require("./npm.js")
+ , fs = require("graceful-fs")
+ , npmconf = require("npmconf")
+ , types = npmconf.defs.types
+ , ini = require("ini")
+ , editor = require("editor")
+ , os = require("os")
+
+config.completion = function (opts, cb) {
+ var argv = opts.conf.argv.remain
+ if (argv[1] !== "config") argv.unshift("config")
+ if (argv.length === 2) {
+ var cmds = ["get", "set", "delete", "ls", "rm", "edit"]
+ if (opts.partialWord !== "l") cmds.push("list")
+ return cb(null, cmds)
+ }
+
+ var action = argv[2]
+ switch (action) {
+ case "set":
+ // todo: complete with valid values, if possible.
+ if (argv.length > 3) return cb(null, [])
+ // fallthrough
+ case "get":
+ case "delete":
+ case "rm":
+ return cb(null, Object.keys(types))
+ case "edit":
+ case "list": case "ls":
+ return cb(null, [])
+ default: return cb(null, [])
+ }
+}
+
+// npm config set key value
+// npm config get key
+// npm config list
+function config (args, cb) {
+ var action = args.shift()
+ switch (action) {
+ case "set": return set(args[0], args[1], cb)
+ case "get": return get(args[0], cb)
+ case "delete": case "rm": case "del": return del(args[0], cb)
+ case "list": case "ls": return list(cb)
+ case "edit": return edit(cb)
+ default: return unknown(action, cb)
+ }
+}
+
+function edit (cb) {
+ var e = npm.config.get("editor")
+ , which = npm.config.get("global") ? "global" : "user"
+ , f = npm.config.get(which + "config")
+ if (!e) return cb(new Error("No EDITOR config or environ set."))
+ npm.config.save(which, function (er) {
+ if (er) return cb(er)
+ fs.readFile(f, "utf8", function (er, data) {
+ if (er) data = ""
+ data = [ ";;;;"
+ , "; npm "+(npm.config.get("global") ?
+ "globalconfig" : "userconfig")+" file"
+ , "; this is a simple ini-formatted file"
+ , "; lines that start with semi-colons are comments."
+ , "; read `npm help config` for help on the various options"
+ , ";;;;"
+ , ""
+ , data
+ ].concat( [ ";;;;"
+ , "; all options with default values"
+ , ";;;;"
+ ]
+ )
+ .concat(Object.keys(npmconf.defaults).reduce(function (arr, key) {
+ var obj = {};
+ obj[key] = npmconf.defaults[key]
+ if (key === "logstream") return arr
+ return arr.concat(
+ ini.stringify(obj)
+ .replace(/\n$/m, '')
+ .replace(/^/g, '; ')
+ .replace(/\n/g, '\n; ')
+ .split('\n'))
+ }, []))
+ .concat([""])
+ .join(os.EOL)
+ fs.writeFile
+ ( f
+ , data
+ , "utf8"
+ , function (er) {
+ if (er) return cb(er)
+ editor(f, { editor: e }, cb)
+ }
+ )
+ })
+ })
+}
+
+function del (key, cb) {
+ if (!key) return cb(new Error("no key provided"))
+ var where = npm.config.get("global") ? "global" : "user"
+ npm.config.del(key, where)
+ npm.config.save(where, cb)
+}
+
+function set (key, val, cb) {
+ if (key === undefined) {
+ return unknown("", cb)
+ }
+ if (val === undefined) {
+ if (key.indexOf("=") !== -1) {
+ var k = key.split("=")
+ key = k.shift()
+ val = k.join("=")
+ } else {
+ val = ""
+ }
+ }
+ key = key.trim()
+ val = val.trim()
+ log.info("config", "set %j %j", key, val)
+ var where = npm.config.get("global") ? "global" : "user"
+ npm.config.set(key, val, where)
+ npm.config.save(where, cb)
+}
+
+function get (key, cb) {
+ if (!key) return list(cb)
+ if (key.charAt(0) === "_") {
+ return cb(new Error("---sekretz---"))
+ }
+ console.log(npm.config.get(key))
+ cb()
+}
+
+function sort (a, b) {
+ return a > b ? 1 : -1
+}
+
+function public (k) {
+ return !(k.charAt(0) === "_" || types[k] !== types[k])
+}
+
+function getKeys (data) {
+ return Object.keys(data).filter(public).sort(sort)
+}
+
+function list (cb) {
+ var msg = ""
+ , long = npm.config.get("long")
+
+ var cli = npm.config.sources.cli.data
+ , cliKeys = getKeys(cli)
+ if (cliKeys.length) {
+ msg += "; cli configs\n"
+ cliKeys.forEach(function (k) {
+ if (cli[k] && typeof cli[k] === "object") return
+ if (k === "argv") return
+ msg += k + " = " + JSON.stringify(cli[k]) + "\n"
+ })
+ msg += "\n"
+ }
+
+ // env configs
+ var env = npm.config.sources.env.data
+ , envKeys = getKeys(env)
+ if (envKeys.length) {
+ msg += "; environment configs\n"
+ envKeys.forEach(function (k) {
+ if (env[k] !== npm.config.get(k)) {
+ if (!long) return
+ msg += "; " + k + " = " + JSON.stringify(env[k])
+ + " (overridden)\n"
+ } else msg += k + " = " + JSON.stringify(env[k]) + "\n"
+ })
+ msg += "\n"
+ }
+
+ // user config file
+ var uconf = npm.config.sources.user.data
+ , uconfKeys = getKeys(uconf)
+ if (uconfKeys.length) {
+ msg += "; userconfig " + npm.config.get("userconfig") + "\n"
+ uconfKeys.forEach(function (k) {
+ var val = (k.charAt(0) === "_")
+ ? "---sekretz---"
+ : JSON.stringify(uconf[k])
+ if (uconf[k] !== npm.config.get(k)) {
+ if (!long) return
+ msg += "; " + k + " = " + val
+ + " (overridden)\n"
+ } else msg += k + " = " + val + "\n"
+ })
+ msg += "\n"
+ }
+
+ // global config file
+ var gconf = npm.config.sources.global.data
+ , gconfKeys = getKeys(gconf)
+ if (gconfKeys.length) {
+ msg += "; globalconfig " + npm.config.get("globalconfig") + "\n"
+ gconfKeys.forEach(function (k) {
+ var val = (k.charAt(0) === "_")
+ ? "---sekretz---"
+ : JSON.stringify(gconf[k])
+ if (gconf[k] !== npm.config.get(k)) {
+ if (!long) return
+ msg += "; " + k + " = " + val
+ + " (overridden)\n"
+ } else msg += k + " = " + val + "\n"
+ })
+ msg += "\n"
+ }
+
+ // builtin config file
+ var builtin = npm.config.sources.builtin || {}
+ if (builtin && builtin.data) {
+ var bconf = builtin.data
+ , bpath = builtin.path
+ , bconfKeys = getKeys(bconf)
+ if (bconfKeys.length) {
+ msg += "; builtin config " + bpath + "\n"
+ bconfKeys.forEach(function (k) {
+ var val = (k.charAt(0) === "_")
+ ? "---sekretz---"
+ : JSON.stringify(bconf[k])
+ if (bconf[k] !== npm.config.get(k)) {
+ if (!long) return
+ msg += "; " + k + " = " + val
+ + " (overridden)\n"
+ } else msg += k + " = " + val + "\n"
+ })
+ msg += "\n"
+ }
+ }
+
+ // only show defaults if --long
+ if (!long) {
+ msg += "; node bin location = " + process.execPath + "\n"
+ + "; cwd = " + process.cwd() + "\n"
+ + "; HOME = " + process.env.HOME + "\n"
+ + "; 'npm config ls -l' to show all defaults.\n"
+
+ console.log(msg)
+ return cb()
+ }
+
+ var defaults = npmconf.defaults
+ , defKeys = getKeys(defaults)
+ msg += "; default values\n"
+ defKeys.forEach(function (k) {
+ if (defaults[k] && typeof defaults[k] === "object") return
+ var val = JSON.stringify(defaults[k])
+ if (defaults[k] !== npm.config.get(k)) {
+ msg += "; " + k + " = " + val
+ + " (overridden)\n"
+ } else msg += k + " = " + val + "\n"
+ })
+ msg += "\n"
+
+ console.log(msg)
+ return cb()
+}
+
+function unknown (action, cb) {
+ cb("Usage:\n" + config.usage)
+}
diff --git a/lib/dedupe.js b/lib/dedupe.js
new file mode 100644
index 0000000..e6762e1
--- /dev/null
+++ b/lib/dedupe.js
@@ -0,0 +1,352 @@
+// traverse the node_modules/package.json tree
+// looking for duplicates. If any duplicates are found,
+// then move them up to the highest level necessary
+// in order to make them no longer duplicated.
+//
+// This is kind of ugly, and really highlights the need for
+// much better "put pkg X at folder Y" abstraction. Oh well,
+// whatever. Perfect enemy of the good, and all that.
+
+var url = require("url")
+var fs = require("fs")
+var asyncMap = require("slide").asyncMap
+var path = require("path")
+var readJson = require("read-package-json")
+var semver = require("semver")
+var rm = require("./utils/gently-rm.js")
+var log = require("npmlog")
+var npm = require("./npm.js")
+
+module.exports = dedupe
+
+dedupe.usage = "npm dedupe [pkg pkg...]"
+
+function dedupe (args, silent, cb) {
+ if (typeof silent === "function") cb = silent, silent = false
+ var dryrun = false
+ if (npm.command.match(/^find/)) dryrun = true
+ return dedupe_(npm.prefix, args, {}, dryrun, silent, cb)
+}
+
+function dedupe_ (dir, filter, unavoidable, dryrun, silent, cb) {
+ readInstalled(path.resolve(dir), {}, null, function (er, data, counter) {
+ if (er) {
+ return cb(er)
+ }
+
+ if (!data) {
+ return cb()
+ }
+
+ // find out which things are dupes
+ var dupes = Object.keys(counter || {}).filter(function (k) {
+ if (filter.length && -1 === filter.indexOf(k)) return false
+ return counter[k] > 1 && !unavoidable[k]
+ }).reduce(function (s, k) {
+ s[k] = []
+ return s
+ }, {})
+
+ // any that are unavoidable need to remain as they are. don't even
+ // try to touch them or figure it out. Maybe some day, we can do
+ // something a bit more clever here, but for now, just skip over it,
+ // and all its children.
+ ;(function U (obj) {
+ if (unavoidable[obj.name]) {
+ obj.unavoidable = true
+ }
+ if (obj.parent && obj.parent.unavoidable) {
+ obj.unavoidable = true
+ }
+ Object.keys(obj.children).forEach(function (k) {
+ U(obj.children[k])
+ })
+ })
+
+ // then collect them up and figure out who needs them
+ ;(function C (obj) {
+ if (dupes[obj.name] && !obj.unavoidable) {
+ dupes[obj.name].push(obj)
+ obj.duplicate = true
+ }
+ obj.dependents = whoDepends(obj)
+ Object.keys(obj.children).forEach(function (k) {
+ C(obj.children[k])
+ })
+ })(data)
+
+ if (dryrun) {
+ var k = Object.keys(dupes)
+ if (!k.length) return cb()
+ return npm.commands.ls(k, silent, cb)
+ }
+
+ var summary = Object.keys(dupes).map(function (n) {
+ return [n, dupes[n].filter(function (d) {
+ return d && d.parent && !d.parent.duplicate && !d.unavoidable
+ }).map(function M (d) {
+ return [d.path, d.version, d.dependents.map(function (k) {
+ return [k.path, k.version, k.dependencies[d.name] || ""]
+ })]
+ })]
+ }).map(function (item) {
+ var set = item[1]
+
+ var ranges = set.map(function (i) {
+ return i[2].map(function (d) {
+ return d[2]
+ })
+ }).reduce(function (l, r) {
+ return l.concat(r)
+ }, []).map(function (v, i, set) {
+ if (set.indexOf(v) !== i) return false
+ return v
+ }).filter(function (v) {
+ return v !== false
+ })
+
+ var locs = set.map(function (i) {
+ return i[0]
+ })
+
+ var versions = set.map(function (i) {
+ return i[1]
+ }).filter(function (v, i, set) {
+ return set.indexOf(v) === i
+ })
+
+ var has = set.map(function (i) {
+ return [i[0], i[1]]
+ }).reduce(function (set, kv) {
+ set[kv[0]] = kv[1]
+ return set
+ }, {})
+
+ var loc = locs.length ? locs.reduce(function (a, b) {
+ // a=/path/to/node_modules/foo/node_modules/bar
+ // b=/path/to/node_modules/elk/node_modules/bar
+ // ==/path/to/node_modules/bar
+ var nmReg = new RegExp("\\" + path.sep + "node_modules\\" + path.sep)
+ a = a.split(nmReg)
+ b = b.split(nmReg)
+ var name = a.pop()
+ b.pop()
+ // find the longest chain that both A and B share.
+ // then push the name back on it, and join by /node_modules/
+ for (var i = 0, al = a.length, bl = b.length; i < al && i < bl && a[i] === b[i]; i++);
+ return a.slice(0, i).concat(name).join(path.sep + "node_modules" + path.sep)
+ }) : undefined
+
+ return [item[0], { item: item
+ , ranges: ranges
+ , locs: locs
+ , loc: loc
+ , has: has
+ , versions: versions
+ }]
+ }).filter(function (i) {
+ return i[1].loc
+ })
+
+ findVersions(npm, summary, function (er, set) {
+ if (er) return cb(er)
+ if (!set.length) return cb()
+ installAndRetest(set, filter, dir, unavoidable, silent, cb)
+ })
+ })
+}
+
+function installAndRetest (set, filter, dir, unavoidable, silent, cb) {
+ //return cb(null, set)
+ var remove = []
+
+ asyncMap(set, function (item, cb) {
+ // [name, has, loc, locMatch, regMatch, others]
+ var name = item[0]
+ var has = item[1]
+ var where = item[2]
+ var locMatch = item[3]
+ var regMatch = item[4]
+ var others = item[5]
+
+ // nothing to be done here. oh well. just a conflict.
+ if (!locMatch && !regMatch) {
+ log.warn("unavoidable conflict", item[0], item[1])
+ log.warn("unavoidable conflict", "Not de-duplicating")
+ unavoidable[item[0]] = true
+ return cb()
+ }
+
+ // nothing to do except to clean up the extraneous deps
+ if (locMatch && has[where] === locMatch) {
+ remove.push.apply(remove, others)
+ return cb()
+ }
+
+ if (regMatch) {
+ var what = name + "@" + regMatch
+ // where is /path/to/node_modules/foo/node_modules/bar
+ // for package "bar", but we need it to be just
+ // /path/to/node_modules/foo
+ var nmReg = new RegExp("\\" + path.sep + "node_modules\\" + path.sep)
+ where = where.split(nmReg)
+ where.pop()
+ where = where.join(path.sep + "node_modules" + path.sep)
+ remove.push.apply(remove, others)
+
+ return npm.commands.install(where, what, cb)
+ }
+
+ // hrm?
+ return cb(new Error("danger zone\n" + name + " " +
+ regMatch + " " + locMatch))
+
+ }, function (er) {
+ if (er) return cb(er)
+ asyncMap(remove, rm, function (er) {
+ if (er) return cb(er)
+ remove.forEach(function (r) {
+ log.info("rm", r)
+ })
+ dedupe_(dir, filter, unavoidable, false, silent, cb)
+ })
+ })
+}
+
+function findVersions (npm, summary, cb) {
+ // now, for each item in the summary, try to find the maximum version
+ // that will satisfy all the ranges. next step is to install it at
+ // the specified location.
+ asyncMap(summary, function (item, cb) {
+ var name = item[0]
+ var data = item[1]
+ var loc = data.loc
+ var locs = data.locs.filter(function (l) {
+ return l !== loc
+ })
+
+ // not actually a dupe, or perhaps all the other copies were
+ // children of a dupe, so this'll maybe be picked up later.
+ if (locs.length === 0) {
+ return cb(null, [])
+ }
+
+ // { <folder>: <version> }
+ var has = data.has
+
+ // the versions that we already have.
+ // if one of these is ok, then prefer to use that.
+ // otherwise, try fetching from the registry.
+ var versions = data.versions
+
+ var ranges = data.ranges
+ var uri = url.resolve(npm.config.get("registry"), name)
+ npm.registry.get(uri, null, function (er, data) {
+ var regVersions = er ? [] : Object.keys(data.versions)
+ var locMatch = bestMatch(versions, ranges)
+ var regMatch;
+ var tag = npm.config.get("tag")
+ var distTag = data["dist-tags"] && data["dist-tags"][tag]
+ if (distTag && data.versions[distTag] && matches(distTag, ranges)) {
+ regMatch = distTag
+ } else {
+ regMatch = bestMatch(regVersions, ranges)
+ }
+
+ cb(null, [[name, has, loc, locMatch, regMatch, locs]])
+ })
+ }, cb)
+}
+
+function matches (version, ranges) {
+ return !ranges.some(function (r) {
+ return !semver.satisfies(version, r, true)
+ })
+}
+
+function bestMatch (versions, ranges) {
+ return versions.filter(function (v) {
+ return matches(v, ranges)
+ }).sort(semver.compareLoose).pop()
+}
+
+
+function readInstalled (dir, counter, parent, cb) {
+ var pkg, children, realpath
+
+ fs.realpath(dir, function (er, rp) {
+ realpath = rp
+ next()
+ })
+
+ readJson(path.resolve(dir, "package.json"), function (er, data) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
+ if (er) return cb() // not a package, probably.
+ counter[data.name] = counter[data.name] || 0
+ counter[data.name]++
+ pkg =
+ { _id: data._id
+ , name: data.name
+ , version: data.version
+ , dependencies: data.dependencies || {}
+ , optionalDependencies: data.optionalDependencies || {}
+ , devDependencies: data.devDependencies || {}
+ , bundledDependencies: data.bundledDependencies || []
+ , path: dir
+ , realPath: dir
+ , children: {}
+ , parent: parent
+ , family: Object.create(parent ? parent.family : null)
+ , unavoidable: false
+ , duplicate: false
+ }
+ if (parent) {
+ parent.children[data.name] = pkg
+ parent.family[data.name] = pkg
+ }
+ next()
+ })
+
+ fs.readdir(path.resolve(dir, "node_modules"), function (er, c) {
+ children = c || [] // error is ok, just means no children.
+ children = children.filter(function (p) {
+ return !p.match(/^[\._-]/)
+ })
+ next()
+ })
+
+ function next () {
+ if (!children || !pkg || !realpath) return
+
+ // ignore devDependencies. Just leave them where they are.
+ children = children.filter(function (c) {
+ return !pkg.devDependencies.hasOwnProperty(c)
+ })
+
+ pkg.realPath = realpath
+ if (pkg.realPath !== pkg.path) children = []
+ var d = path.resolve(dir, "node_modules")
+ asyncMap(children, function (child, cb) {
+ readInstalled(path.resolve(d, child), counter, pkg, cb)
+ }, function (er) {
+ cb(er, pkg, counter)
+ })
+ }
+}
+
+function whoDepends (pkg) {
+ var start = pkg.parent || pkg
+ return whoDepends_(pkg, [], start)
+}
+
+function whoDepends_ (pkg, who, test) {
+ if (test !== pkg &&
+ test.dependencies[pkg.name] &&
+ test.family[pkg.name] === pkg) {
+ who.push(test)
+ }
+ Object.keys(test.children).forEach(function (n) {
+ whoDepends_(pkg, who, test.children[n])
+ })
+ return who
+}
diff --git a/lib/deprecate.js b/lib/deprecate.js
new file mode 100644
index 0000000..175b69c
--- /dev/null
+++ b/lib/deprecate.js
@@ -0,0 +1,35 @@
+var url = require("url")
+ , npm = require("./npm.js")
+
+module.exports = deprecate
+
+deprecate.usage = "npm deprecate <pkg>[@<version>] <message>"
+
+deprecate.completion = function (opts, cb) {
+ // first, get a list of remote packages this user owns.
+ // once we have a user account, then don't complete anything.
+ var un = npm.config.get("username")
+ if (!npm.config.get("username")) return cb()
+ if (opts.conf.argv.remain.length > 2) return cb()
+ // get the list of packages by user
+ var path = "/-/by-user/"+encodeURIComponent(un)
+ , uri = url.resolve(npm.config.get("registry"), path)
+ npm.registry.get(uri, { timeout : 60000 }, function (er, list) {
+ if (er) return cb()
+ console.error(list)
+ return cb(null, list[un])
+ })
+}
+
+function deprecate (args, cb) {
+ var pkg = args[0]
+ , msg = args[1]
+ if (msg === undefined) return cb("Usage: " + deprecate.usage)
+ // fetch the data and make sure it exists.
+ pkg = pkg.split(/@/)
+ var name = pkg.shift()
+ , ver = pkg.join("@")
+ , uri = url.resolve(npm.config.get("registry"), name)
+
+ npm.registry.deprecate(uri, ver, msg, cb)
+}
diff --git a/lib/docs.js b/lib/docs.js
new file mode 100644
index 0000000..77073fb
--- /dev/null
+++ b/lib/docs.js
@@ -0,0 +1,68 @@
+module.exports = docs
+
+docs.usage = "npm docs <pkgname>"
+docs.usage += "\n"
+docs.usage += "npm docs ."
+
+docs.completion = function (opts, cb) {
+ var uri = url_.resolve(npm.config.get("registry"), "/-/short")
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
+}
+
+var url_ = require("url")
+ , npm = require("./npm.js")
+ , registry = npm.registry
+ , opener = require("opener")
+ , path = require("path")
+ , log = require("npmlog")
+
+function url (json) {
+ return json.homepage ? json.homepage : "https://npmjs.org/package/" + json.name
+}
+
+function docs (args, cb) {
+ args = args || []
+ var pending = args.length
+ if (!pending) return getDoc('.', cb)
+ args.forEach(function(proj) {
+ getDoc(proj, function(err) {
+ if (err) {
+ return cb(err)
+ }
+ --pending || cb()
+ })
+ })
+}
+
+function getDoc (project, cb) {
+ project = project || '.'
+ var package = path.resolve(process.cwd(), "package.json")
+
+ if (project === '.' || project === './') {
+ var json
+ try {
+ json = require(package)
+ if (!json.name) throw new Error('package.json does not have a valid "name" property')
+ project = json.name
+ } catch (e) {
+ log.error(e.message)
+ return cb(docs.usage)
+ }
+
+ return opener(url(json), { command: npm.config.get("browser") }, cb)
+ }
+
+ var uri = url_.resolve(npm.config.get("registry"), project + "/latest")
+ registry.get(uri, { timeout : 3600 }, function (er, json) {
+ var github = "https://github.com/" + project + "#readme"
+
+ if (er) {
+ if (project.split("/").length !== 2) return cb(er)
+ return opener(github, { command: npm.config.get("browser") }, cb)
+ }
+
+ return opener(url(json), { command: npm.config.get("browser") }, cb)
+ })
+}
diff --git a/lib/edit.js b/lib/edit.js
new file mode 100644
index 0000000..ddf501d
--- /dev/null
+++ b/lib/edit.js
@@ -0,0 +1,31 @@
+// npm edit <pkg>[@<version>]
+// open the package folder in the $EDITOR
+
+module.exports = edit
+edit.usage = "npm edit <pkg>"
+
+edit.completion = require("./utils/completion/installed-shallow.js")
+
+var npm = require("./npm.js")
+ , path = require("path")
+ , fs = require("graceful-fs")
+ , editor = require("editor")
+
+function edit (args, cb) {
+ var p = args[0]
+ if (args.length !== 1 || !p) return cb(edit.usage)
+ var e = npm.config.get("editor")
+ if (!e) return cb(new Error(
+ "No editor set. Set the 'editor' config, or $EDITOR environ."))
+ p = p.split("/")
+ .join("/node_modules/")
+ .replace(/(\/node_modules)+/, "/node_modules")
+ var f = path.resolve(npm.dir, p)
+ fs.lstat(f, function (er) {
+ if (er) return cb(er)
+ editor(f, { editor: e }, function (er) {
+ if (er) return cb(er)
+ npm.commands.rebuild(args, cb)
+ })
+ })
+}
diff --git a/lib/explore.js b/lib/explore.js
new file mode 100644
index 0000000..767d9a8
--- /dev/null
+++ b/lib/explore.js
@@ -0,0 +1,37 @@
+// npm explore <pkg>[@<version>]
+// open a subshell to the package folder.
+
+module.exports = explore
+explore.usage = "npm explore <pkg> [ -- <cmd>]"
+explore.completion = require("./utils/completion/installed-shallow.js")
+
+var npm = require("./npm.js")
+ , spawn = require("child_process").spawn
+ , path = require("path")
+ , fs = require("graceful-fs")
+
+function explore (args, cb) {
+ if (args.length < 1 || !args[0]) return cb(explore.usage)
+ var p = args.shift()
+ args = args.join(" ").trim()
+ if (args) args = ["-c", args]
+ else args = []
+
+ var cwd = path.resolve(npm.dir, p)
+ var sh = npm.config.get("shell")
+ fs.stat(cwd, function (er, s) {
+ if (er || !s.isDirectory()) return cb(new Error(
+ "It doesn't look like "+p+" is installed."))
+ if (!args.length) console.log(
+ "\nExploring "+cwd+"\n"+
+ "Type 'exit' or ^D when finished\n")
+
+ npm.spinner.stop()
+ var shell = spawn(sh, args, { cwd: cwd, customFds: [0, 1, 2] })
+ shell.on("close", function (er) {
+ // only fail if non-interactive.
+ if (!args.length) return cb()
+ cb(er)
+ })
+ })
+}
diff --git a/lib/faq.js b/lib/faq.js
new file mode 100644
index 0000000..912db00
--- /dev/null
+++ b/lib/faq.js
@@ -0,0 +1,8 @@
+
+module.exports = faq
+
+faq.usage = "npm faq"
+
+var npm = require("./npm.js")
+
+function faq (args, cb) { npm.commands.help(["faq"], cb) }
diff --git a/lib/get.js b/lib/get.js
new file mode 100644
index 0000000..aa05800
--- /dev/null
+++ b/lib/get.js
@@ -0,0 +1,12 @@
+
+module.exports = get
+
+get.usage = "npm get <key> <value> (See `npm config`)"
+
+var npm = require("./npm.js")
+
+get.completion = npm.commands.config.completion
+
+function get (args, cb) {
+ npm.commands.config(["get"].concat(args), cb)
+}
diff --git a/lib/help-search.js b/lib/help-search.js
new file mode 100644
index 0000000..d855345
--- /dev/null
+++ b/lib/help-search.js
@@ -0,0 +1,210 @@
+
+module.exports = helpSearch
+
+var fs = require("graceful-fs")
+ , path = require("path")
+ , asyncMap = require("slide").asyncMap
+ , npm = require("./npm.js")
+ , glob = require("glob")
+ , color = require("ansicolors")
+
+helpSearch.usage = "npm help-search <text>"
+
+function helpSearch (args, silent, cb) {
+ if (typeof cb !== "function") cb = silent, silent = false
+ if (!args.length) return cb(helpSearch.usage)
+
+ var docPath = path.resolve(__dirname, "..", "doc")
+ return glob(docPath + "/*/*.md", function (er, files) {
+ if (er)
+ return cb(er)
+ readFiles(files, function (er, data) {
+ if (er)
+ return cb(er)
+ searchFiles(args, data, function (er, results) {
+ if (er)
+ return cb(er)
+ formatResults(args, results, cb)
+ })
+ })
+ })
+}
+
+function readFiles (files, cb) {
+ var res = {}
+ asyncMap(files, function (file, cb) {
+ fs.readFile(file, 'utf8', function (er, data) {
+ res[file] = data
+ return cb(er)
+ })
+ }, function (er) {
+ return cb(er, res)
+ })
+}
+
+function searchFiles (args, files, cb) {
+ var results = []
+ Object.keys(files).forEach(function (file) {
+ var data = files[file]
+
+ // skip if no matches at all
+ var match
+ for (var a = 0, l = args.length; a < l && !match; a++) {
+ match = data.toLowerCase().indexOf(args[a].toLowerCase()) !== -1
+ }
+ if (!match)
+ return
+
+ var lines = data.split(/\n+/)
+
+ // if a line has a search term, then skip it and the next line.
+ // if the next line has a search term, then skip all 3
+ // otherwise, set the line to null. then remove the nulls.
+ l = lines.length
+ for (var i = 0; i < l; i ++) {
+ var line = lines[i]
+ , nextLine = lines[i + 1]
+ , ll
+
+ match = false
+ if (nextLine) {
+ for (a = 0, ll = args.length; a < ll && !match; a ++) {
+ match = nextLine.toLowerCase()
+ .indexOf(args[a].toLowerCase()) !== -1
+ }
+ if (match) {
+ // skip over the next line, and the line after it.
+ i += 2
+ continue
+ }
+ }
+
+ match = false
+ for (a = 0, ll = args.length; a < ll && !match; a ++) {
+ match = line.toLowerCase().indexOf(args[a].toLowerCase()) !== -1
+ }
+ if (match) {
+ // skip over the next line
+ i ++
+ continue
+ }
+
+ lines[i] = null
+ }
+
+ // now squish any string of nulls into a single null
+ lines = lines.reduce(function (l, r) {
+ if (!(r === null && l[l.length-1] === null)) l.push(r)
+ return l
+ }, [])
+
+ if (lines[lines.length - 1] === null) lines.pop()
+ if (lines[0] === null) lines.shift()
+
+ // now see how many args were found at all.
+ var found = {}
+ , totalHits = 0
+ lines.forEach(function (line) {
+ args.forEach(function (arg) {
+ var hit = (line || "").toLowerCase()
+ .split(arg.toLowerCase()).length - 1
+ if (hit > 0) {
+ found[arg] = (found[arg] || 0) + hit
+ totalHits += hit
+ }
+ })
+ })
+
+ var cmd = "npm help "
+ if (path.basename(path.dirname(file)) === "api") {
+ cmd = "npm apihelp "
+ }
+ cmd += path.basename(file, ".md").replace(/^npm-/, "")
+ results.push({ file: file
+ , cmd: cmd
+ , lines: lines
+ , found: Object.keys(found)
+ , hits: found
+ , totalHits: totalHits
+ })
+ })
+
+ // if only one result, then just show that help section.
+ if (results.length === 1) {
+ return npm.commands.help([results[0].file.replace(/\.md$/, "")], cb)
+ }
+
+ if (results.length === 0) {
+ console.log("No results for " + args.map(JSON.stringify).join(" "))
+ return cb()
+ }
+
+ // sort results by number of results found, then by number of hits
+ // then by number of matching lines
+ results = results.sort(function (a, b) {
+ return a.found.length > b.found.length ? -1
+ : a.found.length < b.found.length ? 1
+ : a.totalHits > b.totalHits ? -1
+ : a.totalHits < b.totalHits ? 1
+ : a.lines.length > b.lines.length ? -1
+ : a.lines.length < b.lines.length ? 1
+ : 0
+ })
+
+ cb(null, results)
+}
+
+function formatResults (args, results, cb) {
+ if (!results) return cb(null)
+
+ var cols = Math.min(process.stdout.columns || Infinity, 80) + 1
+
+ var out = results.map(function (res) {
+ var out = res.cmd
+ , r = Object.keys(res.hits).map(function (k) {
+ return k + ":" + res.hits[k]
+ }).sort(function (a, b) {
+ return a > b ? 1 : -1
+ }).join(" ")
+
+ out += ((new Array(Math.max(1, cols - out.length - r.length)))
+ .join(" ")) + r
+
+ if (!npm.config.get("long")) return out
+
+ out = "\n\n" + out
+ + "\n" + (new Array(cols)).join("—") + "\n"
+ + res.lines.map(function (line, i) {
+ if (line === null || i > 3) return ""
+ for (var out = line, a = 0, l = args.length; a < l; a ++) {
+ var finder = out.toLowerCase().split(args[a].toLowerCase())
+ , newOut = ""
+ , p = 0
+
+ finder.forEach(function (f) {
+ newOut += out.substr(p, f.length)
+
+ var hilit = out.substr(p + f.length, args[a].length)
+ if (npm.color) hilit = color.bgBlack(color.red(hilit))
+ newOut += hilit
+
+ p += f.length + args[a].length
+ })
+ }
+
+ return newOut
+ }).join("\n").trim()
+ return out
+ }).join("\n")
+
+ if (results.length && !npm.config.get("long")) {
+ out = "Top hits for "+(args.map(JSON.stringify).join(" "))
+ + "\n" + (new Array(cols)).join("—") + "\n"
+ + out
+ + "\n" + (new Array(cols)).join("—") + "\n"
+ + "(run with -l or --long to see more context)"
+ }
+
+ console.log(out.trim())
+ cb(null, results)
+}
diff --git a/lib/help.js b/lib/help.js
new file mode 100644
index 0000000..8f54d69
--- /dev/null
+++ b/lib/help.js
@@ -0,0 +1,233 @@
+
+module.exports = help
+
+help.completion = function (opts, cb) {
+ if (opts.conf.argv.remain.length > 2) return cb(null, [])
+ getSections(cb)
+}
+
+var path = require("path")
+ , spawn = require("child_process").spawn
+ , npm = require("./npm.js")
+ , log = require("npmlog")
+ , opener = require("opener")
+ , glob = require("glob")
+
+function help (args, cb) {
+ npm.spinner.stop()
+ var argv = npm.config.get("argv").cooked
+
+ var argnum = 0
+ if (args.length === 2 && ~~args[0]) {
+ argnum = ~~args.shift()
+ }
+
+ // npm help foo bar baz: search topics
+ if (args.length > 1 && args[0]) {
+ return npm.commands["help-search"](args, argnum, cb)
+ }
+
+ var section = npm.deref(args[0]) || args[0]
+
+ // npm help <noargs>: show basic usage
+ if (!section) {
+ var valid = argv[0] === 'help' ? 0 : 1
+ return npmUsage(valid, cb)
+ }
+
+
+ // npm <cmd> -h: show command usage
+ if ( npm.config.get("usage")
+ && npm.commands[section]
+ && npm.commands[section].usage
+ ) {
+ npm.config.set("loglevel", "silent")
+ log.level = "silent"
+ console.log(npm.commands[section].usage)
+ return cb()
+ }
+
+ // npm apihelp <section>: Prefer section 3 over section 1
+ var apihelp = argv.length && -1 !== argv[0].indexOf("api")
+ var pref = apihelp ? [3, 1, 5, 7] : [1, 3, 5, 7]
+ if (argnum)
+ pref = [ argnum ].concat(pref.filter(function (n) {
+ return n !== argnum
+ }))
+
+ // npm help <section>: Try to find the path
+ var manroot = path.resolve(__dirname, "..", "man")
+
+ // legacy
+ if (section === "global")
+ section = "folders"
+ else if (section === "json")
+ section = "package.json"
+
+ // find either /section.n or /npm-section.n
+ var f = "+(npm-" + section + "|" + section + ").[0-9]"
+ return glob(manroot + "/*/" + f, function (er, mans) {
+ if (er)
+ return cb(er)
+
+ if (!mans.length)
+ return npm.commands["help-search"](args, cb)
+
+ viewMan(pickMan(mans, pref), cb)
+ })
+}
+
+function pickMan (mans, pref_) {
+ var nre = /([0-9]+)$/
+ var pref = {}
+ pref_.forEach(function (sect, i) {
+ pref[sect] = i
+ })
+ mans = mans.sort(function (a, b) {
+ var an = a.match(nre)[1]
+ var bn = b.match(nre)[1]
+ return an === bn ? (a > b ? -1 : 1)
+ : pref[an] < pref[bn] ? -1
+ : 1
+ })
+ return mans[0]
+}
+
+function viewMan (man, cb) {
+ var nre = /([0-9]+)$/
+ var num = man.match(nre)[1]
+ var section = path.basename(man, "." + num)
+
+ // at this point, we know that the specified man page exists
+ var manpath = path.join(__dirname, "..", "man")
+ , env = {}
+ Object.keys(process.env).forEach(function (i) {
+ env[i] = process.env[i]
+ })
+ env.MANPATH = manpath
+ var viewer = npm.config.get("viewer")
+
+ var conf
+ switch (viewer) {
+ case "woman":
+ var a = ["-e", "(woman-find-file \"" + man + "\")"]
+ conf = { env: env, customFds: [ 0, 1, 2] }
+ var woman = spawn("emacsclient", a, conf)
+ woman.on("close", cb)
+ break
+
+ case "browser":
+ opener(htmlMan(man), { command: npm.config.get("browser") }, cb)
+ break
+
+ default:
+ conf = { env: env, customFds: [ 0, 1, 2] }
+ var manProcess = spawn("man", [num, section], conf)
+ manProcess.on("close", cb)
+ break
+ }
+}
+
+function htmlMan (man) {
+ var sect = +man.match(/([0-9]+)$/)[1]
+ var f = path.basename(man).replace(/([0-9]+)$/, "html")
+ switch (sect) {
+ case 1:
+ sect = "cli"
+ break
+ case 3:
+ sect = "api"
+ break
+ case 5:
+ sect = "files"
+ break
+ case 7:
+ sect = "misc"
+ break
+ default:
+ throw new Error("invalid man section: " + sect)
+ }
+ return path.resolve(__dirname, "..", "html", "doc", sect, f)
+}
+
+function npmUsage (valid, cb) {
+ npm.config.set("loglevel", "silent")
+ log.level = "silent"
+ console.log
+ ( ["\nUsage: npm <command>"
+ , ""
+ , "where <command> is one of:"
+ , npm.config.get("long") ? usages()
+ : " " + wrap(Object.keys(npm.commands))
+ , ""
+ , "npm <cmd> -h quick help on <cmd>"
+ , "npm -l display full usage info"
+ , "npm faq commonly asked questions"
+ , "npm help <term> search for help on <term>"
+ , "npm help npm involved overview"
+ , ""
+ , "Specify configs in the ini-formatted file:"
+ , " " + npm.config.get("userconfig")
+ , "or on the command line via: npm <command> --key value"
+ , "Config info can be viewed via: npm help config"
+ , ""
+ , "npm@" + npm.version + " " + path.dirname(__dirname)
+ ].join("\n"))
+ cb(valid)
+}
+
+function usages () {
+ // return a string of <cmd>: <usage>
+ var maxLen = 0
+ return Object.keys(npm.commands).filter(function (c) {
+ return c === npm.deref(c)
+ }).reduce(function (set, c) {
+ set.push([c, npm.commands[c].usage || ""])
+ maxLen = Math.max(maxLen, c.length)
+ return set
+ }, []).map(function (item) {
+ var c = item[0]
+ , usage = item[1]
+ return "\n " + c + (new Array(maxLen - c.length + 2).join(" "))
+ + (usage.split("\n")
+ .join("\n" + (new Array(maxLen + 6).join(" "))))
+ }).join("\n")
+}
+
+
+function wrap (arr) {
+ var out = ['']
+ , l = 0
+ , line
+
+ line = process.stdout.columns
+ if (!line)
+ line = 60
+ else
+ line = Math.min(60, Math.max(line - 16, 24))
+
+ arr.sort(function (a,b) { return a<b?-1:1 })
+ .forEach(function (c) {
+ if (out[l].length + c.length + 2 < line) {
+ out[l] += ', '+c
+ } else {
+ out[l++] += ','
+ out[l] = c
+ }
+ })
+ return out.join("\n ").substr(2)
+}
+
+function getSections (cb) {
+ var g = path.resolve(__dirname, "../man/man[0-9]/*.[0-9]")
+ glob(g, function (er, files) {
+ if (er)
+ return cb(er)
+ cb(null, Object.keys(files.reduce(function (acc, file) {
+ file = path.basename(file).replace(/\.[0-9]+$/, "")
+ file = file.replace(/^npm-/, "")
+ acc[file] = true
+ return acc
+ }, { help: true })))
+ })
+}
diff --git a/lib/init.js b/lib/init.js
new file mode 100644
index 0000000..8ae991f
--- /dev/null
+++ b/lib/init.js
@@ -0,0 +1,41 @@
+
+// initialize a package.json file
+
+module.exports = init
+
+var log = require("npmlog")
+ , npm = require("./npm.js")
+ , initJson = require("init-package-json")
+
+init.usage = "npm init"
+
+function init (args, cb) {
+ var dir = process.cwd()
+ log.pause()
+ npm.spinner.stop()
+ var initFile = npm.config.get('init-module')
+
+ console.log(
+ ["This utility will walk you through creating a package.json file."
+ ,"It only covers the most common items, and tries to guess sane defaults."
+ ,""
+ ,"See `npm help json` for definitive documentation on these fields"
+ ,"and exactly what they do."
+ ,""
+ ,"Use `npm install <pkg> --save` afterwards to install a package and"
+ ,"save it as a dependency in the package.json file."
+ ,""
+ ,"Press ^C at any time to quit."
+ ].join("\n"))
+
+ initJson(dir, initFile, npm.config, function (er, data) {
+ log.resume()
+ log.silly('package data', data)
+ log.info('init', 'written successfully')
+ if (er && er.message === 'canceled') {
+ log.warn('init', 'canceled')
+ return cb(null, data)
+ }
+ cb(er, data)
+ })
+}
diff --git a/lib/install.js b/lib/install.js
new file mode 100644
index 0000000..8f20bc8
--- /dev/null
+++ b/lib/install.js
@@ -0,0 +1,981 @@
+// npm install <pkg> <pkg> <pkg>
+//
+// See doc/install.md for more description
+
+// Managing contexts...
+// there's a lot of state associated with an "install" operation, including
+// packages that are already installed, parent packages, current shrinkwrap, and
+// so on. We maintain this state in a "context" object that gets passed around.
+// every time we dive into a deeper node_modules folder, the "family" list that
+// gets passed along uses the previous "family" list as its __proto__. Any
+// "resolved precise dependency" things that aren't already on this object get
+// added, and then that's passed to the next generation of installation.
+
+module.exports = install
+
+install.usage = "npm install"
+ + "\nnpm install <pkg>"
+ + "\nnpm install <pkg>@<tag>"
+ + "\nnpm install <pkg>@<version>"
+ + "\nnpm install <pkg>@<version range>"
+ + "\nnpm install <folder>"
+ + "\nnpm install <tarball file>"
+ + "\nnpm install <tarball url>"
+ + "\nnpm install <git:// url>"
+ + "\nnpm install <github username>/<github project>"
+ + "\n\nCan specify one or more: npm install ./foo.tgz bar@stable /some/folder"
+ + "\nIf no argument is supplied and ./npm-shrinkwrap.json is "
+ + "\npresent, installs dependencies specified in the shrinkwrap."
+ + "\nOtherwise, installs dependencies from ./package.json."
+
+install.completion = function (opts, cb) {
+ // install can complete to a folder with a package.json, or any package.
+ // if it has a slash, then it's gotta be a folder
+ // if it starts with https?://, then just give up, because it's a url
+ // for now, not yet implemented.
+ var registry = npm.registry
+ , uri = url.resolve(npm.config.get("registry"), "-/short")
+ registry.get(uri, null, function (er, pkgs) {
+ if (er) return cb()
+ if (!opts.partialWord) return cb(null, pkgs)
+
+ var name = opts.partialWord.split("@").shift()
+ pkgs = pkgs.filter(function (p) {
+ return p.indexOf(name) === 0
+ })
+
+ if (pkgs.length !== 1 && opts.partialWord === name) {
+ return cb(null, pkgs)
+ }
+
+ uri = url.resolve(npm.config.get("registry"), pkgs[0])
+ registry.get(uri, null, function (er, d) {
+ if (er) return cb()
+ return cb(null, Object.keys(d["dist-tags"] || {})
+ .concat(Object.keys(d.versions || {}))
+ .map(function (t) {
+ return pkgs[0] + "@" + t
+ }))
+ })
+ })
+}
+
+var npm = require("./npm.js")
+ , semver = require("semver")
+ , readJson = require("read-package-json")
+ , readInstalled = require("read-installed")
+ , log = require("npmlog")
+ , path = require("path")
+ , fs = require("graceful-fs")
+ , cache = require("./cache.js")
+ , asyncMap = require("slide").asyncMap
+ , chain = require("slide").chain
+ , url = require("url")
+ , mkdir = require("mkdirp")
+ , lifecycle = require("./utils/lifecycle.js")
+ , archy = require("archy")
+ , isGitUrl = require("./utils/is-git-url.js")
+ , npmInstallChecks = require("npm-install-checks")
+ , sortedObject = require("sorted-object")
+
+function install (args, cb_) {
+ var hasArguments = !!args.length
+
+ function cb (er, installed) {
+ if (er) return cb_(er)
+
+ findPeerInvalid(where, function (er, problem) {
+ if (er) return cb_(er)
+
+ if (problem) {
+ var peerInvalidError = new Error("The package " + problem.name +
+ " does not satisfy its siblings' peerDependencies requirements!")
+ peerInvalidError.code = "EPEERINVALID"
+ peerInvalidError.packageName = problem.name
+ peerInvalidError.peersDepending = problem.peersDepending
+ return cb(peerInvalidError)
+ }
+
+ var tree = treeify(installed || [])
+ , pretty = prettify(tree, installed).trim()
+
+ if (pretty) console.log(pretty)
+ save(where, installed, tree, pretty, hasArguments, cb_)
+ })
+ }
+
+ // the /path/to/node_modules/..
+ var where = path.resolve(npm.dir, "..")
+
+ // internal api: install(where, what, cb)
+ if (arguments.length === 3) {
+ where = args
+ args = [].concat(cb_) // pass in [] to do default dep-install
+ cb_ = arguments[2]
+ log.verbose("install", "where,what", [where, args])
+ }
+
+ if (!npm.config.get("global")) {
+ args = args.filter(function (a) {
+ return path.resolve(a) !== where
+ })
+ }
+
+ mkdir(where, function (er) {
+ if (er) return cb(er)
+ // install dependencies locally by default,
+ // or install current folder globally
+ if (!args.length) {
+ var opt = { dev: npm.config.get("dev") || !npm.config.get("production") }
+
+ if (npm.config.get("global")) args = ["."]
+ else return readDependencies(null, where, opt, function (er, data) {
+ if (er) {
+ log.error("install", "Couldn't read dependencies")
+ return cb(er)
+ }
+ var deps = Object.keys(data.dependencies || {})
+ log.verbose("install", "where, deps", [where, deps])
+ var context = { family: {}
+ , ancestors: {}
+ , explicit: false
+ , parent: data
+ , root: true
+ , wrap: null }
+
+ if (data.name === path.basename(where) &&
+ path.basename(path.dirname(where)) === "node_modules") {
+ // Only include in ancestry if it can actually be required.
+ // Otherwise, it does not count.
+ context.family[data.name] =
+ context.ancestors[data.name] = data.version
+ }
+
+ installManyTop(deps.map(function (dep) {
+ var target = data.dependencies[dep]
+ target = dep + "@" + target
+ return target
+ }), where, context, function(er, results) {
+ if (er) return cb(er, results)
+ lifecycle(data, "prepublish", where, function(er) {
+ return cb(er, results)
+ })
+ })
+ })
+ }
+
+ // initial "family" is the name:version of the root, if it's got
+ // a package.json file.
+ var jsonFile = path.resolve(where, "package.json")
+ readJson(jsonFile, log.warn, function (er, data) {
+ if (er
+ && er.code !== "ENOENT"
+ && er.code !== "ENOTDIR") return cb(er)
+ if (er) data = null
+ var context = { family: {}
+ , ancestors: {}
+ , explicit: true
+ , parent: data
+ , root: true
+ , wrap: null }
+ if (data && data.name === path.basename(where) &&
+ path.basename(path.dirname(where)) === "node_modules") {
+ context.family[data.name] = context.ancestors[data.name] = data.version
+ }
+ var fn = npm.config.get("global") ? installMany : installManyTop
+ fn(args, where, context, cb)
+ })
+ })
+}
+
+function findPeerInvalid (where, cb) {
+ readInstalled(where, { log: log.warn, dev: true }, function (er, data) {
+ if (er) return cb(er)
+
+ cb(null, findPeerInvalid_(data.dependencies, []))
+ })
+}
+
+function findPeerInvalid_ (packageMap, fpiList) {
+ if (fpiList.indexOf(packageMap) !== -1)
+ return
+
+ fpiList.push(packageMap)
+
+ for (var packageName in packageMap) {
+ var pkg = packageMap[packageName]
+
+ if (pkg.peerInvalid) {
+ var peersDepending = {};
+ for (var peerName in packageMap) {
+ var peer = packageMap[peerName]
+ if (peer.peerDependencies && peer.peerDependencies[packageName]) {
+ peersDepending[peer.name + "@" + peer.version] =
+ peer.peerDependencies[packageName]
+ }
+ }
+ return { name: pkg.name, peersDepending: peersDepending }
+ }
+
+ if (pkg.dependencies) {
+ var invalid = findPeerInvalid_(pkg.dependencies, fpiList)
+ if (invalid)
+ return invalid
+ }
+ }
+
+ return null
+}
+
+// reads dependencies for the package at "where". There are several cases,
+// depending on our current state and the package's configuration:
+//
+// 1. If "context" is specified, then we examine the context to see if there's a
+// shrinkwrap there. In that case, dependencies are read from the shrinkwrap.
+// 2. Otherwise, if an npm-shrinkwrap.json file is present, dependencies are
+// read from there.
+// 3. Otherwise, dependencies come from package.json.
+//
+// Regardless of which case we fall into, "cb" is invoked with a first argument
+// describing the full package (as though readJson had been used) but with
+// "dependencies" read as described above. The second argument to "cb" is the
+// shrinkwrap to use in processing this package's dependencies, which may be
+// "wrap" (in case 1) or a new shrinkwrap (in case 2).
+function readDependencies (context, where, opts, cb) {
+ var wrap = context ? context.wrap : null
+
+ readJson( path.resolve(where, "package.json")
+ , log.warn
+ , function (er, data) {
+ if (er && er.code === "ENOENT") er.code = "ENOPACKAGEJSON"
+ if (er) return cb(er)
+
+ if (opts && opts.dev) {
+ if (!data.dependencies) data.dependencies = {}
+ Object.keys(data.devDependencies || {}).forEach(function (k) {
+ data.dependencies[k] = data.devDependencies[k]
+ })
+ }
+
+ if (!npm.config.get("optional") && data.optionalDependencies) {
+ Object.keys(data.optionalDependencies).forEach(function (d) {
+ delete data.dependencies[d]
+ })
+ }
+
+ // User has opted out of shrinkwraps entirely
+ if (npm.config.get("shrinkwrap") === false)
+ return cb(null, data, null)
+
+ if (wrap) {
+ log.verbose("readDependencies: using existing wrap", [where, wrap])
+ var rv = {}
+ Object.keys(data).forEach(function (key) {
+ rv[key] = data[key]
+ })
+ rv.dependencies = {}
+ Object.keys(wrap).forEach(function (key) {
+ log.verbose("from wrap", [key, wrap[key]])
+ rv.dependencies[key] = readWrap(wrap[key])
+ })
+ log.verbose("readDependencies returned deps", rv.dependencies)
+ return cb(null, rv, wrap)
+ }
+
+ var wrapfile = path.resolve(where, "npm-shrinkwrap.json")
+
+ fs.readFile(wrapfile, "utf8", function (er, wrapjson) {
+ if (er) {
+ log.verbose("readDependencies", "using package.json deps")
+ return cb(null, data, null)
+ }
+
+ var newwrap
+ try {
+ newwrap = JSON.parse(wrapjson)
+ } catch (ex) {
+ return cb(ex)
+ }
+
+ log.info("shrinkwrap", "file %j", wrapfile)
+ var rv = {}
+ Object.keys(data).forEach(function (key) {
+ rv[key] = data[key]
+ })
+ rv.dependencies = {}
+ Object.keys(newwrap.dependencies || {}).forEach(function (key) {
+ rv.dependencies[key] = readWrap(newwrap.dependencies[key])
+ })
+
+ // fold in devDependencies if not already present, at top level
+ if (opts && opts.dev) {
+ Object.keys(data.devDependencies || {}).forEach(function (k) {
+ rv.dependencies[k] = rv.dependencies[k] || data.devDependencies[k]
+ })
+ }
+
+ log.verbose("readDependencies returned deps", rv.dependencies)
+ return cb(null, rv, newwrap.dependencies)
+ })
+ })
+}
+
+function readWrap (w) {
+ return (w.resolved) ? w.resolved
+ : (w.from && url.parse(w.from).protocol) ? w.from
+ : w.version
+}
+
+// if the -S|--save option is specified, then write installed packages
+// as dependencies to a package.json file.
+// This is experimental.
+function save (where, installed, tree, pretty, hasArguments, cb) {
+ if (!hasArguments ||
+ !npm.config.get("save") &&
+ !npm.config.get("save-dev") &&
+ !npm.config.get("save-optional") ||
+ npm.config.get("global")) {
+ return cb(null, installed, tree, pretty)
+ }
+
+ var saveBundle = npm.config.get('save-bundle')
+ var savePrefix = npm.config.get('save-prefix') || "^";
+
+ // each item in the tree is a top-level thing that should be saved
+ // to the package.json file.
+ // The relevant tree shape is { <folder>: {what:<pkg>} }
+ var saveTarget = path.resolve(where, "package.json")
+ , things = Object.keys(tree).map(function (k) {
+ // if "what" was a url, then save that instead.
+ var t = tree[k]
+ , u = url.parse(t.from)
+ , w = t.what.split("@")
+ if (u && u.protocol) w[1] = t.from
+ return w
+ }).reduce(function (set, k) {
+ var rangeDescriptor = semver.valid(k[1], true) &&
+ semver.gte(k[1], "0.1.0", true) &&
+ !npm.config.get("save-exact")
+ ? savePrefix : ""
+ set[k[0]] = rangeDescriptor + k[1]
+ return set
+ }, {})
+
+ // don't use readJson, because we don't want to do all the other
+ // tricky npm-specific stuff that's in there.
+ fs.readFile(saveTarget, function (er, data) {
+ // ignore errors here, just don't save it.
+ try {
+ data = JSON.parse(data.toString("utf8"))
+ } catch (ex) {
+ er = ex
+ }
+
+ if (er) {
+ return cb(null, installed, tree, pretty)
+ }
+
+ var deps = npm.config.get("save-optional") ? "optionalDependencies"
+ : npm.config.get("save-dev") ? "devDependencies"
+ : "dependencies"
+
+ if (saveBundle) {
+ var bundle = data.bundleDependencies || data.bundledDependencies
+ delete data.bundledDependencies
+ if (!Array.isArray(bundle)) bundle = []
+ data.bundleDependencies = bundle.sort()
+ }
+
+ log.verbose('saving', things)
+ data[deps] = data[deps] || {}
+ Object.keys(things).forEach(function (t) {
+ data[deps][t] = things[t]
+ if (saveBundle) {
+ var i = bundle.indexOf(t)
+ if (i === -1) bundle.push(t)
+ data.bundleDependencies = bundle.sort()
+ }
+ })
+
+ data[deps] = sortedObject(data[deps])
+
+ data = JSON.stringify(data, null, 2) + "\n"
+ fs.writeFile(saveTarget, data, function (er) {
+ cb(er, installed, tree, pretty)
+ })
+ })
+}
+
+
+// Outputting *all* the installed modules is a bit confusing,
+// because the length of the path does not make it clear
+// that the submodules are not immediately require()able.
+// TODO: Show the complete tree, ls-style, but only if --long is provided
+function prettify (tree, installed) {
+ if (npm.config.get("json")) {
+ function red (set, kv) {
+ set[kv[0]] = kv[1]
+ return set
+ }
+
+ tree = Object.keys(tree).map(function (p) {
+ if (!tree[p]) return null
+ var what = tree[p].what.split("@")
+ , name = what.shift()
+ , version = what.join("@")
+ , o = { name: name, version: version, from: tree[p].from }
+ o.dependencies = tree[p].children.map(function P (dep) {
+ var what = dep.what.split("@")
+ , name = what.shift()
+ , version = what.join("@")
+ , o = { version: version, from: dep.from }
+ o.dependencies = dep.children.map(P).reduce(red, {})
+ return [name, o]
+ }).reduce(red, {})
+ return o
+ })
+
+ return JSON.stringify(tree, null, 2)
+ }
+ if (npm.config.get("parseable")) return parseable(installed)
+
+ return Object.keys(tree).map(function (p) {
+ return archy({ label: tree[p].what + " " + p
+ , nodes: (tree[p].children || []).map(function P (c) {
+ if (npm.config.get("long")) {
+ return { label: c.what, nodes: c.children.map(P) }
+ }
+ var g = c.children.map(function (g) {
+ return g.what
+ }).join(", ")
+ if (g) g = " (" + g + ")"
+ return c.what + g
+ })
+ }, "", { unicode: npm.config.get("unicode") })
+ }).join("\n")
+}
+
+function parseable (installed) {
+ var long = npm.config.get("long")
+ , cwd = process.cwd()
+ return installed.map(function (item) {
+ return path.resolve(cwd, item[1]) +
+ ( long ? ":" + item[0] : "" )
+ }).join("\n")
+}
+
+function treeify (installed) {
+ // each item is [what, where, parent, parentDir]
+ // If no parent, then report it.
+ // otherwise, tack it into the parent's children list.
+ // If the parent isn't a top-level then ignore it.
+ var whatWhere = installed.reduce(function (l, r) {
+ var parentDir = r[3]
+ , parent = r[2]
+ , where = r[1]
+ , what = r[0]
+ , from = r[4]
+ l[where] = { parentDir: parentDir
+ , parent: parent
+ , children: []
+ , where: where
+ , what: what
+ , from: from }
+ return l
+ }, {})
+
+ // log.warn("install", whatWhere, "whatWhere")
+ return Object.keys(whatWhere).reduce(function (l, r) {
+ var ww = whatWhere[r]
+ //log.warn("r, ww", [r, ww])
+ if (!ww.parent) {
+ l[r] = ww
+ } else {
+ var p = whatWhere[ww.parentDir]
+ if (p) p.children.push(ww)
+ else l[r] = ww
+ }
+ return l
+ }, {})
+}
+
+
+// just like installMany, but also add the existing packages in
+// where/node_modules to the family object.
+function installManyTop (what, where, context, cb_) {
+ function cb (er, d) {
+ if (context.explicit || er) return cb_(er, d)
+ // since this wasn't an explicit install, let's build the top
+ // folder, so that `npm install` also runs the lifecycle scripts.
+ npm.commands.build([where], false, true, function (er) {
+ return cb_(er, d)
+ })
+ }
+
+ if (context.explicit) return next()
+
+ readJson(path.join(where, "package.json"), log.warn, function (er, data) {
+ if (er) return next(er)
+ lifecycle(data, "preinstall", where, next)
+ })
+
+ function next (er) {
+ if (er) return cb(er)
+ installManyTop_(what, where, context, cb)
+ }
+}
+
+function installManyTop_ (what, where, context, cb) {
+ var nm = path.resolve(where, "node_modules")
+
+ fs.readdir(nm, function (er, pkgs) {
+ if (er) return installMany(what, where, context, cb)
+ pkgs = pkgs.filter(function (p) {
+ return !p.match(/^[\._-]/)
+ })
+ asyncMap(pkgs.map(function (p) {
+ return path.resolve(nm, p, "package.json")
+ }), function (jsonfile, cb) {
+ readJson(jsonfile, log.warn, function (er, data) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
+ if (er) return cb(null, [])
+ return cb(null, [[data.name, data.version]])
+ })
+ }, function (er, packages) {
+ // if there's nothing in node_modules, then don't freak out.
+ if (er) packages = []
+ // add all the existing packages to the family list.
+ // however, do not add to the ancestors list.
+ packages.forEach(function (p) {
+ context.family[p[0]] = p[1]
+ })
+ return installMany(what, where, context, cb)
+ })
+ })
+}
+
+function installMany (what, where, context, cb) {
+ // readDependencies takes care of figuring out whether the list of
+ // dependencies we'll iterate below comes from an existing shrinkwrap from a
+ // parent level, a new shrinkwrap at this level, or package.json at this
+ // level, as well as which shrinkwrap (if any) our dependencies should use.
+ var opt = { dev: npm.config.get("dev") }
+ readDependencies(context, where, opt, function (er, data, wrap) {
+ if (er) data = {}
+
+ var parent = data
+
+ var d = data.dependencies || {}
+
+ // if we're explicitly installing "what" into "where", then the shrinkwrap
+ // for "where" doesn't apply. This would be the case if someone were adding
+ // a new package to a shrinkwrapped package. (data.dependencies will not be
+ // used here except to indicate what packages are already present, so
+ // there's no harm in using that.)
+ if (context.explicit) wrap = null
+
+ // what is a list of things.
+ // resolve each one.
+ asyncMap( what
+ , targetResolver(where, context, d)
+ , function (er, targets) {
+
+ if (er) return cb(er)
+
+ // each target will be a data object corresponding
+ // to a package, folder, or whatever that is in the cache now.
+ var newPrev = Object.create(context.family)
+ , newAnc = Object.create(context.ancestors)
+
+ if (!context.root) {
+ newAnc[data.name] = data.version
+ }
+ targets.forEach(function (t) {
+ newPrev[t.name] = t.version
+ })
+ log.silly("resolved", targets)
+ targets.filter(function (t) { return t }).forEach(function (t) {
+ log.info("install", "%s into %s", t._id, where)
+ })
+ asyncMap(targets, function (target, cb) {
+ log.info("installOne", target._id)
+ var wrapData = wrap ? wrap[target.name] : null
+ var newWrap = wrapData && wrapData.dependencies
+ ? wrap[target.name].dependencies || {}
+ : null
+ var newContext = { family: newPrev
+ , ancestors: newAnc
+ , parent: parent
+ , explicit: false
+ , wrap: newWrap }
+ installOne(target, where, newContext, cb)
+ }, cb)
+ })
+ })
+}
+
+function targetResolver (where, context, deps) {
+ var alreadyInstalledManually = context.explicit ? [] : null
+ , nm = path.resolve(where, "node_modules")
+ , parent = context.parent
+ , wrap = context.wrap
+
+ if (!context.explicit) fs.readdir(nm, function (er, inst) {
+ if (er) return alreadyInstalledManually = []
+
+ // don't even mess with non-package looking things
+ inst = inst.filter(function (p) {
+ return !p.match(/^[\._-]/)
+ })
+
+ asyncMap(inst, function (pkg, cb) {
+ readJson(path.resolve(nm, pkg, "package.json"), log.warn, function (er, d) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
+ // error means it's not a package, most likely.
+ if (er) return cb(null, [])
+
+ // if it's a bundled dep, then assume that anything there is valid.
+ // otherwise, make sure that it's a semver match with what we want.
+ var bd = parent.bundleDependencies
+ if (bd && bd.indexOf(d.name) !== -1 ||
+ semver.satisfies(d.version, deps[d.name] || "*", true) ||
+ deps[d.name] === d._resolved) {
+ return cb(null, d.name)
+ }
+
+ // see if the package had been previously linked
+ fs.lstat(path.resolve(nm, pkg), function(err, s) {
+ if (err) return cb(null, [])
+ if (s.isSymbolicLink()) {
+ return cb(null, d.name)
+ }
+
+ // something is there, but it's not satisfactory. Clobber it.
+ return cb(null, [])
+ })
+ })
+ }, function (er, inst) {
+ // this is the list of things that are valid and should be ignored.
+ alreadyInstalledManually = inst
+ })
+ })
+
+ var to = 0
+ return function resolver (what, cb) {
+ if (!alreadyInstalledManually) return setTimeout(function () {
+ resolver(what, cb)
+ }, to++)
+
+ // now we know what's been installed here manually,
+ // or tampered with in some way that npm doesn't want to overwrite.
+ if (alreadyInstalledManually.indexOf(what.split("@").shift()) !== -1) {
+ log.verbose("already installed", "skipping %s %s", what, where)
+ return cb(null, [])
+ }
+
+ // check for a version installed higher in the tree.
+ // If installing from a shrinkwrap, it must match exactly.
+ if (context.family[what]) {
+ if (wrap && wrap[what].version === context.family[what]) {
+ log.verbose("shrinkwrap", "use existing", what)
+ return cb(null, [])
+ }
+ }
+
+ // if it's identical to its parent, then it's probably someone
+ // doing `npm install foo` inside of the foo project. Print
+ // a warning, and skip it.
+ if (parent && parent.name === what && !npm.config.get("force")) {
+ log.warn("install", "Refusing to install %s as a dependency of itself"
+ , what)
+ return cb(null, [])
+ }
+
+ if (wrap) {
+ var name = what.split(/@/).shift()
+ if (wrap[name]) {
+ var wrapTarget = readWrap(wrap[name])
+ what = name + "@" + wrapTarget
+ } else {
+ log.verbose("shrinkwrap", "skipping %s (not in shrinkwrap)", what)
+ }
+ } else if (deps[what]) {
+ what = what + "@" + deps[what]
+ }
+
+ // This is where we actually fetch the package, if it's not already
+ // in the cache.
+ // If it's a git repo, then we want to install it, even if the parent
+ // already has a matching copy.
+ // If it's not a git repo, and the parent already has that pkg, then
+ // we can skip installing it again.
+ cache.add(what, null, false, function (er, data) {
+ if (er && parent && parent.optionalDependencies &&
+ parent.optionalDependencies.hasOwnProperty(what.split("@")[0])) {
+ log.warn("optional dep failed, continuing", what)
+ log.verbose("optional dep failed, continuing", [what, er])
+ return cb(null, [])
+ }
+
+ var isGit = false
+ , maybeGit = what.split("@").slice(1).join()
+
+ if (maybeGit)
+ isGit = isGitUrl(url.parse(maybeGit))
+
+ if (!er &&
+ data &&
+ !context.explicit &&
+ context.family[data.name] === data.version &&
+ !npm.config.get("force") &&
+ !isGit) {
+ log.info("already installed", data.name + "@" + data.version)
+ return cb(null, [])
+ }
+
+ if (data && !data._from) data._from = what
+ if (er && parent && parent.name) er.parent = parent.name
+ return cb(er, data || [])
+ })
+ }
+}
+
+// we've already decided to install this. if anything's in the way,
+// then uninstall it first.
+function installOne (target, where, context, cb) {
+ // the --link flag makes this a "link" command if it's at the
+ // the top level.
+ if (where === npm.prefix && npm.config.get("link")
+ && !npm.config.get("global")) {
+ return localLink(target, where, context, cb)
+ }
+ installOne_(target, where, context, function (er, installedWhat) {
+
+ // check if this one is optional to its parent.
+ if (er && context.parent && context.parent.optionalDependencies &&
+ context.parent.optionalDependencies.hasOwnProperty(target.name)) {
+ log.warn("optional dep failed, continuing", target._id)
+ log.verbose("optional dep failed, continuing", [target._id, er])
+ er = null
+ }
+
+ cb(er, installedWhat)
+ })
+
+}
+
+function localLink (target, where, context, cb) {
+ log.verbose("localLink", target._id)
+ var jsonFile = path.resolve( npm.globalDir, target.name
+ , "package.json" )
+ , parent = context.parent
+
+ readJson(jsonFile, log.warn, function (er, data) {
+ if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
+ if (er || data._id === target._id) {
+ if (er) {
+ install( path.resolve(npm.globalDir, "..")
+ , target._id
+ , function (er) {
+ if (er) return cb(er, [])
+ thenLink()
+ })
+ } else thenLink()
+
+ function thenLink () {
+ npm.commands.link([target.name], function (er, d) {
+ log.silly("localLink", "back from link", [er, d])
+ cb(er, [resultList(target, where, parent && parent._id)])
+ })
+ }
+
+ } else {
+ log.verbose("localLink", "install locally (no link)", target._id)
+ installOne_(target, where, context, cb)
+ }
+ })
+}
+
+function resultList (target, where, parentId) {
+ var nm = path.resolve(where, "node_modules")
+ , targetFolder = path.resolve(nm, target.name)
+ , prettyWhere = where
+
+ if (!npm.config.get("global")) {
+ prettyWhere = path.relative(process.cwd(), where)
+ }
+
+ if (prettyWhere === ".") prettyWhere = null
+
+ if (!npm.config.get("global")) {
+ // print out the folder relative to where we are right now.
+ targetFolder = path.relative(process.cwd(), targetFolder)
+ }
+
+ return [ target._id
+ , targetFolder
+ , prettyWhere && parentId
+ , parentId && prettyWhere
+ , target._from ]
+}
+
+// name => install locations
+var installOnesInProgress = Object.create(null)
+
+function isIncompatibleInstallOneInProgress(target, where) {
+ return target.name in installOnesInProgress &&
+ installOnesInProgress[target.name].indexOf(where) !== -1
+}
+
+function installOne_ (target, where, context, cb) {
+ var nm = path.resolve(where, "node_modules")
+ , targetFolder = path.resolve(nm, target.name)
+ , prettyWhere = path.relative(process.cwd(), where)
+ , parent = context.parent
+
+ if (prettyWhere === ".") prettyWhere = null
+
+ if (isIncompatibleInstallOneInProgress(target, where)) {
+ // just call back, with no error. the error will be detected in the
+ // final check for peer-invalid dependencies
+ return cb()
+ }
+
+ if (!(target.name in installOnesInProgress)) {
+ installOnesInProgress[target.name] = []
+ }
+ installOnesInProgress[target.name].push(where)
+ var indexOfIOIP = installOnesInProgress[target.name].length - 1
+ , force = npm.config.get("force")
+ , nodeVersion = npm.config.get("node-version")
+ , strict = npm.config.get("engine-strict")
+ , c = npmInstallChecks
+
+ chain
+ ( [ [c.checkEngine, target, npm.version, nodeVersion, force, strict]
+ , [c.checkPlatform, target, force]
+ , [c.checkCycle, target, context.ancestors]
+ , [c.checkGit, targetFolder]
+ , [write, target, targetFolder, context] ]
+ , function (er, d) {
+ installOnesInProgress[target.name].splice(indexOfIOIP, 1)
+
+ if (er) return cb(er)
+
+ d.push(resultList(target, where, parent && parent._id))
+ cb(er, d)
+ }
+ )
+}
+
+function write (target, targetFolder, context, cb_) {
+ var up = npm.config.get("unsafe-perm")
+ , user = up ? null : npm.config.get("user")
+ , group = up ? null : npm.config.get("group")
+ , family = context.family
+
+ function cb (er, data) {
+ // cache.unpack returns the data object, and all we care about
+ // is the list of installed packages from that last thing.
+ if (!er) return cb_(er, data)
+
+ if (false === npm.config.get("rollback")) return cb_(er)
+ npm.commands.unbuild([targetFolder], true, function (er2) {
+ if (er2) log.error("error rolling back", target._id, er2)
+ return cb_(er, data)
+ })
+ }
+
+ var bundled = []
+
+ chain
+ ( [ [ cache.unpack, target.name, target.version, targetFolder
+ , null, null, user, group ]
+ , [ fs, "writeFile"
+ , path.resolve(targetFolder, "package.json")
+ , JSON.stringify(target, null, 2) + "\n" ]
+ , [ lifecycle, target, "preinstall", targetFolder ]
+ , function (cb) {
+ if (!target.bundleDependencies) return cb()
+
+ var bd = path.resolve(targetFolder, "node_modules")
+ fs.readdir(bd, function (er, b) {
+ // nothing bundled, maybe
+ if (er) return cb()
+ bundled = b || []
+ cb()
+ })
+ } ]
+
+ // nest the chain so that we can throw away the results returned
+ // up until this point, since we really don't care about it.
+ , function X (er) {
+ if (er) return cb(er)
+
+ // before continuing to installing dependencies, check for a shrinkwrap.
+ var opt = { dev: npm.config.get("dev") }
+ readDependencies(context, targetFolder, opt, function (er, data, wrap) {
+ var deps = prepareForInstallMany(data, "dependencies", bundled, wrap,
+ family)
+ var depsTargetFolder = targetFolder
+ var depsContext = { family: family
+ , ancestors: context.ancestors
+ , parent: target
+ , explicit: false
+ , wrap: wrap }
+
+ var peerDeps = prepareForInstallMany(data, "peerDependencies", bundled,
+ wrap, family)
+ var pdTargetFolder = path.resolve(targetFolder, "..", "..")
+ var pdContext = context
+
+ var actions =
+ [ [ installManyAndBuild, deps, depsTargetFolder, depsContext ] ]
+
+ if (peerDeps.length > 0) {
+ actions.push(
+ [ installMany, peerDeps, pdTargetFolder, pdContext ]
+ )
+ }
+
+ chain(actions, cb)
+ })
+ })
+}
+
+function installManyAndBuild (deps, targetFolder, context, cb) {
+ installMany(deps, targetFolder, context, function (er, d) {
+ log.verbose("about to build", targetFolder)
+ if (er) return cb(er)
+ npm.commands.build( [targetFolder]
+ , npm.config.get("global")
+ , true
+ , function (er) { return cb(er, d) })
+ })
+}
+
+function prepareForInstallMany (packageData, depsKey, bundled, wrap, family) {
+ var deps = Object.keys(packageData[depsKey] || {})
+
+ // don't install bundleDependencies, unless they're missing.
+ if (packageData.bundleDependencies) {
+ deps = deps.filter(function (d) {
+ return packageData.bundleDependencies.indexOf(d) === -1 ||
+ bundled.indexOf(d) === -1
+ })
+ }
+
+ return deps.filter(function (d) {
+ // prefer to not install things that are satisfied by
+ // something in the "family" list, unless we're installing
+ // from a shrinkwrap.
+ if (wrap) return wrap
+ if (semver.validRange(family[d], true))
+ return !semver.satisfies(family[d], packageData[depsKey][d], true)
+ return true
+ }).map(function (d) {
+ var t = packageData[depsKey][d]
+ t = d + "@" + t
+ return t
+ })
+}
diff --git a/lib/link.js b/lib/link.js
new file mode 100644
index 0000000..8022fc7
--- /dev/null
+++ b/lib/link.js
@@ -0,0 +1,173 @@
+// link with no args: symlink the folder to the global location
+// link with package arg: symlink the global to the local
+
+var npm = require("./npm.js")
+ , symlink = require("./utils/link.js")
+ , fs = require("graceful-fs")
+ , log = require("npmlog")
+ , asyncMap = require("slide").asyncMap
+ , chain = require("slide").chain
+ , path = require("path")
+ , rm = require("./utils/gently-rm.js")
+ , build = require("./build.js")
+
+module.exports = link
+
+link.usage = "npm link (in package dir)"
+ + "\nnpm link <pkg> (link global into local)"
+
+link.completion = function (opts, cb) {
+ var dir = npm.globalDir
+ fs.readdir(dir, function (er, files) {
+ cb(er, files.filter(function (f) {
+ return !f.match(/^[\._-]/)
+ }))
+ })
+}
+
+function link (args, cb) {
+ if (process.platform === "win32") {
+ var semver = require("semver")
+ if (!semver.satisfies(process.version, ">=0.7.9")) {
+ var msg = "npm link not supported on windows prior to node 0.7.9"
+ , e = new Error(msg)
+ e.code = "ENOTSUP"
+ e.errno = require("constants").ENOTSUP
+ return cb(e)
+ }
+ }
+
+ if (npm.config.get("global")) {
+ return cb(new Error("link should never be --global.\n"
+ +"Please re-run this command with --local"))
+ }
+
+ if (args.length === 1 && args[0] === ".") args = []
+ if (args.length) return linkInstall(args, cb)
+ linkPkg(npm.prefix, cb)
+}
+
+function linkInstall (pkgs, cb) {
+ asyncMap(pkgs, function (pkg, cb) {
+ function n (er, data) {
+ if (er) return cb(er, data)
+ // install returns [ [folder, pkgId], ... ]
+ // but we definitely installed just one thing.
+ var d = data.filter(function (d) { return !d[3] })
+ pp = d[0][1]
+ pkg = path.basename(pp)
+ target = path.resolve(npm.dir, pkg)
+ next()
+ }
+
+ var t = path.resolve(npm.globalDir, "..")
+ , pp = path.resolve(npm.globalDir, pkg)
+ , rp = null
+ , target = path.resolve(npm.dir, pkg)
+
+ // if it's a folder or a random not-installed thing, then
+ // link or install it first
+ if (pkg.indexOf("/") !== -1 || pkg.indexOf("\\") !== -1) {
+ return fs.lstat(path.resolve(pkg), function (er, st) {
+ if (er || !st.isDirectory()) {
+ npm.commands.install(t, pkg, n)
+ } else {
+ rp = path.resolve(pkg)
+ linkPkg(rp, n)
+ }
+ })
+ }
+
+ fs.lstat(pp, function (er, st) {
+ if (er) {
+ rp = pp
+ return npm.commands.install(t, pkg, n)
+ } else if (!st.isSymbolicLink()) {
+ rp = pp
+ next()
+ } else {
+ return fs.realpath(pp, function (er, real) {
+ if (er) log.warn("invalid symbolic link", pkg)
+ else rp = real
+ next()
+ })
+ }
+ })
+
+ function next () {
+ chain
+ ( [ [npm.commands, "unbuild", [target]]
+ , [function (cb) {
+ log.verbose("link", "symlinking %s to %s", pp, target)
+ cb()
+ }]
+ , [symlink, pp, target]
+ // do run lifecycle scripts - full build here.
+ , rp && [build, [target]]
+ , [ resultPrinter, pkg, pp, target, rp ] ]
+ , cb )
+ }
+ }, cb)
+}
+
+function linkPkg (folder, cb_) {
+ var me = folder || npm.prefix
+ , readJson = require("read-package-json")
+
+ log.verbose("linkPkg", folder)
+
+ readJson(path.resolve(me, "package.json"), function (er, d) {
+ function cb (er) {
+ return cb_(er, [[d && d._id, target, null, null]])
+ }
+ if (er) return cb(er)
+ if (!d.name) {
+ er = new Error("Package must have a name field to be linked")
+ return cb(er)
+ }
+ var target = path.resolve(npm.globalDir, d.name)
+ rm(target, function (er) {
+ if (er) return cb(er)
+ symlink(me, target, function (er) {
+ if (er) return cb(er)
+ log.verbose("link", "build target", target)
+ // also install missing dependencies.
+ npm.commands.install(me, [], function (er) {
+ if (er) return cb(er)
+ // build the global stuff. Don't run *any* scripts, because
+ // install command already will have done that.
+ build([target], true, build._noLC, true, function (er) {
+ if (er) return cb(er)
+ resultPrinter(path.basename(me), me, target, cb)
+ })
+ })
+ })
+ })
+ })
+}
+
+function resultPrinter (pkg, src, dest, rp, cb) {
+ if (typeof cb !== "function") cb = rp, rp = null
+ var where = dest
+ rp = (rp || "").trim()
+ src = (src || "").trim()
+ // XXX If --json is set, then look up the data from the package.json
+ if (npm.config.get("parseable")) {
+ return parseableOutput(dest, rp || src, cb)
+ }
+ if (rp === src) rp = null
+ console.log(where + " -> " + src + (rp ? " -> " + rp: ""))
+ cb()
+}
+
+function parseableOutput (dest, rp, cb) {
+ // XXX this should match ls --parseable and install --parseable
+ // look up the data from package.json, format it the same way.
+ //
+ // link is always effectively "long", since it doesn't help much to
+ // *just* print the target folder.
+ // However, we don't actually ever read the version number, so
+ // the second field is always blank.
+ console.log(dest + "::" + rp)
+ cb()
+}
diff --git a/lib/ls.js b/lib/ls.js
new file mode 100644
index 0000000..781b644
--- /dev/null
+++ b/lib/ls.js
@@ -0,0 +1,352 @@
+
+// show the installed versions of packages
+//
+// --parseable creates output like this:
+// <fullpath>:<name@ver>:<realpath>:<flags>
+// Flags are a :-separated list of zero or more indicators
+
+module.exports = exports = ls
+
+var npm = require("./npm.js")
+ , readInstalled = require("read-installed")
+ , log = require("npmlog")
+ , path = require("path")
+ , archy = require("archy")
+ , semver = require("semver")
+ , url = require("url")
+ , isGitUrl = require("./utils/is-git-url.js")
+ , color = require("ansicolors")
+
+ls.usage = "npm ls"
+
+ls.completion = require("./utils/completion/installed-deep.js")
+
+function ls (args, silent, cb) {
+ if (typeof cb !== "function") cb = silent, silent = false
+
+ var dir = path.resolve(npm.dir, "..")
+
+ // npm ls 'foo@~1.3' bar 'baz@<2'
+ if (!args) args = []
+ else args = args.map(function (a) {
+ var nv = a.split("@")
+ , name = nv.shift()
+ , ver = semver.validRange(nv.join("@")) || ""
+
+ return [ name, ver ]
+ })
+
+ var depth = npm.config.get("depth")
+ var opt = { depth: depth, log: log.warn, dev: true }
+ readInstalled(dir, opt, function (er, data) {
+ var bfs = bfsify(data, args)
+ , lite = getLite(bfs)
+
+ if (er || silent) return cb(er, data, lite)
+
+ var long = npm.config.get("long")
+ , json = npm.config.get("json")
+ , out
+ if (json) {
+ var seen = []
+ var d = long ? bfs : lite
+ // the raw data can be circular
+ out = JSON.stringify(d, function (k, o) {
+ if (typeof o === "object") {
+ if (-1 !== seen.indexOf(o)) return "[Circular]"
+ seen.push(o)
+ }
+ return o
+ }, 2)
+ } else if (npm.config.get("parseable")) {
+ out = makeParseable(bfs, long, dir)
+ } else if (data) {
+ out = makeArchy(bfs, long, dir)
+ }
+ console.log(out)
+
+ if (args.length && !data._found) process.exitCode = 1
+
+ // if any errors were found, then complain and exit status 1
+ if (lite.problems && lite.problems.length) {
+ er = lite.problems.join("\n")
+ }
+ cb(er, data, lite)
+ })
+}
+
+function alphasort (a, b) {
+ a = a.toLowerCase()
+ b = b.toLowerCase()
+ return a > b ? 1
+ : a < b ? -1 : 0
+}
+
+function getLite (data, noname) {
+ var lite = {}
+ , maxDepth = npm.config.get("depth")
+
+ if (!noname && data.name) lite.name = data.name
+ if (data.version) lite.version = data.version
+ if (data.extraneous) {
+ lite.extraneous = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "extraneous: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
+ if (data._from)
+ lite.from = data._from
+
+ if (data._resolved)
+ lite.resolved = data._resolved
+
+ if (data.invalid) {
+ lite.invalid = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "invalid: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
+ if (data.peerInvalid) {
+ lite.peerInvalid = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "peer invalid: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
+ if (data.dependencies) {
+ var deps = Object.keys(data.dependencies)
+ if (deps.length) lite.dependencies = deps.map(function (d) {
+ var dep = data.dependencies[d]
+ if (typeof dep === "string") {
+ lite.problems = lite.problems || []
+ var p
+ if (data.depth > maxDepth) {
+ p = "max depth reached: "
+ } else {
+ p = "missing: "
+ }
+ p += d + "@" + dep
+ + ", required by "
+ + data.name + "@" + data.version
+ lite.problems.push(p)
+ return [d, { required: dep, missing: true }]
+ }
+ return [d, getLite(dep, true)]
+ }).reduce(function (deps, d) {
+ if (d[1].problems) {
+ lite.problems = lite.problems || []
+ lite.problems.push.apply(lite.problems, d[1].problems)
+ }
+ deps[d[0]] = d[1]
+ return deps
+ }, {})
+ }
+ return lite
+}
+
+function bfsify (root, args, current, queue, seen) {
+ // walk over the data, and turn it from this:
+ // +-- a
+ // | `-- b
+ // | `-- a (truncated)
+ // `--b (truncated)
+ // into this:
+ // +-- a
+ // `-- b
+ // which looks nicer
+ args = args || []
+ current = current || root
+ queue = queue || []
+ seen = seen || [root]
+ var deps = current.dependencies = current.dependencies || {}
+ Object.keys(deps).forEach(function (d) {
+ var dep = deps[d]
+ if (typeof dep !== "object") return
+ if (seen.indexOf(dep) !== -1) {
+ if (npm.config.get("parseable") || !npm.config.get("long")) {
+ delete deps[d]
+ return
+ } else {
+ dep = deps[d] = Object.create(dep)
+ dep.dependencies = {}
+ }
+ }
+ queue.push(dep)
+ seen.push(dep)
+ })
+
+ if (!queue.length) {
+ // if there were args, then only show the paths to found nodes.
+ return filterFound(root, args)
+ }
+ return bfsify(root, args, queue.shift(), queue, seen)
+}
+
+function filterFound (root, args) {
+ if (!args.length) return root
+ var deps = root.dependencies
+ if (deps) Object.keys(deps).forEach(function (d) {
+ var dep = filterFound(deps[d], args)
+
+ // see if this one itself matches
+ var found = false
+ for (var i = 0; !found && i < args.length; i ++) {
+ if (d === args[i][0]) {
+ found = semver.satisfies(dep.version, args[i][1], true)
+ }
+ }
+ // included explicitly
+ if (found) dep._found = true
+ // included because a child was included
+ if (dep._found && !root._found) root._found = 1
+ // not included
+ if (!dep._found) delete deps[d]
+ })
+ if (!root._found) root._found = false
+ return root
+}
+
+function makeArchy (data, long, dir) {
+ var out = makeArchy_(data, long, dir, 0)
+ return archy(out, "", { unicode: npm.config.get("unicode") })
+}
+
+function makeArchy_ (data, long, dir, depth, parent, d) {
+ if (typeof data === "string") {
+ if (depth -1 <= npm.config.get("depth")) {
+ // just missing
+ var unmet = "UNMET DEPENDENCY"
+ if (npm.color) {
+ unmet = color.bgBlack(color.red(unmet))
+ }
+ data = unmet + " " + d + "@" + data
+ } else {
+ data = d+"@"+ data
+ }
+ return data
+ }
+
+ var out = {}
+ // the top level is a bit special.
+ out.label = data._id || ""
+ if (data._found === true && data._id) {
+ if (npm.color) {
+ out.label = color.bgBlack(color.yellow(out.label.trim())) + " "
+ }
+ else {
+ out.label = out.label.trim() + " "
+ }
+ }
+ if (data.link) out.label += " -> " + data.link
+
+ if (data.invalid) {
+ if (data.realName !== data.name) out.label += " ("+data.realName+")"
+ var invalid = "invalid"
+ if (npm.color) invalid = color.bgBlack(color.red(invalid))
+ out.label += " " + invalid
+ }
+
+ if (data.peerInvalid) {
+ var peerInvalid = "peer invalid"
+ if (npm.color) peerInvalid = color.bgBlack(color.red(peerInvalid))
+ out.label += " " + peerInvalid
+ }
+
+ if (data.extraneous && data.path !== dir) {
+ var extraneous = "extraneous"
+ if (npm.color) extraneous = color.bgBlack(color.green(extraneous))
+ out.label += " " + extraneous
+ }
+
+ // add giturl to name@version
+ if (data._resolved) {
+ if (isGitUrl(url.parse(data._resolved)))
+ out.label += " (" + data._resolved + ")"
+ }
+
+ if (long) {
+ if (dir === data.path) out.label += "\n" + dir
+ out.label += "\n" + getExtras(data, dir)
+ } else if (dir === data.path) {
+ if (out.label) out.label += " "
+ out.label += dir
+ }
+
+ // now all the children.
+ out.nodes = Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeArchy_(data.dependencies[d], long, dir, depth + 1, data, d)
+ })
+
+ if (out.nodes.length === 0 && data.path === dir) {
+ out.nodes = ["(empty)"]
+ }
+
+ return out
+}
+
+function getExtras (data) {
+ var extras = []
+
+ if (data.description) extras.push(data.description)
+ if (data.repository) extras.push(data.repository.url)
+ if (data.homepage) extras.push(data.homepage)
+ if (data._from) {
+ var from = data._from
+ if (from.indexOf(data.name + "@") === 0) {
+ from = from.substr(data.name.length + 1)
+ }
+ var u = url.parse(from)
+ if (u.protocol) extras.push(from)
+ }
+ return extras.join("\n")
+}
+
+
+function makeParseable (data, long, dir, depth, parent, d) {
+ depth = depth || 0
+
+ return [ makeParseable_(data, long, dir, depth, parent, d) ]
+ .concat(Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeParseable(data.dependencies[d], long, dir, depth + 1, data, d)
+ }))
+ .filter(function (x) { return x })
+ .join("\n")
+}
+
+function makeParseable_ (data, long, dir, depth, parent, d) {
+ if (data.hasOwnProperty("_found") && data._found !== true) return ""
+
+ if (typeof data === "string") {
+ if (data.depth < npm.config.get("depth")) {
+ data = npm.config.get("long")
+ ? path.resolve(parent.path, "node_modules", d)
+ + ":"+d+"@"+JSON.stringify(data)+":INVALID:MISSING"
+ : ""
+ } else {
+ data = path.resolve(data.path || "", "node_modules", d || "")
+ + (npm.config.get("long")
+ ? ":" + d + "@" + JSON.stringify(data)
+ + ":" // no realpath resolved
+ + ":MAXDEPTH"
+ : "")
+ }
+
+ return data
+ }
+
+ if (!npm.config.get("long")) return data.path
+
+ return data.path
+ + ":" + (data._id || "")
+ + ":" + (data.realPath !== data.path ? data.realPath : "")
+ + (data.extraneous ? ":EXTRANEOUS" : "")
+ + (data.invalid ? ":INVALID" : "")
+ + (data.peerInvalid ? ":PEERINVALID" : "")
+}
diff --git a/lib/npm.js b/lib/npm.js
new file mode 100644
index 0000000..c7288e2
--- /dev/null
+++ b/lib/npm.js
@@ -0,0 +1,472 @@
+;(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 <args>',\n"
+ +"or type 'node npm <args>'.")
+ WScript.quit(1)
+ return
+}
+
+
+// monkey-patch support for 0.6 child processes
+require('child-process-close')
+
+var EventEmitter = require("events").EventEmitter
+ , npm = module.exports = new EventEmitter()
+ , npmconf = require("npmconf")
+ , log = require("npmlog")
+ , fs = require("graceful-fs")
+ , path = require("path")
+ , abbrev = require("abbrev")
+ , which = require("which")
+ , semver = require("semver")
+ , RegClient = require("npm-registry-client")
+ , 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 = {}
+
+try {
+ var pv = process.version.replace(/^v/, '')
+ // startup, ok to do this synchronously
+ var j = JSON.parse(fs.readFileSync(
+ path.join(__dirname, "../package.json"))+"")
+ npm.version = j.version
+ npm.nodeVersionRequired = j.engines.node
+ if (!semver.satisfies(pv, j.engines.node)) {
+ log.warn("unsupported version", [""
+ ,"npm requires node version: "+j.engines.node
+ ,"And you have: "+pv
+ ,"which is not satisfactory."
+ ,""
+ ,"Bad things will likely happen. You have been warned."
+ ,""].join("\n"))
+ }
+} 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"