npm: upgrade to 1.1.41
authorisaacs <i@izs.me>
Fri, 13 Jul 2012 18:40:38 +0000 (11:40 -0700)
committerisaacs <i@izs.me>
Fri, 13 Jul 2012 19:08:17 +0000 (12:08 -0700)
291 files changed:
deps/npm/.gitignore [new file with mode: 0644]
deps/npm/Makefile
deps/npm/doc/cli/config.md
deps/npm/doc/cli/list.md
deps/npm/doc/cli/version.md
deps/npm/html/api/bin.html
deps/npm/html/api/bugs.html
deps/npm/html/api/commands.html
deps/npm/html/api/config.html
deps/npm/html/api/deprecate.html
deps/npm/html/api/docs.html
deps/npm/html/api/edit.html
deps/npm/html/api/explore.html
deps/npm/html/api/help-search.html
deps/npm/html/api/init.html
deps/npm/html/api/install.html
deps/npm/html/api/link.html
deps/npm/html/api/load.html
deps/npm/html/api/ls.html
deps/npm/html/api/npm.html
deps/npm/html/api/outdated.html
deps/npm/html/api/owner.html
deps/npm/html/api/pack.html
deps/npm/html/api/prefix.html
deps/npm/html/api/prune.html
deps/npm/html/api/publish.html
deps/npm/html/api/rebuild.html
deps/npm/html/api/restart.html
deps/npm/html/api/root.html
deps/npm/html/api/run-script.html
deps/npm/html/api/search.html
deps/npm/html/api/shrinkwrap.html
deps/npm/html/api/start.html
deps/npm/html/api/stop.html
deps/npm/html/api/submodule.html
deps/npm/html/api/tag.html
deps/npm/html/api/test.html
deps/npm/html/api/uninstall.html
deps/npm/html/api/unpublish.html
deps/npm/html/api/update.html
deps/npm/html/api/version.html
deps/npm/html/api/view.html
deps/npm/html/api/whoami.html
deps/npm/html/doc/README.html
deps/npm/html/doc/adduser.html
deps/npm/html/doc/bin.html
deps/npm/html/doc/bugs.html
deps/npm/html/doc/build.html
deps/npm/html/doc/bundle.html
deps/npm/html/doc/cache.html
deps/npm/html/doc/changelog.html
deps/npm/html/doc/coding-style.html
deps/npm/html/doc/completion.html
deps/npm/html/doc/config.html
deps/npm/html/doc/deprecate.html
deps/npm/html/doc/developers.html
deps/npm/html/doc/disputes.html
deps/npm/html/doc/docs.html
deps/npm/html/doc/edit.html
deps/npm/html/doc/explore.html
deps/npm/html/doc/faq.html
deps/npm/html/doc/folders.html
deps/npm/html/doc/help-search.html
deps/npm/html/doc/help.html
deps/npm/html/doc/index.html
deps/npm/html/doc/init.html
deps/npm/html/doc/install.html
deps/npm/html/doc/json.html
deps/npm/html/doc/link.html
deps/npm/html/doc/list.html
deps/npm/html/doc/npm.html
deps/npm/html/doc/outdated.html
deps/npm/html/doc/owner.html
deps/npm/html/doc/pack.html
deps/npm/html/doc/prefix.html
deps/npm/html/doc/prune.html
deps/npm/html/doc/publish.html
deps/npm/html/doc/rebuild.html
deps/npm/html/doc/registry.html
deps/npm/html/doc/removing-npm.html
deps/npm/html/doc/restart.html
deps/npm/html/doc/root.html
deps/npm/html/doc/run-script.html
deps/npm/html/doc/scripts.html
deps/npm/html/doc/search.html
deps/npm/html/doc/semver.html
deps/npm/html/doc/shrinkwrap.html
deps/npm/html/doc/star.html
deps/npm/html/doc/start.html
deps/npm/html/doc/stop.html
deps/npm/html/doc/submodule.html
deps/npm/html/doc/tag.html
deps/npm/html/doc/test.html
deps/npm/html/doc/uninstall.html
deps/npm/html/doc/unpublish.html
deps/npm/html/doc/update.html
deps/npm/html/doc/version.html
deps/npm/html/doc/view.html
deps/npm/html/doc/whoami.html
deps/npm/html/n-64.png [new file with mode: 0644]
deps/npm/html/n-large.png [new file with mode: 0644]
deps/npm/html/npm-16.png [new file with mode: 0644]
deps/npm/html/npm-256-square.png [new file with mode: 0644]
deps/npm/html/npm-256w.png [new file with mode: 0644]
deps/npm/html/npm-64-square.png [new file with mode: 0644]
deps/npm/html/npm-fin.png [new file with mode: 0644]
deps/npm/html/npm-large-trans.png [new file with mode: 0644]
deps/npm/html/npm-large.png [new file with mode: 0644]
deps/npm/html/npm-logo-white-trans.png [new file with mode: 0644]
deps/npm/html/npm.png [new file with mode: 0644]
deps/npm/lib/cache.js
deps/npm/lib/install.js
deps/npm/lib/ls.js
deps/npm/lib/npm.js
deps/npm/lib/test.js
deps/npm/lib/utils/config-defs.js
deps/npm/lib/utils/error-handler.js
deps/npm/lib/utils/fetch.js
deps/npm/lib/version.js
deps/npm/man/man1/config.1
deps/npm/man/man1/list.1
deps/npm/man/man1/npm.1
deps/npm/man/man1/version.1
deps/npm/man/man3/npm.3
deps/npm/node_modules/ansi/examples/beep/index.js [new file with mode: 0755]
deps/npm/node_modules/ansi/examples/clear/index.js [new file with mode: 0755]
deps/npm/node_modules/ansi/examples/cursorPosition.js [new file with mode: 0755]
deps/npm/node_modules/ansi/examples/imgcat/index.js [new file with mode: 0755]
deps/npm/node_modules/ansi/examples/imgcat/yoshi.png [new file with mode: 0644]
deps/npm/node_modules/ansi/examples/progress/index.js [new file with mode: 0644]
deps/npm/node_modules/ansi/examples/starwars.js [new file with mode: 0755]
deps/npm/node_modules/couch-login/README.md [new file with mode: 0644]
deps/npm/node_modules/couch-login/couch-login.js [new file with mode: 0644]
deps/npm/node_modules/couch-login/package.json [new file with mode: 0644]
deps/npm/node_modules/couch-login/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/couch-login/test/registry.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/bundle.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/dir-tar.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/dir.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/example.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/ig-tar.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/example/tar.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/fstream-npm.js
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/package.json
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js [new file with mode: 0644]
deps/npm/node_modules/fstream-npm/package.json
deps/npm/node_modules/glob/examples/g.js [new file with mode: 0644]
deps/npm/node_modules/glob/examples/usr-local.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/00-setup.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/bash-comparison.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/cwd-test.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/pause-resume.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/root-nomount.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/root.js [new file with mode: 0644]
deps/npm/node_modules/glob/test/zz-cleanup.js [new file with mode: 0644]
deps/npm/node_modules/graceful-fs/graceful-fs.js
deps/npm/node_modules/graceful-fs/package.json
deps/npm/node_modules/init-package-json/example.js [new file with mode: 0644]
deps/npm/node_modules/init-package-json/test/basic.input [new file with mode: 0644]
deps/npm/node_modules/init-package-json/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/lockfile/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/lockfile/test/fixtures/bad-child.js [new file with mode: 0644]
deps/npm/node_modules/lockfile/test/fixtures/child.js [new file with mode: 0644]
deps/npm/node_modules/lru-cache/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/minimatch/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/minimatch/test/brace-expand.js [new file with mode: 0644]
deps/npm/node_modules/minimatch/test/caching.js [new file with mode: 0644]
deps/npm/node_modules/minimatch/test/defaults.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/examples/pow.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/examples/pow.js.orig [new file with mode: 0644]
deps/npm/node_modules/mkdirp/examples/pow.js.rej [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/chmod.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/clobber.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/mkdirp.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/perm.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/perm_sync.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/race.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/rel.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/return.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/return_sync.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/root.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/sync.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/umask.js [new file with mode: 0644]
deps/npm/node_modules/mkdirp/test/umask_sync.js [new file with mode: 0644]
deps/npm/node_modules/node-gyp/bin/node-gyp.js
deps/npm/node_modules/node-gyp/lib/build.js
deps/npm/node_modules/node-gyp/lib/configure.js
deps/npm/node_modules/node-gyp/lib/install.js
deps/npm/node_modules/node-gyp/lib/node-gyp.js
deps/npm/node_modules/node-gyp/package.json
deps/npm/node_modules/npm-registry-client/index.js
deps/npm/node_modules/npm-registry-client/lib/get.js
deps/npm/node_modules/npm-registry-client/lib/request.js
deps/npm/node_modules/npm-registry-client/package.json
deps/npm/node_modules/npm-registry-client/test/00-setup.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/adduser-new.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/adduser-update.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/fixtures/server.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/retries.js [new file with mode: 0644]
deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js [new file with mode: 0644]
deps/npm/node_modules/npmlog/example.js [new file with mode: 0644]
deps/npm/node_modules/npmlog/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/osenv/test/unix.js [new file with mode: 0644]
deps/npm/node_modules/osenv/test/windows.js [new file with mode: 0644]
deps/npm/node_modules/read-installed/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/read-package-json/package.json
deps/npm/node_modules/read-package-json/read-json.js
deps/npm/node_modules/read-package-json/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/read/example/example.js [new file with mode: 0644]
deps/npm/node_modules/read/test/basic.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/googledoodle.png [new file with mode: 0644]
deps/npm/node_modules/request/tests/run.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/server.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/squid.conf [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.cnf [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.crl [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.crt [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.csr [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.key [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/ca.srl [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/server.cnf [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/server.crt [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/server.csr [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/server.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/ca/server.key [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/npm-ca.crt [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/test.crt [new file with mode: 0644]
deps/npm/node_modules/request/tests/ssl/test.key [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-body.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-cookie.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-cookiejar.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-defaults.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-errors.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-headers.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-httpModule.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-https-strict.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-https.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-oauth.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-params.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-pipes.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-pool.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-proxy.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-qs.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-redirect.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-s3.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-timeout.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-toJSON.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-tunnel.js [new file with mode: 0644]
deps/npm/node_modules/retry/example/dns.js [new file with mode: 0644]
deps/npm/node_modules/retry/test/common.js [new file with mode: 0644]
deps/npm/node_modules/retry/test/integration/test-retry-operation.js [new file with mode: 0644]
deps/npm/node_modules/retry/test/integration/test-timeouts.js [new file with mode: 0644]
deps/npm/node_modules/retry/test/runner.js [new file with mode: 0644]
deps/npm/node_modules/slide/nodejs-controlling-flow.pdf [new file with mode: 0644]
deps/npm/package.json
deps/npm/scripts/relocate.sh [new file with mode: 0755]
deps/npm/test/disabled/bundlerecurs/package.json [new file with mode: 0644]
deps/npm/test/disabled/change-bin-1/bin/foo [new file with mode: 0644]
deps/npm/test/disabled/change-bin-1/package.json [new file with mode: 0644]
deps/npm/test/disabled/change-bin-2/bin/bar [new file with mode: 0644]
deps/npm/test/disabled/change-bin-2/package.json [new file with mode: 0644]
deps/npm/test/disabled/failer/package.json [new file with mode: 0644]
deps/npm/test/disabled/fast/package.json [new file with mode: 0644]
deps/npm/test/disabled/package-bar/package.json [new file with mode: 0644]
deps/npm/test/disabled/package-config/package.json [new file with mode: 0644]
deps/npm/test/disabled/package-config/test.js [new file with mode: 0755]
deps/npm/test/disabled/package-foo/package.json [new file with mode: 0644]
deps/npm/test/disabled/slow/package.json [new file with mode: 0644]
deps/npm/test/disabled/startstop/package.json [new file with mode: 0644]
deps/npm/test/packages/npm-test-files/ignore3 [new file with mode: 0644]
deps/npm/test/packages/npm-test-files/ignoredir1/a [new file with mode: 0644]
deps/npm/test/packages/npm-test-files/ignoredir2/a [new file with mode: 0644]
deps/npm/test/packages/npm-test-files/sub/ignore1 [new file with mode: 0644]
deps/npm/test/packages/npm-test-files/sub/ignore3 [new file with mode: 0644]
deps/npm/test/packages/npm-test-ignore/ignore3 [new file with mode: 0644]
deps/npm/test/packages/npm-test-ignore/ignoredir1/a [new file with mode: 0644]
deps/npm/test/packages/npm-test-ignore/ignoredir2/a [new file with mode: 0644]
deps/npm/test/packages/npm-test-ignore/sub/ignore1 [new file with mode: 0644]
deps/npm/test/packages/npm-test-ignore/sub/ignore3 [new file with mode: 0644]

diff --git a/deps/npm/.gitignore b/deps/npm/.gitignore
new file mode 100644 (file)
index 0000000..842fca9
--- /dev/null
@@ -0,0 +1,17 @@
+*.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
+/html/api/
+/html/doc/
+/man/
+/doc/*/index.md
+/npmrc
+/release/
index 2663075..96e3f37 100644 (file)
@@ -101,16 +101,10 @@ man: $(cli_docs) $(api_docs)
 test:
        node cli.js test
 
-version: link
-       git add package.json &&\
-       git ci -m v$(shell npm -v)
-
 publish: link doc
-       @git tag -d v$(shell npm -v) || true
        @git push origin :v$(shell npm -v) || true
        @npm unpublish npm@$(shell npm -v) || true
        git clean -fd
-       git tag -s -m v$(shell npm -v) v$(shell npm -v) &&\
        git push origin --tags &&\
        npm publish &&\
        npm tag npm@$(shell npm -v) $(shell npm -v | awk -F. '{print $$1 "." $$2}') &&\
@@ -131,6 +125,6 @@ release:
        @bash scripts/release.sh
 
 sandwich:
-       @[ $$(whoami) = "root" ] && (echo "ok"; echo "ham" > sandwich) || echo "make it yourself"
+       @[ $$(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 zip-publish
index 537af5c..7bd46cd 100644 (file)
@@ -694,6 +694,17 @@ character to indicate reverse sort.
 
 The shell to run for the `npm explore` command.
 
+### 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.
+
 ### strict-ssl
 
 * Default: true
index 93d86cd..3dd709b 100644 (file)
@@ -3,20 +3,26 @@ npm-ls(1) -- List installed packages
 
 ## SYNOPSIS
 
-    npm list
-    npm ls
-    npm la
-    npm ll
+    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.
 
-It does not take positional arguments, though you may set config flags
-like with any other command, such as `-g` to list global packages.
+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:
 
-It will print out extraneous, missing, and invalid packages.
+    npm@@VERSION@ /path/to/npm
+    └─┬ init-package-json@0.0.4
+      └── promzard@0.1.5
+
+It will show print out extraneous, missing, and invalid packages.
 
 When run as `ll` or `la`, it shows extended information by default.
 
index 480c90d..ca9b5fb 100644 (file)
@@ -3,7 +3,7 @@ npm-version(1) -- Bump a package version
 
 ## SYNOPSIS
 
-    npm version <newversion> [--message commit-message]
+    npm version [<newversion> | major | minor | patch | build]
 
 ## DESCRIPTION
 
@@ -11,14 +11,23 @@ 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 that amount.
+second argument to semver.inc (one of "build", "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`) command line option, npm
-will use it as a commit message when creating a version commit.
+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.
 
 ## SEE ALSO
 
index 9071e79..1053a36 100644 (file)
@@ -19,7 +19,7 @@
 <p>This function should not be used programmatically.  Instead, just refer
 to the <code>npm.bin</code> member.</p>
 </div>
-<p id="footer">bin &mdash; npm@1.1.36</p>
+<p id="footer">bin &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e658db..ac67604 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <p>This command will launch a browser, so this command may not be the most
 friendly for programmatic use.</p>
 </div>
-<p id="footer">bugs &mdash; npm@1.1.36</p>
+<p id="footer">bugs &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 61cdac2..fcc5252 100644 (file)
@@ -28,7 +28,7 @@ usage, or <code>man 3 npm-&lt;command&gt;</code> for programmatic usage.</p>
 
 <ul><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer">commands &mdash; npm@1.1.36</p>
+<p id="footer">commands &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7977282..aecd3cc 100644 (file)
@@ -33,7 +33,7 @@ functions instead.</p>
 
 <ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
 </div>
-<p id="footer">config &mdash; npm@1.1.36</p>
+<p id="footer">config &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 727aa43..f6d2630 100644 (file)
@@ -30,7 +30,7 @@ install the package.</p></li></ul>
 
 <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">deprecate &mdash; npm@1.1.36</p>
+<p id="footer">deprecate &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7c22c55..9cae642 100644 (file)
@@ -25,7 +25,7 @@ optional version number.</p>
 <p>This command will launch a browser, so this command may not be the most
 friendly for programmatic use.</p>
 </div>
-<p id="footer">docs &mdash; npm@1.1.36</p>
+<p id="footer">docs &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ce5e41a..271ab22 100644 (file)
@@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p>
 <p>Since this command opens an editor in a new process, be careful about where
 and how this is used.</p>
 </div>
-<p id="footer">edit &mdash; npm@1.1.36</p>
+<p id="footer">edit &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cda6d48..c20f1a8 100644 (file)
@@ -24,7 +24,7 @@ sure to use <code>npm rebuild &lt;pkg&gt;</code> if you make any changes.</p>
 
 <p>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.</p>
 </div>
-<p id="footer">explore &mdash; npm@1.1.36</p>
+<p id="footer">explore &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fb8ff2c..69dfb97 100644 (file)
@@ -32,7 +32,7 @@ Name of the file that matched</li></ul>
 
 <p>The silent parameter is not neccessary not used, but it may in the future.</p>
 </div>
-<p id="footer">help-search &mdash; npm@1.1.36</p>
+<p id="footer">help-search &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7f19cc1..0e3402b 100644 (file)
@@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p>
 
 <p><a href="../doc/json.html">json(1)</a></p>
 </div>
-<p id="footer">init &mdash; npm@1.1.36</p>
+<p id="footer">init &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index bb3302d..1d91817 100644 (file)
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
 <p>Finally, 'callback' is a function that will be called when all packages have been
 installed or when an error has been encountered.</p>
 </div>
-<p id="footer">install &mdash; npm@1.1.36</p>
+<p id="footer">install &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1afd31e..3d74392 100644 (file)
@@ -39,7 +39,7 @@ npm.commands.link('redis', cb)  # link-install the package</code></pre>
 <p>Now, any changes to the redis package will be reflected in
 the package in the current working directory</p>
 </div>
-<p id="footer">link &mdash; npm@1.1.36</p>
+<p id="footer">link &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 71df640..619c4b9 100644 (file)
@@ -32,7 +32,7 @@ config object.</p>
 
 <p>For a list of all the available command-line configs, see <code>npm help config</code></p>
 </div>
-<p id="footer">load &mdash; npm@1.1.36</p>
+<p id="footer">load &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f067240..aec3a6a 100644 (file)
@@ -59,7 +59,7 @@ project.</p>
 This means that if a submodule a same dependency as a parent module, then the
 dependency will only be output once.</p>
 </div>
-<p id="footer">ls &mdash; npm@1.1.36</p>
+<p id="footer">ls &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a9cf167..238a621 100644 (file)
@@ -24,7 +24,7 @@ npm.load(configObject, function (er, npm) {
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.36</p>
+<p>1.1.41</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -91,7 +91,7 @@ method names.  Use the <code>npm.deref</code> method to find the real name.</p>
 
 <pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre>
 </div>
-<p id="footer">npm &mdash; npm@1.1.36</p>
+<p id="footer">npm &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4e8dae3..0533155 100644 (file)
@@ -19,7 +19,7 @@ currently outdated.</p>
 
 <p>If the 'packages' parameter is left out, npm will check all packages.</p>
 </div>
-<p id="footer">outdated &mdash; npm@1.1.36</p>
+<p id="footer">outdated &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d40b0f7..792ed77 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">owner &mdash; npm@1.1.36</p>
+<p id="footer">owner &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0fcc3b5..5fd48be 100644 (file)
@@ -25,7 +25,7 @@ overwritten the second time.</p>
 
 <p>If no arguments are supplied, then npm packs the current package folder.</p>
 </div>
-<p id="footer">pack &mdash; npm@1.1.36</p>
+<p id="footer">pack &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b7ad956..f6bd522 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">prefix &mdash; npm@1.1.36</p>
+<p id="footer">prefix &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1aad29b..b219008 100644 (file)
@@ -23,7 +23,7 @@
 <p>Extraneous packages are packages that are not listed on the parent
 package's dependencies list.</p>
 </div>
-<p id="footer">prune &mdash; npm@1.1.36</p>
+<p id="footer">prune &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a425f37..b96ce81 100644 (file)
@@ -32,7 +32,7 @@ the registry.  Overwrites when the "force" environment variable is set.</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul>
 </div>
-<p id="footer">publish &mdash; npm@1.1.36</p>
+<p id="footer">publish &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cc86371..f84a95d 100644 (file)
@@ -22,7 +22,7 @@ the new binary. If no 'packages' parameter is specify, every package will be reb
 
 <p>See <code>npm help build</code></p>
 </div>
-<p id="footer">rebuild &mdash; npm@1.1.36</p>
+<p id="footer">rebuild &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 172db36..7da404d 100644 (file)
@@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p>
 
 <ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
 </div>
-<p id="footer">restart &mdash; npm@1.1.36</p>
+<p id="footer">restart &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7437950..3c38de8 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically.</p>
 </div>
-<p id="footer">root &mdash; npm@1.1.36</p>
+<p id="footer">root &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 34cb7ca..53a65af 100644 (file)
@@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p>
 
 <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul>
 </div>
-<p id="footer">run-script &mdash; npm@1.1.36</p>
+<p id="footer">run-script &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6acf530..76d13c2 100644 (file)
@@ -32,7 +32,7 @@ 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).</p>
 </div>
-<p id="footer">search &mdash; npm@1.1.36</p>
+<p id="footer">search &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 69fd1bd..b989e41 100644 (file)
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
 <p>Finally, 'callback' is a function that will be called when the shrinkwrap has
 been saved.</p>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.1.36</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 94a43b8..8e4bae7 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">start &mdash; npm@1.1.36</p>
+<p id="footer">start &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8d5ab88..aab27f3 100644 (file)
@@ -19,7 +19,7 @@
 <p>npm can run stop on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">stop &mdash; npm@1.1.36</p>
+<p id="footer">stop &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 109abda..2a0a6db 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li>npm help json</li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.1.36</p>
+<p id="footer">submodule &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7c349c9..bfa536f 100644 (file)
@@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be
 used. For more information about how to set this config, check
 <code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p>
 </div>
-<p id="footer">tag &mdash; npm@1.1.36</p>
+<p id="footer">tag &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8cdd763..b922933 100644 (file)
@@ -22,7 +22,7 @@ true.</p>
 <p>npm can run tests on multiple packages. Just specify multiple packages
 in the <code>packages</code> parameter.</p>
 </div>
-<p id="footer">test &mdash; npm@1.1.36</p>
+<p id="footer">test &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f372bf6..03ca456 100644 (file)
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
 <p>Finally, 'callback' is a function that will be called when all packages have been
 uninstalled or when an error has been encountered.</p>
 </div>
-<p id="footer">uninstall &mdash; npm@1.1.36</p>
+<p id="footer">uninstall &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 860c1c5..e5de916 100644 (file)
@@ -26,7 +26,7 @@ is what is meant.</p>
 <p>If no version is specified, or if all versions are removed then
 the root package entry is removed from the registry entirely.</p>
 </div>
-<p id="footer">unpublish &mdash; npm@1.1.36</p>
+<p id="footer">unpublish &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f40b264..0b2d8af 100644 (file)
@@ -18,7 +18,7 @@
 
 <p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p>
 </div>
-<p id="footer">update &mdash; npm@1.1.36</p>
+<p id="footer">update &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e842bb0..cadf2cf 100644 (file)
@@ -24,7 +24,7 @@ fail if the repo is not clean.</p>
 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.</p>
 </div>
-<p id="footer">version &mdash; npm@1.1.36</p>
+<p id="footer">version &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 74e8648..a5b00c4 100644 (file)
@@ -99,7 +99,7 @@ the field name.</p>
 
 <p>corresponding to the list of fields selected.</p>
 </div>
-<p id="footer">view &mdash; npm@1.1.36</p>
+<p id="footer">view &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1a4fb26..756f200 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">whoami &mdash; npm@1.1.36</p>
+<p id="footer">whoami &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a2c01ae..555fb35 100644 (file)
@@ -261,7 +261,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.1.36</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1afb3c0..92d177b 100644 (file)
@@ -39,7 +39,7 @@ authorize on a new machine.</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul>
 </div>
-<p id="footer">adduser &mdash; npm@1.1.36</p>
+<p id="footer">adduser &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cd5a94b..c803ed5 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">bin &mdash; npm@1.1.36</p>
+<p id="footer">bin &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e3def71..0b3f390 100644 (file)
@@ -36,7 +36,7 @@ config param.</p>
 
 <ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">bugs &mdash; npm@1.1.36</p>
+<p id="footer">bugs &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9351cdb..b1ebb38 100644 (file)
@@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">build &mdash; npm@1.1.36</p>
+<p id="footer">build &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 72eade4..bef8a62 100644 (file)
@@ -20,7 +20,7 @@ install packages into the local space.</p>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">bundle &mdash; npm@1.1.36</p>
+<p id="footer">bundle &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5da9402..78f5a38 100644 (file)
@@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul>
 </div>
-<p id="footer">cache &mdash; npm@1.1.36</p>
+<p id="footer">cache &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3c2687f..6470a78 100644 (file)
@@ -65,7 +65,7 @@
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul>
 </div>
-<p id="footer">changelog &mdash; npm@1.1.36</p>
+<p id="footer">changelog &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index df86286..d033ccc 100644 (file)
@@ -180,7 +180,7 @@ set to anything."</p>
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">coding-style &mdash; npm@1.1.36</p>
+<p id="footer">coding-style &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 73501b8..bdc35b9 100644 (file)
@@ -33,7 +33,7 @@ completions based on the arguments.</p>
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">completion &mdash; npm@1.1.36</p>
+<p id="footer">completion &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 27ed281..e9ae4c2 100644 (file)
@@ -610,6 +610,16 @@ Windows</li><li>Type: path</li></ul>
 
 <p>The shell to run for the <code>npm explore</code> command.</p>
 
+<h3 id="sign-git-tag">sign-git-tag</h3>
+
+<ul><li>Default: false</li><li>Type: Boolean</li></ul>
+
+<p>If set to true, then the <code>npm version</code> command will tag the version
+using <code>-s</code> to add a signature.</p>
+
+<p>Note that git requires you to have set up GPG keys in your git configs
+for this to work properly.</p>
+
 <h3 id="strict-ssl">strict-ssl</h3>
 
 <ul><li>Default: true</li><li>Type: Boolean</li></ul>
@@ -735,7 +745,7 @@ then answer "no" to any prompt.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul>
 </div>
-<p id="footer">config &mdash; npm@1.1.36</p>
+<p id="footer">config &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e30db82..7924aa8 100644 (file)
@@ -29,7 +29,7 @@ something like this:</p>
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">deprecate &mdash; npm@1.1.36</p>
+<p id="footer">deprecate &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dbd006e..50ff828 100644 (file)
@@ -160,7 +160,7 @@ from a fresh checkout.</p>
 
 <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul>
 </div>
-<p id="footer">developers &mdash; npm@1.1.36</p>
+<p id="footer">developers &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a229f48..0e6dc4d 100644 (file)
@@ -80,7 +80,7 @@ license statement)</li><li>Illegal content.</li></ol>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
 </div>
-<p id="footer">disputes &mdash; npm@1.1.36</p>
+<p id="footer">disputes &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7e0640a..32a65ec 100644 (file)
@@ -37,7 +37,7 @@ config param.</p>
 
 <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">docs &mdash; npm@1.1.36</p>
+<p id="footer">docs &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d84553e..5fcc2d4 100644 (file)
@@ -37,7 +37,7 @@ or <code>"notepad"</code> on Windows.</li><li>Type: path</li></ul>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">edit &mdash; npm@1.1.36</p>
+<p id="footer">edit &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 89320f1..dc8d903 100644 (file)
@@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul>
 
 <ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">explore &mdash; npm@1.1.36</p>
+<p id="footer">explore &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d8a1a32..21ce261 100644 (file)
@@ -241,7 +241,7 @@ We'll have someone kick it or something.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
 </div>
-<p id="footer">faq &mdash; npm@1.1.36</p>
+<p id="footer">faq &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0b68254..c93a3e6 100644 (file)
@@ -205,7 +205,7 @@ cannot be found elsewhere.  See <code><a href="../doc/json.html">json(1)</a></co
 
 <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul>
 </div>
-<p id="footer">folders &mdash; npm@1.1.36</p>
+<p id="footer">folders &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 61f6ad9..ab8ecf8 100644 (file)
@@ -38,7 +38,7 @@ where the terms were found in the documentation.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul>
 </div>
-<p id="footer">help-search &mdash; npm@1.1.36</p>
+<p id="footer">help-search &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0802f4b..5f93bbc 100644 (file)
@@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p>
 
 <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul>
 </div>
-<p id="footer">help &mdash; npm@1.1.36</p>
+<p id="footer">help &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9720b92..b17f59a 100644 (file)
 
 <p> Display npm username</p>
 </div>
-<p id="footer">index &mdash; npm@1.1.36</p>
+<p id="footer">index &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 433f360..872bf23 100644 (file)
@@ -29,7 +29,7 @@ without a really good reason to do so.</p>
 
 <ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/version.html">version(1)</a></li></ul>
 </div>
-<p id="footer">init &mdash; npm@1.1.36</p>
+<p id="footer">init &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 294ef28..2fbd63b 100644 (file)
@@ -133,7 +133,7 @@ affects a real use-case, it will be investigated.</p>
 
 <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></li></ul>
 </div>
-<p id="footer">install &mdash; npm@1.1.36</p>
+<p id="footer">install &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 082e2ba..5c86e4c 100644 (file)
@@ -524,7 +524,7 @@ overridden.</p>
 
 <ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul>
 </div>
-<p id="footer">json &mdash; npm@1.1.36</p>
+<p id="footer">json &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 18c3f9f..c4f75e2 100644 (file)
@@ -58,7 +58,7 @@ installation target into your project's <code>node_modules</code> folder.</p>
 
 <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">link &mdash; npm@1.1.36</p>
+<p id="footer">link &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5fd5595..1045602 100644 (file)
 
 <h2 id="SYNOPSIS">SYNOPSIS</h2>
 
-<pre><code>npm list
-npm ls
-npm la
-npm ll</code></pre>
+<pre><code>npm list [&lt;pkg&gt; ...]
+npm ls [&lt;pkg&gt; ...]
+npm la [&lt;pkg&gt; ...]
+npm ll [&lt;pkg&gt; ...]</code></pre>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
 <p>This command will print to stdout all the versions of packages that are
 installed, as well as their dependencies, in a tree-structure.</p>
 
-<p>It does not take positional arguments, though you may set config flags
-like with any other command, such as <code>-g</code> to list global packages.</p>
+<p>Positional arguments are <code>name@version-range</code> identifiers, which will
+limit the results to only the paths to the packages named.  Note that
+nested packages will <em>also</em> show the paths to the specified packages.
+For example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
 
-<p>It will print out extraneous, missing, and invalid packages.</p>
+<pre><code>npm@1.1.41 /path/to/npm
+└─┬ init-package-json@0.0.4
+  └── promzard@0.1.5</code></pre>
+
+<p>It will show print out extraneous, missing, and invalid packages.</p>
 
 <p>When run as <code>ll</code> or <code>la</code>, it shows extended information by default.</p>
 
@@ -58,7 +64,7 @@ project.</p>
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul>
 </div>
-<p id="footer">list &mdash; npm@1.1.36</p>
+<p id="footer">list &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9e8120c..0904f73 100644 (file)
@@ -14,7 +14,7 @@
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.36</p>
+<p>1.1.41</p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p>
 
 <ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul>
 </div>
-<p id="footer">npm &mdash; npm@1.1.36</p>
+<p id="footer">npm &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b7f4a58..dbb9d95 100644 (file)
@@ -21,7 +21,7 @@ packages are currently outdated.</p>
 
 <ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul>
 </div>
-<p id="footer">outdated &mdash; npm@1.1.36</p>
+<p id="footer">outdated &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e9f01a5..243bcbf 100644 (file)
@@ -34,7 +34,7 @@ that is not implemented at this time.</p>
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
 </div>
-<p id="footer">owner &mdash; npm@1.1.36</p>
+<p id="footer">owner &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5990294..748f109 100644 (file)
@@ -29,7 +29,7 @@ overwritten the second time.</p>
 
 <ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">pack &mdash; npm@1.1.36</p>
+<p id="footer">pack &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index afa7fde..ab048e7 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">prefix &mdash; npm@1.1.36</p>
+<p id="footer">prefix &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ec678aa..7e1f1cd 100644 (file)
@@ -25,7 +25,7 @@ package's dependencies list.</p>
 
 <ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">prune &mdash; npm@1.1.36</p>
+<p id="footer">prune &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1b0b4e5..014fa4d 100644 (file)
@@ -29,7 +29,7 @@ the registry.  Overwrites when the "--force" flag is set.</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul>
 </div>
-<p id="footer">publish &mdash; npm@1.1.36</p>
+<p id="footer">publish &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 10b6432..9602a2c 100644 (file)
@@ -25,7 +25,7 @@ the new binary.</p>
 
 <ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">rebuild &mdash; npm@1.1.36</p>
+<p id="footer">rebuild &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e85aacf..3662e22 100644 (file)
@@ -97,7 +97,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul>
 </div>
-<p id="footer">registry &mdash; npm@1.1.36</p>
+<p id="footer">registry &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8fcd3bc..99193eb 100644 (file)
@@ -58,7 +58,7 @@ modules.  To track those down, you can do the following:</p>
 
 <ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul>
 </div>
-<p id="footer">removing-npm &mdash; npm@1.1.36</p>
+<p id="footer">removing-npm &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 33c6f89..ffab7a6 100644 (file)
@@ -24,7 +24,7 @@ the "start" script.</p>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">restart &mdash; npm@1.1.36</p>
+<p id="footer">restart &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9725e59..9d006c3 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">root &mdash; npm@1.1.36</p>
+<p id="footer">root &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6ebc209..13bb1b0 100644 (file)
@@ -23,7 +23,7 @@ called directly, as well.</p>
 
 <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">run-script &mdash; npm@1.1.36</p>
+<p id="footer">run-script &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 053a3b2..f659e7d 100644 (file)
@@ -177,7 +177,7 @@ will sudo the npm command in question.</li></ul>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
 </div>
-<p id="footer">scripts &mdash; npm@1.1.36</p>
+<p id="footer">scripts &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f9a5bd5..07c38ef 100644 (file)
@@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p>
 
 <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul>
 </div>
-<p id="footer">search &mdash; npm@1.1.36</p>
+<p id="footer">search &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b1e6443..a5054ad 100644 (file)
@@ -104,7 +104,7 @@ that satisfies the range, or null if none of them do.</li></ul>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li></ul>
 </div>
-<p id="footer">semver &mdash; npm@1.1.36</p>
+<p id="footer">semver &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 29dd869..c5a18db 100644 (file)
@@ -169,7 +169,7 @@ versions.</p>
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.1.36</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ef75bf9..cef44a3 100644 (file)
@@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p>
 
 <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
 </div>
-<p id="footer">star &mdash; npm@1.1.36</p>
+<p id="footer">star &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0a17b06..4f6c639 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">start &mdash; npm@1.1.36</p>
+<p id="footer">start &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 55203f9..153d531 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul>
 </div>
-<p id="footer">stop &mdash; npm@1.1.36</p>
+<p id="footer">stop &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c98b0a9..254e401 100644 (file)
@@ -33,7 +33,7 @@ dependencies into the submodule folder.</p>
 
 <ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
 </div>
-<p id="footer">submodule &mdash; npm@1.1.36</p>
+<p id="footer">submodule &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 81e3afa..be8b162 100644 (file)
@@ -21,7 +21,7 @@
 
 <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">tag &mdash; npm@1.1.36</p>
+<p id="footer">tag &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6921008..1f8fa63 100644 (file)
@@ -23,7 +23,7 @@ true.</p>
 
 <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul>
 </div>
-<p id="footer">test &mdash; npm@1.1.36</p>
+<p id="footer">test &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e59fe56..268482a 100644 (file)
@@ -22,7 +22,7 @@ on its behalf.</p>
 
 <ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul>
 </div>
-<p id="footer">uninstall &mdash; npm@1.1.36</p>
+<p id="footer">uninstall &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 524fe2e..bb8e574 100644 (file)
@@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p>
 
 <ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul>
 </div>
-<p id="footer">unpublish &mdash; npm@1.1.36</p>
+<p id="footer">unpublish &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3b84fde..88c27ce 100644 (file)
@@ -23,7 +23,7 @@
 
 <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
 </div>
-<p id="footer">update &mdash; npm@1.1.36</p>
+<p id="footer">update &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e9d0726..cc6f53f 100644 (file)
@@ -10,7 +10,7 @@
 
 <h2 id="SYNOPSIS">SYNOPSIS</h2>
 
-<pre><code>npm version &lt;newversion&gt; [--message commit-message]</code></pre>
+<pre><code>npm version [&lt;newversion&gt; | major | minor | patch | build]</code></pre>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
 data back to the package.json file.</p>
 
 <p>The <code>newversion</code> argument should be a valid semver string, <em>or</em> a valid
-second argument to semver.inc (one of "patch", "minor", or "major"). In 
-the second case, the existing version will be incremented by that amount.</p>
+second argument to semver.inc (one of "build", "patch", "minor", or
+"major"). In the second case, the existing version will be incremented
+by 1 in the specified field.</p>
 
 <p>If run in a git repo, it will also create a version commit and tag, and
 fail if the repo is not clean.</p>
 
-<p>If supplied with <code>--message</code> (shorthand: <code>-m</code>) command line option, npm
-will use it as a commit message when creating a version commit.</p>
+<p>If supplied with <code>--message</code> (shorthand: <code>-m</code>) config option, npm will
+use it as a commit message when creating a version commit.  If the
+<code>message</code> config contains <code>%s</code> then that will be replaced with the
+resulting version number.  For example:</p>
+
+<pre><code>npm version patch -m "Upgrade to %s for reasons"</code></pre>
+
+<p>If the <code>sign-git-tag</code> config is set, then the tag will be signed using
+the <code>-s</code> flag to git.  Note that you must have a default GPG key set up
+in your git config for this to work properly.</p>
 
 <h2 id="SEE-ALSO">SEE ALSO</h2>
 
 <ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul>
 </div>
-<p id="footer">version &mdash; npm@1.1.36</p>
+<p id="footer">version &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fe67a60..97e208b 100644 (file)
@@ -88,7 +88,7 @@ the field name.</p>
 
 <ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul>
 </div>
-<p id="footer">view &mdash; npm@1.1.36</p>
+<p id="footer">view &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3824ae5..dd15587 100644 (file)
@@ -20,7 +20,7 @@
 
 <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul>
 </div>
-<p id="footer">whoami &mdash; npm@1.1.36</p>
+<p id="footer">whoami &mdash; npm@1.1.41</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/n-64.png b/deps/npm/html/n-64.png
new file mode 100644 (file)
index 0000000..d4145ef
Binary files /dev/null and b/deps/npm/html/n-64.png differ
diff --git a/deps/npm/html/n-large.png b/deps/npm/html/n-large.png
new file mode 100644 (file)
index 0000000..9e1525f
Binary files /dev/null and b/deps/npm/html/n-large.png differ
diff --git a/deps/npm/html/npm-16.png b/deps/npm/html/npm-16.png
new file mode 100644 (file)
index 0000000..c3c9d05
Binary files /dev/null and b/deps/npm/html/npm-16.png differ
diff --git a/deps/npm/html/npm-256-square.png b/deps/npm/html/npm-256-square.png
new file mode 100644 (file)
index 0000000..f7f18b5
Binary files /dev/null and b/deps/npm/html/npm-256-square.png differ
diff --git a/deps/npm/html/npm-256w.png b/deps/npm/html/npm-256w.png
new file mode 100644 (file)
index 0000000..dac32c8
Binary files /dev/null and b/deps/npm/html/npm-256w.png differ
diff --git a/deps/npm/html/npm-64-square.png b/deps/npm/html/npm-64-square.png
new file mode 100644 (file)
index 0000000..eef2629
Binary files /dev/null and b/deps/npm/html/npm-64-square.png differ
diff --git a/deps/npm/html/npm-fin.png b/deps/npm/html/npm-fin.png
new file mode 100644 (file)
index 0000000..7efbef6
Binary files /dev/null and b/deps/npm/html/npm-fin.png differ
diff --git a/deps/npm/html/npm-large-trans.png b/deps/npm/html/npm-large-trans.png
new file mode 100644 (file)
index 0000000..7f6c738
Binary files /dev/null and b/deps/npm/html/npm-large-trans.png differ
diff --git a/deps/npm/html/npm-large.png b/deps/npm/html/npm-large.png
new file mode 100644 (file)
index 0000000..27d8317
Binary files /dev/null and b/deps/npm/html/npm-large.png differ
diff --git a/deps/npm/html/npm-logo-white-trans.png b/deps/npm/html/npm-logo-white-trans.png
new file mode 100644 (file)
index 0000000..0af8ad7
Binary files /dev/null and b/deps/npm/html/npm-logo-white-trans.png differ
diff --git a/deps/npm/html/npm.png b/deps/npm/html/npm.png
new file mode 100644 (file)
index 0000000..d78ff53
Binary files /dev/null and b/deps/npm/html/npm.png differ
index 3d77272..de7ccad 100644 (file)
@@ -506,19 +506,6 @@ function addNameRange (name, range, data, cb) {
              , {name:name, range:range, hasData:!!data})
     engineFilter(data)
 
-    if (npm.config.get("registry")) return next_()
-
-    cachedFilter(data, range, function (er) {
-      if (er) return cb(er)
-      if (Object.keys(data.versions).length === 0) {
-        return cb(new Error( "Can't fetch, and not cached: "
-                           + data.name + "@" + range))
-      }
-      next_()
-    })
-  }
-
-  function next_ () {
     log.silly("addNameRange", "versions"
              , [data.name, Object.keys(data.versions || {})])
 
@@ -540,39 +527,6 @@ function addNameRange (name, range, data, cb) {
   }
 }
 
-// filter the versions down based on what's already in cache.
-function cachedFilter (data, range, cb) {
-  log.silly("cachedFilter", data.name)
-  ls_(data.name, 1, function (er, files) {
-    if (er) {
-      log.error("cachedFilter", "Not in cache, can't fetch", data.name)
-      return cb(er)
-    }
-    files = files.map(function (f) {
-      return path.basename(f.replace(/(\\|\/)$/, ""))
-    }).filter(function (f) {
-      return semver.valid(f) && semver.satisfies(f, range)
-    })
-
-    if (files.length === 0) {
-      return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range))
-    }
-
-    log.silly("cached", [data.name, files])
-    Object.keys(data.versions).forEach(function (v) {
-      if (files.indexOf(v) === -1) delete data.versions[v]
-    })
-
-    if (Object.keys(data.versions).length === 0) {
-      log.error("cachedFilter", "Not in cache, can't fetch", data.name)
-      return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range))
-    }
-
-    log.silly("filtered", [data.name, Object.keys(data.versions)])
-    cb(null, data)
-  })
-}
-
 function installTargetsError (requested, data) {
   var targets = Object.keys(data["dist-tags"]).filter(function (f) {
     return (data.versions || {}).hasOwnProperty(f)
index 1aabb46..e64766b 100644 (file)
@@ -388,7 +388,7 @@ function treeify (installed) {
     return l
   }, {})
 
-  //log.warn("install", whatWhere, "whatWhere")
+  // log.warn("install", whatWhere, "whatWhere")
   return Object.keys(whatWhere).reduce(function (l, r) {
     var ww = whatWhere[r]
     //log.warn("r, ww", [r, ww])
@@ -668,7 +668,11 @@ function localLink (target, where, context, cb) {
 function resultList (target, where, parentId) {
   var nm = path.resolve(where, "node_modules")
     , targetFolder = path.resolve(nm, target.name)
-    , prettyWhere = path.relative(process.cwd(), where)
+    , prettyWhere = where
+
+  if (!npm.config.get("global")) {
+    prettyWhere = path.relative(process.cwd(), where)
+  }
 
   if (prettyWhere === ".") prettyWhere = null
 
index 02e7fe2..2b45ca3 100644 (file)
@@ -13,22 +13,30 @@ var npm = require("./npm.js")
   , log = require("npmlog")
   , path = require("path")
   , archy = require("archy")
+  , semver = require("semver")
 
 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
 
-  if (args.length) {
-    // TODO: it would actually be nice to maybe show the locally
-    // installed packages only matching the argument names.
-    log.warn("ls doesn't take positional args. Try the 'search' command")
-  }
-
   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 ]
+  })
+
   readInstalled(dir, npm.config.get("depth"), function (er, data) {
-    var lite = getLite(bfsify(data))
+    var bfs = bfsify(data, args)
+      , lite = getLite(bfs)
     if (er || silent) return cb(er, data, lite)
 
     var long = npm.config.get("long")
@@ -36,7 +44,7 @@ function ls (args, silent, cb) {
       , out
     if (json) {
       var seen = []
-      var d = long ? bfsify(data) : lite
+      var d = long ? bfs : lite
       // the raw data can be circular
       out = JSON.stringify(d, function (k, o) {
         if (typeof o === "object") {
@@ -46,14 +54,19 @@ function ls (args, silent, cb) {
         return o
       }, 2)
     } else if (npm.config.get("parseable")) {
-      out = makeParseable(bfsify(data), long, dir)
+      out = makeParseable(bfs, long, dir)
     } else if (data) {
-      out = makeArchy(bfsify(data), long, dir)
+      out = makeArchy(bfs, long, dir)
     }
     output.write(out, function (er) { cb(er, data, lite) })
   })
 }
 
+// only include 
+function filter (data, args) {
+
+}
+
 function alphasort (a, b) {
   a = a.toLowerCase()
   b = b.toLowerCase()
@@ -124,7 +137,7 @@ function getLite (data, noname) {
   return lite
 }
 
-function bfsify (root, current, queue, seen) {
+function bfsify (root, args, current, queue, seen) {
   // walk over the data, and turn it from this:
   // +-- a
   // |   `-- b
@@ -134,6 +147,7 @@ function bfsify (root, current, queue, seen) {
   // +-- a
   // `-- b
   // which looks nicer
+  args = args || []
   current = current || root
   queue = queue || []
   seen = seen || [root]
@@ -153,10 +167,37 @@ function bfsify (root, current, queue, seen) {
     queue.push(dep)
     seen.push(dep)
   })
-  if (!queue.length) return root
-  return bfsify(root, queue.shift(), queue, seen)
+
+  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])
+      }
+    }
+    // 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)
@@ -178,8 +219,11 @@ function makeArchy_ (data, long, dir, depth, parent, d) {
 
   var out = {}
   // the top level is a bit special.
-  out.label = data._id ? data._id + " " : ""
-  if (data.link) out.label += "-> " + data.link
+  out.label = data._id || ""
+  if (data._found === true && data._id) {
+    out.label = "\033[33;40m" + out.label.trim() + "\033[m "
+  }
+  if (data.link) out.label += " -> " + data.link
 
   if (data.invalid) {
     if (data.realName !== data.name) out.label += " ("+data.realName+")"
@@ -237,10 +281,13 @@ function makeParseable (data, long, dir, depth, parent, d) {
     .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")) {
       var p = parent.link || parent.path
index 6113604..dd85b83 100644 (file)
@@ -275,10 +275,15 @@ function load (npm, conf, cb) {
 
       // at this point the configs are all set.
       // go ahead and spin up the registry client.
+      var token
+      try { token = JSON.parse(npm.config.get("_token")) }
+      catch (er) { token = null }
+
       npm.registry = new RegClient(
         { registry: npm.config.get("registry")
         , cache: npm.config.get("cache")
         , auth: npm.config.get("_auth")
+        , token: token
         , alwaysAuth: npm.config.get("always-auth")
         , email: npm.config.get("email")
         , proxy: npm.config.get("proxy")
@@ -293,8 +298,19 @@ function load (npm, conf, cb) {
         , retryFactor: npm.config.get("fetch-retry-factor")
         , retryMinTimeout: npm.config.get("fetch-retry-mintimeout")
         , retryMaxTimeout: npm.config.get("fetch-retry-maxtimeout")
+        , cacheMin: npm.config.get("cache-min")
+        , cacheMax: npm.config.get("cache-max")
         })
 
+      // save the token cookie in the config file
+      if (npm.registry.couchLogin) {
+        npm.registry.couchLogin.tokenSet = function (tok, cb) {
+          ini.set("_token", JSON.stringify(tok), "user")
+          // ignore save error.  best effort.
+          ini.save("user", function () {})
+        }
+      }
+
       var umask = parseInt(conf.umask, 8)
       npm.modes = { exec: 0777 & (~umask)
                   , file: 0666 & (~umask)
index 9a9c642..d741807 100644 (file)
@@ -6,6 +6,9 @@ var testCmd = require("./utils/lifecycle.js").cmd("test")
 function test (args, cb) {
   testCmd(args, function (er) {
     if (!er) return cb()
-    return cb("Test failed.  See above for more details.")
+    if (er.code === "ELIFECYCLE") {
+      return cb("Test failed.  See above for more details.")
+    }
+    return cb(er)
   })
 }
index ee2c22f..4237ae6 100644 (file)
@@ -189,6 +189,7 @@ Object.defineProperty(exports, "defaults", {get: function () {
     , searchexclude: null
     , searchsort: "name"
     , shell : osenv.shell()
+    , "sign-git-tag": false
     , "strict-ssl": true
     , tag : "latest"
     , tmp : temp
@@ -280,6 +281,7 @@ exports.types =
                 , "date", "-date"
                 , "keywords", "-keywords" ]
   , shell : String
+  , "sign-git-tag": Boolean
   , "strict-ssl": Boolean
   , tag : String
   , tmp : path
index 01bf5f8..09d4853 100644 (file)
@@ -93,6 +93,7 @@ function errorHandler (er) {
   var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
   if (m && !er.code) er.code = m
 
+  var didStack = false
   switch (er.code) {
   case "ECONNREFUSED":
     log.error("", er)
@@ -208,12 +209,13 @@ function errorHandler (er) {
     } // else passthrough
 
   default:
-    log.error("", er)
-    log.error("", ["You may report this log at:"
-              ,"    <http://github.com/isaacs/npm/issues>"
-              ,"or email it to:"
-              ,"    <npm-@googlegroups.com>"
-              ].join("\n"))
+    didStack = true
+    log.error("", er.stack || er.message || er)
+    log.error("", ["If you need help, you may report this log at:"
+                  ,"    <http://github.com/isaacs/npm/issues>"
+                  ,"or email it to:"
+                  ,"    <npm-@googlegroups.com>"
+                  ].join("\n"))
     break
   }
 
@@ -238,17 +240,20 @@ function errorHandler (er) {
     , "fstream_finish_call"
     , "fstream_linkpath"
     , "code"
-    , "message"
     , "errno"
+    , "stack"
+    , "fstream_stack"
     ].forEach(function (k) {
-      if (er[k]) log.error(k, er[k])
+      var v = er[k]
+      if (k === "stack") {
+        if (didStack) return
+        if (!v) v = er.message
+      }
+      if (!v) return
+      if (k === "fstream_stack") v = v.join("\n")
+      log.error(k, v)
     })
 
-  if (er.fstream_stack) {
-    log.error("fstream_stack", er.fstream_stack.join("\n"))
-  }
-
-  if (er.errno && typeof er.errno !== "object") log.error(er.errno, "errno")
   exit(typeof er.errno === "number" ? er.errno : 1)
 }
 
index f1e004e..6042abc 100644 (file)
@@ -71,7 +71,6 @@ function makeRequest (remote, fstr, headers) {
 
   var opts = { url: remote
              , proxy: proxy
-             , follow: false
              , strictSSL: npm.config.get("strict-ssl")
              , ca: remote.host === regHost ? npm.config.get("ca") : undefined
              , headers: { "user-agent": npm.config.get("user-agent") }}
index d1a6b56..67a4b4c 100644 (file)
@@ -10,7 +10,7 @@ var exec = require("./utils/exec.js")
   , log = require("npmlog")
   , npm = require("./npm.js")
 
-version.usage = "npm version <newversion> [--message commit-message]"
+version.usage = "npm version [<newversion> | major | minor | patch | build]\n"
               + "\n(run in package dir)\n"
               + "'npm -v' or 'npm --version' to print npm version "
               + "("+npm.version+")\n"
@@ -52,19 +52,23 @@ function checkGit (data, cb) {
       , function (er, code, stdout, stderr) {
     var lines = stdout.trim().split("\n").filter(function (line) {
       return line.trim() && !line.match(/^\?\? /)
+    }).map(function (line) {
+      return line.trim()
     })
     if (lines.length) return cb(new Error(
       "Git working directory not clean.\n"+lines.join("\n")))
     write(data, function (er) {
       if (er) return cb(er)
       var message = npm.config.get("message").replace(/%s/g, data.version)
+        , sign = npm.config.get("sign-git-tag")
+        , flag = sign ? "-sm" : "-am"
       chain
         ( [ [ exec, npm.config.get("git")
             , ["add","package.json"], process.env, false ]
           , [ exec, npm.config.get("git")
             , ["commit", "-m", message ], process.env, false ]
           , [ exec, npm.config.get("git")
-            , ["tag", "v"+data.version], process.env, false ] ]
+            , ["tag", "v"+data.version, flag, message], process.env, false ] ]
         , cb )
     })
   })
index 61eee6d..a67e5ac 100644 (file)
@@ -1199,6 +1199,24 @@ Type: path
 .P
 The shell to run for the \fBnpm explore\fR command\.
 .
+.SS "sign\-git\-tag"
+.
+.IP "\(bu" 4
+Default: false
+.
+.IP "\(bu" 4
+Type: Boolean
+.
+.IP "" 0
+.
+.P
+If set to true, then the \fBnpm version\fR command will tag the version
+using \fB\-s\fR to add a signature\.
+.
+.P
+Note that git requires you to have set up GPG keys in your git configs
+for this to work properly\.
+.
 .SS "strict\-ssl"
 .
 .IP "\(bu" 4
index 6e84ff4..7d26e62 100644 (file)
@@ -9,10 +9,10 @@
 .SH "SYNOPSIS"
 .
 .nf
-npm list
-npm ls
-npm la
-npm ll
+npm list [<pkg> \.\.\.]
+npm ls [<pkg> \.\.\.]
+npm la [<pkg> \.\.\.]
+npm ll [<pkg> \.\.\.]
 .
 .fi
 .
@@ -21,11 +21,24 @@ This command will print to stdout all the versions of packages that are
 installed, as well as their dependencies, in a tree\-structure\.
 .
 .P
-It does not take positional arguments, though you may set config flags
-like with any other command, such as \fB\-g\fR to list global packages\.
+Positional arguments are \fBname@version\-range\fR identifiers, which will
+limit the results to only the paths to the packages named\.  Note that
+nested packages will \fIalso\fR show the paths to the specified packages\.
+For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
+.
+.IP "" 4
+.
+.nf
+npm@1.1.41 /path/to/npm
+└─┬ init\-package\-json@0\.0\.4
+  └── promzard@0\.1\.5
+.
+.fi
+.
+.IP "" 0
 .
 .P
-It will print out extraneous, missing, and invalid packages\.
+It will show print out extraneous, missing, and invalid packages\.
 .
 .P
 When run as \fBll\fR or \fBla\fR, it shows extended information by default\.
index a6129e0..fd3eb00 100644 (file)
@@ -14,7 +14,7 @@ npm <command> [args]
 .fi
 .
 .SH "VERSION"
-1.1.36
+1.1.41
 .
 .SH "DESCRIPTION"
 npm is the package manager for the Node JavaScript platform\.  It puts
index d5197ce..757f661 100644 (file)
@@ -9,7 +9,7 @@
 .SH "SYNOPSIS"
 .
 .nf
-npm version <newversion> [\-\-message commit\-message]
+npm version [<newversion> | major | minor | patch | build]
 .
 .fi
 .
@@ -19,16 +19,32 @@ data back to the package\.json file\.
 .
 .P
 The \fBnewversion\fR argument should be a valid semver string, \fIor\fR a valid
-second argument to semver\.inc (one of "patch", "minor", or "major")\. In 
-the second case, the existing version will be incremented by that amount\.
+second argument to semver\.inc (one of "build", "patch", "minor", or
+"major")\. In the second case, the existing version will be incremented
+by 1 in the specified field\.
 .
 .P
 If run in a git repo, it will also create a version commit and tag, and
 fail if the repo is not clean\.
 .
 .P
-If supplied with \fB\-\-message\fR (shorthand: \fB\-m\fR) command line option, npm
-will use it as a commit message when creating a version commit\.
+If supplied with \fB\-\-message\fR (shorthand: \fB\-m\fR) config option, npm will
+use it as a commit message when creating a version commit\.  If the \fBmessage\fR config contains \fB%s\fR then that will be replaced with the
+resulting version number\.  For example:
+.
+.IP "" 4
+.
+.nf
+npm version patch \-m "Upgrade to %s for reasons"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+If the \fBsign\-git\-tag\fR config is set, then the tag will be signed using
+the \fB\-s\fR flag to git\.  Note that you must have a default GPG key set up
+in your git config for this to work properly\.
 .
 .SH "SEE ALSO"
 .
index a6860c9..71ba61d 100644 (file)
@@ -21,7 +21,7 @@ npm\.load(configObject, function (er, npm) {
 .fi
 .
 .SH "VERSION"
-1.1.36
+1.1.41
 .
 .SH "DESCRIPTION"
 This is the API documentation for npm\.
diff --git a/deps/npm/node_modules/ansi/examples/beep/index.js b/deps/npm/node_modules/ansi/examples/beep/index.js
new file mode 100755 (executable)
index 0000000..c1ec929
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env node
+
+/**
+ * Invokes the terminal "beep" sound once per second on every exact second.
+ */
+
+process.title = 'beep'
+
+var cursor = require('../../')(process.stdout)
+
+function beep () {
+  cursor.beep()
+  setTimeout(beep, 1000 - (new Date()).getMilliseconds())
+}
+
+setTimeout(beep, 1000 - (new Date()).getMilliseconds())
diff --git a/deps/npm/node_modules/ansi/examples/clear/index.js b/deps/npm/node_modules/ansi/examples/clear/index.js
new file mode 100755 (executable)
index 0000000..6ac21ff
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env node
+
+/**
+ * Like GNU ncurses "clear" command.
+ * https://github.com/mscdex/node-ncurses/blob/master/deps/ncurses/progs/clear.c
+ */
+
+process.title = 'clear'
+
+function lf () { return '\n' }
+
+require('../../')(process.stdout)
+  .write(Array.apply(null, Array(process.stdout.getWindowSize()[1])).map(lf).join(''))
+  .eraseData(2)
+  .goto(1, 1)
diff --git a/deps/npm/node_modules/ansi/examples/cursorPosition.js b/deps/npm/node_modules/ansi/examples/cursorPosition.js
new file mode 100755 (executable)
index 0000000..0f45bdb
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env node
+
+var tty = require('tty')
+var cursor = require('../')(process.stdout)
+
+// listen for the queryPosition report on stdin
+process.stdin.resume()
+tty.setRawMode(true)
+
+process.stdin.once('data', function (b) {
+  var match = /\[(\d+)\;(\d+)R$/.exec(b.toString())
+  if (match) {
+    var xy = match.slice(1, 3).reverse().map(Number)
+    console.error(xy)
+  }
+
+  // cleanup and close stdin
+  tty.setRawMode(false)
+  process.stdin.pause()
+})
+
+
+// send the query position request code to stdout
+cursor.queryPosition()
diff --git a/deps/npm/node_modules/ansi/examples/imgcat/index.js b/deps/npm/node_modules/ansi/examples/imgcat/index.js
new file mode 100755 (executable)
index 0000000..5ff2c13
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env node
+
+process.title = 'imgcat'
+
+var ansi = require('../../')
+  , cursor = ansi(process.stdout, { enabled: true })
+  , tty = require('tty')
+  , Canvas = require('canvas')
+  , imageFile = process.argv[2] || __dirname + '/yoshi.png'
+  , screenWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity
+  , maxWidth = parseInt(process.argv[3], 10) || screenWidth
+  , image = require('fs').readFileSync(imageFile)
+  , pixel = '  '
+  , alphaThreshold = 0
+
+var img = new Canvas.Image();
+img.src = image;
+
+function draw () {
+  var width = maxWidth / pixel.length
+    , scaleW = img.width > width ? width / img.width : 1
+    , w = Math.floor(img.width * scaleW)
+    , h = Math.floor(img.height * scaleW);
+
+  var canvas = new Canvas(w, h)
+    , ctx = canvas.getContext('2d');
+
+  ctx.drawImage(img, 0, 0, w, h);
+
+  var data = ctx.getImageData(0, 0, w, h).data;
+
+  for (var i=0, l=data.length; i<l; i+=4) {
+    var r = data[i]
+      , g = data[i+1]
+      , b = data[i+2]
+      , alpha = data[i+3];
+    if (alpha > alphaThreshold) {
+      cursor.bg.rgb(r, g, b);
+    } else {
+      cursor.bg.reset();
+    }
+    process.stdout.write(pixel);
+    if ((i/4|0) % w === (w-1)) {
+      cursor.bg.reset();
+      process.stdout.write('\n');
+    }
+  }
+}
+
+draw();
diff --git a/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png b/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png
new file mode 100644 (file)
index 0000000..267ede2
Binary files /dev/null and b/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png differ
diff --git a/deps/npm/node_modules/ansi/examples/progress/index.js b/deps/npm/node_modules/ansi/examples/progress/index.js
new file mode 100644 (file)
index 0000000..d28dbda
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/env node
+
+var assert = require('assert')
+  , ansi = require('../../')
+
+function Progress (stream, width) {
+  this.cursor = ansi(stream)
+  this.delta = this.cursor.newlines
+  this.width = width | 0 || 10
+  this.open = '['
+  this.close = ']'
+  this.complete = '█'
+  this.incomplete = '_'
+
+  // initial render
+  this.progress = 0
+}
+
+Object.defineProperty(Progress.prototype, 'progress', {
+    get: get
+  , set: set
+  , configurable: true
+  , enumerable: true
+})
+
+function get () {
+  return this._progress
+}
+
+function set (v) {
+  this._progress = Math.max(0, Math.min(v, 100))
+
+  var w = this.width - this.complete.length - this.incomplete.length
+    , n = w * (this._progress / 100) | 0
+    , i = w - n
+    , com = c(this.complete, n)
+    , inc = c(this.incomplete, i)
+    , delta = this.cursor.newlines - this.delta
+
+  assert.equal(com.length + inc.length, w)
+
+  if (delta > 0) {
+    this.cursor.up(delta)
+    this.delta = this.cursor.newlines
+  }
+
+  this.cursor
+    .horizontalAbsolute(0)
+    .eraseLine(2)
+    .fg.white()
+    .write(this.open)
+    .fg.grey()
+    .bold()
+    .write(com)
+    .resetBold()
+    .write(inc)
+    .fg.white()
+    .write(this.close)
+    .fg.reset()
+    .write('\n')
+}
+
+function c (char, length) {
+  return Array.apply(null, Array(length)).map(function () {
+    return char
+  }).join('')
+}
+
+
+
+
+// Usage
+var width = parseInt(process.argv[2], 10) || process.stdout.getWindowSize()[0] / 2
+  , p = new Progress(process.stdout, width)
+
+;(function tick () {
+  p.progress += Math.random() * 5
+  p.cursor
+    .eraseLine(2)
+    .write('Progress: ')
+    .bold().write(p.progress.toFixed(2))
+    .write('%')
+    .resetBold()
+    .write('\n')
+  if (p.progress < 100)
+    setTimeout(tick, 100)
+})()
diff --git a/deps/npm/node_modules/ansi/examples/starwars.js b/deps/npm/node_modules/ansi/examples/starwars.js
new file mode 100755 (executable)
index 0000000..a1fcad4
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+/**
+ * A little script to play the ASCII Star Wars, but with a hidden cursor,
+ * since over `telnet(1)` the cursor remains visible which is annoying.
+ */
+
+process.title = 'starwars'
+
+var net = require('net')
+  , cursor = require('../')(process.stdout)
+
+// enable "raw mode" so that keystrokes aren't visible
+process.stdin.resume()
+if (process.stdin.setRawMode) {
+  process.stdin.setRawMode(true)
+} else {
+  require('tty').setRawMode(true)
+}
+
+// connect to the ASCII Star Wars server
+var socket = net.connect(23, 'towel.blinkenlights.nl')
+
+socket.on('connect', function () {
+  cursor.hide()
+  socket.pipe(process.stdout)
+})
+
+process.stdin.on('data', function (data) {
+  if (data.toString() === '\u0003') {
+    // Ctrl+C; a.k.a SIGINT
+    socket.destroy()
+    process.stdin.pause()
+  }
+})
+
+process.on('exit', function () {
+  cursor.show().write('\n')
+})
diff --git a/deps/npm/node_modules/couch-login/README.md b/deps/npm/node_modules/couch-login/README.md
new file mode 100644 (file)
index 0000000..0b6c75d
--- /dev/null
@@ -0,0 +1,241 @@
+# couch-login
+
+This module lets you log into couchdb to get a session token, then make
+requests using that session.  It is basically just a thin wrapper around
+[@mikeal's request module](https://github.com/mikeal/request).
+
+This is handy if you want a user to take actions in a couchdb database
+on behalf of a user, without having to store their couchdb username and
+password anywhere.  (You do need to store the AuthSession token
+somewhere, though.)
+
+## Usage
+
+```javascript
+var CouchLogin = require('couch-login')
+
+// Nothing about this module is http-server specific of course.
+// You could also use it to do authenticated requests against
+// a couchdb using sessions and storing the token somewhere else.
+
+http.createServer(function (req, res) {
+  var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')
+
+  // .. look up the token in the user's session or whatever ..
+  // Look at couch.decorate(req, res) for more on doing that
+  // automatically, below.
+
+  if (sessionToken) {
+    // this user already logged in.
+    couch.token = sessionToken
+
+    // now we can do things on their behalf, like:
+    // 1. View their session info.
+    // like doing request.get({ uri: couch + '/_session', ... })
+    // but with the cookie and whatnot
+
+    couch.get('/_session', function (er, resp, data) {
+      // er = some kind of communication error.
+      // resp = response object from the couchdb request.
+      // data = parsed JSON response body.
+      if (er || resp.statusCode !== 200) {
+        res.statusCode = resp.statusCode || 403
+        return res.end('Invalid login or something')
+      }
+
+      // now we have the session info, we know who this user is.
+      // hitting couchdb for this on every request is kinda costly,
+      // so maybe you should store the username wherever you're storing
+      // the sessionToken.  RedSess is a good util for this, if you're
+      // into redis.  And if you're not into redis, you're crazy,
+      // because it is awesome.
+
+      // now let's get the user record.
+      // note that this will 404 for anyone other than the user,
+      // unless they're a server admin.
+      couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)
+
+      // PUTs and DELETEs will also use their session, of course, so
+      // your validate_doc_update's will see their info in userCtx
+    })
+
+  } else {
+    // don't have a sessionToken.
+    // get a username and password from the post body or something.
+    // maybe redirect to a /login page or something to ask for that.
+    var login = { name: name, password: password }
+    couch.login(login, function (er, resp, data) {
+      // again, er is an error, resp is the response obj, data is the json
+      if (er || resp.statusCode !== 200) {
+        res.statusCode = resp.statusCode || 403
+        return res.end('Invalid login or something')
+      }
+
+      // the data is something like
+      // {"ok":true,"name":"testuser","roles":[]}
+      // and couch.token is the token you'll need to save somewhere.
+
+      // at this point, you can start making authenticated requests to
+      // couchdb, or save data in their session, or do whatever it is
+      // that you need to do.
+
+      res.statusCode = 200
+      res.write("Who's got two thumbs and just logged you into couch?\n")
+      setTimeout(function () {
+        res.end("THIS GUY!")
+      }, 500)
+    })
+  }
+})
+```
+
+## Class: CouchLogin
+### new CouchLogin(couchdbUrl, token)
+
+Create a new CouchLogin object bound to the couchdb url.
+
+In addition to these, the `get`, `post`, `put`, and `del` methods all
+proxy to the associated method on [request](https://github.com/mikeal/request).
+
+However, as you'll note in the example above, only the pathname portion
+of the url is required.  Urls will be appended to the couchdb url passed
+into the constructor.
+
+If you have to talk to more than one couchdb, then you'll need more than
+one CouchLogin object, for somewhat obvious reasons.
+
+All callbacks get called with the following arguments, which are exactly
+identical to the arguments passed to a `request` callback.
+
+* `er` {Error | null} Set if a communication error happens.
+* `resp` {HTTP Response} The response from the request to couchdb
+* `data` {Object} The parsed JSON data from couch
+
+If the token is the string "anonymous", then it will not attempt to log
+in before making requests.  If the token is not "anonymous", then it
+must be an object with the appropriate fields.
+
+### couch.token
+
+* {Object}
+
+An object representing the couchdb session token.  (Basically just a
+cookie and a timeout.)
+
+If the token has already timed out, then setting it will have no effect.
+
+### couch.tokenSet
+
+If set, this method is called whenever the token is saved.
+
+For example, you could assign a function to this method to save the
+token into a redis session, a cookie, or in some other database.
+
+Takes a callback which should be called when the token is saved.
+
+### couch.tokenGet
+
+If set, this method is called to look up the token on demand.
+
+The inverse of couch.tokenSet.  Takes a callback which is called with
+the `cb(er || null, token)`.
+
+### couch.tokenDel
+
+If set, this method is called to delete the token when it should be
+discarded.
+
+Related to tokenGet and tokenSet.  Takes a callback which should be
+called when the token is deleted.
+
+### couch.anonymous()
+
+Return a new CouchLogin object that points at the same couchdb server,
+but doesn't try to log in before making requests.
+
+This is handy for situations where the user is not logged in at the
+moment, but a request needs to be made anyway, and does not require
+authorization.
+
+### couch.login(auth, callback)
+
+* `auth` {Object} The login details
+  * `name` {String}
+  * `password` {String}
+* `callback` {Function}
+
+When the callback is called, the `couch.token` will already have been
+set (assuming it worked!), so subsequent requests will be done as that
+user.
+
+### couch.get(path, callback)
+
+GET the supplied path from the couchdb using the credentials on the
+token.
+
+Fails if the token is invalid or expired.
+
+### couch.del(path, callback)
+
+DELETE the supplied path from the couchdb using the credentials on the
+token.
+
+Fails if the token is invalid or expired.
+
+### couch.post(path, data, callback)
+
+POST the data to the supplied path in the couchdb, using the credentials
+on the token.
+
+Fails if the token is invalid or expired.
+
+### couch.put(path, data, callback)
+
+PUT the data to the supplied path in the couchdb, using the credentials
+on the token.
+
+Fails if the token is invalid or expired.
+
+### couch.changePass(newAuth, callback)
+
+Must already be logged in.  Updates the `_users` document with new salt
+and hash, and re-logs in with the new credentials.  Callback is called
+with the same arguments as login, or the first step of the process that
+failed.
+
+### couch.signup(userData, callback)
+
+Create a new user account.  The userData must contain at least a `name`
+and `password` field.  Any additional data will be copied to the user
+record.  The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and
+`date` fields are generated.
+
+Also signs in as the newly created user, on successful account creation.
+
+### couch.deleteAccount(name, callback)
+
+Deletes a user account.  If not logged in as the user, or a server
+admin, then the request will fail.
+
+Note that this immediately invalidates any session tokens for the
+deleted user account.  If you are deleting the user's record, then you
+ought to follow this with `couch.logout(callback)` so that it won't try
+to re-use the invalid session.
+
+### couch.logout(callback)
+
+Delete the session out of couchdb.  This makes the token permanently
+invalid, and deletes it.
+
+### couch.decorate(req, res)
+
+Set up `req.couch` and `res.couch` as references to this couch login
+instance.
+
+Additionall, if `req.session` or `res.session` is set, then it'll call
+`session.get('couch_token', cb)` as the tokenGet method,
+`session.set('couch_token', token, cb)` as the tokenSet method, and
+`session.del('couch_token', cb)` as the tokenDel method.
+
+This works really nice with
+[RedSess](https://github.com/isaacs/redsess).
diff --git a/deps/npm/node_modules/couch-login/couch-login.js b/deps/npm/node_modules/couch-login/couch-login.js
new file mode 100644 (file)
index 0000000..d240da0
--- /dev/null
@@ -0,0 +1,287 @@
+var request = require('request')
+, url = require('url')
+, crypto = require('crypto')
+
+module.exports = CouchLogin
+
+function CouchLogin (couch, tok) {
+  if (!(this instanceof CouchLogin)) {
+    return new CouchLogin(couch)
+  }
+
+  if (!couch) throw new Error(
+    "Need to pass a couch url to CouchLogin constructor")
+
+  // having auth completely defeats the purpose
+  couch = url.parse(couch)
+  delete couch.auth
+
+  if (tok === 'anonymous') tok = NaN
+  this.token = tok
+  this.couch = url.format(couch)
+}
+
+CouchLogin.prototype =
+{ get: makeReq('GET')
+, del: makeReq('DELETE')
+, put: makeReq('PUT', true)
+, post: makeReq('POST', true)
+, login: login
+, logout: logout
+, decorate: decorate
+, changePass: changePass
+, signup: signup
+, deleteAccount: deleteAccount
+, anon: anon
+, anonymous: anon
+, valid: valid
+}
+
+Object.defineProperty(CouchLogin.prototype, 'constructor',
+  { value: CouchLogin, enumerable: false })
+
+function decorate (req, res) {
+  req.couch = res.couch = this
+
+  // backed by some sort of set(k,v,cb), get(k,cb) session storage.
+  var session = req.session || res.session || null
+  if (session) {
+    this.tokenGet = function (cb) {
+      session.get('couch_token', cb)
+    }
+
+    // don't worry about it failing.  it'll just mean a login next time.
+    this.tokenSet = function (tok, cb) {
+      session.set('couch_token', tok, cb || function () {})
+    }
+
+    this.tokenDel = function (cb) {
+      session.del('couch_token', cb || function () {})
+    }
+  }
+
+  return this
+}
+
+function anon () {
+  return new CouchLogin(this.couch, NaN)
+}
+
+function makeReq (meth, body, f) { return function madeReq (p, d, cb) {
+  f = f || (this.token !== this.token)
+  if (!f && !valid(this.token)) {
+    // lazily get the token.
+    if (this.tokenGet) return this.tokenGet(function (er, tok) {
+      if (er || !valid(tok)) {
+        if (!body) cb = d, d = null
+        return cb(new Error('auth token expired or invalid'))
+      }
+      this.token = tok
+      return madeReq.call(this, p, d, cb)
+    }.bind(this))
+
+    // no getter, no token, no business.
+    return process.nextTick(function () {
+      if (!body) cb = d, d = null
+      cb(new Error('auth token expired or invalid'))
+    })
+  }
+
+  if (!body) cb = d, d = null
+
+  var h = {}
+  , u = url.resolve(this.couch, p)
+  , req = { uri: u, headers: h, json: true, body: d, method: meth }
+
+  if (this.token) {
+    h.cookie = 'AuthSession=' + this.token.AuthSession
+  }
+
+  request(req, function (er, res, data) {
+    // update cookie.
+    if (er || res.statusCode !== 200) return cb(er, res, data)
+    addToken.call(this, res)
+    return cb(er, res, data)
+  }.bind(this))
+}}
+
+function login (auth, cb) {
+  var a = { name: auth.name, password: auth.password }
+  makeReq('post', true, true).call(this, '/_session', a, cb)
+}
+
+function changePass (auth, cb) {
+  if (!auth.name || !auth.password) return cb(new Error('invalid auth'))
+
+  var u = '/_users/org.couchdb.user:' + auth.name
+  this.get(u, function (er, res, data) {
+    if (er || res.statusCode !== 200) return cb(er, res, data)
+
+    // copy any other keys we're setting here.
+    // note that name, password_sha, salt, and date
+    // are all set explicitly below.
+    Object.keys(auth).filter(function (k) {
+      return k.charAt(0) !== '_'
+          && k !== 'password'
+          && k !== 'password_sha'
+          && k !== 'salt'
+    }).forEach(function (k) {
+      data[k] = auth[k]
+    })
+
+    var newSalt = crypto.randomBytes(30).toString('hex')
+    , newPass = auth.password
+    , newSha = sha(newPass + newSalt)
+
+    data.password_sha = newSha
+    data.salt = newSalt
+    data.date = new Date().toISOString()
+
+    this.put(u + '?rev=' + data._rev, data, function (er, res, data) {
+      if (er || res.statusCode >= 400) return cb(er, res, data)
+      this.login(auth, cb)
+    }.bind(this))
+  }.bind(this))
+}
+
+// They said that there should probably be a warning before
+// deleting the user's whole account, so here it is:
+//
+// WATCH OUT!
+function deleteAccount (name, cb) {
+  var u = '/_users/org.couchdb.user:' + name
+  this.get(u, thenPut.bind(this))
+
+  function thenPut (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    // user accts can't be just DELETE'd by non-admins
+    // so we take the existing doc and just slap a _deleted
+    // flag on it to fake it.  Works the same either way
+    // in couch.
+    data._deleted = true
+    this.put(u + '?rev=' + data._rev, data, cb)
+  }
+}
+
+
+
+function signup (auth, cb) {
+  if (this.token) return this.logout(function (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    if (this.token) {
+      return cb(new Error('failed to delete token'), res, data)
+    }
+
+    this.signup(auth, cb)
+  }.bind(this))
+
+  // make a new user record.
+  var newSalt = crypto.randomBytes(30).toString('hex')
+  , newSha = sha(auth.password + newSalt)
+  , user = { _id: 'org.couchdb.user:' + auth.name
+           , name: auth.name
+           , roles: []
+           , type: 'user'
+           , password_sha: newSha
+           , salt: newSalt
+           , date: new Date().toISOString() }
+
+  Object.keys(auth).forEach(function (k) {
+    if (k === 'name' || k === 'password') return
+    user[k] = auth[k]
+  })
+
+  var u = '/_users/' + user._id
+  makeReq('put', true, true).call(this, u, user, function (er, res, data) {
+    if (er || res.statusCode >= 400) {
+      return cb(er, res, data)
+    }
+
+    // it worked! log in as that user and get their record
+    this.login(auth, function (er, res, data) {
+      if (er || (res && res.statusCode >= 400) || data && data.error) {
+        return cb(er, res, data)
+      }
+      this.get(u, cb)
+    }.bind(this))
+  }.bind(this))
+}
+
+function addToken (res) {
+  // attach the token, if a new one was provided.
+  var sc = res.headers['set-cookie']
+  if (!sc) return
+  if (!Array.isArray(sc)) sc = [sc]
+
+  sc = sc.filter(function (c) {
+    return c.match(/^AuthSession=/)
+  })[0]
+
+  if (!sc.length) return
+
+  sc = sc.split(/\s*;\s*/).map(function (p) {
+    return p.split('=')
+  }).reduce(function (set, p) {
+    var k = p[0] === 'AuthSession' ? p[0] : p[0].toLowerCase()
+    , v = k === 'expires' ? Date.parse(p[1])
+        : p[1] === '' || p[1] === undefined ? true // HttpOnly
+        : p[1]
+    set[k] = v
+    return set
+  }, {})
+
+  if (sc.hasOwnProperty('max-age')) {
+    var ma = sc['max-age']
+    sc.expires = (ma <= 0) ? 0 : Date.now() + (ma * 1000)
+    delete sc['max-age']
+  }
+
+  this.token = sc
+  if (this.tokenSet) this.tokenSet(this.token)
+}
+
+
+function logout (cb) {
+  if (!this.token && this.tokenGet) {
+    return this.tokenGet(function (er, tok) {
+      if (er || !tok) return cb()
+      this.token = tok
+      this.logout(cb)
+    }.bind(this))
+  }
+
+  if (!valid(this.token)) {
+    this.token = null
+    if (this.tokenDel) this.tokenDel()
+    return process.nextTick(cb)
+  }
+
+  var h = { cookie: 'AuthSession=' + this.token.AuthSession }
+  , u = url.resolve(this.couch, '/_session')
+  , req = { uri: u, headers: h, json: true }
+
+  request.del(req, function (er, res, data) {
+    if (er || res.statusCode !== 200) {
+      return cb(er, res, data)
+    }
+
+    this.token = null
+    if (this.tokenDel) this.tokenDel()
+    cb(er, res, data)
+  }.bind(this))
+}
+
+function valid (token) {
+  var d = token && token.expires
+  return token && token.expires > Date.now()
+}
+
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
diff --git a/deps/npm/node_modules/couch-login/package.json b/deps/npm/node_modules/couch-login/package.json
new file mode 100644 (file)
index 0000000..f39660a
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "i@izs.me",
+    "url": "http://blog.izs.me/"
+  },
+  "name": "couch-login",
+  "description": "A module for doing logged-in requests to a couchdb server",
+  "version": "0.1.6",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/couch-login.git"
+  },
+  "main": "couch-login.js",
+  "scripts": {
+    "test": "tap test/*.js"
+  },
+  "dependencies": {
+    "request": "~2.9.202"
+  },
+  "devDependencies": {
+    "tap": "~0.2.4"
+  },
+  "readme": "# couch-login\n\nThis module lets you log into couchdb to get a session token, then make\nrequests using that session.  It is basically just a thin wrapper around\n[@mikeal's request module](https://github.com/mikeal/request).\n\nThis is handy if you want a user to take actions in a couchdb database\non behalf of a user, without having to store their couchdb username and\npassword anywhere.  (You do need to store the AuthSession token\nsomewhere, though.)\n\n## Usage\n\n```javascript\nvar CouchLogin = require('couch-login')\n\n// Nothing about this module is http-server specific of course.\n// You could also use it to do authenticated requests against\n// a couchdb using sessions and storing the token somewhere else.\n\nhttp.createServer(function (req, res) {\n  var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')\n\n  // .. look up the token in the user's session or whatever ..\n  // Look at couch.decorate(req, res) for more on doing that\n  // automatically, below.\n\n  if (sessionToken) {\n    // this user already logged in.\n    couch.token = sessionToken\n\n    // now we can do things on their behalf, like:\n    // 1. View their session info.\n    // like doing request.get({ uri: couch + '/_session', ... })\n    // but with the cookie and whatnot\n\n    couch.get('/_session', function (er, resp, data) {\n      // er = some kind of communication error.\n      // resp = response object from the couchdb request.\n      // data = parsed JSON response body.\n      if (er || resp.statusCode !== 200) {\n        res.statusCode = resp.statusCode || 403\n        return res.end('Invalid login or something')\n      }\n\n      // now we have the session info, we know who this user is.\n      // hitting couchdb for this on every request is kinda costly,\n      // so maybe you should store the username wherever you're storing\n      // the sessionToken.  RedSess is a good util for this, if you're\n      // into redis.  And if you're not into redis, you're crazy,\n      // because it is awesome.\n\n      // now let's get the user record.\n      // note that this will 404 for anyone other than the user,\n      // unless they're a server admin.\n      couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)\n\n      // PUTs and DELETEs will also use their session, of course, so\n      // your validate_doc_update's will see their info in userCtx\n    })\n\n  } else {\n    // don't have a sessionToken.\n    // get a username and password from the post body or something.\n    // maybe redirect to a /login page or something to ask for that.\n    var login = { name: name, password: password }\n    couch.login(login, function (er, resp, data) {\n      // again, er is an error, resp is the response obj, data is the json\n      if (er || resp.statusCode !== 200) {\n        res.statusCode = resp.statusCode || 403\n        return res.end('Invalid login or something')\n      }\n\n      // the data is something like\n      // {\"ok\":true,\"name\":\"testuser\",\"roles\":[]}\n      // and couch.token is the token you'll need to save somewhere.\n\n      // at this point, you can start making authenticated requests to\n      // couchdb, or save data in their session, or do whatever it is\n      // that you need to do.\n\n      res.statusCode = 200\n      res.write(\"Who's got two thumbs and just logged you into couch?\\n\")\n      setTimeout(function () {\n        res.end(\"THIS GUY!\")\n      }, 500)\n    })\n  }\n})\n```\n\n## Class: CouchLogin\n### new CouchLogin(couchdbUrl, token)\n\nCreate a new CouchLogin object bound to the couchdb url.\n\nIn addition to these, the `get`, `post`, `put`, and `del` methods all\nproxy to the associated method on [request](https://github.com/mikeal/request).\n\nHowever, as you'll note in the example above, only the pathname portion\nof the url is required.  Urls will be appended to the couchdb url passed\ninto the constructor.\n\nIf you have to talk to more than one couchdb, then you'll need more than\none CouchLogin object, for somewhat obvious reasons.\n\nAll callbacks get called with the following arguments, which are exactly\nidentical to the arguments passed to a `request` callback.\n\n* `er` {Error | null} Set if a communication error happens.\n* `resp` {HTTP Response} The response from the request to couchdb\n* `data` {Object} The parsed JSON data from couch\n\nIf the token is the string \"anonymous\", then it will not attempt to log\nin before making requests.  If the token is not \"anonymous\", then it\nmust be an object with the appropriate fields.\n\n### couch.token\n\n* {Object}\n\nAn object representing the couchdb session token.  (Basically just a\ncookie and a timeout.)\n\nIf the token has already timed out, then setting it will have no effect.\n\n### couch.tokenSet\n\nIf set, this method is called whenever the token is saved.\n\nFor example, you could assign a function to this method to save the\ntoken into a redis session, a cookie, or in some other database.\n\nTakes a callback which should be called when the token is saved.\n\n### couch.tokenGet\n\nIf set, this method is called to look up the token on demand.\n\nThe inverse of couch.tokenSet.  Takes a callback which is called with\nthe `cb(er || null, token)`.\n\n### couch.tokenDel\n\nIf set, this method is called to delete the token when it should be\ndiscarded.\n\nRelated to tokenGet and tokenSet.  Takes a callback which should be\ncalled when the token is deleted.\n\n### couch.anonymous()\n\nReturn a new CouchLogin object that points at the same couchdb server,\nbut doesn't try to log in before making requests.\n\nThis is handy for situations where the user is not logged in at the\nmoment, but a request needs to be made anyway, and does not require\nauthorization.\n\n### couch.login(auth, callback)\n\n* `auth` {Object} The login details\n  * `name` {String}\n  * `password` {String}\n* `callback` {Function}\n\nWhen the callback is called, the `couch.token` will already have been\nset (assuming it worked!), so subsequent requests will be done as that\nuser.\n\n### couch.get(path, callback)\n\nGET the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.del(path, callback)\n\nDELETE the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.post(path, data, callback)\n\nPOST the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.put(path, data, callback)\n\nPUT the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.changePass(newAuth, callback)\n\nMust already be logged in.  Updates the `_users` document with new salt\nand hash, and re-logs in with the new credentials.  Callback is called\nwith the same arguments as login, or the first step of the process that\nfailed.\n\n### couch.signup(userData, callback)\n\nCreate a new user account.  The userData must contain at least a `name`\nand `password` field.  Any additional data will be copied to the user\nrecord.  The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and\n`date` fields are generated.\n\nAlso signs in as the newly created user, on successful account creation.\n\n### couch.deleteAccount(name, callback)\n\nDeletes a user account.  If not logged in as the user, or a server\nadmin, then the request will fail.\n\nNote that this immediately invalidates any session tokens for the\ndeleted user account.  If you are deleting the user's record, then you\nought to follow this with `couch.logout(callback)` so that it won't try\nto re-use the invalid session.\n\n### couch.logout(callback)\n\nDelete the session out of couchdb.  This makes the token permanently\ninvalid, and deletes it.\n\n### couch.decorate(req, res)\n\nSet up `req.couch` and `res.couch` as references to this couch login\ninstance.\n\nAdditionall, if `req.session` or `res.session` is set, then it'll call\n`session.get('couch_token', cb)` as the tokenGet method,\n`session.set('couch_token', token, cb)` as the tokenSet method, and\n`session.del('couch_token', cb)` as the tokenDel method.\n\nThis works really nice with\n[RedSess](https://github.com/isaacs/redsess).\n",
+  "_id": "couch-login@0.1.6",
+  "_from": "couch-login@~0.1.6"
+}
diff --git a/deps/npm/node_modules/couch-login/test/basic.js b/deps/npm/node_modules/couch-login/test/basic.js
new file mode 100644 (file)
index 0000000..b81a5e6
--- /dev/null
@@ -0,0 +1,286 @@
+var tap = require('tap')
+, CouchLogin = require('../couch-login.js')
+
+// Yeah, go ahead and abuse my staging server, whatevs.
+
+var auth = { name: 'testuser', password: 'test' }
+, newAuth = { name: 'testuser', password: 'asdfasdf' }
+, couch = new CouchLogin('https://isaacs-staging.couch.xxx/')
+, u = '/_users/org.couchdb.user:' + auth.name
+, userRecordMarker
+
+// simulate the 'must change password on next login' thing
+newAuth.mustChangePass = true
+auth.mustChangePass = false
+
+
+function okStatus (t, res) {
+  var x = { found: res.statusCode, wanted: 'around 200' }
+  var r = res.statusCode
+  x.ok = (r >= 200 && r < 300)
+  return t.ok(x.ok, 'Status code should be 200-ish', x)
+}
+
+tap.test('login', function (t) {
+  couch.login(auth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.deepEqual(data, { ok: true, name: 'testuser', roles: [] })
+    t.ok(couch.token)
+    t.deepEqual(couch.token,
+      { AuthSession: couch.token && couch.token.AuthSession,
+        version: '1',
+        expires: couch.token && couch.token.expires,
+        path: '/',
+        httponly: true })
+    t.ok(couch.token, 'has token')
+    t.end()
+  })
+})
+
+var userRecord
+tap.test('get', function (t) {
+  couch.get(u, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+    userRecord = data
+    okStatus(t, res)
+    t.end()
+  })
+})
+
+var userRecordMarker = require('crypto').randomBytes(30).toString('base64')
+tap.test('add key to user record', function (t) {
+  userRecord.testingCouchLogin = userRecordMarker
+  var revved = u + '?rev=' + userRecord._rev
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+    // get again so we have the current rev
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data)
+      t.ok(userRecord)
+      t.equal(data.testingCouchLogin, userRecord.testingCouchLogin)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+tap.test('remove key', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  delete userRecord.testingCouchLogin
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(couch.token, 'token')
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+var crypto = require('crypto')
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
+
+tap.test('change password manually', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  , newPass = newAuth.password
+  , newSalt = 'test-salt-two'
+  , newSha = sha(newPass + newSalt)
+
+  userRecord.salt = newSalt
+  userRecord.password_sha = newSha
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    // changing password invalidates session.
+    // need to re-login
+    couch.login(newAuth, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+
+      couch.get(u, function (er, res, data) {
+        t.ifError(er)
+        if (er) return t.end()
+        okStatus(t, res)
+        t.ok(data, 'data')
+        t.ok(couch.token, 'token')
+        t.equal(data.testingCouchLogin, undefined)
+        userRecord = data
+        t.end()
+      })
+    })
+  })
+})
+
+tap.test('change password back manually', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  , newPass = auth.password
+  , newSalt = 'test-salt'
+  , newSha = sha(newPass + newSalt)
+
+  userRecord.salt = newSalt
+  userRecord.password_sha = newSha
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+
+    couch.login(auth, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+
+      couch.get(u, function (er, res, data) {
+        t.ifError(er)
+        if (er) return t.end()
+        okStatus(t, res)
+        t.ok(data, 'data')
+        t.ok(couch.token, 'token')
+        userRecord = data
+        t.end()
+      })
+    })
+  })
+})
+
+tap.test('change password easy', function (t) {
+  couch.changePass(newAuth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      t.equal(data.mustChangePass, true)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+tap.test('change password back easy', function (t) {
+  couch.changePass(auth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      t.equal(data.mustChangePass, false)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+
+tap.test('logout', function (t) {
+  couch.logout(function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.notOk(couch.token, 'token')
+    t.end()
+  })
+})
+
+// now try some logged out monkey business!
+tap.test('logged out post', function (t) {
+  couch.post('/yeah-right', {foo: 100}, function (er, res, data) {
+    t.ok(er, 'should get an error')
+    t.notOk(couch.token, 'token')
+    t.end()
+  })
+})
+
+tap.test('anonymous put', function (t) {
+  var guy = couch.anonymous()
+  guy.put('/remember', {november:5}, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    t.equal(res.statusCode, 401)
+    t.deepEqual(data, { error: 'unauthorized'
+                      , reason: 'You are not a server admin.' })
+    t.end()
+  })
+})
+
+tap.test('anonymous get', function (t) {
+  var guy = couch.anonymous()
+  guy.get('/', function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    t.equal(res.statusCode, 200)
+    t.deepEqual(data, { couchdb: 'Welcome', version: '1.2.0' })
+    t.end()
+  })
+})
+
+
+
+var signupUser = { name: 'test-user-signup', password: 'signup-test' }
+
+tap.test('sign up as new user', function (t) {
+  couch.signup(signupUser, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.has(data,
+      { _id: 'org.couchdb.user:test-user-signup',
+        name: 'test-user-signup',
+        roles: [],
+        type: 'user' })
+    t.ok(data._rev, 'rev')
+    t.ok(data.date, 'date')
+    t.ok(data.password_sha, 'hash')
+    t.ok(data.salt, 'salt')
+    t.ok(couch.token, 'token')
+    // now delete account
+    var name = signupUser.name
+    couch.deleteAccount(name, function (er, res, data) {
+      t.ifError(er, 'should be no error deleting account')
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.end()
+    })
+  })
+})
diff --git a/deps/npm/node_modules/couch-login/test/registry.js b/deps/npm/node_modules/couch-login/test/registry.js
new file mode 100644 (file)
index 0000000..56a21f6
--- /dev/null
@@ -0,0 +1,254 @@
+// Should be able to use this module to log into the registry, as well.
+
+var tap = require('tap')
+, CouchLogin = require('../couch-login.js')
+
+// Yeah, go ahead and abuse my staging server, whatevs.
+
+var auth = { name: 'testuser', password: 'test' }
+, newAuth = { name: 'testuser', password: 'asdfasdf' }
+, couch = new CouchLogin('https://staging.npmjs.org/')
+, u = '/_users/org.couchdb.user:' + auth.name
+, userRecordMarker
+
+// simulate the 'must change password on next login' thing
+newAuth.mustChangePass = true
+auth.mustChangePass = false
+
+
+function okStatus (t, res) {
+  var x = { found: res.statusCode, wanted: 'around 200' }
+  var r = res.statusCode
+  x.ok = (r >= 200 && r < 300)
+  return t.ok(x.ok, 'Status code should be 200-ish', x)
+}
+
+tap.test('login', function (t) {
+  couch.login(auth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.deepEqual(data, { ok: true, name: 'testuser', roles: [] })
+    t.ok(couch.token)
+    t.deepEqual(couch.token,
+      { AuthSession: couch.token && couch.token.AuthSession,
+        version: '1',
+        expires: couch.token && couch.token.expires,
+        path: '/',
+        httponly: true })
+    t.ok(couch.token, 'has token')
+    t.end()
+  })
+})
+
+var userRecord
+tap.test('get', function (t) {
+  couch.get(u, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+    userRecord = data
+    okStatus(t, res)
+    t.end()
+  })
+})
+
+var userRecordMarker = require('crypto').randomBytes(30).toString('base64')
+tap.test('add key to user record', function (t) {
+  userRecord.testingCouchLogin = userRecordMarker
+  var revved = u + '?rev=' + userRecord._rev
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+    // get again so we have the current rev
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data)
+      t.ok(userRecord)
+      t.equal(data.testingCouchLogin, userRecord.testingCouchLogin)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+tap.test('remove key', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  delete userRecord.testingCouchLogin
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(couch.token, 'token')
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+var crypto = require('crypto')
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
+
+tap.test('change password manually', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  , newPass = newAuth.password
+  , newSalt = 'test-salt-two'
+  , newSha = sha(newPass + newSalt)
+
+  userRecord.salt = newSalt
+  userRecord.password_sha = newSha
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    // changing password invalidates session.
+    // need to re-login
+    couch.login(newAuth, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+
+      couch.get(u, function (er, res, data) {
+        t.ifError(er)
+        if (er) return t.end()
+        okStatus(t, res)
+        t.ok(data, 'data')
+        t.ok(couch.token, 'token')
+        t.equal(data.testingCouchLogin, undefined)
+        userRecord = data
+        t.end()
+      })
+    })
+  })
+})
+
+tap.test('change password back manually', function (t) {
+  var revved = u + '?rev=' + userRecord._rev
+  , newPass = auth.password
+  , newSalt = 'test-salt'
+  , newSha = sha(newPass + newSalt)
+
+  userRecord.salt = newSalt
+  userRecord.password_sha = newSha
+  couch.put(revved, userRecord, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.ok(couch.token, 'token')
+
+    couch.login(auth, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+
+      couch.get(u, function (er, res, data) {
+        t.ifError(er)
+        if (er) return t.end()
+        okStatus(t, res)
+        t.ok(data, 'data')
+        t.ok(couch.token, 'token')
+        userRecord = data
+        t.end()
+      })
+    })
+  })
+})
+
+tap.test('change password easy', function (t) {
+  couch.changePass(newAuth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      t.equal(data.mustChangePass, true)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+tap.test('change password back easy', function (t) {
+  couch.changePass(auth, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+
+    couch.get(u, function (er, res, data) {
+      t.ifError(er)
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.ok(couch.token, 'token')
+      t.equal(data.testingCouchLogin, undefined)
+      t.equal(data.mustChangePass, false)
+      userRecord = data
+      t.end()
+    })
+  })
+})
+
+
+tap.test('logout', function (t) {
+  couch.logout(function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.notOk(couch.token, 'token')
+    t.end()
+  })
+})
+
+var signupUser = { name: 'test-user-signup', password: 'signup-test' }
+
+tap.test('sign up as new user', function (t) {
+  couch.signup(signupUser, function (er, res, data) {
+    t.ifError(er)
+    if (er) return t.end()
+    okStatus(t, res)
+    t.ok(data, 'data')
+    t.has(data,
+      { _id: 'org.couchdb.user:test-user-signup',
+        name: 'test-user-signup',
+        roles: [],
+        type: 'user' })
+    t.ok(data._rev, 'rev')
+    t.ok(data.date, 'date')
+    t.ok(data.password_sha, 'hash')
+    t.ok(data.salt, 'salt')
+    t.ok(couch.token, 'token')
+    // now delete account
+    var name = signupUser.name
+    couch.deleteAccount(name, function (er, res, data) {
+      t.ifError(er, 'should be no error deleting account')
+      if (er) return t.end()
+      okStatus(t, res)
+      t.ok(data, 'data')
+      t.end()
+    })
+  })
+})
diff --git a/deps/npm/node_modules/fstream-npm/example/bundle.js b/deps/npm/node_modules/fstream-npm/example/bundle.js
new file mode 100644 (file)
index 0000000..159e4f7
--- /dev/null
@@ -0,0 +1,13 @@
+// this example will bundle every dependency
+var P = require("../")
+P({ path: "./" })
+  .on("package", bundleIt)
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path.substr(e.root.dirname.length + 1))
+    e.on("package", bundleIt)
+  })
+
+function bundleIt (p) {
+  p.bundleDependencies = Object.keys(p.dependencies || {})
+}
+
diff --git a/deps/npm/node_modules/fstream-npm/example/dir-tar.js b/deps/npm/node_modules/fstream-npm/example/dir-tar.js
new file mode 100644 (file)
index 0000000..f2bad92
--- /dev/null
@@ -0,0 +1,19 @@
+// this will show what ends up in the fstream-npm package
+var P = require("fstream").DirReader
+var tar = require("tar")
+function f (entry) {
+  return entry.basename !== ".git"
+}
+
+new P({ path: "./", type: "Directory", Directory: true, filter: f })
+  .on("package", function (p) {
+    console.error("package", p)
+  })
+  .on("ignoreFile", function (e) {
+    console.error("ignoreFile", e)
+  })
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path.substr(e.root.path.length + 1))
+  })
+  .pipe(tar.Pack())
+  .pipe(process.stdout)
diff --git a/deps/npm/node_modules/fstream-npm/example/dir.js b/deps/npm/node_modules/fstream-npm/example/dir.js
new file mode 100644 (file)
index 0000000..75e2eed
--- /dev/null
@@ -0,0 +1,25 @@
+// this will show what ends up in the fstream-npm package
+var P = require("../")
+var DW = require("fstream").DirWriter
+
+var target = new DW({ Directory: true, type: "Directory",
+                      path: __dirname + "/output"})
+
+function f (entry) {
+  return entry.basename !== ".git"
+}
+
+P({ path: "./", type: "Directory", isDirectory: true, filter: f })
+  .on("package", function (p) {
+    console.error("package", p)
+  })
+  .on("ignoreFile", function (e) {
+    console.error("ignoreFile", e)
+  })
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path)
+  })
+  .pipe(target)
+  .on("end", function () {
+    console.error("ended")
+  })
diff --git a/deps/npm/node_modules/fstream-npm/example/example.js b/deps/npm/node_modules/fstream-npm/example/example.js
new file mode 100644 (file)
index 0000000..0b53931
--- /dev/null
@@ -0,0 +1,12 @@
+// this will show what ends up in the fstream-npm package
+var P = require("../")
+P({ path: "./" })
+  .on("package", function (p) {
+    console.error("package", p)
+  })
+  .on("ignoreFile", function (e) {
+    console.error("ignoreFile", e)
+  })
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path.substr(e.root.dirname.length + 1))
+  })
diff --git a/deps/npm/node_modules/fstream-npm/example/ig-tar.js b/deps/npm/node_modules/fstream-npm/example/ig-tar.js
new file mode 100644 (file)
index 0000000..c1db810
--- /dev/null
@@ -0,0 +1,19 @@
+// this will show what ends up in the fstream-npm package
+var P = require("fstream-ignore")
+var tar = require("tar")
+function f (entry) {
+  return entry.basename !== ".git"
+}
+
+new P({ path: "./", type: "Directory", Directory: true, filter: f })
+  .on("package", function (p) {
+    console.error("package", p)
+  })
+  .on("ignoreFile", function (e) {
+    console.error("ignoreFile", e)
+  })
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path.substr(e.root.path.length + 1))
+  })
+  .pipe(tar.Pack())
+  .pipe(process.stdout)
diff --git a/deps/npm/node_modules/fstream-npm/example/tar.js b/deps/npm/node_modules/fstream-npm/example/tar.js
new file mode 100644 (file)
index 0000000..f9bcaea
--- /dev/null
@@ -0,0 +1,25 @@
+// this will show what ends up in the fstream-npm package
+var P = require("../")
+var tar = require("tar")
+function f () {
+  return true
+}
+// function f (entry) {
+//   return entry.basename !== ".git"
+// }
+
+new P({ path: "./", type: "Directory", isDirectory: true, filter: f })
+  .on("package", function (p) {
+    console.error("package", p)
+  })
+  .on("ignoreFile", function (e) {
+    console.error("ignoreFile", e)
+  })
+  .on("entry", function (e) {
+    console.error(e.constructor.name, e.path)
+  })
+  .on("end", function () {
+    console.error("ended")
+  })
+  .pipe(tar.Pack())
+  .pipe(process.stdout)
index 43c0f16..5678347 100644 (file)
@@ -90,6 +90,9 @@ Packer.prototype.applyIgnores = function (entry, partial, entryObj) {
   // package.json files can never be ignored.
   if (entry === "package.json") return true
 
+  // readme files should never be ignored.
+  if (entry.match(/^readme(\.[^\.]*)$/i)) return true
+
   // special rules.  see below.
   if (entry === "node_modules" && this.packageRoot) return true
 
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js
new file mode 100644 (file)
index 0000000..ff45342
--- /dev/null
@@ -0,0 +1,13 @@
+var Ignore = require("../")
+Ignore({ path: __dirname
+       , ignoreFiles: [".ignore", ".gitignore"]
+       })
+  .on("child", function (c) {
+    console.error(c.path.substr(c.root.path.length + 1))
+    c.on("ignoreFile", onIgnoreFile)
+  })
+  .on("ignoreFile", onIgnoreFile)
+
+function onIgnoreFile (e) {
+  console.error("adding ignore file", e.path)
+}
index ed82c65..773e797 100644 (file)
     "rimraf": "",
     "mkdirp": ""
   },
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
+  "readme": "# fstream-ignore\n\nA fstream DirReader that filters out files that match globs in `.ignore`\nfiles throughout the tree, like how git ignores files based on a\n`.gitignore` file.\n\nHere's an example:\n\n```javascript\nvar Ignore = require(\"fstream-ignore\")\nIgnore({ path: __dirname\n       , ignoreFiles: [\".ignore\", \".gitignore\"]\n       })\n  .on(\"child\", function (c) {\n    console.error(c.path.substr(c.root.path.length + 1))\n  })\n  .pipe(tar.Pack())\n  .pipe(fs.createWriteStream(\"foo.tar\"))\n```\n\nThis will tar up the files in __dirname into `foo.tar`, ignoring\nanything matched by the globs in any .iginore or .gitignore file.\n",
   "_id": "fstream-ignore@0.0.5",
-  "optionalDependencies": {},
-  "engines": {
-    "node": "*"
-  },
-  "_engineSupported": true,
-  "_npmVersion": "1.1.23",
-  "_nodeVersion": "v0.7.10-pre",
-  "_defaultsLoaded": true,
   "_from": "fstream-ignore@~0.0.5"
 }
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore
new file mode 100644 (file)
index 0000000..773679d
--- /dev/null
@@ -0,0 +1,2 @@
+.gitignore
+.*.swp
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore
new file mode 100644 (file)
index 0000000..1b26d0d
--- /dev/null
@@ -0,0 +1 @@
+*/a
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js
new file mode 100644 (file)
index 0000000..7d7e4a1
--- /dev/null
@@ -0,0 +1,71 @@
+// The test fixtures work like this:
+// These dirs are all created: {a,b,c}/{a,b,c}/{a,b,c}/
+// in each one, these files are created:
+// {.,}{a,b,c}{a,b,c}{a,b,c}
+//
+// So, there'll be a/b/c/abc, a/b/c/aba, etc., and dot-versions of each.
+//
+// Each test then writes their own ignore file rules for their purposes,
+// and is responsible for removing them afterwards.
+
+var mkdirp = require("mkdirp")
+var path = require("path")
+var i = 0
+var tap = require("tap")
+var fs = require("fs")
+var rimraf = require("rimraf")
+var fixtures = path.resolve(__dirname, "fixtures")
+
+var chars = ['a', 'b', 'c']
+var dirs = []
+
+for (var i = 0; i < 3; i ++) {
+  for (var j = 0; j < 3; j ++) {
+    for (var k = 0; k < 3; k ++) {
+      dirs.push(chars[i] + '/' + chars[j] + '/' + chars[k])
+    }
+  }
+}
+
+var files = []
+
+for (var i = 0; i < 3; i ++) {
+  for (var j = 0; j < 3; j ++) {
+    for (var k = 0; k < 3; k ++) {
+      files.push(chars[i] + chars[j] + chars[k])
+      files.push('.' + chars[i] + chars[j] + chars[k])
+    }
+  }
+}
+
+tap.test("remove fixtures", function (t) {
+  rimraf(path.resolve(__dirname, "fixtures"), function (er) {
+    t.ifError(er, "remove fixtures")
+    t.end()
+  })
+})
+
+tap.test("create fixtures", function (t) {
+  dirs.forEach(function (dir) {
+    dir = path.resolve(fixtures, dir)
+    t.test("mkdir "+dir, function (t) {
+      mkdirp(dir, function (er) {
+        t.ifError(er, "mkdir "+dir)
+        if (er) return t.end()
+
+        files.forEach(function (file) {
+          file = path.resolve(dir, file)
+          t.test("writeFile "+file, function (t) {
+            fs.writeFile(file, path.basename(file), function (er) {
+              t.ifError(er, "writing "+file)
+              t.end()
+            })
+          })
+        })
+        t.end()
+      })
+    })
+  })
+  t.end()
+})
+
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js
new file mode 100644 (file)
index 0000000..3718076
--- /dev/null
@@ -0,0 +1,28 @@
+var IgnoreFile = require("../")
+
+// set the ignores just for this test
+var c = require("./common.js")
+c.ignores({ "a/.basic-ignore": ["b/", "aca"] })
+
+// the files that we expect to not see
+var notAllowed =
+  [ /^\/a\/b\/.*/
+  , /^\/a\/.*\/aca$/ ]
+
+
+require("tap").test("basic ignore rules", function (t) {
+  t.pass("start")
+
+  IgnoreFile({ path: __dirname + "/fixtures"
+             , ignoreFiles: [".basic-ignore"] })
+    .on("ignoreFile", function (e) {
+      console.error("ignore file!", e)
+    })
+    .on("child", function (e) {
+      var p = e.path.substr(e.root.path.length)
+      notAllowed.forEach(function (na) {
+        t.dissimilar(p, na)
+      })
+    })
+    .on("close", t.end.bind(t))
+})
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js
new file mode 100644 (file)
index 0000000..0e6cd98
--- /dev/null
@@ -0,0 +1,40 @@
+if (require.main === module) {
+  console.log("0..1")
+  console.log("ok 1 trivial pass")
+  return
+}
+
+var fs = require("fs")
+var path = require("path")
+var rimraf = require("rimraf")
+
+exports.ignores = ignores
+exports.writeIgnoreFile = writeIgnoreFile
+exports.writeIgnores = writeIgnores
+exports.clearIgnores = clearIgnores
+
+function writeIgnoreFile (file, rules) {
+  file = path.resolve(__dirname, "fixtures", file)
+  if (Array.isArray(rules)) {
+    rules = rules.join("\n")
+  }
+  fs.writeFileSync(file, rules)
+  console.error(file, rules)
+}
+
+function writeIgnores (set) {
+  Object.keys(set).forEach(function (f) {
+    writeIgnoreFile(f, set[f])
+  })
+}
+
+function clearIgnores (set) {
+  Object.keys(set).forEach(function (file) {
+    fs.unlinkSync(path.resolve(__dirname, "fixtures", file))
+  })
+}
+
+function ignores (set) {
+  writeIgnores(set)
+  process.on("exit", clearIgnores.bind(null, set))
+}
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js
new file mode 100644 (file)
index 0000000..43eec4b
--- /dev/null
@@ -0,0 +1,41 @@
+// ignore most things
+var IgnoreFile = require("../")
+
+// set the ignores just for this test
+var c = require("./common.js")
+c.ignores({ ".ignore": ["*", "!a/b/c/.abc", "!/c/b/a/cba"] })
+
+// the only files we expect to see
+var expected =
+  [ "/a/b/c/.abc"
+  , "/a"
+  , "/a/b"
+  , "/a/b/c"
+  , "/c/b/a/cba"
+  , "/c"
+  , "/c/b"
+  , "/c/b/a" ]
+
+require("tap").test("basic ignore rules", function (t) {
+  t.pass("start")
+
+  IgnoreFile({ path: __dirname + "/fixtures"
+             , ignoreFiles: [".ignore"] })
+    .on("ignoreFile", function (e) {
+      console.error("ignore file!", e)
+    })
+    .on("child", function (e) {
+      var p = e.path.substr(e.root.path.length)
+      var i = expected.indexOf(p)
+      if (i === -1) {
+        t.fail("unexpected file found", {file: p})
+      } else {
+        t.pass(p)
+        expected.splice(i, 1)
+      }
+    })
+    .on("close", function () {
+      t.notOk(expected.length, "all expected files should be seen")
+      t.end()
+    })
+})
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js
new file mode 100644 (file)
index 0000000..a9ede59
--- /dev/null
@@ -0,0 +1,51 @@
+// ignore most things
+var IgnoreFile = require("../")
+
+// set the ignores just for this test
+var c = require("./common.js")
+c.ignores(
+  { ".ignore": ["*", "a", "c", "!a/b/c/.abc", "!/c/b/a/cba"]
+  , "a/.ignore": [ "!*", ".ignore" ] // unignore everything
+  , "a/a/.ignore": [ "*" ] // re-ignore everything
+  , "a/b/.ignore": [ "*", "!/c/.abc" ] // original unignore
+  , "a/c/.ignore": [ "*" ] // ignore everything again
+  , "c/b/a/.ignore": [ "!cba", "!.cba", "!/a{bc,cb}" ]
+  })
+
+// the only files we expect to see
+var expected =
+  [ "/a"
+  , "/a/a"
+  , "/a/b"
+  , "/a/b/c"
+  , "/a/b/c/.abc"
+  , "/a/c"
+  , "/c"
+  , "/c/b"
+  , "/c/b/a"
+  , "/c/b/a/cba"
+  , "/c/b/a/.cba"
+  , "/c/b/a/abc"
+  , "/c/b/a/acb" ]
+
+require("tap").test("basic ignore rules", function (t) {
+  t.pass("start")
+
+  IgnoreFile({ path: __dirname + "/fixtures"
+             , ignoreFiles: [".ignore"] })
+    .on("child", function (e) {
+      var p = e.path.substr(e.root.path.length)
+      var i = expected.indexOf(p)
+      if (i === -1) {
+        console.log("not ok "+p)
+        t.fail("unexpected file found", {found: p})
+      } else {
+        t.pass(p)
+        expected.splice(i, 1)
+      }
+    })
+    .on("close", function () {
+      t.deepEqual(expected, [], "all expected files should be seen")
+      t.end()
+    })
+})
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js
new file mode 100644 (file)
index 0000000..5812354
--- /dev/null
@@ -0,0 +1,38 @@
+// ignore most things
+var IgnoreFile = require("../")
+
+// set the ignores just for this test
+var c = require("./common.js")
+c.ignores({ ".ignore": ["*", "a", "c", "!a/b/c/.abc", "!/c/b/a/cba"] })
+
+// the only files we expect to see
+var expected =
+  [ "/a/b/c/.abc"
+  , "/a"
+  , "/a/b"
+  , "/a/b/c"
+  , "/c/b/a/cba"
+  , "/c"
+  , "/c/b"
+  , "/c/b/a" ]
+
+require("tap").test("basic ignore rules", function (t) {
+  t.pass("start")
+
+  IgnoreFile({ path: __dirname + "/fixtures"
+             , ignoreFiles: [".ignore"] })
+    .on("child", function (e) {
+      var p = e.path.substr(e.root.path.length)
+      var i = expected.indexOf(p)
+      if (i === -1) {
+        t.fail("unexpected file found", {f: p})
+      } else {
+        t.pass(p)
+        expected.splice(i, 1)
+      }
+    })
+    .on("close", function () {
+      t.notOk(expected.length, "all expected files should be seen")
+      t.end()
+    })
+})
diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js
new file mode 100644 (file)
index 0000000..82f064a
--- /dev/null
@@ -0,0 +1,10 @@
+var tap = require("tap")
+, rimraf = require("rimraf")
+, path = require("path")
+
+tap.test("remove fixtures", function (t) {
+  rimraf(path.resolve(__dirname, "fixtures"), function (er) {
+    t.ifError(er, "remove fixtures")
+    t.end()
+  })
+})
index fa46c74..edb1922 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "fstream-npm",
   "description": "fstream class for creating npm packages",
-  "version": "0.1.0",
+  "version": "0.1.1",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/fstream-npm.git"
     "inherits": ""
   },
   "license": "BSD",
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_id": "fstream-npm@0.1.0",
-  "devDependencies": {},
-  "optionalDependencies": {},
-  "engines": {
-    "node": "*"
-  },
-  "_engineSupported": true,
-  "_npmVersion": "1.1.23",
-  "_nodeVersion": "v0.7.10-pre",
-  "_defaultsLoaded": true,
+  "readme": "# fstream-npm\n\nThis is an fstream DirReader class that will read a directory and filter\nthings according to the semantics of what goes in an npm package.\n\nFor example:\n\n```javascript\n// This will print out all the files that would be included\n// by 'npm publish' or 'npm install' of this directory.\n\nvar FN = require(\"fstream-npm\")\nFN({ path: \"./\" })\n  .on(\"child\", function (e) {\n    console.error(e.path.substr(e.root.path.length + 1))\n  })\n```\n\n",
+  "_id": "fstream-npm@0.1.1",
   "_from": "fstream-npm@0.1"
 }
diff --git a/deps/npm/node_modules/glob/examples/g.js b/deps/npm/node_modules/glob/examples/g.js
new file mode 100644 (file)
index 0000000..be122df
--- /dev/null
@@ -0,0 +1,9 @@
+var Glob = require("../").Glob
+
+var pattern = "test/a/**/[cg]/../[cg]"
+console.log(pattern)
+
+var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
+  console.log("matches", matches)
+})
+console.log("after")
diff --git a/deps/npm/node_modules/glob/examples/usr-local.js b/deps/npm/node_modules/glob/examples/usr-local.js
new file mode 100644 (file)
index 0000000..327a425
--- /dev/null
@@ -0,0 +1,9 @@
+var Glob = require("../").Glob
+
+var pattern = "{./*/*,/*,/usr/local/*}"
+console.log(pattern)
+
+var mg = new Glob(pattern, {mark: true}, function (er, matches) {
+  console.log("matches", matches)
+})
+console.log("after")
diff --git a/deps/npm/node_modules/glob/test/00-setup.js b/deps/npm/node_modules/glob/test/00-setup.js
new file mode 100644 (file)
index 0000000..2b60643
--- /dev/null
@@ -0,0 +1,61 @@
+// just a little pre-run script to set up the fixtures.
+// zz-finish cleans it up
+
+var mkdirp = require("mkdirp")
+var path = require("path")
+var i = 0
+var tap = require("tap")
+var fs = require("fs")
+var rimraf = require("rimraf")
+
+var files =
+[ "a/.abcdef/x/y/z/a"
+, "a/abcdef/g/h"
+, "a/abcfed/g/h"
+, "a/b/c/d"
+, "a/bc/e/f"
+, "a/c/d/c/b"
+, "a/cb/e/f"
+]
+
+var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
+var symlinkFrom = "../.."
+
+files = files.map(function (f) {
+  return path.resolve(__dirname, f)
+})
+
+tap.test("remove fixtures", function (t) {
+  rimraf(path.resolve(__dirname, "a"), function (er) {
+    t.ifError(er, "remove fixtures")
+    t.end()
+  })
+})
+
+files.forEach(function (f) {
+  tap.test(f, function (t) {
+    var d = path.dirname(f)
+    mkdirp(d, 0755, function (er) {
+      if (er) {
+        t.fail(er)
+        return t.bailout()
+      }
+      fs.writeFile(f, "i like tests", function (er) {
+        t.ifError(er, "make file")
+        t.end()
+      })
+    })
+  })
+})
+
+tap.test("symlinky", function (t) {
+  var d = path.dirname(symlinkTo)
+  console.error("mkdirp", d)
+  mkdirp(d, 0755, function (er) {
+    t.ifError(er)
+    fs.symlink(symlinkFrom, symlinkTo, function (er) {
+      t.ifError(er, "make symlink")
+      t.end()
+    })
+  })
+})
diff --git a/deps/npm/node_modules/glob/test/bash-comparison.js b/deps/npm/node_modules/glob/test/bash-comparison.js
new file mode 100644 (file)
index 0000000..fbadc31
--- /dev/null
@@ -0,0 +1,119 @@
+// basic test
+// show that it does the same thing by default as the shell.
+var tap = require("tap")
+, child_process = require("child_process")
+
+// put more patterns here.
+, globs =
+  [
+  "test/a/*/+(c|g)/./d"
+  ,"test/a/**/[cg]/../[cg]"
+  ,"test/a/{b,c,d,e,f}/**/g"
+  ,"test/a/b/**"
+  ,"test/**/g"
+  ,"test/a/abc{fed,def}/g/h"
+  ,"test/a/abc{fed/g,def}/**/"
+  ,"test/a/abc{fed/g,def}/**///**/"
+  ,"test/**/a/**/"
+  ,"test/+(a|b|c)/a{/,bc*}/**"
+  ,"test/*/*/*/f"
+  ,"test/**/f"
+  ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
+  ,"{./*/*,/usr/local/*}"
+  ,"{/*,*}" // evil owl face!  how you taunt me!
+  ]
+, glob = require("../")
+, path = require("path")
+
+// run from the root of the project
+// this is usually where you're at anyway, but be sure.
+process.chdir(path.resolve(__dirname, ".."))
+
+function alphasort (a, b) {
+  a = a.toLowerCase()
+  b = b.toLowerCase()
+  return a > b ? 1 : a < b ? -1 : 0
+}
+
+globs.forEach(function (pattern) {
+  var echoOutput
+  tap.test(pattern, function (t) {
+    var bashPattern = pattern
+    , cmd = "shopt -s globstar && " +
+            "shopt -s extglob && " +
+            "shopt -s nullglob && " +
+            // "shopt >&2; " +
+            "eval \'for i in " + bashPattern + "; do echo $i; done\'"
+    , cp = child_process.spawn("bash", ["-c",cmd])
+    , out = []
+    , globResult
+    cp.stdout.on("data", function (c) {
+      out.push(c)
+    })
+    cp.stderr.on("data", function (c) {
+      process.stderr.write(c)
+    })
+    cp.stdout.on("close", function () {
+      echoOutput = flatten(out)
+      if (!echoOutput) echoOutput = []
+      else {
+        echoOutput = echoOutput.split(/\r*\n/).map(function (m) {
+          // Bash is a oddly inconsistent with slashes in the
+          // the results.  This implementation is a bit more
+          // normalized.  Account for this in the test results.
+          return m.replace(/\/+/g, "/").replace(/\/$/, "")
+        }).sort(alphasort).reduce(function (set, f) {
+          if (f !== set[set.length - 1]) set.push(f)
+          return set
+        }, []).sort(alphasort)
+      }
+      next()
+    })
+
+    glob(pattern, function (er, matches) {
+      // sort and unpark, just to match the shell results
+      matches = matches.map(function (m) {
+        return m.replace(/\/+/g, "/").replace(/\/$/, "")
+      }).sort(alphasort).reduce(function (set, f) {
+        if (f !== set[set.length - 1]) set.push(f)
+        return set
+      }, []).sort(alphasort)
+
+      t.ifError(er, pattern + " should not error")
+      globResult = matches
+      next()
+    })
+
+    function next () {
+      if (!echoOutput || !globResult) return
+
+      t.deepEqual(globResult, echoOutput, "should match shell")
+      t.end()
+    }
+  })
+
+  tap.test(pattern + " sync", function (t) {
+    var matches = glob.sync(pattern).map(function (m) {
+        return m.replace(/\/+/g, "/").replace(/\/$/, "")
+      }).sort(alphasort).reduce(function (set, f) {
+        if (f !== set[set.length - 1]) set.push(f)
+        return set
+      }, []).sort(alphasort)
+
+    t.deepEqual(matches, echoOutput, "should match shell")
+    t.end()
+  })
+})
+
+function flatten (chunks) {
+  var s = 0
+  chunks.forEach(function (c) { s += c.length })
+  var out = new Buffer(s)
+  s = 0
+  chunks.forEach(function (c) {
+    c.copy(out, s)
+    s += c.length
+  })
+
+  return out.toString().trim()
+}
diff --git a/deps/npm/node_modules/glob/test/cwd-test.js b/deps/npm/node_modules/glob/test/cwd-test.js
new file mode 100644 (file)
index 0000000..352c27e
--- /dev/null
@@ -0,0 +1,55 @@
+var tap = require("tap")
+
+var origCwd = process.cwd()
+process.chdir(__dirname)
+
+tap.test("changing cwd and searching for **/d", function (t) {
+  var glob = require('../')
+  var path = require('path')
+  t.test('.', function (t) {
+    glob('**/d', function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
+      t.end()
+    })
+  })
+
+  t.test('a', function (t) {
+    glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ 'b/c/d', 'c/d' ])
+      t.end()
+    })
+  })
+
+  t.test('a/b', function (t) {
+    glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ 'c/d' ])
+      t.end()
+    })
+  })
+
+  t.test('a/b/', function (t) {
+    glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ 'c/d' ])
+      t.end()
+    })
+  })
+
+  t.test('.', function (t) {
+    glob('**/d', {cwd: process.cwd()}, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
+      t.end()
+    })
+  })
+
+  t.test('cd -', function (t) {
+    process.chdir(origCwd)
+    t.end()
+  })
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/glob/test/pause-resume.js b/deps/npm/node_modules/glob/test/pause-resume.js
new file mode 100644 (file)
index 0000000..481d1aa
--- /dev/null
@@ -0,0 +1,98 @@
+// show that no match events happen while paused.
+var tap = require("tap")
+, child_process = require("child_process")
+// just some gnarly pattern with lots of matches
+, pattern = "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
+, glob = require("../")
+, Glob = glob.Glob
+, path = require("path")
+
+// run from the root of the project
+// this is usually where you're at anyway, but be sure.
+process.chdir(path.resolve(__dirname, ".."))
+
+function alphasort (a, b) {
+  a = a.toLowerCase()
+  b = b.toLowerCase()
+  return a > b ? 1 : a < b ? -1 : 0
+}
+
+function cleanResults (m) {
+  // normalize discrepancies in ordering, duplication,
+  // and ending slashes.
+  return m.map(function (m) {
+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
+  }).sort(alphasort).reduce(function (set, f) {
+    if (f !== set[set.length - 1]) set.push(f)
+    return set
+  }, []).sort(alphasort)
+}
+
+function flatten (chunks) {
+  var s = 0
+  chunks.forEach(function (c) { s += c.length })
+  var out = new Buffer(s)
+  s = 0
+  chunks.forEach(function (c) {
+    c.copy(out, s)
+    s += c.length
+  })
+
+  return out.toString().trim()
+}
+var bashResults
+tap.test("get bash output", function (t) {
+  var bashPattern = pattern
+  , cmd = "shopt -s globstar && " +
+          "shopt -s extglob && " +
+          "shopt -s nullglob && " +
+          // "shopt >&2; " +
+          "eval \'for i in " + bashPattern + "; do echo $i; done\'"
+  , cp = child_process.spawn("bash", ["-c",cmd])
+  , out = []
+  , globResult
+  cp.stdout.on("data", function (c) {
+    out.push(c)
+  })
+  cp.stderr.on("data", function (c) {
+    process.stderr.write(c)
+  })
+  cp.stdout.on("close", function () {
+    bashResults = flatten(out)
+    if (!bashResults) return t.fail("Didn't get results from bash")
+    else {
+      bashResults = cleanResults(bashResults.split(/\r*\n/))
+    }
+    t.ok(bashResults.length, "got some results")
+    t.end()
+  })
+})
+
+var globResults = []
+tap.test("use a Glob object, and pause/resume it", function (t) {
+  var g = new Glob(pattern)
+  , paused = false
+  , res = []
+
+  g.on("match", function (m) {
+    t.notOk(g.paused, "must not be paused")
+    globResults.push(m)
+    g.pause()
+    t.ok(g.paused, "must be paused")
+    setTimeout(g.resume.bind(g), 1)
+  })
+
+  g.on("end", function (matches) {
+    t.pass("reached glob end")
+    globResults = cleanResults(globResults)
+    matches = cleanResults(matches)
+    t.deepEqual(matches, globResults,
+      "end event matches should be the same as match events")
+
+    t.deepEqual(matches, bashResults,
+      "glob matches should be the same as bash results")
+
+    t.end()
+  })
+})
+
diff --git a/deps/npm/node_modules/glob/test/root-nomount.js b/deps/npm/node_modules/glob/test/root-nomount.js
new file mode 100644 (file)
index 0000000..3ac5979
--- /dev/null
@@ -0,0 +1,39 @@
+var tap = require("tap")
+
+var origCwd = process.cwd()
+process.chdir(__dirname)
+
+tap.test("changing root and searching for /b*/**", function (t) {
+  var glob = require('../')
+  var path = require('path')
+  t.test('.', function (t) {
+    glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [])
+      t.end()
+    })
+  })
+
+  t.test('a', function (t) {
+    glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
+      t.end()
+    })
+  })
+
+  t.test('root=a, cwd=a/b', function (t) {
+    glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
+      t.end()
+    })
+  })
+
+  t.test('cd -', function (t) {
+    process.chdir(origCwd)
+    t.end()
+  })
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/glob/test/root.js b/deps/npm/node_modules/glob/test/root.js
new file mode 100644 (file)
index 0000000..5ccdd0e
--- /dev/null
@@ -0,0 +1,43 @@
+var tap = require("tap")
+
+var origCwd = process.cwd()
+process.chdir(__dirname)
+
+tap.test("changing root and searching for /b*/**", function (t) {
+  var glob = require('../')
+  var path = require('path')
+  t.test('.', function (t) {
+    glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [])
+      t.end()
+    })
+  })
+
+  t.test('a', function (t) {
+    glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
+        return path.join(path.resolve('a'), m)
+      }))
+      t.end()
+    })
+  })
+
+  t.test('root=a, cwd=a/b', function (t) {
+    glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
+      t.ifError(er)
+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
+        return path.join(path.resolve('a'), m)
+      }))
+      t.end()
+    })
+  })
+
+  t.test('cd -', function (t) {
+    process.chdir(origCwd)
+    t.end()
+  })
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/glob/test/zz-cleanup.js b/deps/npm/node_modules/glob/test/zz-cleanup.js
new file mode 100644 (file)
index 0000000..e085f0f
--- /dev/null
@@ -0,0 +1,11 @@
+// remove the fixtures
+var tap = require("tap")
+, rimraf = require("rimraf")
+, path = require("path")
+
+tap.test("cleanup fixtures", function (t) {
+  rimraf(path.resolve(__dirname, "a"), function (er) {
+    t.ifError(er, "removed")
+    t.end()
+  })
+})
index ecbda31..856fc66 100644 (file)
@@ -151,14 +151,6 @@ if (constants.hasOwnProperty('O_SYMLINK') &&
 }
 
 
-// lstat on windows, missing from early 0.5 versions
-// replacing with stat isn't quite perfect, but good enough to get by.
-if (process.platform === "win32" && !process.binding("fs").lstat) {
-  fs.lstat = fs.stat
-  fs.lstatSync = fs.statSync
-}
-
-
 // lutimes implementation, or no-op
 if (!fs.lutimes) {
   if (constants.hasOwnProperty("O_SYMLINK")) {
@@ -255,6 +247,22 @@ function chownErOk (er) {
 }
 
 
+// if lchmod/lchown do not exist, then make them no-ops
+if (!fs.lchmod) {
+  fs.lchmod = function (path, mode, cb) {
+    process.nextTick(cb)
+  }
+  fs.lchmodSync = function () {}
+}
+if (!fs.lchown) {
+  fs.lchown = function (path, uid, gid, cb) {
+    process.nextTick(cb)
+  }
+  fs.lchownSync = function () {}
+}
+
+
+
 
 // on Windows, A/V software can lock the directory, causing this
 // to fail with an EACCES or EPERM if the directory contains newly
index 757d301..fe4de9e 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "graceful-fs",
   "description": "fs monkey-patching to avoid EMFILE and other problems",
-  "version": "1.1.8",
+  "version": "1.1.9",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-graceful-fs.git"
     "node": ">=0.4.0"
   },
   "devDependencies": {},
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_id": "graceful-fs@1.1.8",
-  "dependencies": {},
-  "optionalDependencies": {},
-  "_engineSupported": true,
-  "_npmVersion": "1.1.10",
-  "_nodeVersion": "v0.7.7-pre",
-  "_defaultsLoaded": true,
+  "readme": "Just like node's `fs` module, but it does an incremental back-off when\nEMFILE is encountered.\n\nUseful in asynchronous situations where one needs to try to open lots\nand lots of files.\n",
+  "_id": "graceful-fs@1.1.9",
   "_from": "graceful-fs@~1.1.1"
 }
diff --git a/deps/npm/node_modules/init-package-json/example.js b/deps/npm/node_modules/init-package-json/example.js
new file mode 100644 (file)
index 0000000..ebab729
--- /dev/null
@@ -0,0 +1,14 @@
+var init = require('./init-package-json.js')
+var path = require('path')
+var initFile = path.resolve(process.env.HOME, '.npm-init')
+var dir = process.cwd()
+
+var npm = require('npm')
+npm.load(function (er, npm) {
+  if (er) throw er
+  init(dir, initFile, npm.config.get(), function (er, data) {
+    if (er) throw er
+    console.log('written successfully')
+  })
+})
+
diff --git a/deps/npm/node_modules/init-package-json/test/basic.input b/deps/npm/node_modules/init-package-json/test/basic.input
new file mode 100644 (file)
index 0000000..b41ba50
--- /dev/null
@@ -0,0 +1,15 @@
+var assert = require('assert')
+
+exports.name = prompt('name', package.name || basename)
+exports.version = '1.2.5'
+exports.description = prompt('description', package.description)
+exports.author = 'me <em@i.l> (http://url)'
+exports.scripts = package.scripts || {}
+exports.scripts.test = 'make test'
+exports.main = package.main || 'main.js'
+exports.config = JSON.parse(JSON.stringify(config))
+try {delete exports.config.config}catch(e){}
+try {delete exports.package.config}catch(e){}
+try {delete exports.package.package}catch(e){}
+try {delete exports.config.package}catch(e){}
+exports.package = JSON.parse(JSON.stringify(package))
diff --git a/deps/npm/node_modules/init-package-json/test/basic.js b/deps/npm/node_modules/init-package-json/test/basic.js
new file mode 100644 (file)
index 0000000..e1c4486
--- /dev/null
@@ -0,0 +1,35 @@
+var tap = require('tap')
+var init = require('../')
+var rimraf = require('rimraf')
+
+tap.test('the basics', function (t) {
+  var i = __dirname + '/basic.input'
+  var dir = __dirname
+  init(dir, i, {foo:'bar'}, function (er, data) {
+    if (er) throw er
+    var expect =
+      { name: 'the-name',
+        version: '1.2.5',
+        description: 'description',
+        author: 'me <em@i.l> (http://url)',
+        scripts: { test: 'make test' },
+        main: 'main.js',
+        config: { foo: 'bar' },
+        package: {} }
+    t.same(data, expect)
+    t.end()
+  })
+  setTimeout(function () {
+    process.stdin.emit('data', 'the-name\n')
+  }, 50)
+  setTimeout(function () {
+    process.stdin.emit('data', 'description\n')
+  }, 100)
+  setTimeout(function () {
+    process.stdin.emit('data', 'yes\n')
+  }, 150)
+})
+
+tap.test('teardown', function (t) {
+  rimraf(__dirname + '/package.json', t.end.bind(t))
+})
diff --git a/deps/npm/node_modules/lockfile/test/basic.js b/deps/npm/node_modules/lockfile/test/basic.js
new file mode 100644 (file)
index 0000000..77308cd
--- /dev/null
@@ -0,0 +1,226 @@
+var test = require('tap').test
+var lockFile = require('../lockfile.js')
+var path = require('path')
+var fs = require('fs')
+
+test('setup', function (t) {
+  try { lockFile.unlockSync('basic-lock') } catch (er) {}
+  try { lockFile.unlockSync('sync-lock') } catch (er) {}
+  try { lockFile.unlockSync('never-forget') } catch (er) {}
+  try { lockFile.unlockSync('stale-lock') } catch (er) {}
+  try { lockFile.unlockSync('watch-lock') } catch (er) {}
+  try { lockFile.unlockSync('retry-lock') } catch (er) {}
+  t.end()
+})
+
+test('basic test', function (t) {
+  lockFile.check('basic-lock', function (er, locked) {
+    if (er) throw er
+    t.notOk(locked)
+    lockFile.lock('basic-lock', function (er) {
+      if (er) throw er
+      lockFile.lock('basic-lock', function (er) {
+        t.ok(er)
+        lockFile.check('basic-lock', function (er, locked) {
+          if (er) throw er
+          t.ok(locked)
+          lockFile.unlock('basic-lock', function (er) {
+            if (er) throw er
+            lockFile.check('basic-lock', function (er, locked) {
+              if (er) throw er
+              t.notOk(locked)
+              t.end()
+            })
+          })
+        })
+      })
+    })
+  })
+})
+
+test('sync test', function (t) {
+  var locked
+  locked = lockFile.checkSync('sync-lock')
+  t.notOk(locked)
+  lockFile.lockSync('sync-lock')
+  locked = lockFile.checkSync('sync-lock')
+  t.ok(locked)
+  lockFile.unlockSync('sync-lock')
+  locked = lockFile.checkSync('sync-lock')
+  t.notOk(locked)
+  t.end()
+})
+
+test('exit cleanup test', function (t) {
+  var child = require.resolve('./fixtures/child.js')
+  var node = process.execPath
+  var spawn = require('child_process').spawn
+  spawn(node, [child]).on('exit', function () {
+    setTimeout(function () {
+      var locked = lockFile.checkSync('never-forget')
+      t.notOk(locked)
+      t.end()
+    }, 100)
+  })
+})
+
+test('error exit cleanup test', function (t) {
+  var child = require.resolve('./fixtures/bad-child.js')
+  var node = process.execPath
+  var spawn = require('child_process').spawn
+  spawn(node, [child]).on('exit', function () {
+    setTimeout(function () {
+      var locked = lockFile.checkSync('never-forget')
+      t.notOk(locked)
+      t.end()
+    }, 100)
+  })
+})
+
+
+test('staleness test', function (t) {
+  lockFile.lock('stale-lock', function (er) {
+    if (er) throw er
+
+    var opts = { stale: 1 }
+    setTimeout(next, 10)
+    function next () {
+      lockFile.check('stale-lock', opts, function (er, locked) {
+        if (er) throw er
+        t.notOk(locked)
+        lockFile.lock('stale-lock', opts, function (er) {
+          if (er) throw er
+          lockFile.unlock('stale-lock', function (er) {
+            if (er) throw er
+            t.end()
+          })
+        })
+      })
+    }
+  })
+})
+
+test('staleness sync test', function (t) {
+  var opts = { stale: 1 }
+  lockFile.lockSync('stale-lock')
+  setTimeout(next, 10)
+  function next () {
+    var locked
+    locked = lockFile.checkSync('stale-lock', opts)
+    t.notOk(locked)
+    lockFile.lockSync('stale-lock', opts)
+    lockFile.unlockSync('stale-lock')
+    t.end()
+  }
+})
+
+test('watch test', function (t) {
+  var opts = { wait: 100 }
+  var fdx
+  lockFile.lock('watch-lock', function (er, fd1) {
+    if (er) throw er
+    setTimeout(unlock, 10)
+    function unlock () {
+      console.error('unlocking it')
+      lockFile.unlockSync('watch-lock')
+      // open another file, so the fd gets reused
+      // so we can know that it actually re-opened it fresh,
+      // rather than just getting the same lock as before.
+      fdx = fs.openSync('x', 'w')
+      fdy = fs.openSync('x', 'w')
+    }
+
+    // should have gotten a new fd
+    lockFile.lock('watch-lock', opts, function (er, fd2) {
+      if (er) throw er
+      t.notEqual(fd1, fd2)
+      fs.closeSync(fdx)
+      fs.closeSync(fdy)
+      fs.unlinkSync('x')
+      lockFile.unlockSync('watch-lock')
+      t.end()
+    })
+  })
+})
+
+test('retries', function (t) {
+  // next 5 opens will fail.
+  var opens = 5
+  fs._open = fs.open
+  fs.open = function (path, mode, cb) {
+    if (--opens === 0) {
+      fs.open = fs._open
+      return fs.open(path, mode, cb)
+    }
+    var er = new Error('bogus')
+    // to be, or not to be, that is the question.
+    er.code = opens % 2 ? 'EEXIST' : 'ENOENT'
+    process.nextTick(cb.bind(null, er))
+  }
+
+  lockFile.lock('retry-lock', { retries: opens }, function (er, fd) {
+    if (er) throw er
+    t.equal(opens, 0)
+    t.ok(fd)
+    lockFile.unlockSync('retry-lock')
+    t.end()
+  })
+})
+
+test('retryWait', function (t) {
+  // next 5 opens will fail.
+  var opens = 5
+  fs._open = fs.open
+  fs.open = function (path, mode, cb) {
+    if (--opens === 0) {
+      fs.open = fs._open
+      return fs.open(path, mode, cb)
+    }
+    var er = new Error('bogus')
+    // to be, or not to be, that is the question.
+    er.code = opens % 2 ? 'EEXIST' : 'ENOENT'
+    process.nextTick(cb.bind(null, er))
+  }
+
+  var opts = { retries: opens, retryWait: 100 }
+  lockFile.lock('retry-lock', opts, function (er, fd) {
+    if (er) throw er
+    t.equal(opens, 0)
+    t.ok(fd)
+    lockFile.unlockSync('retry-lock')
+    t.end()
+  })
+})
+
+test('retry sync', function (t) {
+  // next 5 opens will fail.
+  var opens = 5
+  fs._openSync = fs.openSync
+  fs.openSync = function (path, mode) {
+    if (--opens === 0) {
+      fs.openSync = fs._openSync
+      return fs.openSync(path, mode)
+    }
+    var er = new Error('bogus')
+    // to be, or not to be, that is the question.
+    er.code = opens % 2 ? 'EEXIST' : 'ENOENT'
+    throw er
+  }
+
+  var opts = { retries: opens }
+  lockFile.lockSync('retry-lock', opts)
+  t.equal(opens, 0)
+  lockFile.unlockSync('retry-lock')
+  t.end()
+})
+
+test('cleanup', function (t) {
+  try { lockFile.unlockSync('basic-lock') } catch (er) {}
+  try { lockFile.unlockSync('sync-lock') } catch (er) {}
+  try { lockFile.unlockSync('never-forget') } catch (er) {}
+  try { lockFile.unlockSync('stale-lock') } catch (er) {}
+  try { lockFile.unlockSync('watch-lock') } catch (er) {}
+  try { lockFile.unlockSync('retry-lock') } catch (er) {}
+  t.end()
+})
+
diff --git a/deps/npm/node_modules/lockfile/test/fixtures/bad-child.js b/deps/npm/node_modules/lockfile/test/fixtures/bad-child.js
new file mode 100644 (file)
index 0000000..e653045
--- /dev/null
@@ -0,0 +1,5 @@
+var lockFile = require('../../lockfile.js')
+
+lockFile.lockSync('never-forget')
+
+throw new Error('waaaaaaaaa')
diff --git a/deps/npm/node_modules/lockfile/test/fixtures/child.js b/deps/npm/node_modules/lockfile/test/fixtures/child.js
new file mode 100644 (file)
index 0000000..5b61d6c
--- /dev/null
@@ -0,0 +1,3 @@
+var lockFile = require('../../lockfile.js')
+
+lockFile.lock('never-forget', function () {})
diff --git a/deps/npm/node_modules/lru-cache/test/basic.js b/deps/npm/node_modules/lru-cache/test/basic.js
new file mode 100644 (file)
index 0000000..6af0edf
--- /dev/null
@@ -0,0 +1,171 @@
+var test = require("tap").test
+  , LRU = require("../")
+
+test("basic", function (t) {
+  var cache = new LRU(10)
+  cache.set("key", "value")
+  t.equal(cache.get("key"), "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.length, 1)
+  t.equal(cache.maxLength, 10)
+  t.end()
+})
+
+test("least recently set", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), "B")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.get("a")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
+
+test("del", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.del("a")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("maxLength", function (t) {
+  var cache = new LRU(3)
+
+  // test changing the maxLength, verify that the LRU items get dropped.
+  cache.maxLength = 100
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  cache.maxLength = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+
+  // now remove the maxLength restriction, and try again.
+  cache.maxLength = "hello"
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  // should trigger an immediate resize
+  cache.maxLength = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  t.end()
+})
+
+test("reset", function (t) {
+  var cache = new LRU(10)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.reset()
+  t.equal(cache.length, 0)
+  t.equal(cache.maxLength, 10)
+  t.equal(cache.get("a"), undefined)
+  t.equal(cache.get("b"), undefined)
+  t.end()
+})
+
+
+// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made
+// about the format/layout of the response.
+test("dump", function (t) {
+  var cache = new LRU(10)
+  var d = cache.dump();
+  t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
+  cache.set("a", "A")
+  var d = cache.dump()  // { a: { key: "a", value: "A", lu: 0 } }
+  t.ok(d.a)
+  t.equal(d.a.key, "a")
+  t.equal(d.a.value, "A")
+  t.equal(d.a.lu, 0)
+
+  cache.set("b", "B")
+  cache.get("b")
+  d = cache.dump()
+  t.ok(d.b)
+  t.equal(d.b.key, "b")
+  t.equal(d.b.value, "B")
+  t.equal(d.b.lu, 2)
+
+  t.end()
+})
+
+
+test("basic with weighed length", function (t) {
+  var cache = new LRU(100, function (item) { return item.size } )
+  cache.set("key", {val: "value", size: 50})
+  t.equal(cache.get("key").val, "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.lengthCalculator(cache.get("key")), 50)
+  t.equal(cache.length, 50)
+  t.equal(cache.maxLength, 100)
+  t.end()
+})
+
+
+test("weighed length item too large", function (t) {
+  var cache = new LRU(10, function (item) { return item.size } )
+  t.equal(cache.maxLength, 10)
+
+  // should fall out immediately
+  cache.set("key", {val: "value", size: 50})
+
+  t.equal(cache.length, 0)
+  t.equal(cache.get("key"), undefined)
+  t.end()
+})
+
+test("least recently set with weighed length", function (t) {
+  var cache = new LRU(8, function (item) { return item.length })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("c"), "CCC")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten with weighed length", function (t) {
+  var cache = new LRU(8, function (item) { return item.length })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.get("a")
+  cache.get("b")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("c"), undefined)
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("b"), "BB")
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
diff --git a/deps/npm/node_modules/minimatch/test/basic.js b/deps/npm/node_modules/minimatch/test/basic.js
new file mode 100644 (file)
index 0000000..cf1778a
--- /dev/null
@@ -0,0 +1,273 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  ; [ "http://www.bashcookbook.com/bashinfo" +
+      "/source/bash-1.14.7/tests/glob-test"
+    , ["a*", ["a", "abc", "abd", "abe"]]
+    , ["X*", ["X*"], {nonull: true}]
+
+    // allow null glob expansion
+    , ["X*", []]
+
+    // isaacs: Slightly different than bash/sh/ksh
+    // \\* is not un-escaped to literal "*" in a failed match,
+    // but it does make it get treated as a literal star
+    , ["\\*", ["\\*"], {nonull: true}]
+    , ["\\**", ["\\**"], {nonull: true}]
+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+    , ["b*/", ["bdir/"]]
+    , ["c*", ["c", "ca", "cb"]]
+    , ["**", files]
+
+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+    , "legendary larry crashes bashes"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+    , "character classes"
+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+       "bdir/", "ca", "cb", "dd", "de"]]
+    , ["a*[^c]", ["abd", "abe"]]
+    , function () { files.push("a-b", "aXb") }
+    , ["a[X-]b", ["a-b", "aXb"]]
+    , function () { files.push(".x", ".y") }
+    , ["[^a-c]*", ["d", "dd", "de"]]
+    , function () { files.push("a*b/", "a*b/ooo") }
+    , ["a\\*b/*", ["a*b/ooo"]]
+    , ["a\\*?/*", ["a*b/ooo"]]
+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+    , ["*.\\*", ["r.*"], null, ["r.*"]]
+    , ["a[b]c", ["abc"]]
+    , ["a[\\b]c", ["abc"]]
+    , ["a?c", ["abc"]]
+    , ["a\\*c", [], {null: true}, ["abc"]]
+    , ["", [""], { null: true }, [""]]
+
+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
+      "bash/tests/glob-test"
+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
+    , ["a***c", ["abc"], null, ["abc"]]
+    , ["a*****?c", ["abc"], null, ["abc"]]
+    , ["?*****??", ["abc"], null, ["abc"]]
+    , ["*****??", ["abc"], null, ["abc"]]
+    , ["?*****?c", ["abc"], null, ["abc"]]
+    , ["?***?****c", ["abc"], null, ["abc"]]
+    , ["?***?****?", ["abc"], null, ["abc"]]
+    , ["?***?****", ["abc"], null, ["abc"]]
+    , ["*******c", ["abc"], null, ["abc"]]
+    , ["*******?", ["abc"], null, ["abc"]]
+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["[-abc]", ["-"], null, ["-"]]
+    , ["[abc-]", ["-"], null, ["-"]]
+    , ["\\", ["\\"], null, ["\\"]]
+    , ["[\\\\]", ["\\"], null, ["\\"]]
+    , ["[[]", ["["], null, ["["]]
+    , ["[", ["["], null, ["["]]
+    , ["[*", ["[abc"], null, ["[abc"]]
+    , "a right bracket shall lose its special meaning and\n" +
+      "represent itself in a bracket expression if it occurs\n" +
+      "first in the list.  -- POSIX.2 2.8.3.2"
+    , ["[]]", ["]"], null, ["]"]]
+    , ["[]-]", ["]"], null, ["]"]]
+    , ["[a-\z]", ["p"], null, ["p"]]
+    , ["??**********?****?", [], { null: true }, ["abc"]]
+    , ["??**********?****c", [], { null: true }, ["abc"]]
+    , ["?************c****?****", [], { null: true }, ["abc"]]
+    , ["*c*?**", [], { null: true }, ["abc"]]
+    , ["a*****c*?**", [], { null: true }, ["abc"]]
+    , ["a********???*******", [], { null: true }, ["abc"]]
+    , ["[]", [], { null: true }, ["a"]]
+    , ["[abc", [], { null: true }, ["["]]
+
+    , "nocase tests"
+    , ["XYZ", ["xYz"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["ab*", ["ABC"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+
+    // [ pattern, [matches], MM opts, files, TAP opts]
+    , "onestar/twostar"
+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+    , ["{/?,*}", ["/a", "bb"], {null: true}
+      , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+    , "dots should not match unless requested"
+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+    // .. and . can only match patterns starting with .,
+    // even when options.dot is set.
+    , function () {
+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+      }
+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+    , ["a/*/b", ["a/c/b"], {dot:false}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+    // this also tests that changing the options needs
+    // to change the cache key, even if the pattern is
+    // the same!
+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+      , [ ".a/.d", "a/.d", "a/b"]]
+
+    , "paren sets cannot contain slashes"
+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+    // brace sets trump all else.
+    //
+    // invalid glob pattern.  fails on bash4 and bsdglob.
+    // however, in this implementation, it's easier just
+    // to do the intuitive thing, and let brace-expansion
+    // actually come before parsing any extglob patterns,
+    // like the documentation seems to say.
+    //
+    // XXX: if anyone complains about this, either fix it
+    // or tell them to grow up and stop complaining.
+    //
+    // bash/bsdglob says this:
+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+    // but we do this instead:
+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+    // test partial parsing in the presence of comment/negation chars
+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+      , {}
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+    // crazy nested {,,} and *(||) tests.
+    , function () {
+        files = [ "a", "b", "c", "d"
+                , "ab", "ac", "ad"
+                , "bc", "cb"
+                , "bc,d", "c,db", "c,d"
+                , "d)", "(b|c", "*(b|c"
+                , "b|c", "b|cc", "cb|c"
+                , "x(a|b|c)", "x(a|c)"
+                , "(a|b|c)", "(a|c)"]
+      }
+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+    // a
+    // *(b|c)
+    // *(b|d)
+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+    // test various flag settings.
+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+      , { noext: true } ]
+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+    // begin channelling Boole and deMorgan...
+    , "negation tests"
+    , function () {
+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+      }
+
+    // anything that is NOT a* matches.
+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+    // anything that IS !a* matches.
+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+    // anything that IS a* matches
+    , ["!!a*", ["a!b"]]
+
+    // anything that is NOT !a* matches
+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+    // negation nestled within a pattern
+    , function () {
+        files = [ "foo.js"
+                , "foo.bar"
+                // can't match this one without negative lookbehind.
+                , "foo.js.js"
+                , "blar.js"
+                , "foo."
+                , "boo.js.boo" ]
+      }
+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+    ].forEach(function (c) {
+      if (typeof c === "function") return c()
+      if (typeof c === "string") return t.comment(c)
+
+      var pattern = c[0]
+        , expect = c[1].sort(alpha)
+        , options = c[2] || {}
+        , f = c[3] || files
+        , tapOpts = c[4] || {}
+
+      // options.debug = true
+      var m = new mm.Minimatch(pattern, options)
+      var r = m.makeRe()
+      tapOpts.re = String(r) || JSON.stringify(r)
+      tapOpts.files = JSON.stringify(f)
+      tapOpts.pattern = pattern
+      tapOpts.set = m.set
+      tapOpts.negated = m.negate
+
+      var actual = mm.match(f, pattern, options)
+      actual.sort(alpha)
+
+      t.equivalent( actual, expect
+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                  , tapOpts )
+    })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}
diff --git a/deps/npm/node_modules/minimatch/test/brace-expand.js b/deps/npm/node_modules/minimatch/test/brace-expand.js
new file mode 100644 (file)
index 0000000..7ee278a
--- /dev/null
@@ -0,0 +1,33 @@
+var tap = require("tap")
+  , minimatch = require("../")
+
+tap.test("brace expansion", function (t) {
+  // [ pattern, [expanded] ]
+  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
+      , [ "abxy"
+        , "abxz"
+        , "acdxy"
+        , "acdxz"
+        , "acexy"
+        , "acexz"
+        , "afhxy"
+        , "afhxz"
+        , "aghxy"
+        , "aghxz" ] ]
+    , [ "a{1..5}b"
+      , [ "a1b"
+        , "a2b"
+        , "a3b"
+        , "a4b"
+        , "a5b" ] ]
+    , [ "a{b}c", ["a{b}c"] ]
+  ].forEach(function (tc) {
+    var p = tc[0]
+      , expect = tc[1]
+    t.equivalent(minimatch.braceExpand(p), expect, p)
+  })
+  console.error("ending")
+  t.end()
+})
+
+
diff --git a/deps/npm/node_modules/minimatch/test/caching.js b/deps/npm/node_modules/minimatch/test/caching.js
new file mode 100644 (file)
index 0000000..0fec4b0
--- /dev/null
@@ -0,0 +1,14 @@
+var Minimatch = require("../minimatch.js").Minimatch
+var tap = require("tap")
+tap.test("cache test", function (t) {
+  var mm1 = new Minimatch("a?b")
+  var mm2 = new Minimatch("a?b")
+  t.equal(mm1, mm2, "should get the same object")
+  // the lru should drop it after 100 entries
+  for (var i = 0; i < 100; i ++) {
+    new Minimatch("a"+i)
+  }
+  mm2 = new Minimatch("a?b")
+  t.notEqual(mm1, mm2, "cache should have dropped")
+  t.end()
+})
diff --git a/deps/npm/node_modules/minimatch/test/defaults.js b/deps/npm/node_modules/minimatch/test/defaults.js
new file mode 100644 (file)
index 0000000..25f1f60
--- /dev/null
@@ -0,0 +1,274 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  ; [ "http://www.bashcookbook.com/bashinfo" +
+      "/source/bash-1.14.7/tests/glob-test"
+    , ["a*", ["a", "abc", "abd", "abe"]]
+    , ["X*", ["X*"], {nonull: true}]
+
+    // allow null glob expansion
+    , ["X*", []]
+
+    // isaacs: Slightly different than bash/sh/ksh
+    // \\* is not un-escaped to literal "*" in a failed match,
+    // but it does make it get treated as a literal star
+    , ["\\*", ["\\*"], {nonull: true}]
+    , ["\\**", ["\\**"], {nonull: true}]
+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+    , ["b*/", ["bdir/"]]
+    , ["c*", ["c", "ca", "cb"]]
+    , ["**", files]
+
+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+    , "legendary larry crashes bashes"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+    , "character classes"
+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+       "bdir/", "ca", "cb", "dd", "de"]]
+    , ["a*[^c]", ["abd", "abe"]]
+    , function () { files.push("a-b", "aXb") }
+    , ["a[X-]b", ["a-b", "aXb"]]
+    , function () { files.push(".x", ".y") }
+    , ["[^a-c]*", ["d", "dd", "de"]]
+    , function () { files.push("a*b/", "a*b/ooo") }
+    , ["a\\*b/*", ["a*b/ooo"]]
+    , ["a\\*?/*", ["a*b/ooo"]]
+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+    , ["*.\\*", ["r.*"], null, ["r.*"]]
+    , ["a[b]c", ["abc"]]
+    , ["a[\\b]c", ["abc"]]
+    , ["a?c", ["abc"]]
+    , ["a\\*c", [], {null: true}, ["abc"]]
+    , ["", [""], { null: true }, [""]]
+
+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
+      "bash/tests/glob-test"
+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
+    , ["a***c", ["abc"], null, ["abc"]]
+    , ["a*****?c", ["abc"], null, ["abc"]]
+    , ["?*****??", ["abc"], null, ["abc"]]
+    , ["*****??", ["abc"], null, ["abc"]]
+    , ["?*****?c", ["abc"], null, ["abc"]]
+    , ["?***?****c", ["abc"], null, ["abc"]]
+    , ["?***?****?", ["abc"], null, ["abc"]]
+    , ["?***?****", ["abc"], null, ["abc"]]
+    , ["*******c", ["abc"], null, ["abc"]]
+    , ["*******?", ["abc"], null, ["abc"]]
+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["[-abc]", ["-"], null, ["-"]]
+    , ["[abc-]", ["-"], null, ["-"]]
+    , ["\\", ["\\"], null, ["\\"]]
+    , ["[\\\\]", ["\\"], null, ["\\"]]
+    , ["[[]", ["["], null, ["["]]
+    , ["[", ["["], null, ["["]]
+    , ["[*", ["[abc"], null, ["[abc"]]
+    , "a right bracket shall lose its special meaning and\n" +
+      "represent itself in a bracket expression if it occurs\n" +
+      "first in the list.  -- POSIX.2 2.8.3.2"
+    , ["[]]", ["]"], null, ["]"]]
+    , ["[]-]", ["]"], null, ["]"]]
+    , ["[a-\z]", ["p"], null, ["p"]]
+    , ["??**********?****?", [], { null: true }, ["abc"]]
+    , ["??**********?****c", [], { null: true }, ["abc"]]
+    , ["?************c****?****", [], { null: true }, ["abc"]]
+    , ["*c*?**", [], { null: true }, ["abc"]]
+    , ["a*****c*?**", [], { null: true }, ["abc"]]
+    , ["a********???*******", [], { null: true }, ["abc"]]
+    , ["[]", [], { null: true }, ["a"]]
+    , ["[abc", [], { null: true }, ["["]]
+
+    , "nocase tests"
+    , ["XYZ", ["xYz"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["ab*", ["ABC"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+
+    // [ pattern, [matches], MM opts, files, TAP opts]
+    , "onestar/twostar"
+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+    , ["{/?,*}", ["/a", "bb"], {null: true}
+      , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+    , "dots should not match unless requested"
+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+    // .. and . can only match patterns starting with .,
+    // even when options.dot is set.
+    , function () {
+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+      }
+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+    , ["a/*/b", ["a/c/b"], {dot:false}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+    // this also tests that changing the options needs
+    // to change the cache key, even if the pattern is
+    // the same!
+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+      , [ ".a/.d", "a/.d", "a/b"]]
+
+    , "paren sets cannot contain slashes"
+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+    // brace sets trump all else.
+    //
+    // invalid glob pattern.  fails on bash4 and bsdglob.
+    // however, in this implementation, it's easier just
+    // to do the intuitive thing, and let brace-expansion
+    // actually come before parsing any extglob patterns,
+    // like the documentation seems to say.
+    //
+    // XXX: if anyone complains about this, either fix it
+    // or tell them to grow up and stop complaining.
+    //
+    // bash/bsdglob says this:
+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+    // but we do this instead:
+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+    // test partial parsing in the presence of comment/negation chars
+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+      , {}
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+    // crazy nested {,,} and *(||) tests.
+    , function () {
+        files = [ "a", "b", "c", "d"
+                , "ab", "ac", "ad"
+                , "bc", "cb"
+                , "bc,d", "c,db", "c,d"
+                , "d)", "(b|c", "*(b|c"
+                , "b|c", "b|cc", "cb|c"
+                , "x(a|b|c)", "x(a|c)"
+                , "(a|b|c)", "(a|c)"]
+      }
+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+    // a
+    // *(b|c)
+    // *(b|d)
+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+    // test various flag settings.
+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+      , { noext: true } ]
+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+    // begin channelling Boole and deMorgan...
+    , "negation tests"
+    , function () {
+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+      }
+
+    // anything that is NOT a* matches.
+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+    // anything that IS !a* matches.
+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+    // anything that IS a* matches
+    , ["!!a*", ["a!b"]]
+
+    // anything that is NOT !a* matches
+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+    // negation nestled within a pattern
+    , function () {
+        files = [ "foo.js"
+                , "foo.bar"
+                // can't match this one without negative lookbehind.
+                , "foo.js.js"
+                , "blar.js"
+                , "foo."
+                , "boo.js.boo" ]
+      }
+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+    ].forEach(function (c) {
+      if (typeof c === "function") return c()
+      if (typeof c === "string") return t.comment(c)
+
+      var pattern = c[0]
+        , expect = c[1].sort(alpha)
+        , options = c[2] || {}
+        , f = c[3] || files
+        , tapOpts = c[4] || {}
+
+      // options.debug = true
+      var Class = mm.defaults(options).Minimatch
+      var m = new Class(pattern, {})
+      var r = m.makeRe()
+      tapOpts.re = String(r) || JSON.stringify(r)
+      tapOpts.files = JSON.stringify(f)
+      tapOpts.pattern = pattern
+      tapOpts.set = m.set
+      tapOpts.negated = m.negate
+
+      var actual = mm.match(f, pattern, options)
+      actual.sort(alpha)
+
+      t.equivalent( actual, expect
+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                  , tapOpts )
+    })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}
diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js b/deps/npm/node_modules/mkdirp/examples/pow.js
new file mode 100644 (file)
index 0000000..e692421
--- /dev/null
@@ -0,0 +1,6 @@
+var mkdirp = require('mkdirp');
+
+mkdirp('/tmp/foo/bar/baz', function (err) {
+    if (err) console.error(err)
+    else console.log('pow!')
+});
diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js.orig b/deps/npm/node_modules/mkdirp/examples/pow.js.orig
new file mode 100644 (file)
index 0000000..7741462
--- /dev/null
@@ -0,0 +1,6 @@
+var mkdirp = require('mkdirp');
+
+mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
+    if (err) console.error(err)
+    else console.log('pow!')
+});
diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js.rej b/deps/npm/node_modules/mkdirp/examples/pow.js.rej
new file mode 100644 (file)
index 0000000..81e7f43
--- /dev/null
@@ -0,0 +1,19 @@
+--- examples/pow.js
++++ examples/pow.js
+@@ -1,6 +1,15 @@
+-var mkdirp = require('mkdirp').mkdirp;
++var mkdirp = require('../').mkdirp,
++    mkdirpSync = require('../').mkdirpSync;
+ mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
+     if (err) console.error(err)
+     else console.log('pow!')
+ });
++
++try {
++  mkdirpSync('/tmp/bar/foo/baz', 0755);
++  console.log('double pow!');
++}
++catch (ex) {
++  console.log(ex);
++}
\ No newline at end of file
diff --git a/deps/npm/node_modules/mkdirp/test/chmod.js b/deps/npm/node_modules/mkdirp/test/chmod.js
new file mode 100644 (file)
index 0000000..520dcb8
--- /dev/null
@@ -0,0 +1,38 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+var ps = [ '', 'tmp' ];
+
+for (var i = 0; i < 25; i++) {
+    var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    ps.push(dir);
+}
+
+var file = ps.join('/');
+
+test('chmod-pre', function (t) {
+    var mode = 0744
+    mkdirp(file, mode, function (er) {
+        t.ifError(er, 'should not error');
+        fs.stat(file, function (er, stat) {
+            t.ifError(er, 'should exist');
+            t.ok(stat && stat.isDirectory(), 'should be directory');
+            t.equal(stat && stat.mode & 0777, mode, 'should be 0744');
+            t.end();
+        });
+    });
+});
+
+test('chmod', function (t) {
+    var mode = 0755
+    mkdirp(file, mode, function (er) {
+        t.ifError(er, 'should not error');
+        fs.stat(file, function (er, stat) {
+            t.ifError(er, 'should exist');
+            t.ok(stat && stat.isDirectory(), 'should be directory');
+            t.end();
+        });
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/clobber.js b/deps/npm/node_modules/mkdirp/test/clobber.js
new file mode 100644 (file)
index 0000000..0eb7099
--- /dev/null
@@ -0,0 +1,37 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+var ps = [ '', 'tmp' ];
+
+for (var i = 0; i < 25; i++) {
+    var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    ps.push(dir);
+}
+
+var file = ps.join('/');
+
+// a file in the way
+var itw = ps.slice(0, 3).join('/');
+
+
+test('clobber-pre', function (t) {
+    console.error("about to write to "+itw)
+    fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.');
+
+    fs.stat(itw, function (er, stat) {
+        t.ifError(er)
+        t.ok(stat && stat.isFile(), 'should be file')
+        t.end()
+    })
+})
+
+test('clobber', function (t) {
+    t.plan(2);
+    mkdirp(file, 0755, function (err) {
+        t.ok(err);
+        t.equal(err.code, 'ENOTDIR');
+        t.end();
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/mkdirp.js b/deps/npm/node_modules/mkdirp/test/mkdirp.js
new file mode 100644 (file)
index 0000000..b07cd70
--- /dev/null
@@ -0,0 +1,28 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('woo', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    
+    var file = '/tmp/' + [x,y,z].join('/');
+    
+    mkdirp(file, 0755, function (err) {
+        if (err) t.fail(err);
+        else path.exists(file, function (ex) {
+            if (!ex) t.fail('file not created')
+            else fs.stat(file, function (err, stat) {
+                if (err) t.fail(err)
+                else {
+                    t.equal(stat.mode & 0777, 0755);
+                    t.ok(stat.isDirectory(), 'target not a directory');
+                    t.end();
+                }
+            })
+        })
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/perm.js b/deps/npm/node_modules/mkdirp/test/perm.js
new file mode 100644 (file)
index 0000000..23a7abb
--- /dev/null
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('async perm', function (t) {
+    t.plan(2);
+    var file = '/tmp/' + (Math.random() * (1<<30)).toString(16);
+    
+    mkdirp(file, 0755, function (err) {
+        if (err) t.fail(err);
+        else path.exists(file, function (ex) {
+            if (!ex) t.fail('file not created')
+            else fs.stat(file, function (err, stat) {
+                if (err) t.fail(err)
+                else {
+                    t.equal(stat.mode & 0777, 0755);
+                    t.ok(stat.isDirectory(), 'target not a directory');
+                    t.end();
+                }
+            })
+        })
+    });
+});
+
+test('async root perm', function (t) {
+    mkdirp('/tmp', 0755, function (err) {
+        if (err) t.fail(err);
+        t.end();
+    });
+    t.end();
+});
diff --git a/deps/npm/node_modules/mkdirp/test/perm_sync.js b/deps/npm/node_modules/mkdirp/test/perm_sync.js
new file mode 100644 (file)
index 0000000..f685f60
--- /dev/null
@@ -0,0 +1,39 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('sync perm', function (t) {
+    t.plan(2);
+    var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json';
+    
+    mkdirp.sync(file, 0755);
+    path.exists(file, function (ex) {
+        if (!ex) t.fail('file not created')
+        else fs.stat(file, function (err, stat) {
+            if (err) t.fail(err)
+            else {
+                t.equal(stat.mode & 0777, 0755);
+                t.ok(stat.isDirectory(), 'target not a directory');
+                t.end();
+            }
+        })
+    });
+});
+
+test('sync root perm', function (t) {
+    t.plan(1);
+    
+    var file = '/tmp';
+    mkdirp.sync(file, 0755);
+    path.exists(file, function (ex) {
+        if (!ex) t.fail('file not created')
+        else fs.stat(file, function (err, stat) {
+            if (err) t.fail(err)
+            else {
+                t.ok(stat.isDirectory(), 'target not a directory');
+                t.end();
+            }
+        })
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/race.js b/deps/npm/node_modules/mkdirp/test/race.js
new file mode 100644 (file)
index 0000000..96a0447
--- /dev/null
@@ -0,0 +1,41 @@
+var mkdirp = require('../').mkdirp;
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('race', function (t) {
+    t.plan(4);
+    var ps = [ '', 'tmp' ];
+    
+    for (var i = 0; i < 25; i++) {
+        var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+        ps.push(dir);
+    }
+    var file = ps.join('/');
+    
+    var res = 2;
+    mk(file, function () {
+        if (--res === 0) t.end();
+    });
+    
+    mk(file, function () {
+        if (--res === 0) t.end();
+    });
+    
+    function mk (file, cb) {
+        mkdirp(file, 0755, function (err) {
+            if (err) t.fail(err);
+            else path.exists(file, function (ex) {
+                if (!ex) t.fail('file not created')
+                else fs.stat(file, function (err, stat) {
+                    if (err) t.fail(err)
+                    else {
+                        t.equal(stat.mode & 0777, 0755);
+                        t.ok(stat.isDirectory(), 'target not a directory');
+                        if (cb) cb();
+                    }
+                })
+            })
+        });
+    }
+});
diff --git a/deps/npm/node_modules/mkdirp/test/rel.js b/deps/npm/node_modules/mkdirp/test/rel.js
new file mode 100644 (file)
index 0000000..7985824
--- /dev/null
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('rel', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    
+    var cwd = process.cwd();
+    process.chdir('/tmp');
+    
+    var file = [x,y,z].join('/');
+    
+    mkdirp(file, 0755, function (err) {
+        if (err) t.fail(err);
+        else path.exists(file, function (ex) {
+            if (!ex) t.fail('file not created')
+            else fs.stat(file, function (err, stat) {
+                if (err) t.fail(err)
+                else {
+                    process.chdir(cwd);
+                    t.equal(stat.mode & 0777, 0755);
+                    t.ok(stat.isDirectory(), 'target not a directory');
+                    t.end();
+                }
+            })
+        })
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/return.js b/deps/npm/node_modules/mkdirp/test/return.js
new file mode 100644 (file)
index 0000000..bce68e5
--- /dev/null
@@ -0,0 +1,25 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('return value', function (t) {
+    t.plan(4);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+    var file = '/tmp/' + [x,y,z].join('/');
+
+    // should return the first dir created.
+    // By this point, it would be profoundly surprising if /tmp didn't
+    // already exist, since every other test makes things in there.
+    mkdirp(file, function (err, made) {
+        t.ifError(err);
+        t.equal(made, '/tmp/' + x);
+        mkdirp(file, function (err, made) {
+          t.ifError(err);
+          t.equal(made, null);
+        });
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/return_sync.js b/deps/npm/node_modules/mkdirp/test/return_sync.js
new file mode 100644 (file)
index 0000000..7c222d3
--- /dev/null
@@ -0,0 +1,24 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('return value', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+    var file = '/tmp/' + [x,y,z].join('/');
+
+    // should return the first dir created.
+    // By this point, it would be profoundly surprising if /tmp didn't
+    // already exist, since every other test makes things in there.
+    // Note that this will throw on failure, which will fail the test.
+    var made = mkdirp.sync(file);
+    t.equal(made, '/tmp/' + x);
+
+    // making the same file again should have no effect.
+    made = mkdirp.sync(file);
+    t.equal(made, null);
+});
diff --git a/deps/npm/node_modules/mkdirp/test/root.js b/deps/npm/node_modules/mkdirp/test/root.js
new file mode 100644 (file)
index 0000000..97ad7a2
--- /dev/null
@@ -0,0 +1,18 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('root', function (t) {
+    // '/' on unix, 'c:/' on windows.
+    var file = path.resolve('/');
+
+    mkdirp(file, 0755, function (err) {
+        if (err) throw err
+        fs.stat(file, function (er, stat) {
+            if (er) throw er
+            t.ok(stat.isDirectory(), 'target is a directory');
+            t.end();
+        })
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/sync.js b/deps/npm/node_modules/mkdirp/test/sync.js
new file mode 100644 (file)
index 0000000..7530cad
--- /dev/null
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('sync', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+    var file = '/tmp/' + [x,y,z].join('/');
+
+    try {
+        mkdirp.sync(file, 0755);
+    } catch (err) {
+        t.fail(err);
+        return t.end();
+    }
+
+    path.exists(file, function (ex) {
+        if (!ex) t.fail('file not created')
+        else fs.stat(file, function (err, stat) {
+            if (err) t.fail(err)
+            else {
+                t.equal(stat.mode & 0777, 0755);
+                t.ok(stat.isDirectory(), 'target not a directory');
+                t.end();
+            }
+        });
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/umask.js b/deps/npm/node_modules/mkdirp/test/umask.js
new file mode 100644 (file)
index 0000000..64ccafe
--- /dev/null
@@ -0,0 +1,28 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('implicit mode from umask', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    
+    var file = '/tmp/' + [x,y,z].join('/');
+    
+    mkdirp(file, function (err) {
+        if (err) t.fail(err);
+        else path.exists(file, function (ex) {
+            if (!ex) t.fail('file not created')
+            else fs.stat(file, function (err, stat) {
+                if (err) t.fail(err)
+                else {
+                    t.equal(stat.mode & 0777, 0777 & (~process.umask()));
+                    t.ok(stat.isDirectory(), 'target not a directory');
+                    t.end();
+                }
+            })
+        })
+    });
+});
diff --git a/deps/npm/node_modules/mkdirp/test/umask_sync.js b/deps/npm/node_modules/mkdirp/test/umask_sync.js
new file mode 100644 (file)
index 0000000..35bd5cb
--- /dev/null
@@ -0,0 +1,32 @@
+var mkdirp = require('../');
+var path = require('path');
+var fs = require('fs');
+var test = require('tap').test;
+
+test('umask sync modes', function (t) {
+    t.plan(2);
+    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
+
+    var file = '/tmp/' + [x,y,z].join('/');
+
+    try {
+        mkdirp.sync(file);
+    } catch (err) {
+        t.fail(err);
+        return t.end();
+    }
+
+    path.exists(file, function (ex) {
+        if (!ex) t.fail('file not created')
+        else fs.stat(file, function (err, stat) {
+            if (err) t.fail(err)
+            else {
+                t.equal(stat.mode & 0777, (0777 & (~process.umask())));
+                t.ok(stat.isDirectory(), 'target not a directory');
+                t.end();
+            }
+        });
+    });
+});
index 7b7d621..1f0f2c0 100755 (executable)
@@ -25,8 +25,9 @@ if (prog.todo.length === 0) {
 }
 
 log.info('it worked if it ends with', 'ok')
+log.verbose('cli', process.argv)
 log.info('using', 'node-gyp@%s', prog.version)
-log.info('using', 'node@%s', process.versions.node)
+log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, process.arch)
 
 
 /**
@@ -61,7 +62,7 @@ function run () {
   if (prog.todo.length === 0) {
     // done!
     completed = true
-    log.info('done', 'ok')
+    log.info('ok')
     return
   }
   var command = prog.todo.shift()
index c29b97e..f38ec99 100644 (file)
@@ -6,19 +6,20 @@ module.exports = exports = build
  */
 
 var fs = require('graceful-fs')
+  , rm = require('rimraf')
   , path = require('path')
   , glob = require('glob')
   , log = require('npmlog')
   , which = require('which')
   , mkdirp = require('mkdirp')
   , win = process.platform == 'win32'
-  , openbsd = process.platform == 'openbsd'
 
 exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
 
 function build (gyp, argv, callback) {
 
-  var makeCommand = openbsd ? 'gmake' : 'make'
+  var makeCommand = gyp.opts.make || process.env.MAKE
+    || (process.platform.indexOf('bsd') != -1 ? 'gmake' : 'make')
   var command = win ? 'msbuild' : makeCommand
     , buildDir = path.resolve('build')
     , configPath = path.resolve(buildDir, 'config.gypi')
@@ -216,7 +217,47 @@ function build (gyp, argv, callback) {
     if (signal) {
       return callback(new Error('`' + command + '` got signal: ' + signal))
     }
+    //symlinkNodeBinding()
     callback()
   }
 
+  function symlinkNodeBinding () {
+    var buildDir = path.join('build', buildType, '*.node')
+    log.verbose('globbing for files', buildDir)
+    glob(buildDir, function (err, nodeFiles) {
+      if (err) return callback(err)
+      function link () {
+        var file = nodeFiles.shift()
+        if (!file) {
+          // no more files to link... done!
+          return callback()
+        }
+        var dest = path.join('build', path.basename(file))
+        log.info('symlink', 'creating link %j pointing to %j', file, dest)
+        var rel = path.relative('build', file)
+        log.verbose('symlink data', rel)
+        fs.symlink(rel, dest, 'file', function (err) {
+          if (err) {
+            if (err.code === 'EEXIST') {
+              log.verbose('destination already exists; deleting', dest)
+              rm(dest, function (err) {
+                if (err) return callback(err)
+                log.verbose('delete successful; trying symlink again')
+                nodeFiles.unshift(file)
+                link()
+              })
+            } else {
+              callback(err)
+            }
+            return
+          }
+          // process the next file, if any
+          link()
+        })
+      }
+      // start linking
+      link()
+    })
+  }
+
 }
index 1cdd320..3dbd418 100644 (file)
@@ -47,7 +47,7 @@ function configure (gyp, argv, callback) {
   // We're gonna glob C:\python2*
   function guessPython () {
     log.verbose('could not find "' + python + '". guessing location')
-    var rootDir = process.env.HOMEDRIVE || process.env.SystemDrive || 'C:\\'
+    var rootDir = process.env.SystemDrive || 'C:\\'
     if (rootDir[rootDir.length - 1] !== '\\') {
       rootDir += '\\'
     }
@@ -72,11 +72,21 @@ function configure (gyp, argv, callback) {
       if (err) {
         return callback(err)
       }
+      log.verbose('check python version', '`python --version` returned: %j', stderr)
       var version = stderr.trim().replace(/[^\d\.]+/g, '')
-      if (semver.lt(version, '3.0.0')) {
+      var numDots = 0
+      version.replace(/\./g, function () {
+        numDots++
+      })
+      while (numDots < 2) {
+        version += '.0'
+        numDots++
+      }
+      log.verbose('check python version', 'using version %j to check', version)
+      if (semver.gte(version, '2.5.0') && semver.lt(version, '3.0.0')) {
         getNodeDir()
       } else {
-        failPython3()
+        failPythonVersion(version)
       }
     })
   }
@@ -86,10 +96,10 @@ function configure (gyp, argv, callback) {
           + '", you can set the PYTHON env variable.'))
   }
 
-  function failPython3 () {
+  function failPythonVersion (badVersion) {
     callback(new Error('Python executable "' + python
-          + '" is Python 3, which is not supported.\n'
-          + 'You can set the PYTHON env variable to point to a Python 2 interpreter.'))
+          + '" is v' + badVersion + ', which is not supported by gyp.\n'
+          + 'You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.'))
   }
 
   function getNodeDir () {
index 4932b8f..2bcc72b 100644 (file)
@@ -8,6 +8,7 @@ exports.usage = 'Install node development files for the specified node version.'
  */
 
 var fs = require('graceful-fs')
+  , osenv = require('osenv')
   , tar = require('tar')
   , rm = require('rimraf')
   , path = require('path')
@@ -41,7 +42,7 @@ function install (gyp, argv, callback) {
 
   // Determine which node dev files version we are installing
   var versionStr = argv[0] || gyp.opts.target || process.version
-  log.verbose('install', 'input version string', versionStr)
+  log.verbose('install', 'input version string %j', versionStr)
 
   // parse the version to normalize and ensure it's valid
   var version = semver.parse(versionStr)
@@ -57,11 +58,16 @@ function install (gyp, argv, callback) {
     return callback(new Error('Minimum target version is `0.6.0` or greater. Got: ' + versionStr))
   }
 
-  // 0.x.y-pre versions are not published yet. Use previous release.
+  // 0.x.y-pre versions are not published yet and cannot be installed. Bail.
   if (version[5] === '-pre') {
-    version[3] = +version[3] - 1
-    version[5] = null
-    log.verbose('-pre version detected, adjusting patch version')
+    log.verbose('detected "pre" node version', versionStr)
+    if (gyp.opts.nodedir) {
+      log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir)
+      callback()
+    } else {
+      callback(new Error('"pre" versions of node cannot be installed, use the --nodedir flag instead'))
+    }
+    return
   }
 
   // flatten version into String
@@ -107,12 +113,11 @@ function install (gyp, argv, callback) {
     go()
   }
 
-  function download (url, onError) {
+  function download (url) {
     log.http('GET', url)
 
     var requestOpts = {
         uri: url
-      , onResponse: true
     }
 
     // basic support for a proxy server
@@ -124,7 +129,7 @@ function install (gyp, argv, callback) {
       log.verbose('proxy', proxyUrl)
       requestOpts.proxy = proxyUrl
     }
-    var req = request(requestOpts, onError)
+    var req = request(requestOpts)
     req.on('response', function (res) {
       log.http(res.statusCode, url)
     })
@@ -133,181 +138,210 @@ function install (gyp, argv, callback) {
 
   function go () {
 
-  log.verbose('ensuring nodedir is created', devDir)
+    log.verbose('ensuring nodedir is created', devDir)
 
-  // first create the dir for the node dev files
-  mkdir(devDir, function (err, created) {
-    if (err) return cb(err)
-
-    if (created) {
-      log.verbose('created nodedir', created)
-    }
+    // first create the dir for the node dev files
+    mkdir(devDir, function (err, created) {
+      if (err) {
+        if (err.code == 'EACCES') {
+          // this EACCES fallback is a workaround for npm's `sudo` behavior, where
+          // it drops the permissions before invoking any child processes (like
+          // node-gyp). So what happens is the "nobody" user doesn't have
+          // permission to create the dev dir. As a fallback, make the tmpdir() be
+          // the dev dir for this installation. This is not ideal, but at least
+          // the compilation will succeed...
+          gyp.devDir = path.resolve(osenv.tmpdir(), '.node-gyp')
+          log.warn(err.code, 'user "%s" does not have permission to create dev dir "%s"', osenv.user(), devDir)
+          log.warn(err.code, 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir)
+          gyp.commands.install(argv, cb)
+        } else {
+          cb(err)
+        }
+        return
+      }
 
-    // now download the node tarball
-    var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
-      , badDownload = false
-      , extractCount = 0
-      , gunzip = zlib.createGunzip()
-      , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })
-
-    // checks if a file to be extracted from the tarball is valid.
-    // only .h header files and the gyp files get extracted
-    function isValid () {
-      var name = this.path.substring(devDir.length + 1)
-      var isValid = valid(name)
-      if (name === '' && this.type === 'Directory') {
-        // the first directory entry is ok
-        return true
+      if (created) {
+        log.verbose('created nodedir', created)
       }
-      if (isValid) {
-        log.verbose('extracted file from tarball', name)
-        extractCount++
-      } else {
-        // invalid
-        log.silly('ignoring from tarball', name)
+
+      // now download the node tarball
+      var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
+        , badDownload = false
+        , extractCount = 0
+        , gunzip = zlib.createGunzip()
+        , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })
+
+      // checks if a file to be extracted from the tarball is valid.
+      // only .h header files and the gyp files get extracted
+      function isValid () {
+        var name = this.path.substring(devDir.length + 1)
+        var isValid = valid(name)
+        if (name === '' && this.type === 'Directory') {
+          // the first directory entry is ok
+          return true
+        }
+        if (isValid) {
+          log.verbose('extracted file from tarball', name)
+          extractCount++
+        } else {
+          // invalid
+          log.silly('ignoring from tarball', name)
+        }
+        return isValid
       }
-      return isValid
-    }
 
-    gunzip.on('error', cb)
-    extracter.on('error', cb)
-    extracter.on('end', afterTarball)
+      gunzip.on('error', cb)
+      extracter.on('error', cb)
+      extracter.on('end', afterTarball)
 
-    // download the tarball, gunzip and extract!
-    var req = download(tarballUrl, downloadError)
-      .pipe(gunzip)
-      .pipe(extracter)
+      // download the tarball, gunzip and extract!
+      var req = download(tarballUrl)
 
-    // something went wrong downloading the tarball?
-    function downloadError (err, res) {
-      if (err || res.statusCode != 200) {
+      // something went wrong downloading the tarball?
+      req.on('error', function (err) {
         badDownload = true
-        cb(err || new Error(res.statusCode + ' status code downloading tarball'))
-      }
-    }
+        cb(err)
+      })
 
-    // invoked after the tarball has finished being extracted
-    function afterTarball () {
-      if (badDownload) return
-      if (extractCount === 0) {
-        return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
-      }
-      log.verbose('tarball', 'done parsing tarball')
-      var async = 0
+      req.on('close', function () {
+        if (extractCount === 0) {
+          cb(new Error('Connection closed while downloading tarball file'))
+        }
+      })
 
-      if (isLegacy) {
-        // copy over the files from the `legacy` dir
-        async++
-        copyLegacy(deref)
-      }
+      req.on('response', function (res) {
+        if (res.statusCode !== 200) {
+          badDownload = true
+          cb(new Error(res.statusCode + ' status code downloading tarball'))
+          return
+        }
+        // start unzipping and untaring
+        req.pipe(gunzip).pipe(extracter)
+      })
 
-      if (win) {
-        // need to download node.lib
-        async++
-        downloadNodeLib(deref)
-      }
+      // invoked after the tarball has finished being extracted
+      function afterTarball () {
+        if (badDownload) return
+        if (extractCount === 0) {
+          return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
+        }
+        log.verbose('tarball', 'done parsing tarball')
+        var async = 0
 
-      // write the "installVersion" file
-      async++
-      var installVersionPath = path.resolve(devDir, 'installVersion')
-      fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)
+        if (isLegacy) {
+          // copy over the files from the `legacy` dir
+          async++
+          copyLegacy(deref)
+        }
 
-      if (async === 0) {
-        // no async tasks required
-        cb()
-      }
+        if (win) {
+          // need to download node.lib
+          async++
+          downloadNodeLib(deref)
+        }
 
-      function deref (err) {
-        if (err) return cb(err)
-        --async || cb()
-      }
-    }
+        // write the "installVersion" file
+        async++
+        var installVersionPath = path.resolve(devDir, 'installVersion')
+        fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)
 
-    function copyLegacy (done) {
-      // legacy versions of node (< 0.8) require the legacy files to be copied
-      // over since they contain many bugfixes from the current node build system
-      log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version)
+        if (async === 0) {
+          // no async tasks required
+          cb()
+        }
 
-      var legacyDir = path.resolve(__dirname, '..', 'legacy')
-      log.verbose('legacy', 'using "legacy" dir', legacyDir)
-      log.verbose('legacy', 'copying to "dev" dir', devDir)
+        function deref (err) {
+          if (err) return cb(err)
+          --async || cb()
+        }
+      }
 
-      var reader = fstream.Reader({ path: legacyDir, type: 'Directory' })
-      var writer = fstream.Writer({ path: devDir, type: 'Directory' })
+      function copyLegacy (done) {
+        // legacy versions of node (< 0.8) require the legacy files to be copied
+        // over since they contain many bugfixes from the current node build system
+        log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version)
 
-      reader.on('entry', function onEntry (entry) {
-        log.verbose('legacy', 'reading entry:', entry.path)
-        entry.on('entry', onEntry)
-      })
+        var legacyDir = path.resolve(__dirname, '..', 'legacy')
+        log.verbose('legacy', 'using "legacy" dir', legacyDir)
+        log.verbose('legacy', 'copying to "dev" dir', devDir)
 
-      reader.on('error', done)
-      writer.on('error', done)
+        var reader = fstream.Reader({ path: legacyDir, type: 'Directory' })
+        var writer = fstream.Writer({ path: devDir, type: 'Directory' })
 
-      // Like `cp -rpf`
-      reader.pipe(writer)
+        reader.on('entry', function onEntry (entry) {
+          log.verbose('legacy', 'reading entry:', entry.path)
+          entry.on('entry', onEntry)
+        })
 
-      reader.on('end', done)
-    }
+        reader.on('error', done)
+        writer.on('error', done)
 
-    function downloadNodeLib (done) {
-      log.verbose('on Windows; need to download `node.lib`...')
-      var dir32 = path.resolve(devDir, 'ia32')
-        , dir64 = path.resolve(devDir, 'x64')
-        , nodeLibPath32 = path.resolve(dir32, 'node.lib')
-        , nodeLibPath64 = path.resolve(dir64, 'node.lib')
-        , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib'
-        , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib'
-
-      log.verbose('32-bit node.lib dir', dir32)
-      log.verbose('64-bit node.lib dir', dir64)
-      log.verbose('`node.lib` 32-bit url', nodeLibUrl32)
-      log.verbose('`node.lib` 64-bit url', nodeLibUrl64)
-
-      var async = 2
-      mkdir(dir32, function (err) {
-        if (err) return done(err)
-        log.verbose('streaming 32-bit node.lib to:', nodeLibPath32)
-
-        var req = download(nodeLibUrl32)
-        req.on('error', done)
-        req.on('response', function (res) {
-          if (res.statusCode !== 200) {
-            done(new Error(res.statusCode + ' status code downloading 32-bit node.lib'))
-          }
-        })
-        req.on('end', function () {
-          --async || done()
-        })
+        // Like `cp -rpf`
+        reader.pipe(writer)
 
-        var ws = fs.createWriteStream(nodeLibPath32)
-        ws.on('error', cb)
-        req.pipe(ws)
-      })
-      mkdir(dir64, function (err) {
-        if (err) return done(err)
-        log.verbose('streaming 64-bit node.lib to:', nodeLibPath64)
-
-        var req = download(nodeLibUrl64)
-        req.on('error', done)
-        req.on('response', function (res) {
-          if (res.statusCode !== 200) {
-            done(new Error(res.statusCode + ' status code downloading 64-bit node.lib'))
-          }
+        reader.on('end', done)
+      }
+
+      function downloadNodeLib (done) {
+        log.verbose('on Windows; need to download `node.lib`...')
+        var dir32 = path.resolve(devDir, 'ia32')
+          , dir64 = path.resolve(devDir, 'x64')
+          , nodeLibPath32 = path.resolve(dir32, 'node.lib')
+          , nodeLibPath64 = path.resolve(dir64, 'node.lib')
+          , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib'
+          , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib'
+
+        log.verbose('32-bit node.lib dir', dir32)
+        log.verbose('64-bit node.lib dir', dir64)
+        log.verbose('`node.lib` 32-bit url', nodeLibUrl32)
+        log.verbose('`node.lib` 64-bit url', nodeLibUrl64)
+
+        var async = 2
+        mkdir(dir32, function (err) {
+          if (err) return done(err)
+          log.verbose('streaming 32-bit node.lib to:', nodeLibPath32)
+
+          var req = download(nodeLibUrl32)
+          req.on('error', done)
+          req.on('response', function (res) {
+            if (res.statusCode !== 200) {
+              done(new Error(res.statusCode + ' status code downloading 32-bit node.lib'))
+              return
+            }
+
+            var ws = fs.createWriteStream(nodeLibPath32)
+            ws.on('error', cb)
+            req.pipe(ws)
+          })
+          req.on('end', function () {
+            --async || done()
+          })
         })
-        req.on('end', function () {
-          --async || done()
+        mkdir(dir64, function (err) {
+          if (err) return done(err)
+          log.verbose('streaming 64-bit node.lib to:', nodeLibPath64)
+
+          var req = download(nodeLibUrl64)
+          req.on('error', done)
+          req.on('response', function (res) {
+            if (res.statusCode !== 200) {
+              done(new Error(res.statusCode + ' status code downloading 64-bit node.lib'))
+              return
+            }
+
+            var ws = fs.createWriteStream(nodeLibPath64)
+            ws.on('error', cb)
+            req.pipe(ws)
+          })
+          req.on('end', function () {
+            --async || done()
+          })
         })
+      } // downloadNodeLib()
 
-        var ws = fs.createWriteStream(nodeLibPath64)
-        ws.on('error', cb)
-        req.pipe(ws)
-      })
-    }
-
-
-  })
+    }) // mkdir()
 
-  }
+  } // go()
 
   /**
    * Checks if a given filename is "valid" for this installation.
index 61e9dd1..9b22825 100644 (file)
@@ -72,16 +72,17 @@ proto.package = require('../package')
  */
 
 proto.configDefs = {
-    help: Boolean    // everywhere
-  , arch: String     // 'configure'
-  , debug: Boolean   // 'build'
+    help: Boolean     // everywhere
+  , arch: String      // 'configure'
+  , debug: Boolean    // 'build'
   , directory: String // bin
+  , make: String      // 'build'
   , msvs_version: String // 'configure'
-  , ensure: Boolean  // 'install'
-  , solution: String // 'build' (windows only)
-  , proxy: String // 'install'
-  , nodedir: String // 'configure'
-  , loglevel: String // everywhere
+  , ensure: Boolean   // 'install'
+  , solution: String  // 'build' (windows only)
+  , proxy: String     // 'install'
+  , nodedir: String   // 'configure'
+  , loglevel: String  // everywhere
 }
 
 /**
index f3fc686..07c9178 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "node-gyp",
-  "description": "`node-gyp` is a cross-platform command-line tool written in Node.js for compiling",
+  "description": "Node.js native addon build tool",
   "keywords": [
     "native",
     "addon",
@@ -10,7 +10,7 @@
     "bindings",
     "gyp"
   ],
-  "version": "0.5.2",
+  "version": "0.5.8",
   "installVersion": 9,
   "author": {
     "name": "Nathan Rajlich",
@@ -34,6 +34,7 @@
     "mkdirp": "0.3",
     "nopt": "1",
     "npmlog": "0",
+    "osenv": "0",
     "request": "2.9",
     "rimraf": "2",
     "semver": "1",
@@ -44,9 +45,9 @@
     "node": ">= 0.6.0"
   },
   "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n  * On Unix:\n    * `python`\n    * `make`\n    * A proper C/C++ compiler toolchain, like GCC\n  * On Windows:\n    * [Python][windows-python] ([`v2.7.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n    * Microsoft Visual C++ ([Express][msvc] version works well)\n      * For 64-bit builds of node and native modules you will _also_ need the [Windows 7 64-bit SDK][win7sdk]\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n  \"targets\": [\n    {\n      \"target_name\": \"binding\",\n      \"sources\": [ \"src/binding.cc\" ]\n    }\n  ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * ['\"binding.gyp\" files out in the wild' wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n * `build` - Invokes `make`/`msbuild.exe` and builds the native addon\n * `clean` - Removes any generated project files and the `out` dir\n * `configure` - Generates project build files for the current platform\n * `rebuild` - Runs \"clean\", \"configure\" and \"build\" all at once\n * `install` - Installs node development files for the given version.\n * `list` - Lists the currently installed node development file versions\n * `remove` - Removes a node development files for a given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n",
-  "_id": "node-gyp@0.5.2",
+  "_id": "node-gyp@0.5.8",
   "dist": {
-    "shasum": "7410e3dd9d950592ee80d09c7e5ef22286f79c0f"
+    "shasum": "2e6cdb28159c9bdd3fe484c7db81f119ee17e594"
   },
-  "_from": "node-gyp@0.5.2"
+  "_from": "node-gyp@~0.5"
 }
index 673789f..c7bc21e 100644 (file)
@@ -6,24 +6,34 @@ module.exports = RegClient
 var fs = require('fs')
 , url = require('url')
 , path = require('path')
+, CouchLogin = require('couch-login')
 , npmlog
 
 try {
   npmlog = require("npmlog")
 } catch (er) {
   npmlog = { error: noop, warn: noop, info: noop,
-             verbose: noop, silly: noop, http: silly,
+             verbose: noop, silly: noop, http: noop,
              pause: noop, resume: noop }
 }
 
 function noop () {}
 
 function RegClient (options) {
-  // a registry url must be provided.
-  var registry = url.parse(options.registry)
-  if (!registry.protocol) throw new Error(
-    'Invalid registry: ' + registry.url)
-  this.registry = registry.href
+  // if provided, then the registry needs to be a url.
+  // if it's not provided, then we're just using the cache only.
+  var registry = options.registry
+  if (registry) {
+    registry = url.parse(registry)
+    if (!registry.protocol) throw new Error(
+      'Invalid registry: ' + registry.url)
+    this.registry = registry.href
+    if (this.registry.slice(-1) !== '/') {
+      this.registry += '/'
+    }
+  } else {
+    this.registry = null
+  }
 
   this.retries = options.retries || 2
   this.retryFactor = options.retryFactor || 10
@@ -41,7 +51,25 @@ function RegClient (options) {
     a = a.split(":")
     this.username = a.shift()
     this.password = a.join(":")
+  } else {
+    this.username = options.username
+    this.password = options.password
+
+    // if username and password are set, but auth isn't, use them.
+    if (this.username && this.password) {
+      var a = this.username + ":" + this.password
+      this.auth = new Buffer(a, "utf8").toString("base64")
+    }
+  }
+
+  if (this.auth && !this.alwaysAuth && this.registry) {
+    // if we're always authing, then we just send the
+    // user/pass on every thing.  otherwise, create a
+    // session, and use that.
+    this.token = options.token
+    this.couchLogin = new CouchLogin(this.registry, this.token)
   }
+
   this.email = options.email || null
   this.defaultTag = options.tag || "latest"
 
index b56fefc..835eb4c 100644 (file)
@@ -15,6 +15,8 @@ function get (uri, timeout, nofollow, staleOk, cb) {
   timeout = Math.min(timeout, this.cacheMax)
   timeout = Math.max(timeout, this.cacheMin)
 
+  if (!this.registry) timeout = Infinity
+
   if ( process.env.COMP_CWORD !== undefined
     && process.env.COMP_LINE !== undefined
     && process.env.COMP_POINT !== undefined
index 1c6eb35..384b0d8 100644 (file)
@@ -13,6 +13,9 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   if (typeof cb_ !== "function") cb_ = etag, etag = null
   if (typeof cb_ !== "function") cb_ = what, what = null
 
+  if (!this.registry) return cb(new Error(
+    "No registry url provided: " + method + " " + where))
+
   // Since there are multiple places where an error could occur,
   // don't let the cb be called more than once.
   var errState = null
@@ -29,11 +32,12 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   var registry = this.registry
 
   var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/
-    , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
-    , authRequired = (what || this.alwaysAuth)
-                      && !where.match(adduserNew)
-                   || where.match(adduserChange)
-                   || method === "DELETE"
+  , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
+  , nu = where.match(adduserNew)
+  , uc = where.match(adduserChange)
+  , isUpload = what || this.alwaysAuth
+  , isDel = method === "DELETE"
+  , authRequired = isUpload && !nu || uc || isDel
 
   // resolve to a full url on the registry
   if (!where.match(/^https?:\/\//)) {
@@ -58,20 +62,39 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   }
 
   var remote = url.parse(where)
-    , auth = authRequired && this.auth
-
-  if (authRequired && !auth && this.username && this.password) {
-    var a = this.username + ":" + this.password
-    a = new Buffer(a, "utf8").toString("base64")
-    auth = this.auth = a
+  , auth = this.auth
+
+  if (authRequired && !this.alwaysAuth) {
+    var couch = this.couchLogin
+    , token = couch && (this.token || couch.token)
+    , validToken = token && couch.valid(token)
+
+    if (!validToken) token = null
+    else this.token = token
+
+    if (couch && !token) {
+      // login to get a valid token
+      var a = { name: this.username, password: this.password }
+      var args = arguments
+      return this.couchLogin.login(a, function (er, cr, data) {
+        if (er || !couch.valid(couch.token)) {
+          er = er || new Error('login error')
+          return cb(er, cr, data)
+        }
+        this.token = this.couchLogin.token
+        return regRequest.call(this, method, where, what, etag, nofollow, cb_)
+      }.bind(this))
+    }
   }
 
-  if (authRequired && !auth) {
+  // now we either have a valid token, or an auth.
+
+  if (authRequired && !auth && !token) {
     return cb(new Error(
       "Cannot insert data into the registry without auth"))
   }
 
-  if (auth) {
+  if (auth && !token) {
     remote.auth = new Buffer(auth, "base64").toString("utf8")
   }
 
@@ -87,7 +110,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   operation.attempt(function (currentAttempt) {
     self.log.info("retry", "registry request attempt " + currentAttempt
         + " at " + (new Date()).toLocaleTimeString())
-    makeRequest.call(self, method, remote, where, what, etag, nofollow
+    makeRequest.call(self, method, remote, where, what, etag, nofollow, token
                      , function (er, parsed, raw, response) {
       // Only retry on 408, 5xx or no `response`.
       var statusCode = response && response.statusCode
@@ -101,7 +124,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   })
 }
 
-function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
+function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
   var cbCalled = false
   function cb () {
     if (cbCalled) return
@@ -112,7 +135,6 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
   var opts = { url: remote
              , method: method
              , ca: this.ca
-             , follow: false
              , strictSSL: this.strictSSL }
     , headers = opts.headers = {}
   if (etag) {
@@ -120,6 +142,10 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) {
     headers[method === "GET" ? "if-none-match" : "if-match"] = etag
   }
 
+  if (tok) {
+    headers.cookie = 'AuthSession=' + tok.AuthSession
+  }
+
   headers.accept = "application/json"
 
   headers["user-agent"] = this.userAgent
index 08ecd7e..47b6dc4 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "npm-registry-client",
   "description": "Client for the npm registry",
-  "version": "0.0.8",
+  "version": "0.0.10",
   "repository": {
     "url": "git://github.com/isaacs/npm-registry-client"
   },
@@ -24,6 +24,7 @@
     "mkdirp": "~0.3.3",
     "rimraf": "~2.0.1",
     "retry": "0.6.0",
+    "couch-login": "~0.1.6",
     "npmlog": ""
   },
   "devDependencies": {
@@ -34,6 +35,6 @@
   },
   "license": "BSD",
   "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n  // error is an error if there was a problem.\n  // data is the parsed data object\n  // raw is the json string\n  // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n  Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n  certificates.  Default = `true`\n* `userAgent` {String} User agent header to send.  Default =\n  `\"node/{process.version}\"`\n* `log` {Object} The logger to use.  Defaults to `require(\"npmlog\")` if\n  that works, otherwise logs are disabled.\n* `retries` {Number} Number of times to retry on GET failures.\n  Default=2\n* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10\n* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.\n  Default=10000 (10 seconds)\n* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n  Default=60000 (60 seconds)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body.  Objects\n  that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n  * `error` {Error | null}\n  * `data` {Object} the parsed data object\n  * `raw` {String} the json\n  * `res` {Response Object} response from couch\n\nMake a request to the registry.  All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n  before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n  to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder.  However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n  versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry.  When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment.  Mostly used by `client.publish()`.\n",
-  "_id": "npm-registry-client@0.0.8",
+  "_id": "npm-registry-client@0.0.10",
   "_from": "npm-registry-client@0"
 }
diff --git a/deps/npm/node_modules/npm-registry-client/test/00-setup.js b/deps/npm/node_modules/npm-registry-client/test/00-setup.js
new file mode 100644 (file)
index 0000000..747768f
--- /dev/null
@@ -0,0 +1,10 @@
+var tap = require('tap')
+var rimraf = require('rimraf')
+
+tap.test('setup', function (t) {
+  rimraf(__dirname + '/fixtures/cache', function (er) {
+    if (er) throw er
+    t.pass('cache cleaned')
+    t.end()
+  })
+})
diff --git a/deps/npm/node_modules/npm-registry-client/test/adduser-new.js b/deps/npm/node_modules/npm-registry-client/test/adduser-new.js
new file mode 100644 (file)
index 0000000..a0fee04
--- /dev/null
@@ -0,0 +1,51 @@
+var tap = require('tap')
+var server = require('./fixtures/server.js')
+var RC = require('../')
+var client = new RC({
+    cache: __dirname + '/fixtures/cache'
+  , registry: 'http://localhost:' + server.port })
+
+var userdata =
+{ name: 'username',
+  email: 'i@izs.me',
+  _id: 'org.couchdb.user:username',
+  type: 'user',
+  roles: [],
+  date: '2012-06-07T04:11:21.591Z' }
+, password = "password"
+, username = "username"
+, crypto = require("crypto")
+, SD = require('string_decoder').StringDecoder
+, decoder = new SD
+
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
+
+tap.test("create new user account", function (t) {
+  server.expect("/-/user/org.couchdb.user:username", function (req, res) {
+    t.equal(req.method, "PUT")
+    var b = ""
+    req.on("data", function (d) {
+      b += decoder.write(d)
+    })
+
+    req.on("end", function () {
+      var o = JSON.parse(b)
+      var salt = o.salt
+      userdata.salt = salt
+      userdata.password_sha = sha(password + salt)
+      userdata.date = o.date
+      t.deepEqual(o, userdata)
+
+      res.statusCode = 201
+      res.json({created:true})
+    })
+  })
+
+  client.adduser(username, password, "i@izs.me", function (er, data, raw, res) {
+    if (er) throw er
+    t.deepEqual(data, { created: true })
+    t.end()
+  })
+})
diff --git a/deps/npm/node_modules/npm-registry-client/test/adduser-update.js b/deps/npm/node_modules/npm-registry-client/test/adduser-update.js
new file mode 100644 (file)
index 0000000..03a1edb
--- /dev/null
@@ -0,0 +1,68 @@
+var tap = require('tap')
+var server = require('./fixtures/server.js')
+var RC = require('../')
+var client = new RC({
+    cache: __dirname + '/fixtures/cache'
+  , registry: 'http://localhost:' + server.port })
+
+var userdata =
+{ name: 'username',
+  email: 'i@izs.me',
+  _id: 'org.couchdb.user:username',
+  type: 'user',
+  roles: [],
+  _rev: "1-15aac515ac515aac515aac515aac5125"
+}
+
+, password = "password"
+, username = "username"
+, crypto = require("crypto")
+, SD = require('string_decoder').StringDecoder
+, decoder = new SD
+
+
+function sha (s) {
+  return crypto.createHash("sha1").update(s).digest("hex")
+}
+
+tap.test("update a user acct", function (t) {
+  server.expect("PUT", "/-/user/org.couchdb.user:username", function (req, res) {
+    t.equal(req.method, "PUT")
+    res.statusCode = 409
+    res.json({error: "conflict"})
+  })
+
+  server.expect("GET", "/-/user/org.couchdb.user:username", function (req, res) {
+    t.equal(req.method, "GET")
+    res.json(userdata)
+  })
+
+  server.expect("PUT", "/-/user/org.couchdb.user:username/-rev/" + userdata._rev, function (req, res) {
+    t.equal(req.method, "PUT")
+
+    var b = ""
+    req.on("data", function (d) {
+      b += decoder.write(d)
+    })
+
+    req.on("end", function () {
+      var o = JSON.parse(b)
+      var salt = o.salt
+      userdata.salt = salt
+      userdata.password_sha = sha(password + salt)
+      userdata.date = o.date
+      t.deepEqual(o, userdata)
+
+      res.statusCode = 201
+      res.json({created:true})
+    })
+  })
+
+
+
+  client.adduser(username, password, "i@izs.me", function (er, data, raw, res) {
+    if (er) throw er
+    t.deepEqual(data, { created: true })
+    t.end()
+  })
+})
diff --git a/deps/npm/node_modules/npm-registry-client/test/basic.js b/deps/npm/node_modules/npm-registry-client/test/basic.js
new file mode 100644 (file)
index 0000000..022466a
--- /dev/null
@@ -0,0 +1,32 @@
+var tap = require('tap')
+var server = require('./fixtures/server.js')
+var RC = require('../')
+var rimraf = require("rimraf")
+var client = new RC({
+    cache: __dirname + '/fixtures/cache'
+  , registry: 'http://localhost:' + server.port })
+var us = require('./fixtures/underscore/1.3.3/cache.json')
+var usroot = require("./fixtures/underscore/cache.json")
+
+tap.test("basic request", function (t) {
+  server.expect("/underscore/1.3.3", function (req, res) {
+    console.error('got a request')
+    res.json(us)
+  })
+
+  server.expect("/underscore", function (req, res) {
+    console.error('got a request')
+    res.json(usroot)
+  })
+
+  t.plan(2)
+  client.get("/underscore/1.3.3", function (er, data, raw, res) {
+    console.error("got response")
+    t.deepEqual(data, us)
+  })
+
+  client.get("/underscore", function (er, data, raw, res) {
+    console.error("got response")
+    t.deepEqual(data, usroot)
+  })
+})
diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js b/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js
new file mode 100644 (file)
index 0000000..468a89e
--- /dev/null
@@ -0,0 +1,56 @@
+// a fake registry server.
+
+var http = require('http')
+var server = http.createServer(handler)
+var port = server.port = process.env.PORT || 1337
+server.listen(port)
+
+module.exports = server
+
+server._expect = {}
+
+var expect = {}
+function handler (req, res) {
+  req.connection.setTimeout(1000)
+
+  var u = '* ' + req.url
+  , mu = req.method + ' ' + req.url
+
+  var k = server._expect[mu] ? mu : server._expect[u] ? u : null
+  if (!k) throw Error('unexpected request', req.method, req.url)
+
+  var fn = server._expect[k].shift()
+  if (!fn) throw Error('unexpected request', req.method, req.url)
+
+
+  var remain = (Object.keys(server._expect).reduce(function (s, k) {
+    return s + server._expect[k].length
+  }, 0))
+  if (remain === 0) server.close()
+  else console.error("TEST SERVER: %d reqs remain", remain)
+  console.error(Object.keys(server._expect).map(function(k) {
+    return [k, server._expect[k].length]
+  }).reduce(function (acc, kv) {
+    acc[kv[0]] = kv[1]
+    return acc
+  }, {}))
+
+  res.json = json
+  fn(req, res)
+}
+
+function json (o) {
+  this.setHeader('content-type', 'application/json')
+  this.end(JSON.stringify(o))
+}
+
+server.expect = function (method, u, fn) {
+  if (typeof u === 'function') {
+    fn = u
+    u = method
+    method = '*'
+  }
+  u = method + ' ' + u
+  server._expect[u] = server._expect[u] || []
+  server._expect[u].push(fn)
+}
diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json
new file mode 100644 (file)
index 0000000..01da300
--- /dev/null
@@ -0,0 +1 @@
+{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":"                       __                                                         \n                      /\\ \\                                                         __           \n     __  __    ___    \\_\\ \\     __   _ __   ____    ___    ___   _ __    __       /\\_\\    ____  \n    /\\ \\/\\ \\ /' _ `\\  /'_  \\  /'__`\\/\\  __\\/ ,__\\  / ___\\ / __`\\/\\  __\\/'__`\\     \\/\\ \\  /',__\\ \n    \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\  __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\  __/  __  \\ \\ \\/\\__, `\\\n     \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n      \\/___/  \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/  \\/____/\\/___/  \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n                                                                                  \\ \\____/      \n                                                                                   \\/___/\n                                                                               \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}
\ No newline at end of file
diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json
new file mode 100644 (file)
index 0000000..d899f11
--- /dev/null
@@ -0,0 +1 @@
+{"_id":"underscore","_rev":"72-47f2986bfd8e8b55068b204588bbf484","name":"underscore","description":"JavaScript's functional programming helper library.","dist-tags":{"latest":"1.3.3","stable":"1.3.3"},"versions":{"1.0.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.3","_id":"underscore@1.0.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.0.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.4","_id":"underscore@1.0.4","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.4.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.0":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.0","_id":"underscore@1.1.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.0.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.1":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.1","_id":"underscore@1.1.1","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.1.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.2":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.2","_id":"underscore@1.1.2","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.2.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.3","_id":"underscore@1.1.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.8-1","_nodeVersion":"v0.2.5","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore.js","version":"1.1.4","_id":"underscore@1.1.4","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.9","_nodeVersion":"v0.5.0-pre","dist":{"shasum":"9e82274902865625b3a6d4c315a38ffd80047dae","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.4.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.1.5":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.5","_id":"underscore@1.1.5","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.16","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"23601d62c75619998b2f0db24938102793336a56","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.5.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.6":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.6","_id":"underscore@1.1.6","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.18","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"6868da1bdd72d75285be0b4e50f228e70d001a2c","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.6.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.7":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.7","devDependencies":{},"_id":"underscore@1.1.7","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.3","_nodeVersion":"v0.4.7","_defaultsLoaded":true,"dist":{"shasum":"40bab84bad19d230096e8d6ef628bff055d83db0","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz"},"scripts":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.0","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.0","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"b32ce32c8c118caa8031c10b54c7f65ab3b557fd","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.0.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.1","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.1","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"fc5c6b0765673d92a2d4ac8b4dc0aa88702e2bd4","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.1.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.2","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"74dd40e9face84e724eb2edae945b8aedc233ba3","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.2.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.3","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"11b874da70f4683d7d48bba2b44be1e600d2f6cf","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.3.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.4":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.4","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.4","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"e8da6241aa06f64df2473bb2590b8c17c84c3c7e","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.4.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.0","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.0","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"253b2d79b7bb67943ced0fc744eb18267963ede8","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.0.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.1","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.1","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"6cb8aad0e77eb5dbbfb54b22bcd8697309cf9641","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.2","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"1b4e455089ab1d1d38ab6794ffe6cf08f764394a","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.2.tgz"},"readme":"                       __                                                         \n                      /\\ \\                                                         __           \n     __  __    ___    \\_\\ \\     __   _ __   ____    ___    ___   _ __    __       /\\_\\    ____  \n    /\\ \\/\\ \\ /' _ `\\  /'_  \\  /'__`\\/\\  __\\/ ,__\\  / ___\\ / __`\\/\\  __\\/'__`\\     \\/\\ \\  /',__\\ \n    \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\  __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\  __/  __  \\ \\ \\/\\__, `\\\n     \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n      \\/___/  \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/  \\/____/\\/___/  \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n                                                                                  \\ \\____/      \n                                                                                   \\/___/\n                                                                               \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":"                       __                                                         \n                      /\\ \\                                                         __           \n     __  __    ___    \\_\\ \\     __   _ __   ____    ___    ___   _ __    __       /\\_\\    ____  \n    /\\ \\/\\ \\ /' _ `\\  /'_  \\  /'__`\\/\\  __\\/ ,__\\  / ___\\ / __`\\/\\  __\\/'__`\\     \\/\\ \\  /',__\\ \n    \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\  __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\  __/  __  \\ \\ \\/\\__, `\\\n     \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n      \\/___/  \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/  \\/____/\\/___/  \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n                                                                                  \\ \\____/      \n                                                                                   \\/___/\n                                                                               \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"time":{"1.0.3":"2011-12-07T15:12:18.045Z","1.0.4":"2011-12-07T15:12:18.045Z","1.1.0":"2011-12-07T15:12:18.045Z","1.1.1":"2011-12-07T15:12:18.045Z","1.1.2":"2011-12-07T15:12:18.045Z","1.1.3":"2011-12-07T15:12:18.045Z","1.1.4":"2011-12-07T15:12:18.045Z","1.1.5":"2011-12-07T15:12:18.045Z","1.1.6":"2011-12-07T15:12:18.045Z","1.1.7":"2011-12-07T15:12:18.045Z","1.2.0":"2011-12-07T15:12:18.045Z","1.2.1":"2011-12-07T15:12:18.045Z","1.2.2":"2011-11-14T20:28:47.115Z","1.2.3":"2011-12-07T15:12:18.045Z","1.2.4":"2012-01-09T17:23:14.818Z","1.3.0":"2012-01-11T16:41:38.459Z","1.3.1":"2012-01-23T22:57:36.474Z","1.3.2":"2012-04-09T18:38:14.345Z","1.3.3":"2012-04-10T14:43:48.089Z"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"users":{"vesln":true,"mvolkmann":true,"lancehunt":true,"mikl":true,"linus":true,"vasc":true,"bat":true,"dmalam":true,"mbrevoort":true,"danielr":true,"rsimoes":true,"thlorenz":true}}
\ No newline at end of file
diff --git a/deps/npm/node_modules/npm-registry-client/test/retries.js b/deps/npm/node_modules/npm-registry-client/test/retries.js
new file mode 100644 (file)
index 0000000..500abf2
--- /dev/null
@@ -0,0 +1,46 @@
+var tap = require('tap')
+var server = require('./fixtures/server.js')
+var RC = require('../')
+var pkg = { _id: 'some-package@1.2.3',
+            name: 'some-package',
+            version: '1.2.3' }
+var client = new RC({
+    retries: 6
+  , retryMinTimeout: 10
+  , retryMaxTimeout: 100
+  , cache: __dirname + '/fixtures/cache'
+  , registry: 'http://localhost:' + server.port })
+
+tap.test('create new user account', function (t) {
+  // first time, return a 408
+  server.expect('GET', '/some-package/1.2.3', function (req, res) {
+    res.statusCode = 408
+    res.end('Timeout')
+  })
+  // then, slam the door in their face
+  server.expect('GET', '/some-package/1.2.3', function (req, res) {
+    res.destroy()
+  })
+  // then, blame someone else
+  server.expect('GET', '/some-package/1.2.3', function (req, res) {
+    res.statusCode = 502
+    res.end('Gateway Timeout')
+  })
+  // 'No one's home right now, come back later'
+  server.expect('GET', '/some-package/1.2.3', function (req, res) {
+    res.statusCode = 503
+    res.setHeader('retry-after', '10')
+    res.end('Come back later')
+  })
+  // finally, you may enter.
+  server.expect('GET', '/some-package/1.2.3', function (req, res) {
+    res.statusCode = 200
+    res.json(pkg)
+  })
+
+  client.get('/some-package/1.2.3', function (er, data, raw, res) {
+    if (er) throw er
+    t.deepEqual(data, pkg)
+    t.end()
+  })
+})
diff --git a/deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js b/deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js
new file mode 100644 (file)
index 0000000..35253c7
--- /dev/null
@@ -0,0 +1,10 @@
+var tap = require('tap')
+var rimraf = require('rimraf')
+
+tap.test('teardown', function (t) {
+  rimraf(__dirname + '/fixtures/cache', function (er) {
+    if (er) throw er
+    t.pass('cache cleaned')
+    t.end()
+  })
+})
diff --git a/deps/npm/node_modules/npmlog/example.js b/deps/npm/node_modules/npmlog/example.js
new file mode 100644 (file)
index 0000000..c009fb1
--- /dev/null
@@ -0,0 +1,39 @@
+var log = require('./log.js')
+
+log.heading = 'npm'
+
+console.error('log.level=silly')
+log.level = 'silly'
+log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+
+console.error('log.level=silent')
+log.level = 'silent'
+log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+
+console.error('log.level=info')
+log.level = 'info'
+log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+log.error('404', 'This is a longer\n'+
+                 'message, with some details\n'+
+                 'and maybe a stack.\n'+
+                 new Error('a 404 error').stack)
+log.addLevel('noise', 10000, {beep: true})
+log.noise(false, 'LOUD NOISES')
diff --git a/deps/npm/node_modules/npmlog/test/basic.js b/deps/npm/node_modules/npmlog/test/basic.js
new file mode 100644 (file)
index 0000000..8b5e7eb
--- /dev/null
@@ -0,0 +1,461 @@
+var tap = require('tap')
+var log = require('../')
+
+var result = []
+var logEvents = []
+var logInfoEvents = []
+var logPrefixEvents = []
+
+var util = require('util')
+
+var resultExpect =
+[ '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[7m',
+  'sill',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'silly prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[34m',
+  '\u001b[40m',
+  'verb',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'verbose prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[32m',
+  '\u001b[7m',
+  'info',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'info prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[32m',
+  'http',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'http prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[30m',
+  '\u001b[41m',
+  'WARN',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'warn prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'error prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[32m',
+  '\u001b[7m',
+  'info',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'info prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[32m',
+  'http',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'http prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[30m',
+  '\u001b[41m',
+  'WARN',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'warn prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  'error prefix',
+  '\u001b[0m',
+  ' x = {"foo":{"bar":"baz"}}\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  '404',
+  '\u001b[0m',
+  ' This is a longer\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  '404',
+  '\u001b[0m',
+  ' message, with some details\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  '404',
+  '\u001b[0m',
+  ' and maybe a stack.\n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[31m',
+  '\u001b[40m',
+  'ERR!',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u001b[35m',
+  '404',
+  '\u001b[0m',
+  ' \n',
+  '\u001b[0m',
+  '\u001b[37m',
+  '\u001b[40m',
+  'npm',
+  '\u001b[0m',
+  ' ',
+  '\u001b[0m',
+  '\u0007',
+  'noise',
+  '\u001b[0m',
+  '\u001b[35m',
+  '',
+  '\u001b[0m',
+  ' LOUD NOISES\n',
+  '\u001b[0m' ]
+
+var logPrefixEventsExpect =
+[ { id: 2,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 9,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 16,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] } ]
+
+// should be the same.
+var logInfoEventsExpect = logPrefixEventsExpect
+
+var logEventsExpect =
+[ { id: 0,
+    level: 'silly',
+    prefix: 'silly prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 1,
+    level: 'verbose',
+    prefix: 'verbose prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 2,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 3,
+    level: 'http',
+    prefix: 'http prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 4,
+    level: 'warn',
+    prefix: 'warn prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 5,
+    level: 'error',
+    prefix: 'error prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 6,
+    level: 'silent',
+    prefix: 'silent prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 7,
+    level: 'silly',
+    prefix: 'silly prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 8,
+    level: 'verbose',
+    prefix: 'verbose prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 9,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 10,
+    level: 'http',
+    prefix: 'http prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 11,
+    level: 'warn',
+    prefix: 'warn prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 12,
+    level: 'error',
+    prefix: 'error prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 13,
+    level: 'silent',
+    prefix: 'silent prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 14,
+    level: 'silly',
+    prefix: 'silly prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 15,
+    level: 'verbose',
+    prefix: 'verbose prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 16,
+    level: 'info',
+    prefix: 'info prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 17,
+    level: 'http',
+    prefix: 'http prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 18,
+    level: 'warn',
+    prefix: 'warn prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 19,
+    level: 'error',
+    prefix: 'error prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 20,
+    level: 'silent',
+    prefix: 'silent prefix',
+    message: 'x = {"foo":{"bar":"baz"}}',
+    messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] },
+  { id: 21,
+    level: 'error',
+    prefix: '404',
+    message: 'This is a longer\nmessage, with some details\nand maybe a stack.\n',
+    messageRaw: [ 'This is a longer\nmessage, with some details\nand maybe a stack.\n' ] },
+  { id: 22,
+    level: 'noise',
+    prefix: false,
+    message: 'LOUD NOISES',
+    messageRaw: [ 'LOUD NOISES' ] } ]
+
+var Stream = require('stream').Stream
+var s = new Stream()
+s.write = function (m) {
+  result.push(m)
+}
+
+s.writable = true
+s.isTTY = true
+s.end = function () {}
+
+log.stream = s
+
+log.heading = 'npm'
+
+
+tap.test('basic', function (t) {
+  log.on('log', logEvents.push.bind(logEvents))
+  log.on('log.info', logInfoEvents.push.bind(logInfoEvents))
+  log.on('info prefix', logPrefixEvents.push.bind(logPrefixEvents))
+
+  console.error('log.level=silly')
+  log.level = 'silly'
+  log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+
+  console.error('log.level=silent')
+  log.level = 'silent'
+  log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+
+  console.error('log.level=info')
+  log.level = 'info'
+  log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.info('info prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.http('http prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.error('error prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}})
+  log.error('404', 'This is a longer\n'+
+                   'message, with some details\n'+
+                   'and maybe a stack.\n')
+  log.addLevel('noise', 10000, {beep: true})
+  log.noise(false, 'LOUD NOISES')
+
+  t.deepEqual(result, resultExpect, 'result')
+  t.deepEqual(log.record, logEventsExpect, 'record')
+  t.deepEqual(logEvents, logEventsExpect, 'logEvents')
+  t.deepEqual(logInfoEvents, logInfoEventsExpect, 'logInfoEvents')
+  t.deepEqual(logPrefixEvents, logPrefixEventsExpect, 'logPrefixEvents')
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/osenv/test/unix.js b/deps/npm/node_modules/osenv/test/unix.js
new file mode 100644 (file)
index 0000000..b72eb0b
--- /dev/null
@@ -0,0 +1,76 @@
+// only run this test on windows
+// pretending to be another platform is too hacky, since it breaks
+// how the underlying system looks up module paths and runs
+// child processes, and all that stuff is cached.
+if (process.platform === 'win32') {
+  console.log('TAP Version 13\n' +
+              '1..0\n' +
+              '# Skip unix tests, this is not unix\n')
+  return
+}
+var tap = require('tap')
+
+// like unix, but funny
+process.env.USER = 'sirUser'
+process.env.HOME = '/home/sirUser'
+process.env.HOSTNAME = 'my-machine'
+process.env.TMPDIR = '/tmpdir'
+process.env.TMP = '/tmp'
+process.env.TEMP = '/temp'
+process.env.PATH = '/opt/local/bin:/usr/local/bin:/usr/bin/:bin'
+process.env.PS1 = '(o_o) $ '
+process.env.EDITOR = 'edit'
+process.env.VISUAL = 'visualedit'
+process.env.SHELL = 'zsh'
+
+
+tap.test('basic unix sanity test', function (t) {
+  var osenv = require('../osenv.js')
+
+  t.equal(osenv.user(), process.env.USER)
+  t.equal(osenv.home(), process.env.HOME)
+  t.equal(osenv.hostname(), process.env.HOSTNAME)
+  t.same(osenv.path(), process.env.PATH.split(':'))
+  t.equal(osenv.prompt(), process.env.PS1)
+  t.equal(osenv.tmpdir(), process.env.TMPDIR)
+
+  // mildly evil, but it's for a test.
+  process.env.TMPDIR = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), process.env.TMP)
+
+  process.env.TMP = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), process.env.TEMP)
+
+  process.env.TEMP = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), '/home/sirUser/tmp')
+
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  osenv.home = function () { return null }
+  t.equal(osenv.tmpdir(), '/tmp')
+
+  t.equal(osenv.editor(), 'edit')
+  process.env.EDITOR = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.editor(), 'visualedit')
+
+  process.env.VISUAL = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.editor(), 'vi')
+
+  t.equal(osenv.shell(), 'zsh')
+  process.env.SHELL = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.shell(), 'bash')
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/osenv/test/windows.js b/deps/npm/node_modules/osenv/test/windows.js
new file mode 100644 (file)
index 0000000..dd3fe80
--- /dev/null
@@ -0,0 +1,82 @@
+// only run this test on windows
+// pretending to be another platform is too hacky, since it breaks
+// how the underlying system looks up module paths and runs
+// child processes, and all that stuff is cached.
+if (process.platform !== 'win32') {
+  console.log('TAP Version 13\n' +
+              '1..0\n' +
+              '# Skip windows tests, this is not windows\n')
+  return
+}
+
+// load this before clubbing the platform name.
+var tap = require('tap')
+
+process.env.windir = 'C:\\windows'
+process.env.USERDOMAIN = 'some-domain'
+process.env.USERNAME = 'sirUser'
+process.env.USERPROFILE = 'C:\\Users\\sirUser'
+process.env.COMPUTERNAME = 'my-machine'
+process.env.TMPDIR = 'C:\\tmpdir'
+process.env.TMP = 'C:\\tmp'
+process.env.TEMP = 'C:\\temp'
+process.env.Path = 'C:\\Program Files\\;C:\\Binary Stuff\\bin'
+process.env.PROMPT = '(o_o) $ '
+process.env.EDITOR = 'edit'
+process.env.VISUAL = 'visualedit'
+process.env.ComSpec = 'some-com'
+
+tap.test('basic windows sanity test', function (t) {
+  var osenv = require('../osenv.js')
+
+  var osenv = require('../osenv.js')
+
+  t.equal(osenv.user(),
+          process.env.USERDOMAIN + '\\' + process.env.USERNAME)
+  t.equal(osenv.home(), process.env.USERPROFILE)
+  t.equal(osenv.hostname(), process.env.COMPUTERNAME)
+  t.same(osenv.path(), process.env.Path.split(';'))
+  t.equal(osenv.prompt(), process.env.PROMPT)
+  t.equal(osenv.tmpdir(), process.env.TMPDIR)
+
+  // mildly evil, but it's for a test.
+  process.env.TMPDIR = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), process.env.TMP)
+
+  process.env.TMP = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), process.env.TEMP)
+
+  process.env.TEMP = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.tmpdir(), 'C:\\Users\\sirUser\\temp')
+
+  process.env.TEMP = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  osenv.home = function () { return null }
+  t.equal(osenv.tmpdir(), 'C:\\windows\\temp')
+
+  t.equal(osenv.editor(), 'edit')
+  process.env.EDITOR = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.editor(), 'visualedit')
+
+  process.env.VISUAL = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.editor(), 'notepad.exe')
+
+  t.equal(osenv.shell(), 'some-com')
+  process.env.ComSpec = ''
+  delete require.cache[require.resolve('../osenv.js')]
+  var osenv = require('../osenv.js')
+  t.equal(osenv.shell(), 'cmd')
+
+  t.end()
+})
diff --git a/deps/npm/node_modules/read-installed/test/basic.js b/deps/npm/node_modules/read-installed/test/basic.js
new file mode 100644 (file)
index 0000000..0f83320
--- /dev/null
@@ -0,0 +1,34 @@
+var readInstalled = require("../read-installed.js")
+var util = require("util")
+console.error("testing")
+
+var called = 0
+readInstalled(process.cwd(), function (er, map) {
+  console.error(called ++)
+  if (er) return console.error(er.stack || er.message)
+  cleanup(map)
+  console.error(util.inspect(map, true, 10, true))
+})
+
+var seen = []
+function cleanup (map) {
+  if (seen.indexOf(map) !== -1) return
+  seen.push(map)
+  for (var i in map) switch (i) {
+    case "_id":
+    case "path":
+    case "extraneous": case "invalid":
+    case "dependencies": case "name":
+      continue
+    default: delete map[i]
+  }
+  var dep = map.dependencies
+//    delete map.dependencies
+  if (dep) {
+//      map.dependencies = dep
+    for (var i in dep) if (typeof dep[i] === "object") {
+      cleanup(dep[i])
+    }
+  }
+  return map
+}
index e147c24..c3b3000 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "read-package-json",
-  "version": "0.0.12",
+  "version": "0.1.1",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me",
@@ -31,6 +31,6 @@
     "graceful-fs": "~1.1.8"
   },
   "readme": "# read-package-json\n\nThis is the thing that npm uses to read package.json files.  It\nvalidates some stuff, and loads some default things.\n\nIt keeps a cache of the files you've read, so that you don't end\nup reading the same package.json file multiple times.\n\nNote that if you just want to see what's literally in the package.json\nfile, you can usually do `var data = require('some-module/package.json')`.\n\nThis module is basically only needed by npm, but it's handy to see what\nnpm will see when it looks at your package.\n\n## Usage\n\n```javascript\nvar readJson = require('read-package-json')\n\nreadJson('/path/to/package.json', function (er, data) {\n  if (er) {\n    console.error(\"There was an error reading the file\")\n    return\n  }\n\n  console.error('the package data is', data)\n}\n```\n\n## readJson(file, cb)\n\n* `file` {String} The path to the package.json file\n* `cb` {Function}\n\nReads the JSON file and does the things.\n\n## `package.json` Fields\n\nSee `man 5 package.json` or `npm help json`.\n\n## readJson.log\n\nBy default this is a reference to the `npmlog` module.  But if that\nmodule can't be found, then it'll be set to just a dummy thing that does\nnothing.\n\nReplace with your own `{log,warn,error}` object for fun loggy time.\n\n## readJson.extras(file, data, cb)\n\nRun all the extra stuff relative to the file, with the parsed data.\n\nModifies the data as it does stuff.  Calls the cb when it's done.\n\n## readJson.extraSet = [fn, fn, ...]\n\nArray of functions that are called by `extras`.  Each one receives the\narguments `fn(file, data, cb)` and is expected to call `cb(er, data)`\nwhen done or when an error occurs.\n\nOrder is indeterminate, so each function should be completely\nindependent.\n\nMix and match!\n\n## readJson.cache\n\nThe `lru-cache` object that readJson uses to not read the same file over\nand over again.  See\n[lru-cache](https://github.com/isaacs/node-lru-cache) for details.\n\n## Other Relevant Files Besides `package.json`\n\nSome other files have an effect on the resulting data object, in the\nfollowing ways:\n\n### `README?(.*)`\n\nIf there is a `README` or `README.*` file present, then npm will attach\na `readme` field to the data with the contents of this file.\n\nOwing to the fact that roughly 100% of existing node modules have\nMarkdown README files, it will generally be assumed to be Markdown,\nregardless of the extension.  Please plan accordingly.\n\n### `server.js`\n\nIf there is a `server.js` file, and there is not already a\n`scripts.start` field, then `scripts.start` will be set to `node\nserver.js`.\n\n### `AUTHORS`\n\nIf there is not already a `contributors` field, then the `contributors`\nfield will be set to the contents of the `AUTHORS` file, split by lines,\nand parsed.\n\n### `bindings.gyp`\n\nIf a bindings.gyp file exists, and there is not already a\n`scripts.install` field, then the `scripts.install` field will be set to\n`node-gyp rebuild`.\n\n### `wscript`\n\nIf a wscript file exists, and there is not already a `scripts.install`\nfield, then the `scripts.install` field will be set to `node-waf clean ;\nnode-waf configure build`.\n\nNote that the `bindings.gyp` file supercedes this, since node-waf has\nbeen deprecated in favor of node-gyp.\n\n### `index.js`\n\nIf the json file does not exist, but there is a `index.js` file\npresent instead, and that file has a package comment, then it will try\nto parse the package comment, and use that as the data instead.\n\nA package comment looks like this:\n\n```javascript\n/**package\n * { \"name\": \"my-bare-module\"\n * , \"version\": \"1.2.3\"\n * , \"description\": \"etc....\" }\n **/\n\n// or...\n\n/**package\n{ \"name\": \"my-bare-module\"\n, \"version\": \"1.2.3\"\n, \"description\": \"etc....\" }\n**/\n```\n\nThe important thing is that it starts with `/**package`, and ends with\n`**/`.  If the package.json file exists, then the index.js is not\nparsed.\n\n### `{directories.man}/*.[0-9]`\n\nIf there is not already a `man` field defined as an array of files or a\nsingle file, and\nthere is a `directories.man` field defined, then that directory will\nbe searched for manpages.\n\nAny valid manpages found in that directory will be assigned to the `man`\narray, and installed in the appropriate man directory at package install\ntime, when installed globally on a Unix system.\n\n### `{directories.bin}/*`\n\nIf there is not already a `bin` field defined as a string filename or a\nhash of `<name> : <filename>` pairs, then the `directories.bin`\ndirectory will be searched and all the files within it will be linked as\nexecutables at install time.\n\nWhen installing locally, npm links bins into `node_modules/.bin`, which\nis in the `PATH` environ when npm runs scripts.  When\ninstalling globally, they are linked into `{prefix}/bin`, which is\npresumably in the `PATH` environment variable.\n",
-  "_id": "read-package-json@0.0.12",
-  "_from": "read-package-json@0"
+  "_id": "read-package-json@0.1.1",
+  "_from": "read-package-json@~0.1.0"
 }
index ec3bf70..bb1c952 100644 (file)
@@ -223,7 +223,8 @@ function readmeDescription (file, data) {
 function readme (file, data, cb) {
                 if (data.readme) return cb(null, data);
                 var dir = path.dirname(file)
-                glob("README?(.*)", { cwd: dir }, function (er, files) {
+                var globOpts = { cwd: dir, nocase: true }
+                glob("README?(.*)", globOpts, function (er, files) {
                                 if (er) return cb(er);
                                 if (!files.length) return cb()
                                 var rm = path.resolve(dir, files[0])
@@ -340,6 +341,13 @@ function typoWarn (file, data) {
                 })
                 bugsTypoWarn(file, data)
                 scriptTypoWarn(file, data)
+                noreadmeWarn(file, data)
+}
+
+function noreadmeWarn (file, data) {
+                if (data.readme) return;
+                warn(file, data, "No README.md file found!")
+                data.readme = "ERROR: No README.md file found!"
 }
 
 function checkTypo (file, data, d) {
diff --git a/deps/npm/node_modules/read-package-json/test/basic.js b/deps/npm/node_modules/read-package-json/test/basic.js
new file mode 100644 (file)
index 0000000..72ba814
--- /dev/null
@@ -0,0 +1,34 @@
+var tap = require("tap")
+var readJson = require("../")
+var path = require("path")
+var fs = require("fs")
+var readme = fs.readFileSync(path.resolve(__dirname, "../README.md"), "utf8")
+var package = require("../package.json")
+
+console.error("basic test")
+tap.test("basic test", function (t) {
+                var p = path.resolve(__dirname, "../package.json")
+                readJson(p, function (er, data) {
+                                if (er) throw er;
+                                basic_(t, data)
+                })
+})
+function basic_ (t, data) {
+                t.ok(data)
+                t.equal(data.version, package.version)
+                t.equal(data._id, data.name + "@" + data.version)
+                t.equal(data.name, package.name)
+                t.type(data.author, "object")
+                t.equal(data.readme, readme)
+                t.deepEqual(data.scripts, package.scripts)
+                t.equal(data.main, package.main)
+
+                // optional deps are folded in.
+                t.deepEqual(data.optionalDependencies,
+                            package.optionalDependencies)
+                t.has(data.dependencies, package.optionalDependencies)
+                t.has(data.dependencies, package.dependencies)
+
+                t.deepEqual(data.devDependencies, package.devDependencies)
+                t.end()
+}
diff --git a/deps/npm/node_modules/read/example/example.js b/deps/npm/node_modules/read/example/example.js
new file mode 100644 (file)
index 0000000..6800dff
--- /dev/null
@@ -0,0 +1,18 @@
+var read = require("../lib/read.js")
+
+read({prompt: "Username: ", default: "test-user" }, function (er, user) {
+  read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
+    read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) {
+      read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+        console.error({user: user,
+                       pass: pass,
+                       verify: pass2,
+                       four:four,
+                       passMatch: (pass === pass2)})
+        console.error("If the program doesn't end right now,\n"
+                     +"then you may be experiencing this bug:\n"
+                     +"https://github.com/joyent/node/issues/2257")
+      })
+    })
+  })
+})
diff --git a/deps/npm/node_modules/read/test/basic.js b/deps/npm/node_modules/read/test/basic.js
new file mode 100644 (file)
index 0000000..7f19536
--- /dev/null
@@ -0,0 +1,54 @@
+var tap = require('tap')
+var read = require('../lib/read.js')
+
+if (process.argv[2] === 'child') {
+  return child()
+}
+
+var spawn = require('child_process').spawn
+
+tap.test('basic', function (t) {
+  var child = spawn(process.execPath, [__filename, 'child'])
+  var output = ''
+  child.stdout.on('data', function (c) {
+    console.error('data %s', c)
+    output += c
+    if (output.match(/Username: \(test-user\) $/)) {
+      child.stdin.write('a user\n')
+    } else if (output.match(/Password: \(<default hidden>\) $/)) {
+      child.stdin.write('a password\n')
+    } else if (output.match(/characters: $/)) {
+      child.stdin.write('asdf\n')
+    } else if (output.match(/Password again: \(<default hidden>\) $/)) {
+      child.stdin.write('a password\n')
+    }
+  })
+
+  var result = ''
+  child.stderr.on('data', function (c) {
+    result += c
+  })
+
+  child.on('close', function () {
+    result = JSON.parse(result)
+    t.same(result, {"user":"a user","pass":"a password","verify":"a password","four":"asdf","passMatch":true})
+    t.equal(output, 'Username: (test-user) Password: (<default hidden>) Enter 4 characters: Password again: (<default hidden>) ')
+    t.end()
+  })
+})
+
+function child () {
+  read({prompt: "Username: ", default: "test-user" }, function (er, user) {
+    read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
+      read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) {
+        read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+          console.error(JSON.stringify({user: user,
+                         pass: pass,
+                         verify: pass2,
+                         four:four,
+                         passMatch: (pass === pass2)}))
+        })
+      })
+    })
+  })
+}
diff --git a/deps/npm/node_modules/request/tests/googledoodle.png b/deps/npm/node_modules/request/tests/googledoodle.png
new file mode 100644 (file)
index 0000000..f80c9c5
Binary files /dev/null and b/deps/npm/node_modules/request/tests/googledoodle.png differ
diff --git a/deps/npm/node_modules/request/tests/run.js b/deps/npm/node_modules/request/tests/run.js
new file mode 100644 (file)
index 0000000..f3a30d3
--- /dev/null
@@ -0,0 +1,39 @@
+var spawn = require('child_process').spawn
+  , exitCode = 0
+  ;
+
+var tests = [
+    'test-body.js'
+  , 'test-cookie.js'
+  , 'test-cookiejar.js'
+  , 'test-defaults.js'
+  , 'test-errors.js'
+  , 'test-headers.js'
+  , 'test-httpModule.js'
+  , 'test-https.js'
+  , 'test-https-strict.js'
+  , 'test-oauth.js'
+  , 'test-pipes.js'
+  , 'test-pool.js'
+  , 'test-proxy.js'
+  , 'test-qs.js'
+  , 'test-redirect.js'
+  , 'test-timeout.js'
+  , 'test-toJSON.js'
+  , 'test-tunnel.js'
+] 
+
+var next = function () {
+  if (tests.length === 0) process.exit(exitCode);
+  
+  var file = tests.shift()
+  console.log(file)
+  var proc = spawn('node', [ 'tests/' + file ])
+  proc.stdout.pipe(process.stdout)
+  proc.stderr.pipe(process.stderr)
+  proc.on('exit', function (code) {
+       exitCode += code || 0
+       next()
+  })
+}
+next()
diff --git a/deps/npm/node_modules/request/tests/server.js b/deps/npm/node_modules/request/tests/server.js
new file mode 100644 (file)
index 0000000..921f512
--- /dev/null
@@ -0,0 +1,82 @@
+var fs = require('fs')
+  , http = require('http')
+  , path = require('path')
+  , https = require('https')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  ;
+
+exports.createServer =  function (port) {
+  port = port || 6767
+  var s = http.createServer(function (req, resp) {
+    s.emit(req.url, req, resp);
+  })
+  s.port = port
+  s.url = 'http://localhost:'+port
+  return s;
+}
+
+exports.createSSLServer = function(port, opts) {
+  port = port || 16767
+
+  var options = { 'key' : path.join(__dirname, 'ssl', 'test.key')
+                , 'cert': path.join(__dirname, 'ssl', 'test.crt')
+                }
+  if (opts) {
+    for (var i in opts) options[i] = opts[i]
+  }
+
+  for (var i in options) {
+    options[i] = fs.readFileSync(options[i])
+  }
+
+  var s = https.createServer(options, function (req, resp) {
+    s.emit(req.url, req, resp);
+  })
+  s.port = port
+  s.url = 'https://localhost:'+port
+  return s;
+}
+
+exports.createPostStream = function (text) {
+  var postStream = new stream.Stream();
+  postStream.writeable = true;
+  postStream.readable = true;
+  setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0);
+  return postStream;
+}
+exports.createPostValidator = function (text) {
+  var l = function (req, resp) {
+    var r = '';
+    req.on('data', function (chunk) {r += chunk})
+    req.on('end', function () {
+    if (r !== text) console.log(r, text);
+    assert.equal(r, text)
+    resp.writeHead(200, {'content-type':'text/plain'})
+    resp.write('OK')
+    resp.end()
+    })
+  }
+  return l;
+}
+exports.createGetResponse = function (text, contentType) {
+  var l = function (req, resp) {
+    contentType = contentType || 'text/plain'
+    resp.writeHead(200, {'content-type':contentType})
+    resp.write(text)
+    resp.end()
+  }
+  return l;
+}
+exports.createChunkResponse = function (chunks, contentType) {
+  var l = function (req, resp) {
+    contentType = contentType || 'text/plain'
+    resp.writeHead(200, {'content-type':contentType})
+    chunks.forEach(function (chunk) {
+      resp.write(chunk)
+    })
+    resp.end()
+  }
+  return l;
+}
diff --git a/deps/npm/node_modules/request/tests/squid.conf b/deps/npm/node_modules/request/tests/squid.conf
new file mode 100644 (file)
index 0000000..0d4a3b6
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Recommended minimum configuration:
+#
+acl manager proto cache_object
+acl localhost src 127.0.0.1/32 ::1
+acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
+
+# Example rule allowing access from your local networks.
+# Adapt to list your (internal) IP networks from where browsing
+# should be allowed
+acl localnet src 10.0.0.0/8    # RFC1918 possible internal network
+acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
+acl localnet src 192.168.0.0/16        # RFC1918 possible internal network
+acl localnet src fc00::/7       # RFC 4193 local private network range
+acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
+
+acl SSL_ports port 443
+acl Safe_ports port 80         # http
+acl Safe_ports port 21         # ftp
+acl Safe_ports port 443                # https
+acl Safe_ports port 70         # gopher
+acl Safe_ports port 210                # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280                # http-mgmt
+acl Safe_ports port 488                # gss-http
+acl Safe_ports port 591                # filemaker
+acl Safe_ports port 777                # multiling http
+acl CONNECT method CONNECT
+
+#
+# Recommended minimum Access Permission configuration:
+#
+# Only allow cachemgr access from localhost
+http_access allow manager localhost
+http_access deny manager
+
+# Deny requests to certain unsafe ports
+http_access deny !Safe_ports
+
+# Deny CONNECT to other than secure SSL ports
+#http_access deny CONNECT !SSL_ports
+
+# We strongly recommend the following be uncommented to protect innocent
+# web applications running on the proxy server who think the only
+# one who can access services on "localhost" is a local user
+#http_access deny to_localhost
+
+#
+# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
+#
+
+# Example rule allowing access from your local networks.
+# Adapt localnet in the ACL section to list your (internal) IP networks
+# from where browsing should be allowed
+http_access allow localnet
+http_access allow localhost
+
+# And finally deny all other access to this proxy
+http_access deny all
+
+# Squid normally listens to port 3128
+http_port 3128
+
+# We recommend you to use at least the following line.
+hierarchy_stoplist cgi-bin ?
+
+# Uncomment and adjust the following to add a disk cache directory.
+#cache_dir ufs /usr/local/var/cache 100 16 256
+
+# Leave coredumps in the first cache dir
+coredump_dir /usr/local/var/cache
+
+# Add any of your own refresh_pattern entries above these.
+refresh_pattern ^ftp:          1440    20%     10080
+refresh_pattern ^gopher:       1440    0%      1440
+refresh_pattern -i (/cgi-bin/|\?) 0    0%      0
+refresh_pattern .              0       20%     4320
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.cnf b/deps/npm/node_modules/request/tests/ssl/ca/ca.cnf
new file mode 100644 (file)
index 0000000..425a889
--- /dev/null
@@ -0,0 +1,20 @@
+[ req ]
+default_bits           = 1024
+days                   = 3650
+distinguished_name     = req_distinguished_name
+attributes             = req_attributes
+prompt                 = no
+output_password        = password
+
+[ req_distinguished_name ]
+C                      = US
+ST                     = CA
+L                      = Oakland
+O                      = request
+OU                     = request Certificate Authority
+CN                     = requestCA
+emailAddress           = mikeal@mikealrogers.com
+
+[ req_attributes ]
+challengePassword              = password challenge
+
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.crl b/deps/npm/node_modules/request/tests/ssl/ca/ca.crl
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.crt b/deps/npm/node_modules/request/tests/ssl/ca/ca.crt
new file mode 100644 (file)
index 0000000..b4524e4
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
+ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
+A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
+ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD
+VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
+B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl
+YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4
+5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ
+5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD
+xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB
+ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm
+D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo
+88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.csr b/deps/npm/node_modules/request/tests/ssl/ca/ca.csr
new file mode 100644 (file)
index 0000000..e48c56e
--- /dev/null
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
+BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD
+ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG
+SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB
+BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0
+deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br
+44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB
+AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3
+DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj
+bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia
+SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.key b/deps/npm/node_modules/request/tests/ssl/ca/ca.key
new file mode 100644 (file)
index 0000000..a53e7f7
--- /dev/null
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,C8B5887048377F02
+
+nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q
+nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+
+GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH
+gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38
+VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3
+/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb
+4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U
+gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR
+Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh
+FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf
+dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC
+uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb
+EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.srl b/deps/npm/node_modules/request/tests/ssl/ca/ca.srl
new file mode 100644 (file)
index 0000000..17128db
--- /dev/null
@@ -0,0 +1 @@
+ADF62016AA40C9C3
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.cnf b/deps/npm/node_modules/request/tests/ssl/ca/server.cnf
new file mode 100644 (file)
index 0000000..cd1fd1e
--- /dev/null
@@ -0,0 +1,19 @@
+[ req ]
+default_bits           = 1024
+days                   = 3650
+distinguished_name     = req_distinguished_name
+attributes             = req_attributes
+prompt                 = no
+
+[ req_distinguished_name ]
+C                      = US
+ST                     = CA
+L                      = Oakland
+O                      = request
+OU                     = testing
+CN                     = testing.request.mikealrogers.com
+emailAddress           = mikeal@mikealrogers.com
+
+[ req_attributes ]
+challengePassword              = password challenge
+
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.crt b/deps/npm/node_modules/request/tests/ssl/ca/server.crt
new file mode 100644 (file)
index 0000000..efe96ce
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
+ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
+A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
+ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD
+VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
+B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx
+dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr
+ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM
+20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh
+DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj
+7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB
+kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC
+yapjN3RxZbInGhWR+jA=
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.csr b/deps/npm/node_modules/request/tests/ssl/ca/server.csr
new file mode 100644 (file)
index 0000000..a8e7595
--- /dev/null
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
+BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp
+MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq
+hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg
+cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU
+ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw
+7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A
+HidVJ/3u
+-----END CERTIFICATE REQUEST-----
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.js b/deps/npm/node_modules/request/tests/ssl/ca/server.js
new file mode 100644 (file)
index 0000000..05e21c1
--- /dev/null
@@ -0,0 +1,28 @@
+var fs = require("fs")
+var https = require("https")
+var options = { key: fs.readFileSync("./server.key")
+              , cert: fs.readFileSync("./server.crt") }
+
+var server = https.createServer(options, function (req, res) {
+  res.writeHead(200)
+  res.end()
+  server.close()
+})
+server.listen(1337)
+
+var ca = fs.readFileSync("./ca.crt")
+var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca })
+
+https.request({ host: "localhost"
+              , method: "HEAD"
+              , port: 1337
+              , headers: { host: "testing.request.mikealrogers.com" }
+              , agent: agent
+              , ca: [ ca ]
+              , path: "/" }, function (res) {
+  if (res.client.authorized) {
+    console.log("node test: OK")
+  } else {
+    throw new Error(res.client.authorizationError)
+  }
+}).end()
diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.key b/deps/npm/node_modules/request/tests/ssl/ca/server.key
new file mode 100644 (file)
index 0000000..72d8698
--- /dev/null
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg
+cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB
+iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW
+gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0
+JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ
+rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ
+0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/request/tests/ssl/npm-ca.crt b/deps/npm/node_modules/request/tests/ssl/npm-ca.crt
new file mode 100644 (file)
index 0000000..fde2fe9
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x
+IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w
+bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y
+MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV
+BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj
+YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA
+aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE
+OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz
+Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl
+y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC
+l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv
+yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl
+ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/request/tests/ssl/test.crt b/deps/npm/node_modules/request/tests/ssl/test.crt
new file mode 100644 (file)
index 0000000..b357f86
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU
+SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo
+ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx
+MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV
+BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz
+dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto
+wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj
+eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC
+AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV
+l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4
+L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE
+c7U8F6MWLQ==
+-----END CERTIFICATE-----
diff --git a/deps/npm/node_modules/request/tests/ssl/test.key b/deps/npm/node_modules/request/tests/ssl/test.key
new file mode 100644 (file)
index 0000000..b85810d
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt
+NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE
+mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB
+AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt
+Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ
+fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb
+rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6
+V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF
++WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb
+G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf
+Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ
+fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w
+kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w==
+-----END RSA PRIVATE KEY-----
diff --git a/deps/npm/node_modules/request/tests/test-body.js b/deps/npm/node_modules/request/tests/test-body.js
new file mode 100644 (file)
index 0000000..e3fc75d
--- /dev/null
@@ -0,0 +1,80 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetBuffer :
+    { resp : server.createGetResponse(new Buffer("TESTING!"))
+    , encoding: null
+    , expectBody: new Buffer("TESTING!")
+    }
+  , testGetJSON :
+     { resp : server.createGetResponse('{"test":true}', 'application/json')
+     , json : true
+     , expectBody: {"test":true}
+     }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
+
diff --git a/deps/npm/node_modules/request/tests/test-cookie.js b/deps/npm/node_modules/request/tests/test-cookie.js
new file mode 100644 (file)
index 0000000..6c6a7a7
--- /dev/null
@@ -0,0 +1,29 @@
+var Cookie = require('../vendor/cookie')
+  , assert = require('assert');
+
+var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT';
+var cookie = new Cookie(str);
+
+// test .toString()
+assert.equal(cookie.toString(), str);
+
+// test .path
+assert.equal(cookie.path, '/');
+
+// test .httpOnly
+assert.equal(cookie.httpOnly, true);
+
+// test .name
+assert.equal(cookie.name, 'Sid');
+
+// test .value
+assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="');
+
+// test .expires
+assert.equal(cookie.expires instanceof Date, true);
+
+// test .path default
+var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' });
+assert.equal(cookie.path, '/bar');
+
+console.log('All tests passed');
diff --git a/deps/npm/node_modules/request/tests/test-cookiejar.js b/deps/npm/node_modules/request/tests/test-cookiejar.js
new file mode 100644 (file)
index 0000000..76fcd71
--- /dev/null
@@ -0,0 +1,90 @@
+var Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+  , assert = require('assert');
+
+function expires(ms) {
+  return new Date(Date.now() + ms).toUTCString();
+}
+
+// test .get() expiration
+(function() {
+  var jar = new Jar;
+  var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000));
+  jar.add(cookie);
+  setTimeout(function(){
+    var cookies = jar.get({ url: 'http://foo.com/foo' });
+    assert.equal(cookies.length, 1);
+    assert.equal(cookies[0], cookie);
+    setTimeout(function(){
+      var cookies = jar.get({ url: 'http://foo.com/foo' });
+      assert.equal(cookies.length, 0);
+    }, 1000);
+  }, 5);
+})();
+
+// test .get() path support
+(function() {
+  var jar = new Jar;
+  var a = new Cookie('sid=1234; path=/');
+  var b = new Cookie('sid=1111; path=/foo/bar');
+  var c = new Cookie('sid=2222; path=/');
+  jar.add(a);
+  jar.add(b);
+  jar.add(c);
+
+  // should remove the duplicates
+  assert.equal(jar.cookies.length, 2);
+
+  // same name, same path, latter prevails
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], c);
+
+  // same name, diff path, path specifity prevails, latter prevails
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], b);
+
+  var jar = new Jar;
+  var a = new Cookie('sid=1111; path=/foo/bar');
+  var b = new Cookie('sid=1234; path=/');
+  jar.add(a);
+  jar.add(b);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], a);
+
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], b);
+
+  var jar = new Jar;
+  var a = new Cookie('sid=1111; path=/foo/bar');
+  var b = new Cookie('sid=3333; path=/foo/bar');
+  var c = new Cookie('pid=3333; path=/foo/bar');
+  var d = new Cookie('sid=2222; path=/foo/');
+  var e = new Cookie('sid=1234; path=/');
+  jar.add(a);
+  jar.add(b);
+  jar.add(c);
+  jar.add(d);
+  jar.add(e);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/bar' });
+  assert.equal(cookies.length, 2);
+  assert.equal(cookies[0], b);
+  assert.equal(cookies[1], c);
+
+  var cookies = jar.get({ url: 'http://foo.com/foo/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], d);
+
+  var cookies = jar.get({ url: 'http://foo.com/' });
+  assert.equal(cookies.length, 1);
+  assert.equal(cookies[0], e);
+})();
+
+setTimeout(function() {
+  console.log('All tests passed');
+}, 1200);
diff --git a/deps/npm/node_modules/request/tests/test-defaults.js b/deps/npm/node_modules/request/tests/test-defaults.js
new file mode 100644 (file)
index 0000000..6c8b58f
--- /dev/null
@@ -0,0 +1,68 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+s.listen(s.port, function () {
+  var counter = 0;
+  s.on('/get', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'GET')
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end('TESTING!');
+  });
+
+  // test get(string, function)
+  request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual("TESTING!", b);
+    counter += 1;
+  });
+
+  s.on('/post', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.headers['content-type'], 'application/json');
+    assert.equal(req.method, 'POST')
+    resp.writeHead(200, {'Content-Type': 'application/json'});
+    resp.end(JSON.stringify({foo:'bar'}));
+  });
+
+  // test post(string, object, function)
+  request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual('bar', b.foo);
+    counter += 1;
+  });
+
+  s.on('/del', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'DELETE')
+    resp.writeHead(200, {'Content-Type': 'application/json'});
+    resp.end(JSON.stringify({foo:'bar'}));
+  });
+
+  // test .del(string, function)
+  request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){
+    if (e) throw e;
+    assert.deepEqual('bar', b.foo);
+    counter += 1;
+  });
+
+  s.on('/head', function (req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.method, 'HEAD')
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end();
+  });
+
+  // test head.(object, function)
+  request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){
+    if (e) throw e;
+    counter += 1;
+    console.log(counter.toString() + " tests passed.")
+    s.close()
+  });
+
+})
diff --git a/deps/npm/node_modules/request/tests/test-errors.js b/deps/npm/node_modules/request/tests/test-errors.js
new file mode 100644 (file)
index 0000000..1986a59
--- /dev/null
@@ -0,0 +1,37 @@
+var server = require('./server')
+  , events = require('events')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var local = 'http://localhost:8888/asdf'
+
+try {
+  request({uri:local, body:{}})
+  assert.fail("Should have throw") 
+} catch(e) {
+  assert.equal(e.message, 'Argument error, options.body.')
+}
+
+try {
+  request({uri:local, multipart: 'foo'})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Argument error, options.multipart.')
+}
+
+try {
+  request({uri:local, multipart: [{}]})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Body attribute missing in multipart.')
+}
+
+try {
+  request(local, {multipart: [{}]})
+  assert.fail("Should have throw")
+} catch(e) {
+  assert.equal(e.message, 'Body attribute missing in multipart.')
+}
+
+console.log("All tests passed.")
diff --git a/deps/npm/node_modules/request/tests/test-headers.js b/deps/npm/node_modules/request/tests/test-headers.js
new file mode 100644 (file)
index 0000000..31fe3f4
--- /dev/null
@@ -0,0 +1,52 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+  , s = server.createServer()
+
+s.listen(s.port, function () {
+  var serverUri = 'http://localhost:' + s.port
+    , numTests = 0
+    , numOutstandingTests = 0
+
+  function createTest(requestObj, serverAssertFn) {
+    var testNumber = numTests;
+    numTests += 1;
+    numOutstandingTests += 1;
+    s.on('/' + testNumber, function (req, res) {
+      serverAssertFn(req, res);
+      res.writeHead(200);
+      res.end();
+    });
+    requestObj.url = serverUri + '/' + testNumber
+    request(requestObj, function (err, res, body) {
+      assert.ok(!err)
+      assert.equal(res.statusCode, 200)
+      numOutstandingTests -= 1
+      if (numOutstandingTests === 0) {
+        console.log(numTests + ' tests passed.')
+        s.close()
+      }
+    })
+  }
+
+  // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified
+  createTest({headers: {cookie: 'foo=bar'}}, function (req, res) {
+    assert.ok(req.headers.cookie)
+    assert.equal(req.headers.cookie, 'foo=bar')
+  })
+
+  // Issue #125: headers.cookie + cookie jar
+  var jar = new Jar()
+  jar.add(new Cookie('quux=baz'));
+  createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) {
+    assert.ok(req.headers.cookie)
+    assert.equal(req.headers.cookie, 'foo=bar; quux=baz')
+  })
+
+  // There should be no cookie header when neither headers.cookie nor a cookie jar is specified
+  createTest({}, function (req, res) {
+    assert.ok(!req.headers.cookie)
+  })
+})
diff --git a/deps/npm/node_modules/request/tests/test-httpModule.js b/deps/npm/node_modules/request/tests/test-httpModule.js
new file mode 100644 (file)
index 0000000..1866de2
--- /dev/null
@@ -0,0 +1,94 @@
+var http = require('http')
+  , https = require('https')
+  , server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+
+var faux_requests_made = {'http':0, 'https':0}
+function wrap_request(name, module) {
+  // Just like the http or https module, but note when a request is made.
+  var wrapped = {}
+  Object.keys(module).forEach(function(key) {
+    var value = module[key];
+
+    if(key != 'request')
+      wrapped[key] = value;
+    else
+      wrapped[key] = function(options, callback) {
+        faux_requests_made[name] += 1
+        return value.apply(this, arguments)
+      }
+  })
+
+  return wrapped;
+}
+
+
+var faux_http = wrap_request('http', http)
+  , faux_https = wrap_request('https', https)
+  , plain_server = server.createServer()
+  , https_server = server.createSSLServer()
+
+
+plain_server.listen(plain_server.port, function() {
+  plain_server.on('/plain', function (req, res) {
+    res.writeHead(200)
+    res.end('plain')
+  })
+  plain_server.on('/to_https', function (req, res) {
+    res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'})
+    res.end()
+  })
+
+  https_server.listen(https_server.port, function() {
+    https_server.on('/https', function (req, res) {
+      res.writeHead(200)
+      res.end('https')
+    })
+    https_server.on('/to_plain', function (req, res) {
+      res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'})
+      res.end()
+    })
+
+    run_tests()
+    run_tests({})
+    run_tests({'http:':faux_http})
+    run_tests({'https:':faux_https})
+    run_tests({'http:':faux_http, 'https:':faux_https})
+  })
+})
+
+function run_tests(httpModules) {
+  var to_https = 'http://localhost:'+plain_server.port+'/to_https'
+  var to_plain = 'https://localhost:'+https_server.port+'/to_plain'
+
+  request(to_https, {'httpModules':httpModules}, function (er, res, body) {
+    assert.ok(!er, 'Bounce to SSL worked')
+    assert.equal(body, 'https', 'Received HTTPS server body')
+    done()
+  })
+
+  request(to_plain, {'httpModules':httpModules}, function (er, res, body) {
+    assert.ok(!er, 'Bounce to plaintext server worked')
+    assert.equal(body, 'plain', 'Received HTTPS server body')
+    done()
+  })
+}
+
+
+var passed = 0;
+function done() {
+  passed += 1
+  var expected = 10
+
+  if(passed == expected) {
+    plain_server.close()
+    https_server.close()
+
+    assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately')
+    assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately')
+
+    console.log((expected+2) + ' tests passed.')
+  }
+}
diff --git a/deps/npm/node_modules/request/tests/test-https-strict.js b/deps/npm/node_modules/request/tests/test-https-strict.js
new file mode 100644 (file)
index 0000000..f53fc14
--- /dev/null
@@ -0,0 +1,97 @@
+// a test where we validate the siguature of the keys
+// otherwise exactly the same as the ssl test
+
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , fs = require('fs')
+  , path = require('path')
+  , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key')
+           , cert: path.resolve(__dirname, 'ssl/ca/server.crt') }
+  , s = server.createSSLServer(null, opts)
+  , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt')
+  , ca = fs.readFileSync(caFile)
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetJSON :
+    { resp : server.createGetResponse('{"test":true}', 'application/json')
+    , json : true
+    , expectBody: {"test":true}
+    }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--frontier\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--frontier\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--frontier--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      test.strictSSL = true
+      test.ca = ca
+      test.headers = { host: 'testing.request.mikealrogers.com' }
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/request/tests/test-https.js b/deps/npm/node_modules/request/tests/test-https.js
new file mode 100644 (file)
index 0000000..df7330b
--- /dev/null
@@ -0,0 +1,86 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+var s = server.createSSLServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+  , testGetChunkBreak :
+    { resp : server.createChunkResponse(
+      [ new Buffer([239])
+      , new Buffer([163])
+      , new Buffer([191])
+      , new Buffer([206])
+      , new Buffer([169])
+      , new Buffer([226])
+      , new Buffer([152])
+      , new Buffer([131])
+      ])
+    , expectBody: "Ω☃"
+    }
+  , testGetJSON :
+    { resp : server.createGetResponse('{"test":true}', 'application/json')
+    , json : true
+    , expectBody: {"test":true}
+    }
+  , testPutString :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : "PUTTINGDATA"
+    }
+  , testPutBuffer :
+    { resp : server.createPostValidator("PUTTINGDATA")
+    , method : "PUT"
+    , body : new Buffer("PUTTINGDATA")
+    }
+  , testPutJSON :
+    { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+    , method: "PUT"
+    , json: {foo: 'bar'}
+    }
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--frontier\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--frontier\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--frontier--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      test.uri = s.url + '/' + i
+      request(test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/request/tests/test-oauth.js b/deps/npm/node_modules/request/tests/test-oauth.js
new file mode 100644 (file)
index 0000000..72ca923
--- /dev/null
@@ -0,0 +1,117 @@
+var hmacsign = require('../oauth').hmacsign
+  , assert = require('assert')
+  , qs = require('querystring')
+  , request = require('../main')
+  ;
+
+function getsignature (r) {
+  var sign
+  r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) {
+    if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1)
+  })
+  return decodeURIComponent(sign)
+}
+
+// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth
+
+var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', 
+  { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11'
+  , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g'
+  , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk'
+  , oauth_signature_method: 'HMAC-SHA1'
+  , oauth_timestamp: '1272323042'
+  , oauth_version: '1.0'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98")
+
+console.log(reqsign)
+console.log('8wUi7m5HFQy76nowoCThusfgB+Q=')
+assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=')
+
+var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token',
+  { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g'
+  , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8'
+  , oauth_signature_method: 'HMAC-SHA1'
+  , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc'
+  , oauth_timestamp: '1272323047'
+  , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY'
+  , oauth_version: '1.0'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA")
+  
+console.log(accsign)
+console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=')
+assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=')
+
+var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', 
+  { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g"
+  , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y"
+  , oauth_signature_method: "HMAC-SHA1"
+  , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw"
+  , oauth_timestamp: "1272325550"
+  , oauth_version: "1.0"
+  , status: 'setting up my twitter 私のさえずりを設定する'
+  }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA")
+
+console.log(upsign)
+console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=')
+assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=')
+
+
+var rsign = request.post(
+  { url: 'https://api.twitter.com/oauth/request_token'
+  , oauth: 
+    { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11'
+    , consumer_key: 'GDdmIQH6jhtmLUypg82g'
+    , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk'
+    , timestamp: '1272323042'
+    , version: '1.0'
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    }
+  })
+
+setTimeout(function () {
+  console.log(getsignature(rsign))
+  assert.equal(reqsign, getsignature(rsign))
+})
+
+var raccsign = request.post(
+  { url: 'https://api.twitter.com/oauth/access_token'
+  , oauth:  
+    { consumer_key: 'GDdmIQH6jhtmLUypg82g'
+    , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8'
+    , signature_method: 'HMAC-SHA1'
+    , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc'
+    , timestamp: '1272323047'
+    , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY'
+    , version: '1.0'
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" 
+    }
+  })
+
+setTimeout(function () {
+  console.log(getsignature(raccsign))
+  assert.equal(accsign, getsignature(raccsign))
+}, 1) 
+
+var rupsign = request.post(
+  { url: 'http://api.twitter.com/1/statuses/update.json' 
+  , oauth: 
+    { consumer_key: "GDdmIQH6jhtmLUypg82g"
+    , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y"
+    , signature_method: "HMAC-SHA1"
+    , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw"
+    , timestamp: "1272325550"
+    , version: "1.0"
+    , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
+    , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA"
+    }
+  , form: {status: 'setting up my twitter 私のさえずりを設定する'} 
+  })
+setTimeout(function () {
+  console.log(getsignature(rupsign))
+  assert.equal(upsign, getsignature(rupsign))
+}, 1)
+
+
+
+
diff --git a/deps/npm/node_modules/request/tests/test-params.js b/deps/npm/node_modules/request/tests/test-params.js
new file mode 100644 (file)
index 0000000..8354f6d
--- /dev/null
@@ -0,0 +1,92 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+
+var tests =
+  { testGet :
+    { resp : server.createGetResponse("TESTING!")
+    , expectBody: "TESTING!"
+    }
+    , testGetChunkBreak :
+      { resp : server.createChunkResponse(
+        [ new Buffer([239])
+        , new Buffer([163])
+        , new Buffer([191])
+        , new Buffer([206])
+        , new Buffer([169])
+        , new Buffer([226])
+        , new Buffer([152])
+        , new Buffer([131])
+        ])
+      , expectBody: "Ω☃"
+      }
+    , testGetBuffer :
+      { resp : server.createGetResponse(new Buffer("TESTING!"))
+      , encoding: null
+      , expectBody: new Buffer("TESTING!")
+      }
+    , testGetJSON :
+       { resp : server.createGetResponse('{"test":true}', 'application/json')
+       , json : true
+       , expectBody: {"test":true}
+       }
+    , testPutString :
+      { resp : server.createPostValidator("PUTTINGDATA")
+      , method : "PUT"
+      , body : "PUTTINGDATA"
+      }
+    , testPutBuffer :
+      { resp : server.createPostValidator("PUTTINGDATA")
+      , method : "PUT"
+      , body : new Buffer("PUTTINGDATA")
+      }
+    , testPutJSON :
+      { resp : server.createPostValidator(JSON.stringify({foo: 'bar'}))
+      , method: "PUT"
+      , json: {foo: 'bar'}
+      }
+    , testPutMultipart :
+      { resp: server.createPostValidator(
+          '--frontier\r\n' +
+          'content-type: text/html\r\n' +
+          '\r\n' +
+          '<html><body>Oh hi.</body></html>' +
+          '\r\n--frontier\r\n\r\n' +
+          'Oh hi.' +
+          '\r\n--frontier--'
+          )
+      , method: "PUT"
+      , multipart:
+        [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+        , {'body': 'Oh hi.'}
+        ]
+      }
+  }
+
+s.listen(s.port, function () {
+
+  var counter = 0
+
+  for (i in tests) {
+    (function () {
+      var test = tests[i]
+      s.on('/'+i, test.resp)
+      //test.uri = s.url + '/' + i
+      request(s.url + '/' + i, test, function (err, resp, body) {
+        if (err) throw err
+        if (test.expectBody) {
+          assert.deepEqual(test.expectBody, body)
+        }
+        counter = counter - 1;
+        if (counter === 0) {
+          console.log(Object.keys(tests).length+" tests passed.")
+          s.close()
+        }
+      })
+      counter++
+    })()
+  }
+})
diff --git a/deps/npm/node_modules/request/tests/test-pipes.js b/deps/npm/node_modules/request/tests/test-pipes.js
new file mode 100644 (file)
index 0000000..1869874
--- /dev/null
@@ -0,0 +1,202 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , fs = require('fs')
+  , request = require('../main.js')
+  , path = require('path')
+  , util = require('util')
+  ;
+
+var s = server.createServer(3453);
+
+function ValidationStream(str) {
+  this.str = str
+  this.buf = ''
+  this.on('data', function (data) {
+    this.buf += data
+  })
+  this.on('end', function () {
+    assert.equal(this.str, this.buf)
+  })
+  this.writable = true
+}
+util.inherits(ValidationStream, stream.Stream)
+ValidationStream.prototype.write = function (chunk) {
+  this.emit('data', chunk)
+}
+ValidationStream.prototype.end = function (chunk) {
+  if (chunk) emit('data', chunk)
+  this.emit('end')
+}
+
+s.listen(s.port, function () {
+  counter = 0;
+
+  var check = function () {
+    counter = counter - 1
+    if (counter === 0) {
+      console.log('All tests passed.')
+      setTimeout(function () {
+        process.exit();
+      }, 500)
+    }
+  }
+
+  // Test pipeing to a request object
+  s.once('/push', server.createPostValidator("mydata"));
+
+  var mydata = new stream.Stream();
+  mydata.readable = true
+
+  counter++
+  var r1 = request.put({url:'http://localhost:3453/push'}, function () {
+    check();
+  })
+  mydata.pipe(r1)
+
+  mydata.emit('data', 'mydata');
+  mydata.emit('end');
+
+
+  // Test pipeing from a request object.
+  s.once('/pull', server.createGetResponse("mypulldata"));
+
+  var mypulldata = new stream.Stream();
+  mypulldata.writable = true
+
+  counter++
+  request({url:'http://localhost:3453/pull'}).pipe(mypulldata)
+
+  var d = '';
+
+  mypulldata.write = function (chunk) {
+    d += chunk;
+  }
+  mypulldata.end = function () {
+    assert.equal(d, 'mypulldata');
+    check();
+  };
+
+
+  s.on('/cat', function (req, resp) {
+    if (req.method === "GET") {
+      resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4});
+      resp.end('asdf')
+    } else if (req.method === "PUT") {
+      assert.equal(req.headers['content-type'], 'text/plain-test');
+      assert.equal(req.headers['content-length'], 4)
+      var validate = '';
+
+      req.on('data', function (chunk) {validate += chunk})
+      req.on('end', function () {
+        resp.writeHead(201);
+        resp.end();
+        assert.equal(validate, 'asdf');
+        check();
+      })
+    }
+  })
+  s.on('/pushjs', function (req, resp) {
+    if (req.method === "PUT") {
+      assert.equal(req.headers['content-type'], 'text/javascript');
+      check();
+    }
+  })
+  s.on('/catresp', function (req, resp) {
+    request.get('http://localhost:3453/cat').pipe(resp)
+  })
+  s.on('/doodle', function (req, resp) {
+    if (req.headers['x-oneline-proxy']) {
+      resp.setHeader('x-oneline-proxy', 'yup')
+    }
+    resp.writeHead('200', {'content-type':'image/png'})
+    fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp)
+  })
+  s.on('/onelineproxy', function (req, resp) {
+    var x = request('http://localhost:3453/doodle')
+    req.pipe(x)
+    x.pipe(resp)
+  })
+
+  counter++
+  fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs'))
+
+  counter++
+  request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat'))
+
+  counter++
+  request.get('http://localhost:3453/catresp', function (e, resp, body) {
+    assert.equal(resp.headers['content-type'], 'text/plain-test');
+    assert.equal(resp.headers['content-length'], 4)
+    check();
+  })
+
+  var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png'))
+
+  counter++
+  request.get('http://localhost:3453/doodle').pipe(doodleWrite)
+
+  doodleWrite.on('close', function () {
+    assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png')))
+    check()
+  })
+
+  process.on('exit', function () {
+    fs.unlinkSync(path.join(__dirname, 'test.png'))
+  })
+
+  counter++
+  request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) {
+    assert.equal(resp.headers['x-oneline-proxy'], 'yup')
+    check()
+  })
+
+  s.on('/afterresponse', function (req, resp) {
+    resp.write('d')
+    resp.end()
+  })
+
+  counter++
+  var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () {
+    var v = new ValidationStream('d')
+    afterresp.pipe(v)
+    v.on('end', check)
+  })
+  
+  s.on('/forward1', function (req, resp) {
+   resp.writeHead(302, {location:'/forward2'})
+    resp.end()
+  })
+  s.on('/forward2', function (req, resp) {
+    resp.writeHead('200', {'content-type':'image/png'})
+    resp.write('d')
+    resp.end()
+  })
+  
+  counter++
+  var validateForward = new ValidationStream('d')
+  validateForward.on('end', check)
+  request.get('http://localhost:3453/forward1').pipe(validateForward)
+
+  // Test pipe options
+  s.once('/opts', server.createGetResponse('opts response'));
+
+  var optsStream = new stream.Stream();
+  optsStream.writable = true
+  
+  var optsData = '';
+  optsStream.write = function (buf) {
+    optsData += buf;
+    if (optsData === 'opts response') {
+      setTimeout(check, 10);
+    }
+  }
+
+  optsStream.end = function () {
+    assert.fail('end called')
+  };
+
+  counter++
+  request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false })
+})
diff --git a/deps/npm/node_modules/request/tests/test-pool.js b/deps/npm/node_modules/request/tests/test-pool.js
new file mode 100644 (file)
index 0000000..1e7d578
--- /dev/null
@@ -0,0 +1,16 @@
+var request = require('../main')
+  , http = require('http')
+  , assert = require('assert')
+  ;
+
+var s = http.createServer(function (req, resp) {
+  resp.statusCode = 200;
+  resp.end('asdf');
+}).listen(8080, function () {
+  request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) {
+    var agent = resp.request.agent;
+    assert.strictEqual(typeof agent, 'boolean');
+    assert.strictEqual(agent, false);
+    s.close();
+  });
+});
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/tests/test-proxy.js b/deps/npm/node_modules/request/tests/test-proxy.js
new file mode 100644 (file)
index 0000000..647157c
--- /dev/null
@@ -0,0 +1,39 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , fs = require('fs')
+  , request = require('../main.js')
+  , path = require('path')
+  , util = require('util')
+  ;
+
+var port = 6768
+  , called = false
+  , proxiedHost = 'google.com'
+  ;
+
+var s = server.createServer(port)
+s.listen(port, function () {
+  s.on('http://google.com/', function (req, res) {
+    called = true
+    assert.equal(req.headers.host, proxiedHost)
+    res.writeHeader(200)
+    res.end()
+  })
+  request ({
+    url: 'http://'+proxiedHost,
+    proxy: 'http://localhost:'+port
+    /*
+    //should behave as if these arguments where passed:
+    url: 'http://localhost:'+port,
+    headers: {host: proxiedHost}
+    //*/
+  }, function (err, res, body) {
+    s.close()
+  })
+})
+
+process.on('exit', function () {
+  assert.ok(called, 'the request must be made to the proxy server')
+})
diff --git a/deps/npm/node_modules/request/tests/test-qs.js b/deps/npm/node_modules/request/tests/test-qs.js
new file mode 100644 (file)
index 0000000..1aac22b
--- /dev/null
@@ -0,0 +1,28 @@
+var request = request = require('../main.js')
+  , assert = require('assert')
+  ;
+
+// Test adding a querystring
+var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?q=search', req1.path)
+}, 1)
+
+// Test replacing a querystring value
+var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?q=search', req2.path)
+}, 1)
+
+// Test appending a querystring value to the ones present in the uri
+var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }})
+setTimeout(function() {
+       assert.equal('/?x=y&q=search', req3.path)
+}, 1)
+
+// Test leaving a querystring alone
+var req4 = request.get({ uri: 'http://www.google.com?x=y'})
+setTimeout(function() {
+       assert.equal('/?x=y', req4.path)
+}, 1)
diff --git a/deps/npm/node_modules/request/tests/test-redirect.js b/deps/npm/node_modules/request/tests/test-redirect.js
new file mode 100644 (file)
index 0000000..b84844a
--- /dev/null
@@ -0,0 +1,154 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , Cookie = require('../vendor/cookie')
+  , Jar = require('../vendor/cookie/jar')
+
+var s = server.createServer()
+
+s.listen(s.port, function () {
+  var server = 'http://localhost:' + s.port;
+  var hits = {}
+  var passed = 0;
+
+  bouncer(301, 'temp')
+  bouncer(302, 'perm')
+  bouncer(302, 'nope')
+
+  function bouncer(code, label) {
+    var landing = label+'_landing';
+
+    s.on('/'+label, function (req, res) {
+      hits[label] = true;
+      res.writeHead(code, {
+        'location':server + '/'+landing,
+        'set-cookie': 'ham=eggs'
+      })
+      res.end()
+    })
+
+    s.on('/'+landing, function (req, res) {
+      if (req.method !== 'GET') { // We should only accept GET redirects
+        console.error("Got a non-GET request to the redirect destination URL");
+        res.writeHead(400);
+        res.end();
+        return;
+      }
+      // Make sure the cookie doesn't get included twice, see #139:
+      // Make sure cookies are set properly after redirect
+      assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs');
+      hits[landing] = true;
+      res.writeHead(200)
+      res.end(landing)
+    })
+  }
+
+  // Permanent bounce
+  var jar = new Jar()
+  jar.add(new Cookie('quux=baz'))
+  request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.perm, 'Original request is to /perm')
+    assert.ok(hits.perm_landing, 'Forward to permanent landing URL')
+    assert.equal(body, 'perm_landing', 'Got permanent landing content')
+    passed += 1
+    done()
+  })
+  
+  // Temporary bounce
+  request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+  
+  // Prevent bouncing.
+  request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode)
+    assert.ok(hits.nope, 'Original request to /nope')
+    assert.ok(!hits.nope_landing, 'No chasing the redirect')
+    assert.equal(res.statusCode, 302, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should not follow post redirects by default
+  request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when post')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should follow post redirects when followAllRedirects true
+  request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+  
+  request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+
+  // Should not follow delete redirects by default
+  request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode < 301) throw new Error('Status is not a redirect.')
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when delete')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should not follow delete redirects even if followRedirect is set to true
+  request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(!hits.temp_landing, 'No chasing the redirect when delete')
+    assert.equal(res.statusCode, 301, 'Response is the bounce itself')
+    passed += 1
+    done()
+  })
+  
+  // Should follow delete redirects when followAllRedirects true
+  request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) {
+    if (er) throw er
+    if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode)
+    assert.ok(hits.temp, 'Original request is to /temp')
+    assert.ok(hits.temp_landing, 'Forward to temporary landing URL')
+    assert.equal(body, 'temp_landing', 'Got temporary landing content')
+    passed += 1
+    done()
+  })
+
+  var reqs_done = 0;
+  function done() {
+    reqs_done += 1;
+    if(reqs_done == 9) {
+      console.log(passed + ' tests passed.')
+      s.close()
+    }
+  }
+})
diff --git a/deps/npm/node_modules/request/tests/test-s3.js b/deps/npm/node_modules/request/tests/test-s3.js
new file mode 100644 (file)
index 0000000..5f59c4a
--- /dev/null
@@ -0,0 +1,13 @@
+var request = require('../main')
+
+var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', 
+  { aws: 
+    { key: 'AKIAI6KIQRRVMGK3WK5Q'
+    , secret: 'j4kaxM7TUiN7Ou0//v1ZqOVn3Aq7y1ccPh/tHTna'
+    , bucket: 'log.curlybracecast.com'
+    }
+  }, function (e, resp, body) {
+    console.log(r.headers)
+    console.log(body)
+  }
+)
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/tests/test-timeout.js b/deps/npm/node_modules/request/tests/test-timeout.js
new file mode 100644 (file)
index 0000000..673f8ad
--- /dev/null
@@ -0,0 +1,87 @@
+var server = require('./server')
+  , events = require('events')
+  , stream = require('stream')
+  , assert = require('assert')
+  , request = require('../main.js')
+  ;
+
+var s = server.createServer();
+var expectedBody = "waited";
+var remainingTests = 5;
+
+s.listen(s.port, function () {
+  // Request that waits for 200ms
+  s.on('/timeout', function (req, resp) {
+    setTimeout(function(){
+      resp.writeHead(200, {'content-type':'text/plain'})
+      resp.write(expectedBody)
+      resp.end()
+    }, 200);
+  });
+
+  // Scenario that should timeout
+  var shouldTimeout = {
+    url: s.url + "/timeout",
+    timeout:100
+  }
+
+
+  request(shouldTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+
+  // Scenario that shouldn't timeout
+  var shouldntTimeout = {
+    url: s.url + "/timeout",
+    timeout:300
+  }
+
+  request(shouldntTimeout, function (err, resp, body) {
+    assert.equal(err, null);
+    assert.equal(expectedBody, body)
+    checkDone();
+  })
+
+  // Scenario with no timeout set, so shouldn't timeout
+  var noTimeout = {
+    url: s.url + "/timeout"
+  }
+
+  request(noTimeout, function (err, resp, body) {
+    assert.equal(err);
+    assert.equal(expectedBody, body)
+    checkDone();
+  })
+
+  // Scenario with a negative timeout value, should be treated a zero or the minimum delay
+  var negativeTimeout = {
+    url: s.url + "/timeout",
+    timeout:-1000
+  }
+
+  request(negativeTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+  // Scenario with a float timeout value, should be rounded by setTimeout anyway
+  var floatTimeout = {
+    url: s.url + "/timeout",
+    timeout: 100.76
+  }
+
+  request(floatTimeout, function (err, resp, body) {
+    assert.equal(err.code, "ETIMEDOUT");
+    checkDone();
+  })
+
+  function checkDone() {
+    if(--remainingTests == 0) {
+      s.close();
+      console.log("All tests passed.");
+    }
+  }
+})
+
diff --git a/deps/npm/node_modules/request/tests/test-toJSON.js b/deps/npm/node_modules/request/tests/test-toJSON.js
new file mode 100644 (file)
index 0000000..b7c67ef
--- /dev/null
@@ -0,0 +1,14 @@
+var request = require('../main')
+  , http = require('http')
+  , assert = require('assert')
+  ;
+
+var s = http.createServer(function (req, resp) {
+  resp.statusCode = 200
+  resp.end('asdf')
+}).listen(8080, function () {
+  var r = request('http://localhost:8080', function (e, resp) {
+    assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200)
+    s.close()
+  })
+})
\ No newline at end of file
diff --git a/deps/npm/node_modules/request/tests/test-tunnel.js b/deps/npm/node_modules/request/tests/test-tunnel.js
new file mode 100644 (file)
index 0000000..58131b9
--- /dev/null
@@ -0,0 +1,61 @@
+// test that we can tunnel a https request over an http proxy
+// keeping all the CA and whatnot intact.
+//
+// Note: this requires that squid is installed.
+// If the proxy fails to start, we'll just log a warning and assume success.
+
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+  , fs = require('fs')
+  , path = require('path')
+  , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt')
+  , ca = fs.readFileSync(caFile)
+  , child_process = require('child_process')
+  , sqConf = path.resolve(__dirname, 'squid.conf')
+  , sqArgs = ['-f', sqConf, '-N', '-d', '5']
+  , proxy = 'http://localhost:3128'
+  , hadError = null
+
+var squid = child_process.spawn('squid', sqArgs);
+var ready = false
+
+squid.stderr.on('data', function (c) {
+  console.error('SQUIDERR ' + c.toString().trim().split('\n')
+               .join('\nSQUIDERR '))
+  ready = c.toString().match(/ready to serve requests/i)
+})
+
+squid.stdout.on('data', function (c) {
+  console.error('SQUIDOUT ' + c.toString().trim().split('\n')
+               .join('\nSQUIDOUT '))
+})
+
+squid.on('exit', function (c) {
+  console.error('exit '+c)
+  if (c && !ready) {
+    console.error('squid must be installed to run this test.')
+    c = null
+    hadError = null
+    process.exit(0)
+    return
+  }
+
+  if (c) {
+    hadError = hadError || new Error('Squid exited with '+c)
+  }
+  if (hadError) throw hadError
+})
+
+setTimeout(function F () {
+  if (!ready) return setTimeout(F, 100)
+  request({ uri: 'https://registry.npmjs.org/request/'
+          , proxy: 'http://localhost:3128'
+          , ca: ca
+          , json: true }, function (er, body) {
+    hadError = er
+    console.log(er || typeof body)
+    if (!er) console.log("ok")
+    squid.kill('SIGKILL')
+  })
+}, 100)
diff --git a/deps/npm/node_modules/retry/example/dns.js b/deps/npm/node_modules/retry/example/dns.js
new file mode 100644 (file)
index 0000000..e4082af
--- /dev/null
@@ -0,0 +1,31 @@
+var dns = require('dns');
+var retry = require('../lib/retry');
+
+function faultTolerantResolve(address, cb) {
+  var opts = {
+    times: 2,
+    factor: 2,
+    minTimeout: 1 * 1000,
+    maxTimeout: 2 * 1000,
+    randomize: true
+  };
+  var operation = retry.operation(opts);
+
+  operation.attempt(function(currentAttempt) {
+    dns.resolve(address, function(err, addresses) {
+      if (operation.retry(err)) {
+        return;
+      }
+
+      cb(operation.mainError(), operation.errors(), addresses);
+    });
+  });
+}
+
+faultTolerantResolve('nodejs.org', function(err, errors, addresses) {
+  console.warn('err:');
+  console.log(err);
+
+  console.warn('addresses:');
+  console.log(addresses);
+});
\ No newline at end of file
diff --git a/deps/npm/node_modules/retry/test/common.js b/deps/npm/node_modules/retry/test/common.js
new file mode 100644 (file)
index 0000000..2247206
--- /dev/null
@@ -0,0 +1,10 @@
+var common = module.exports;
+var path = require('path');
+
+var rootDir = path.join(__dirname, '..');
+common.dir = {
+  lib: rootDir + '/lib'
+};
+
+common.assert = require('assert');
+common.fake = require('fake');
\ No newline at end of file
diff --git a/deps/npm/node_modules/retry/test/integration/test-retry-operation.js b/deps/npm/node_modules/retry/test/integration/test-retry-operation.js
new file mode 100644 (file)
index 0000000..d873d1f
--- /dev/null
@@ -0,0 +1,80 @@
+var common = require('../common');
+var assert = common.assert;
+var fake = common.fake.create();
+var retry = require(common.dir.lib + '/retry');
+
+(function testErrors() {
+  var operation = retry.operation();
+
+  var error = new Error('some error');
+  var error2 = new Error('some other error');
+  operation._errors.push(error);
+  operation._errors.push(error2);
+
+  assert.deepEqual(operation.errors(), [error, error2]);
+})();
+
+(function testMainErrorReturnsMostFrequentError() {
+  var operation = retry.operation();
+  var error = new Error('some error');
+  var error2 = new Error('some other error');
+
+  operation._errors.push(error);
+  operation._errors.push(error2);
+  operation._errors.push(error);
+
+  assert.strictEqual(operation.mainError(), error);
+})();
+
+(function testMainErrorReturnsLastErrorOnEqualCount() {
+  var operation = retry.operation();
+  var error = new Error('some error');
+  var error2 = new Error('some other error');
+
+  operation._errors.push(error);
+  operation._errors.push(error2);
+
+  assert.strictEqual(operation.mainError(), error2);
+})();
+
+(function testAttempt() {
+  var operation = retry.operation();
+  var fn = new Function();
+
+  var timeoutOpts = {
+    timeout: 1,
+    cb: function() {}
+  };
+  operation.attempt(fn, timeoutOpts);
+
+  assert.strictEqual(fn, operation._fn);
+  assert.strictEqual(timeoutOpts.timeout, operation._operationTimeout);
+  assert.strictEqual(timeoutOpts.cb, operation._operationTimeoutCb);
+})();
+
+(function testRetry() {
+  var times = 3;
+  var error = new Error('some error');
+  var operation = retry.operation([1, 2, 3]);
+  var attempts = 0;
+
+  var finalCallback = fake.callback('finalCallback');
+  fake.expectAnytime(finalCallback);
+
+  var fn = function() {
+    operation.attempt(function(currentAttempt) {
+      attempts++;
+      assert.equal(currentAttempt, attempts);
+      if (operation.retry(error)) {
+        return;
+      }
+
+      assert.strictEqual(attempts, 4);
+      assert.strictEqual(operation.attempts(), attempts);
+      assert.strictEqual(operation.mainError(), error);
+      finalCallback();
+    });
+  };
+
+  fn();
+})();
\ No newline at end of file
diff --git a/deps/npm/node_modules/retry/test/integration/test-timeouts.js b/deps/npm/node_modules/retry/test/integration/test-timeouts.js
new file mode 100644 (file)
index 0000000..7206b0f
--- /dev/null
@@ -0,0 +1,69 @@
+var common = require('../common');
+var assert = common.assert;
+var retry = require(common.dir.lib + '/retry');
+
+(function testDefaultValues() {
+  var timeouts = retry.timeouts();
+
+  assert.equal(timeouts.length, 10);
+  assert.equal(timeouts[0], 1000);
+  assert.equal(timeouts[1], 2000);
+  assert.equal(timeouts[2], 4000);
+})();
+
+(function testDefaultValuesWithRandomize() {
+  var minTimeout = 5000;
+  var timeouts = retry.timeouts({
+    minTimeout: minTimeout,
+    randomize: true
+  });
+
+  assert.equal(timeouts.length, 10);
+  assert.ok(timeouts[0] > minTimeout);
+  assert.ok(timeouts[1] > timeouts[0]);
+  assert.ok(timeouts[2] > timeouts[1]);
+})();
+
+(function testPassedTimeoutsAreUsed() {
+  var timeoutsArray = [1000, 2000, 3000];
+  var timeouts = retry.timeouts(timeoutsArray);
+  assert.deepEqual(timeouts, timeoutsArray);
+  assert.notStrictEqual(timeouts, timeoutsArray);
+})();
+
+(function testTimeoutsAreWithinBoundaries() {
+  var minTimeout = 1000;
+  var maxTimeout = 10000;
+  var timeouts = retry.timeouts({
+    minTimeout: minTimeout,
+    maxTimeout: maxTimeout
+  });
+  for (var i = 0; i < timeouts; i++) {
+    assert.ok(timeouts[i] >= minTimeout);
+    assert.ok(timeouts[i] <= maxTimeout);
+  }
+})();
+
+(function testTimeoutsAreIncremental() {
+  var timeouts = retry.timeouts();
+  var lastTimeout = timeouts[0];
+  for (var i = 0; i < timeouts; i++) {
+    assert.ok(timeouts[i] > lastTimeout);
+    lastTimeout = timeouts[i];
+  }
+})();
+
+(function testTimeoutsAreIncrementalForFactorsLessThanOne() {
+  var timeouts = retry.timeouts({
+    retries: 3,
+    factor: 0.5
+  });
+
+  var expected = [250, 500, 1000];
+  assert.deepEqual(expected, timeouts);
+})();
+
+(function testRetries() {
+  var timeouts = retry.timeouts({retries: 2});
+  assert.strictEqual(timeouts.length, 2);
+})();
diff --git a/deps/npm/node_modules/retry/test/runner.js b/deps/npm/node_modules/retry/test/runner.js
new file mode 100644 (file)
index 0000000..e0ee2f5
--- /dev/null
@@ -0,0 +1,5 @@
+var far = require('far').create();
+
+far.add(__dirname);
+far.include(/\/test-.*\.js$/);
+far.execute();
diff --git a/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf b/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf
new file mode 100644 (file)
index 0000000..ca12d60
Binary files /dev/null and b/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf differ
index 3ead8aa..024807f 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "version": "1.1.36",
+  "version": "1.1.41",
   "name": "npm",
   "publishConfig": {
     "proprietary-attribs": false
     "npmlog": "0",
     "ansi": "~0.1.2",
     "npm-registry-client": "0",
-    "read-package-json": "0",
+    "read-package-json": "~0.1.1",
     "read-installed": "0",
     "glob": "~3.1.9",
     "init-package-json": "0",
     "osenv": "0",
     "lockfile": ">=0.2",
-    "retry": "~0.6.0"
+    "retry": "~0.6.0",
+    "couch-login": "~0.1.6"
   },
   "bundleDependencies": [
     "semver",
     "init-package-json",
     "osenv",
     "lockfile",
-    "retry"
+    "retry",
+    "couch-login"
   ],
   "devDependencies": {
     "ronn": "https://github.com/isaacs/ronnjs/tarball/master",
     "tap": "~0.2.5"
   },
   "engines": {
-    "node": "0.6 || 0.7 || 0.8",
+    "node": ">0.6",
     "npm": "1"
   },
   "scripts": {
diff --git a/deps/npm/scripts/relocate.sh b/deps/npm/scripts/relocate.sh
new file mode 100755 (executable)
index 0000000..b7483f2
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Change the cli shebang to point at the specified node
+# Useful for when the program is moved around after install.
+# Also used by the default 'make install' in node to point
+# npm at the newly installed node, rather than the first one
+# in the PATH, which would be the default otherwise.
+
+# bash /path/to/npm/scripts/relocate.sh $nodepath
+# If $nodepath is blank, then it'll use /usr/bin/env
+
+dir="$(dirname "$(dirname "$0")")"
+cli="$dir"/bin/npm-cli.js
+tmp="$cli".tmp
+
+node="$1"
+if [ "x$node" = "x" ]; then
+  node="/usr/bin/env node"
+fi
+node="#!$node"
+
+sed -e 1d "$cli" > "$tmp"
+echo "$node" > "$cli"
+cat "$tmp" >> "$cli"
+rm "$tmp"
+chmod ogu+x $cli
diff --git a/deps/npm/test/disabled/bundlerecurs/package.json b/deps/npm/test/disabled/bundlerecurs/package.json
new file mode 100644 (file)
index 0000000..d870411
--- /dev/null
@@ -0,0 +1,4 @@
+{ "name" : "bundletest"
+, "version" : "1.0.0"
+, "dependencies" : { "bundletest" : "*" }
+}
diff --git a/deps/npm/test/disabled/change-bin-1/bin/foo b/deps/npm/test/disabled/change-bin-1/bin/foo
new file mode 100644 (file)
index 0000000..fb16c2b
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+echo "foo"
diff --git a/deps/npm/test/disabled/change-bin-1/package.json b/deps/npm/test/disabled/change-bin-1/package.json
new file mode 100644 (file)
index 0000000..0d82f3a
--- /dev/null
@@ -0,0 +1,3 @@
+{"name":"npm-test-change-bin"
+,"version":"1.2.3"
+,"directories":{"bin":"./bin"}}
diff --git a/deps/npm/test/disabled/change-bin-2/bin/bar b/deps/npm/test/disabled/change-bin-2/bin/bar
new file mode 100644 (file)
index 0000000..fb16c2b
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+echo "foo"
diff --git a/deps/npm/test/disabled/change-bin-2/package.json b/deps/npm/test/disabled/change-bin-2/package.json
new file mode 100644 (file)
index 0000000..3fdc538
--- /dev/null
@@ -0,0 +1,3 @@
+{"name":"npm-test-change-bin"
+,"version":"2.3.4"
+,"directories":{"bin":"./bin"}}
diff --git a/deps/npm/test/disabled/failer/package.json b/deps/npm/test/disabled/failer/package.json
new file mode 100644 (file)
index 0000000..ff596d1
--- /dev/null
@@ -0,0 +1,5 @@
+{ "name" : "npm-test-failer"
+, "version" : "9999.999.99"
+, "dependencies" : { "base64" : "*" }
+, "scripts" : { "install" : "exit 1", "test": "echo 'This is where the test output would go'; echo 'more test output'; echo 'MOAR MOAR MoAR'; exit 1" }
+}
diff --git a/deps/npm/test/disabled/fast/package.json b/deps/npm/test/disabled/fast/package.json
new file mode 100644 (file)
index 0000000..fbf26e9
--- /dev/null
@@ -0,0 +1,9 @@
+{ "name" : "fast"
+, "description" : "does nothing, and not very fast"
+, "version" : "1.2.3"
+, "scripts" :
+{   "preinstall" : "sleep 1 && echo fast 1 $(date +%s) && echo fast 2"
+,      "install" : "sleep 1 && echo fast 2 $(date +%s) && echo fast 3"
+,  "postinstall" : "sleep 1 && echo fast 3 $(date +%s) && echo fast 4"
+}
+}
diff --git a/deps/npm/test/disabled/package-bar/package.json b/deps/npm/test/disabled/package-bar/package.json
new file mode 100644 (file)
index 0000000..f9a2780
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "name": "package-bar",
+    "version": "0.5.0",
+    "dependencies": {
+        "package-foo": "*"
+    }
+}
diff --git a/deps/npm/test/disabled/package-config/package.json b/deps/npm/test/disabled/package-config/package.json
new file mode 100644 (file)
index 0000000..7ec97d3
--- /dev/null
@@ -0,0 +1,4 @@
+{"name":"package-config"
+,"version":"1.2.3"
+,"config":{"foo":"bar"}
+,"scripts":{"test":"./test.js"}}
diff --git a/deps/npm/test/disabled/package-config/test.js b/deps/npm/test/disabled/package-config/test.js
new file mode 100755 (executable)
index 0000000..7337b23
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env node
+
+var env = process.env
+  , orig = require(process.env.npm_package_name+"/package.json").config
+  , assert = require("assert")
+
+console.log("Before running this test, do:\n"
+           +"  npm config set package-config:foo boo\n"
+           +"or else it's about to fail.")
+assert.equal(env.npm_package_config_foo, "boo", "foo != boo")
+assert.equal(orig.foo, "bar", "original foo != bar")
+assert.equal(env["npm_config_package-config:foo"], "boo",
+             "package-config:foo != boo")
+console.log({ foo: env.npm_package_config_foo
+            , orig_foo: orig.foo
+            , "package-config:foo": env["npm_config_package-config:foo"]
+            })
diff --git a/deps/npm/test/disabled/package-foo/package.json b/deps/npm/test/disabled/package-foo/package.json
new file mode 100644 (file)
index 0000000..31e791f
--- /dev/null
@@ -0,0 +1,4 @@
+{
+    "name": "package-foo",
+    "version": "0.5.0"
+}
diff --git a/deps/npm/test/disabled/slow/package.json b/deps/npm/test/disabled/slow/package.json
new file mode 100644 (file)
index 0000000..ba6be42
--- /dev/null
@@ -0,0 +1,9 @@
+{ "name" : "slow"
+, "description" : "just like fast, but even slower"
+, "version" : "1.2.3"
+, "scripts" :
+  {   "preinstall" : "sleep 1 && echo slow 1 $(date +%s) && sleep 1 && echo slow 2 $(date +%s)"
+  ,      "install" : "sleep 1 && echo slow 2 $(date +%s) && sleep 1 && echo slow 3 $(date +%s)"
+  ,  "postinstall" : "sleep 1 && echo slow 3 $(date +%s) && sleep 1 && echo slow 4 $(date +%s)"
+  }
+}
diff --git a/deps/npm/test/disabled/startstop/package.json b/deps/npm/test/disabled/startstop/package.json
new file mode 100644 (file)
index 0000000..bee2a2f
--- /dev/null
@@ -0,0 +1,3 @@
+{"name":"startstop"
+,"version":"1.2.3"
+,"scripts":{"start":"echo 'start'","stop":"echo 'stop'"}}
diff --git a/deps/npm/test/packages/npm-test-files/ignore3 b/deps/npm/test/packages/npm-test-files/ignore3
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-files/ignoredir1/a b/deps/npm/test/packages/npm-test-files/ignoredir1/a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-files/ignoredir2/a b/deps/npm/test/packages/npm-test-files/ignoredir2/a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-files/sub/ignore1 b/deps/npm/test/packages/npm-test-files/sub/ignore1
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-files/sub/ignore3 b/deps/npm/test/packages/npm-test-files/sub/ignore3
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-ignore/ignore3 b/deps/npm/test/packages/npm-test-ignore/ignore3
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-ignore/ignoredir1/a b/deps/npm/test/packages/npm-test-ignore/ignoredir1/a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-ignore/ignoredir2/a b/deps/npm/test/packages/npm-test-ignore/ignoredir2/a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-ignore/sub/ignore1 b/deps/npm/test/packages/npm-test-ignore/sub/ignore1
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/deps/npm/test/packages/npm-test-ignore/sub/ignore3 b/deps/npm/test/packages/npm-test-ignore/sub/ignore3
new file mode 100644 (file)
index 0000000..e69de29