npm: Upgrade to 1.1.55
authorisaacs <i@izs.me>
Tue, 21 Aug 2012 22:29:03 +0000 (15:29 -0700)
committerisaacs <i@izs.me>
Tue, 21 Aug 2012 22:29:37 +0000 (15:29 -0700)
170 files changed:
deps/npm/.travis.yml [deleted file]
deps/npm/AUTHORS
deps/npm/doc/cli/dedupe.md [new file with mode: 0644]
deps/npm/doc/cli/index.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/dedupe.html [new file with mode: 0644]
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/lib/dedupe.js [new file with mode: 0644]
deps/npm/lib/npm.js
deps/npm/lib/publish.js
deps/npm/lib/utils/error-handler.js
deps/npm/lib/utils/fetch.js
deps/npm/lib/utils/find-prefix.js
deps/npm/lib/view.js
deps/npm/man/man1/dedupe.1 [new file with mode: 0644]
deps/npm/man/man1/index.1
deps/npm/man/man1/list.1
deps/npm/man/man1/npm.1
deps/npm/man/man3/npm.3
deps/npm/node_modules/couch-login/couch-login.js
deps/npm/node_modules/couch-login/package.json
deps/npm/node_modules/mkdirp/.gitignore.orig [deleted file]
deps/npm/node_modules/mkdirp/.gitignore.rej [deleted file]
deps/npm/node_modules/mkdirp/examples/pow.js.orig [deleted file]
deps/npm/node_modules/mkdirp/examples/pow.js.rej [deleted file]
deps/npm/node_modules/mkdirp/index.js
deps/npm/node_modules/mkdirp/package.json
deps/npm/node_modules/node-gyp/addon.gypi
deps/npm/node_modules/node-gyp/lib/build.js
deps/npm/node_modules/node-gyp/lib/node-gyp.js
deps/npm/node_modules/node-gyp/package.json
deps/npm/node_modules/node-uuid/.npmignore [deleted file]
deps/npm/node_modules/node-uuid/LICENSE.md [deleted file]
deps/npm/node_modules/node-uuid/README.md [deleted file]
deps/npm/node_modules/node-uuid/package.json [deleted file]
deps/npm/node_modules/node-uuid/uuid.js [deleted file]
deps/npm/node_modules/npm-registry-client/README.md
deps/npm/node_modules/npm-registry-client/index.js
deps/npm/node_modules/npm-registry-client/lib/adduser.js
deps/npm/node_modules/npm-registry-client/lib/get.js
deps/npm/node_modules/npm-registry-client/lib/publish.js
deps/npm/node_modules/npm-registry-client/lib/request.js
deps/npm/node_modules/npm-registry-client/lib/star.js
deps/npm/node_modules/npm-registry-client/package.json
deps/npm/node_modules/npm-registry-client/test/retries.js
deps/npm/node_modules/npmconf/npmconf.js
deps/npm/node_modules/npmconf/package.json
deps/npm/node_modules/read-installed/package.json
deps/npm/node_modules/read-installed/read-installed.js
deps/npm/node_modules/read-package-json/package.json
deps/npm/node_modules/read-package-json/read-json.js
deps/npm/node_modules/read/README.md
deps/npm/node_modules/read/lib/read.js
deps/npm/node_modules/read/node_modules/mute-stream/mute.js
deps/npm/node_modules/read/node_modules/mute-stream/package.json
deps/npm/node_modules/read/node_modules/mute-stream/test/basic.js
deps/npm/node_modules/read/package.json
deps/npm/node_modules/read/test/basic.js
deps/npm/node_modules/read/test/defaults.js
deps/npm/node_modules/read/test/many.js
deps/npm/node_modules/request/README.md
deps/npm/node_modules/request/aws2.js [deleted file]
deps/npm/node_modules/request/main.js
deps/npm/node_modules/request/package.json
deps/npm/node_modules/request/tests/server.js
deps/npm/node_modules/request/tests/test-body.js
deps/npm/node_modules/request/tests/test-defaults.js
deps/npm/node_modules/request/tests/test-follow-all-303.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-follow-all.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-https-strict.js
deps/npm/node_modules/request/tests/test-https.js
deps/npm/node_modules/request/tests/test-params.js
deps/npm/node_modules/request/tests/test-protocol-changing-redirect.js [new file with mode: 0644]
deps/npm/node_modules/request/tests/test-s3.js [deleted file]
deps/npm/node_modules/request/tests/test-tunnel.js
deps/npm/node_modules/request/tunnel.js
deps/npm/package.json
deps/npm/test/tap/publish-config.js [new file with mode: 0644]

diff --git a/deps/npm/.travis.yml b/deps/npm/.travis.yml
deleted file mode 100644 (file)
index a385519..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-language: node_js
-before_install: "make &>out || cat out; rm out"
-node_js:
-  - 0.8
index 57fdf6afa89301d34e9aa0f85ac8a4b205eb8a88..d1306adb7daa0caaa6ea821b2567ce9fa678b33b 100644 (file)
@@ -75,3 +75,5 @@ Don Park <donpark@docuverse.com>
 Kei Son <heyacct@gmail.com>
 Nicolas Morel <marsup@gmail.com>
 Mark Dube <markisdee@gmail.com>
+Maxim Bogushevich <boga1@mail.ru>
+Justin Beckwith <justbe@microsoft.com>
diff --git a/deps/npm/doc/cli/dedupe.md b/deps/npm/doc/cli/dedupe.md
new file mode 100644 (file)
index 0000000..220329a
--- /dev/null
@@ -0,0 +1,53 @@
+npm-dedupe(1) -- Reduce duplication
+===================================
+
+## SYNOPSIS
+
+    npm dedupe [package names...]
+
+## DESCRIPTION
+
+Searches the local package tree and attempts to simplify the overall
+structure by moving dependencies further up the tree, where they can
+be more effectively shared by multiple dependent packages.
+
+For example, consider this dependency graph:
+
+    a
+    +-- b <-- depends on c@1.0.x
+    |   `-- c@1.0.3
+    `-- d <-- depends on c@~1.0.9
+        `-- c@1.0.10
+
+In this case, `npm-dedupe(1)` will transform the tree to:
+
+    a
+    +-- b
+    +-- d
+    `-- c@1.0.10
+
+Because of the hierarchical nature of node's module lookup, b and d
+will both get their dependency met by the single c package at the root
+level of the tree.
+
+If a suitable version exists at the target location in the tree
+already, then it will be left untouched, but the other duplicates will
+be deleted.
+
+If no suitable version can be found, then a warning is printed, and
+nothing is done.
+
+If any arguments are supplied, then they are filters, and only the
+named packages will be touched.
+
+Note that this operation transforms the dependency tree, and may
+result in packages getting updated versions, perhaps from the npm
+registry.
+
+This feature is experimental, and may change in future versions.
+
+## SEE ALSO
+
+* npm-ls(1)
+* npm-update(1)
+* npm-install(1)
index ee88f3d8f37a393de3ee92894543c9bc7bc7848f..b2ffd1317970abd2ab1040dcd144c247fe9d6ce9 100644 (file)
@@ -46,6 +46,10 @@ npm-index(1) -- Index of all npm documentation
 
  Manage the npm configuration file
 
+## npm-dedupe(1)
+
+ Reduce duplication
+
 ## npm-deprecate(1)
 
  Deprecate a version of a package
index d3650c27777ec9c370d33386bd7264ee1f42a1f0..8aa2d9572c8068f06cfc1196bdd21de10d8ad24a 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.49</p>
+<p id="footer">bin &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 41c5d2bfbe30cdcf36ce237c1cced0a0ec4aaa0a..219b8034e341b8d04b326340c05fd5f58fc54345 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.49</p>
+<p id="footer">bugs &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2003aca946a1028bf4ee985127f51b50ac6ad0ec..43af61fb47d326a0d9f097ca4fadd01838be5bb8 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.49</p>
+<p id="footer">commands &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 01e720390bb963a7493036e26ebf1d1436c1452b..b7fe10b48abcebb24879ed2fb20691c6cf23cf16 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.49</p>
+<p id="footer">config &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2ba085bd2a4159e25bd7eb05be01a0f67477bbf7..7e72b887cea09608acaed76789a37fdee25443c5 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.49</p>
+<p id="footer">deprecate &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 79e6b98f39573e75b97a6a00eed7aa42a6513978..f86ed17ba6106d6d9ce2755b25158f7e4a00a1bc 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.49</p>
+<p id="footer">docs &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 576a866c0ef045dabe92694cd814f4e184db9581..a3fc44cbab9ec34a1151aa77c8418d65741c177e 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.49</p>
+<p id="footer">edit &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 92dcc7d8c7d01df2b491d49778204f6f66368968..cdcef388428d46cb6643f2039ec2d78ac554a5a1 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 &#39;args&#39; 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.49</p>
+<p id="footer">explore &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5ca7c75681615edc26257a385510fd7d250035ea..1bc95b56c7df131e54d9df1e7e141fbb67b91e55 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.49</p>
+<p id="footer">help-search &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 720ef2b4632aab5b9dffaad062e706009ad65a45..eaf4cd3501275030b41b24ba059298b9066c7826 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.49</p>
+<p id="footer">init &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6faf410bf9557cac593f3b9f35c6c6065c333654..48af7a17df625e6364b3cf4129b18124f9f931b3 100644 (file)
@@ -25,7 +25,7 @@ the name of a package to be installed.</p>
 <p>Finally, &#39;callback&#39; 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.49</p>
+<p id="footer">install &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 28334bc31ba8c3d6b1b57acdfd6c5abd9a830ea6..440491a4f98fef684088d4e009b0486cedf6d80d 100644 (file)
@@ -39,7 +39,7 @@ npm.commands.link(&#39;redis&#39;, 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.49</p>
+<p id="footer">link &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 075e1aa43f13c7af41f2963d46aff4af8f503d1c..ca635512852f11b8de461b4478b25581d83a9bdc 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.49</p>
+<p id="footer">load &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8eeb35b406fddafa0dfc8fe38264ce440d401a42..38fc4e16f7ad62729ce2354aa9a068ee589da90d 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.49</p>
+<p id="footer">ls &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e761aee1c53af517e4b414a141271792716ebd14..57e29b601f96ce9f573872384d38076bd08c865d 100644 (file)
@@ -24,7 +24,7 @@ npm.load(configObject, function (er, npm) {
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.49</p>
+<p>1.1.55</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(&quot;unp&quot;) // cmd === &quot;unpublish&quot;</code></pre>
 </div>
-<p id="footer">npm &mdash; npm@1.1.49</p>
+<p id="footer">npm &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e867abf73b719d6f1158be6df4280890ef23c52b..8e17b408242d191bf48b081cd865945a21f9db48 100644 (file)
@@ -19,7 +19,7 @@ currently outdated.</p>
 
 <p>If the &#39;packages&#39; parameter is left out, npm will check all packages.</p>
 </div>
-<p id="footer">outdated &mdash; npm@1.1.49</p>
+<p id="footer">outdated &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index df85a9dddb4be656ac998121956aa91d31ced516..1a1b366cd263a8445b16ab3dedfbdec0c5cb1087 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.49</p>
+<p id="footer">owner &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0409c5c949cf07da81fa4f9d6927f4d46b2090aa..bdc713f210cf47ab4623416e02fcb6837288fce3 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.49</p>
+<p id="footer">pack &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ecc978e7202dbf2665cfff1b257f26069a7acc0e..a9324dc42148a1447e2deb9dffcd68d960b98457 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">prefix &mdash; npm@1.1.49</p>
+<p id="footer">prefix &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6b9c3a8892215558c349b0cfb632e5ab24249931..a81dd499716f6fadfc3d604a77cd92b3aa367f6c 100644 (file)
@@ -23,7 +23,7 @@
 <p>Extraneous packages are packages that are not listed on the parent
 package&#39;s dependencies list.</p>
 </div>
-<p id="footer">prune &mdash; npm@1.1.49</p>
+<p id="footer">prune &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 48dce3f7a34500ea28eb62122d8c7c2a88e99d27..6df771b9cbb173d5a32d6e63247ea3b3253c6a56 100644 (file)
@@ -32,7 +32,7 @@ the registry.  Overwrites when the &quot;force&quot; environment variable is set
 
 <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.49</p>
+<p id="footer">publish &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dcde5ae6f7f652b56ec82a6044e7c72b21f7969a..664afdce09720a2e3333bf201f01c6435b9954ee 100644 (file)
@@ -22,7 +22,7 @@ the new binary. If no &#39;packages&#39; parameter is specify, every package wil
 
 <p>See <code>npm help build</code></p>
 </div>
-<p id="footer">rebuild &mdash; npm@1.1.49</p>
+<p id="footer">rebuild &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 7edf903a101b1b8b44e2797b4f07c7237f813d12..3222a4512a1db9d0340f4bc5f40b46491fd49626 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.49</p>
+<p id="footer">restart &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4237ca80e1b2e90278e6c70c81c7be7e25ede800..fe58151dc143a1bfc0fcb3b98fb3fd3ce55b237e 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically.</p>
 </div>
-<p id="footer">root &mdash; npm@1.1.49</p>
+<p id="footer">root &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 3ee6d888953ac84577b3dcf23956d1b7bd7eacb8..f1026bc0607ef53f46f18f8e0bf6957ef40943bf 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.49</p>
+<p id="footer">run-script &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4d9ce2b1591f8fc26b124bdd48389f75d480397f..59c1ebae52d647d496692f1d534bdd70c0ce32e4 100644 (file)
@@ -32,7 +32,7 @@ excluded term (the &quot;searchexclude&quot; config). The search is case insensi
 and doesn&#39;t try to read your mind (it doesn&#39;t do any verb tense matching or the
 like).</p>
 </div>
-<p id="footer">search &mdash; npm@1.1.49</p>
+<p id="footer">search &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 2667ac658bf5b123977296c71207e284ba1f3b56..4a010ebc456a9d9e378db271ead0572a0ced54f8 100644 (file)
@@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p>
 <p>Finally, &#39;callback&#39; is a function that will be called when the shrinkwrap has
 been saved.</p>
 </div>
-<p id="footer">shrinkwrap &mdash; npm@1.1.49</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8f5c26fffd249cbce0efdbe43810e45c56c36515..d8b38370616a2c26fef5ce16b989e5f420854072 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.49</p>
+<p id="footer">start &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 8888693a3f1c26d71085994b9af1b3e0b876aceb..bad5cc70aabd7901e56a3b6843baf796bb763e5e 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.49</p>
+<p id="footer">stop &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c9a6fc4a74accd30a93f72aa2d8258ac07a4f076..b19872f8ae0627c100fedb30e1e257f9f2b27a7d 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.49</p>
+<p id="footer">submodule &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dc8e9e416b9ae7540d26d49cf25f881874ef7825..4c7e48b7c244ab195d08b5eecb1fb3a69d5d9d41 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.49</p>
+<p id="footer">tag &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 9de59596dc8480c7b1926eebad3825b0ef8215a7..47257521ef9c31acea0d2342f1c1c2e057bd4bcf 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.49</p>
+<p id="footer">test &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index dfdf1c6c94a384bbb42cdc97ad6cfc34e4b85fb6..7ebf4d20afb6b7dde81b9153a0255f386c47a706 100644 (file)
@@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p>
 <p>Finally, &#39;callback&#39; 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.49</p>
+<p id="footer">uninstall &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ca4dd634a5eccb1ccd7b99a9fbe35812835d317e..071d3bdca0fcb0540a2dac65ea0f58ead238eea1 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.49</p>
+<p id="footer">unpublish &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5149b3555db5b93f97e993699f4913128ecd6142..34badda33cab8c60505fc3afa6db2e3ddf554ca9 100644 (file)
@@ -18,7 +18,7 @@
 
 <p>The &#39;packages&#39; argument is an array of packages to update. The &#39;callback&#39; parameter will be called when done or when an error occurs.</p>
 </div>
-<p id="footer">update &mdash; npm@1.1.49</p>
+<p id="footer">update &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a4104a84de0660289d55160b3fd4a6debab1efe1..ba51d91542a72ddce778f6979b297c38c3eea4a5 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.49</p>
+<p id="footer">version &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 056b39b59bb8d29bcb85d6e70163fae0338058a3..87249b01997025602ee53282c947cd91ad2cc052 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.49</p>
+<p id="footer">view &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0c694baa89740bb8898b2acae00bad40b8ec728a..22ba012499b94699b82ef5d930776fc73f95759a 100644 (file)
@@ -21,7 +21,7 @@
 
 <p>This function is not useful programmatically</p>
 </div>
-<p id="footer">whoami &mdash; npm@1.1.49</p>
+<p id="footer">whoami &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c97a90d14635b1aa8f0092c6db24acc0aa357ba6..48744c98d7d33eb7a29bc175e3360a790d89963e 100644 (file)
@@ -240,7 +240,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.49</p>
+<p id="footer"><a href="../doc/README.html">README</a> &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4eddcd1295b4d4b0e69e698c62b84f531d7f74db..f75c5f0c2f41f158d1954ddd2d184bb05affb74c 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.49</p>
+<p id="footer">adduser &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 211c2aab459129cbacebd7ab76e5ff790573efd2..e913367141bffbc9f8eb0bf54d81694446c77e0a 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.49</p>
+<p id="footer">bin &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e933cace77104993c05f5063438fcacb955a2954..337913de3c224c10b84dfdea2a2c80ba4f58b175 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.49</p>
+<p id="footer">bugs &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d15f2ea2f7163e6a965c3cf5ab74bfeffd64921d..79b481d9b9b1d5dc01777c0bdddf9722efd1861c 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.49</p>
+<p id="footer">build &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 40f049eb369930a8eda6081f99b49d5bfa2c9f25..eb0767e23b94df75ed4487e3c75134efeb8cb2d8 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.49</p>
+<p id="footer">bundle &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f4dfc77e82aa0f99bc668119567d05807a0d6487..69225b4f312a41a4794398cbff50746a50eda2b7 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.49</p>
+<p id="footer">cache &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 87c98d4e8055b7bfa44f73fffa1ebf57cbccd773..a3043518825ec61e2abe70fb274e9f07f7d62edc 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.49</p>
+<p id="footer">changelog &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b13fee073d09c226f6d44fac18ff6d0a139dfea3..00d848504ada06fdf978ba89c959066e7f6ad05e 100644 (file)
@@ -180,7 +180,7 @@ set to anything.&quot;</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.49</p>
+<p id="footer">coding-style &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 34084fa18301866b7f724b422632cf67cd8c70ba..3b06ec7d0ec6f5afdfdca1b5178c3dc68c16a30d 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.49</p>
+<p id="footer">completion &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 86dbd2b46040b3f8c2219bc26a719fbd4a37b036..d7410da18a04a57d303d1cef63f8f7761fa5c235 100644 (file)
@@ -748,7 +748,7 @@ then answer &quot;no&quot; 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.49</p>
+<p id="footer">config &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/html/doc/dedupe.html b/deps/npm/html/doc/dedupe.html
new file mode 100644 (file)
index 0000000..f549081
--- /dev/null
@@ -0,0 +1,92 @@
+<!doctype html>
+<html>
+  <title>dedupe</title>
+  <meta http-equiv="content-type" value="text/html;utf-8">
+  <link rel="stylesheet" type="text/css" href="../static/style.css">
+
+  <body>
+    <div id="wrapper">
+<h1><a href="../doc/dedupe.html">dedupe</a></h1> <p>Reduce duplication</p>
+
+<h2 id="SYNOPSIS">SYNOPSIS</h2>
+
+<pre><code>npm dedupe [package names...]</code></pre>
+
+<h2 id="DESCRIPTION">DESCRIPTION</h2>
+
+<p>Searches the local package tree and attempts to simplify the overall
+structure by moving dependencies further up the tree, where they can
+be more effectively shared by multiple dependent packages.</p>
+
+<p>For example, consider this dependency graph:</p>
+
+<pre><code>a
++-- b &lt;-- depends on c@1.0.x
+|   `-- c@1.0.3
+`-- d &lt;-- depends on c@~1.0.9
+    `-- c@1.0.10</code></pre>
+
+<p>In this case, <code><a href="../doc/dedupe.html">dedupe(1)</a></code> will transform the tree to:</p>
+
+<pre><code>a
++-- b
++-- d
+`-- c@1.0.10</code></pre>
+
+<p>Because of the hierarchical nature of node&#39;s module lookup, b and d
+will both get their dependency met by the single c package at the root
+level of the tree.</p>
+
+<p>If a suitable version exists at the target location in the tree
+already, then it will be left untouched, but the other duplicates will
+be deleted.</p>
+
+<p>If no suitable version can be found, then a warning is printed, and
+nothing is done.</p>
+
+<p>If any arguments are supplied, then they are filters, and only the
+named packages will be touched.</p>
+
+<p>Note that this operation transforms the dependency tree, and may
+result in packages getting updated versions, perhaps from the npm
+registry.</p>
+
+<p>This feature is experimental, and may change in future versions.</p>
+
+<h2 id="SEE-ALSO">SEE ALSO</h2>
+
+<ul><li><a href="../doc/ls.html">ls(1)</a></li><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul>
+</div>
+<p id="footer">dedupe &mdash; npm@1.1.55</p>
+<script>
+;(function () {
+var wrapper = document.getElementById("wrapper")
+var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
+  .filter(function (el) {
+    return el.parentNode === wrapper
+        && el.tagName.match(/H[1-6]/)
+        && el.id
+  })
+var l = 2
+  , toc = document.createElement("ul")
+toc.innerHTML = els.map(function (el) {
+  var i = el.tagName.charAt(1)
+    , out = ""
+  while (i > l) {
+    out += "<ul>"
+    l ++
+  }
+  while (i < l) {
+    out += "</ul>"
+    l --
+  }
+  out += "<li><a href='#" + el.id + "'>" +
+    ( el.innerText || el.text || el.innerHTML)
+    + "</a>"
+  return out
+}).join("\n")
+toc.id = "toc"
+document.body.appendChild(toc)
+})()
+</script>
+</body></html>
index 68f7d3013e93cda553c2c1125186d6bc3ddd60cf..b21e768a5c3747fd8109b6c9e4720bc8adc77f82 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.49</p>
+<p id="footer">deprecate &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a6c30b0132244a0d45ad710434c35854cfea1a56..dfebc19f95e192c2aadab6c5ae13ba8ceab0541b 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.49</p>
+<p id="footer">developers &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5cda8b1af1b192f781f9351c1a76fd91e7a49ae6..ffd47c6cdf9caab07de46892e31b0d8af6be55c9 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.49</p>
+<p id="footer">disputes &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 887cfddd81a0d79ac6f5152af9af7742d7c06225..c02c1bd4ab5646a19f22fbd16c4c77a440d905a8 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.49</p>
+<p id="footer">docs &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ab81081dcdb01eadb7db87f74d11a72991b9a06e..5f2ec47c0fdbd29a5f8665d6881cc7d90e2e35a6 100644 (file)
@@ -37,7 +37,7 @@ or <code>&quot;notepad&quot;</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.49</p>
+<p id="footer">edit &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 90d8d68c48553b8423a81dc085f14c3c95546d28..9bac57cf1659ab82517d2a42d4b21877cfd0b48d 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.49</p>
+<p id="footer">explore &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f9337fc6be11f63a2ddc5829bf1e7c8b68ed6191..9a0063edeb9be6f9cc6ae37e3e2bd77a36c722e6 100644 (file)
@@ -241,7 +241,7 @@ We&#39;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.49</p>
+<p id="footer">faq &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c5ab5d42b65fdd9445ddffd087db39bfe5995068..fd929805e31574365be37528aec22161b6a7ca83 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.49</p>
+<p id="footer">folders &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c1780e75e8b0f75bd51e564198c004a58774a3ea..bfd5d3a39864b579a863e77ef9af6523b04a2e87 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.49</p>
+<p id="footer">help-search &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index df582efbf7465aeacad8761239d6a764af24060f..dec4a9f1cea2709708e4aa2c4c08b7dc0149ea2b 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.49</p>
+<p id="footer">help &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e430b5b4dfac0a1ed76e4643e426de272ade7944..2ceb2b6a0a696167991ec6955fa9822c3cdfc3a9 100644 (file)
 
 <p> Manage the npm configuration file</p>
 
+<h2 id="npm-dedupe-1"><a href="../doc/dedupe.html">dedupe(1)</a></h2>
+
+<p> Reduce duplication</p>
+
 <h2 id="npm-deprecate-1"><a href="../doc/deprecate.html">deprecate(1)</a></h2>
 
 <p> Deprecate a version of a package</p>
 
 <p> Display npm username</p>
 </div>
-<p id="footer">index &mdash; npm@1.1.49</p>
+<p id="footer">index &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5fed6472a03bdb39f8de601b67a8742dee3475fd..322e63c15fd5df14054f37aab6996d919f36fa19 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.49</p>
+<p id="footer">init &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 257a45cc4954e18c467642d56c656d5de52a3a28..502e2be4692edc2db428cb1a10d7951a2d8776d0 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.49</p>
+<p id="footer">install &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index cdeeaa1fcd4d5496589e4c145a14be40f41d859b..f26d01e54bd29acfc7180274cc59624fbfa7dabf 100644 (file)
@@ -525,7 +525,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.49</p>
+<p id="footer">json &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fc953920e53ecae5c1720ae18cdf53bf6aa1d434..443e92899354a96994e6a42a1add51e74ad15bfe 100644 (file)
@@ -58,7 +58,7 @@ installation target into your project&#39;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.49</p>
+<p id="footer">link &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b17f6fc97f8106f6a50c93794011074ce5c4b2b0..eeff3abf7ac64987727c138e3ce8abc008aa0778 100644 (file)
@@ -25,7 +25,7 @@ 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&#39;s source tree will show:</p>
 
-<pre><code>npm@1.1.49 /path/to/npm
+<pre><code>npm@1.1.55 /path/to/npm
 â””─┬ init-package-json@0.0.4
   â””── promzard@0.1.5</code></pre>
 
@@ -64,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.49</p>
+<p id="footer">list &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 83324b92cd47c11440a6ee7150661c3819c9c3d4..4ddfb3a3d90dfbfaa9e9803eebf0d33a2ee1fa98 100644 (file)
@@ -14,7 +14,7 @@
 
 <h2 id="VERSION">VERSION</h2>
 
-<p>1.1.49</p>
+<p>1.1.55</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.49</p>
+<p id="footer">npm &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 607bdd070c95281f0cd819098278f34c46ed5efc..a399607a5c75b5f07ddca05f6510c521868a819a 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.49</p>
+<p id="footer">outdated &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index c2991bac8017e8805ccd46315710a0f0f1aa2206..00239e4a9a87606d3204a0e4543aaa22cec0c0f2 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.49</p>
+<p id="footer">owner &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index f7223cee8dfa3804612c510f942cb4926535977e..178c7fe074e05db33c38d8ee8bf21b78ba9864d8 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.49</p>
+<p id="footer">pack &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 4c74d1f37d13e853cb9a6c53108eed49c3b4d456..8dece479000be7daf7b43c10ab1dd44c0954a823 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.49</p>
+<p id="footer">prefix &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 05bd29bcbdb291c4968b59e1f5a1d8b51186b49a..edbcf34ca48c9e71d1d2c33b6c84bc8efec68db7 100644 (file)
@@ -25,7 +25,7 @@ package&#39;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.49</p>
+<p id="footer">prune &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d028b8479359734c7564843368c8eb79fa2cac4f..184543d43fc4e624918b9dd4efdd91640c52ff35 100644 (file)
@@ -29,7 +29,7 @@ the registry.  Overwrites when the &quot;--force&quot; 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.49</p>
+<p id="footer">publish &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index ca1ad33ba33da69dccaec20c2cd63e689ecebeb3..88d1dc39f314419e3fd712e0c2867b0661ad9f67 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.49</p>
+<p id="footer">rebuild &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 5ef97da14196068675e6351f830b1685aaff0cae..1ff9fdfa3fb7accd72434b7308ad27039cedc854 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.49</p>
+<p id="footer">registry &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 024122a2c5efe079ee25c299dd4ea95dc37782ea..c2b2fe19778902a04f6b4c24e979fab8f239857b 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.49</p>
+<p id="footer">removing-npm &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 251780cb63c462eb6b99c88ade1cebe0e29fddbc..d9c4c155c407f90fe94968c9b1ed0c5b7361a563 100644 (file)
@@ -24,7 +24,7 @@ the &quot;start&quot; 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.49</p>
+<p id="footer">restart &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index fc8ecad30b7f3ab1c1d2232e56c68cdb0a421717..210f22eff432072de42bece2a169dbb125cfc90b 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.49</p>
+<p id="footer">root &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index d28e1b2db5f6a973cc6d0a4106986c69629ef5db..3bcba2dac3b06fb69bc362d742bf1038a1e0c558 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.49</p>
+<p id="footer">run-script &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e71d621cc53a410bd38f7c02ff3048178f41b7a8..441418dfb9fb2994e7e0c23a5b0ee87d6303d5be 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.49</p>
+<p id="footer">scripts &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e002a40f2d17b063b5b99cc710b55739ac5faafe..ff21fe7a99361c5e76a4a511614f7af6c4a68431 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.49</p>
+<p id="footer">search &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 46bce35f05c7902dc2110a53a0db72e248590550..ee114b9b43300649d53dd82c92733d110f09e826 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.49</p>
+<p id="footer">semver &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index de942cc0517e311ef5901264ae33172cff610414..884f674dfe62e54b7ee49d1459c5166e940450be 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.49</p>
+<p id="footer">shrinkwrap &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b06ce6afa2ee2c95aed664ef9a0fa6aa78beae96..2e0fa1df1258b24ba462dc7dfe7912d3811bf6a2 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.49</p>
+<p id="footer">star &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 792c5ef258d9f990cfd3dccc67a4c4ac7d06ed9d..b80fd81fb2e26e820f52ee6835376327a082caba 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.49</p>
+<p id="footer">start &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index a73dc1c7f576f73e2a3eefce7e6ec31d3182f9b0..800fa1d8160b0e7e600a1745816e479f365a07cf 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.49</p>
+<p id="footer">stop &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 45660e8ba61ee06cae6b460994ecd735a0f8d8da..3b58ed98d5f57c4706bdf80914554c9a6d16319c 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.49</p>
+<p id="footer">submodule &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b42386d01b44f4b5ae974e3c553da7f0842dde24..1cfeeba743137d92513259481801b2ea87d96373 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.49</p>
+<p id="footer">tag &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 93a49d0d3d60a621a7deab20e42c5eb788762ef5..21890436f1bd548b19fbb4b807415bb0c9245b4d 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.49</p>
+<p id="footer">test &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 6b3c715f06d882212f3478c523bbd30e4d24c745..cbc5835bb024d58229c33b8d2438cc373220b619 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.49</p>
+<p id="footer">uninstall &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index e1a6560a05b6d827affd779d51f2b8ad2b72f228..36442c872adb39d9948ff5365ea7c9ba94e1f8a3 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.49</p>
+<p id="footer">unpublish &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 64a0a820cf67a632d8fbdb33277dddda5ac94829..10053a78975fda08e7eadeef67afb16a4f7572d6 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.49</p>
+<p id="footer">update &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index b9a0acd3bc765168bde8b30aa24f971084ea5c0a..b6269a5f760bf42864feca2ccc001145b57b8ef2 100644 (file)
@@ -40,7 +40,7 @@ in your git config for this to work properly.</p>
 
 <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.49</p>
+<p id="footer">version &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 0742a1fb4a9eacde38b406cad6ae8ae373a9aa92..5877aaea3e16af78a93e67dece9f2a2f88d813c6 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.49</p>
+<p id="footer">view &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
index 1d4ee84cfca2fcb69759abe52cfedccc9752fd87..342e4d1f17debd94ea821b82135bcf9a3cf602ca 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.49</p>
+<p id="footer">whoami &mdash; npm@1.1.55</p>
 <script>
 ;(function () {
 var wrapper = document.getElementById("wrapper")
diff --git a/deps/npm/lib/dedupe.js b/deps/npm/lib/dedupe.js
new file mode 100644 (file)
index 0000000..9a35790
--- /dev/null
@@ -0,0 +1,334 @@
+// traverse the node_modules/package.json tree
+// looking for duplicates.  If any duplicates are found,
+// then move them up to the highest level necessary
+// in order to make them no longer duplicated.
+//
+// This is kind of ugly, and really highlights the need for
+// much better "put pkg X at folder Y" abstraction.  Oh well,
+// whatever.  Perfect enemy of the good, and all that.
+
+var fs = require("fs")
+var asyncMap = require("slide").asyncMap
+var path = require("path")
+var readJson = require("read-package-json")
+var archy = require("archy")
+var util = require("util")
+var RegClient = require("npm-registry-client")
+var npmconf = require("npmconf")
+var npm = require("npm")
+var semver = require("semver")
+var npm = require("npm")
+var rimraf = require("rimraf")
+var log = require("npmlog")
+var npm = require("./npm.js")
+
+module.exports = dedupe
+
+dedupe.usage = "npm dedupe [pkg pkg...]"
+
+function dedupe (args, silent, cb) {
+  if (typeof silent === "function") cb = silent, silent = false
+  var dryrun = false
+  if (npm.command.match(/^find/)) dryrun = true
+  return dedupe_(npm.prefix, args, {}, dryrun, silent, cb)
+}
+
+function dedupe_ (dir, filter, unavoidable, dryrun, silent, cb) {
+  readInstalled(path.resolve(dir), {}, null, function (er, data, counter) {
+    // find out which things are dupes
+    var dupes = Object.keys(counter).filter(function (k) {
+      if (filter.length && -1 === filter.indexOf(k)) return false
+      return counter[k] > 1 && !unavoidable[k]
+    }).reduce(function (s, k) {
+      s[k] = []
+      return s
+    }, {})
+
+    // any that are unavoidable need to remain as they are.  don't even
+    // try to touch them or figure it out.  Maybe some day, we can do
+    // something a bit more clever here, but for now, just skip over it,
+    // and all its children.
+    ;(function U (obj) {
+      if (unavoidable[obj.name]) {
+        obj.unavoidable = true
+      }
+      if (obj.parent && obj.parent.unavoidable) {
+        obj.unavoidable = true
+      }
+      Object.keys(obj.children).forEach(function (k) {
+        U(obj.children[k])
+      })
+    })
+
+    // then collect them up and figure out who needs them
+    ;(function C (obj) {
+      if (dupes[obj.name] && !obj.unavoidable) {
+        dupes[obj.name].push(obj)
+        obj.duplicate = true
+      }
+      obj.dependents = whoDepends(obj)
+      Object.keys(obj.children).forEach(function (k) {
+        C(obj.children[k])
+      })
+    })(data)
+
+    if (dryrun) {
+      var k = Object.keys(dupes)
+      if (!k.length) return cb()
+      return npm.commands.ls(k, silent, cb)
+    }
+
+    var summary = Object.keys(dupes).map(function (n) {
+      return [n, dupes[n].filter(function (d) {
+        return d && d.parent && !d.parent.duplicate && !d.unavoidable
+      }).map(function M (d) {
+        return [d.path, d.version, d.dependents.map(function (k) {
+          return [k.path, k.version, k.dependencies[d.name] || ""]
+        })]
+      })]
+    }).map(function (item) {
+      var name = item[0]
+      var set = item[1]
+
+      var ranges = set.map(function (i) {
+        return i[2].map(function (d) {
+          return d[2]
+        })
+      }).reduce(function (l, r) {
+        return l.concat(r)
+      }, []).map(function (v, i, set) {
+        if (set.indexOf(v) !== i) return false
+        return v
+      }).filter(function (v) {
+        return v !== false
+      })
+
+      var locs = set.map(function (i) {
+        return i[0]
+      })
+
+      var versions = set.map(function (i) {
+        return i[1]
+      }).filter(function (v, i, set) {
+        return set.indexOf(v) === i
+      })
+
+      var has = set.map(function (i) {
+        return [i[0], i[1]]
+      }).reduce(function (set, kv) {
+        set[kv[0]] = kv[1]
+        return set
+      }, {})
+
+      var loc = locs.length ? locs.reduce(function (a, b) {
+        // a=/path/to/node_modules/foo/node_modules/bar
+        // b=/path/to/node_modules/elk/node_modules/bar
+        // ==/path/to/node_modules/bar
+        a = a.split(/\/node_modules\//)
+        b = b.split(/\/node_modules\//)
+        var name = a.pop()
+        b.pop()
+        // find the longest chain that both A and B share.
+        // then push the name back on it, and join by /node_modules/
+        var res = []
+        for (var i = 0, al = a.length, bl = b.length; i < al && i < bl && a[i] === b[i]; i++);
+        return a.slice(0, i).concat(name).join("/node_modules/")
+      }) : undefined
+
+      return [item[0], { item: item
+                       , ranges: ranges
+                       , locs: locs
+                       , loc: loc
+                       , has: has
+                       , versions: versions
+                       }]
+    }).filter(function (i) {
+      return i[1].loc
+    })
+
+    findVersions(npm, summary, function (er, set) {
+      if (er) return cb(er)
+      if (!set.length) return cb()
+      installAndRetest(set, filter, dir, unavoidable, silent, cb)
+    })
+  })
+}
+
+function installAndRetest (set, filter, dir, unavoidable, silent, cb) {
+  //return cb(null, set)
+  var remove = []
+
+  asyncMap(set, function (item, cb) {
+    // [name, has, loc, locMatch, regMatch, others]
+    var name = item[0]
+    var has = item[1]
+    var where = item[2]
+    var locMatch = item[3]
+    var regMatch = item[4]
+    var others = item[5]
+
+    // nothing to be done here.  oh well.  just a conflict.
+    if (!locMatch && !regMatch) {
+      log.warn("unavoidable conflict", item[0], item[1])
+      log.warn("unavoidable conflict", "Not de-duplicating")
+      unavoidable[item[0]] = true
+      return cb()
+    }
+
+    // nothing to do except to clean up the extraneous deps
+    if (locMatch && has[where] === locMatch) {
+      remove.push.apply(remove, others)
+      return cb()
+    }
+
+    if (regMatch) {
+      var what = name + "@" + regMatch
+      // where is /path/to/node_modules/foo/node_modules/bar
+      // for package "bar", but we need it to be just
+      // /path/to/node_modules/foo
+      where = where.split(/\/node_modules\//)
+      where.pop()
+      where = where.join("/node_modules/")
+      remove.push.apply(remove, others)
+
+      return npm.commands.install(where, what, cb)
+    }
+
+    // hrm?
+    return cb(new Error("danger zone\n" + name + " " +
+                        + regMatch + " " + locMatch))
+
+  }, function (er, installed) {
+    if (er) return cb(er)
+    asyncMap(remove, rimraf, function (er) {
+      if (er) return cb(er)
+      remove.forEach(function (r) {
+        log.info("rm", r)
+      })
+      dedupe_(dir, filter, unavoidable, false, silent, cb)
+    })
+  })
+}
+
+function findVersions (npm, summary, cb) {
+  // now, for each item in the summary, try to find the maximum version
+  // that will satisfy all the ranges.  next step is to install it at
+  // the specified location.
+  asyncMap(summary, function (item, cb) {
+    var name = item[0]
+    var data = item[1]
+    var loc = data.loc
+    var locs = data.locs.filter(function (l) {
+      return l !== loc
+    })
+
+    // not actually a dupe, or perhaps all the other copies were
+    // children of a dupe, so this'll maybe be picked up later.
+    if (locs.length === 0) {
+      return cb()
+    }
+
+    // { <folder>: <version> }
+    var has = data.has
+
+    // the versions that we already have.
+    // if one of these is ok, then prefer to use that.
+    // otherwise, try fetching from the registry.
+    var versions = data.versions
+
+    var ranges = data.ranges
+    npm.registry.get(name, function (er, data) {
+      var regVersions = er ? [] : Object.keys(data.versions)
+      var locMatch = bestMatch(versions, ranges)
+      var regMatch = bestMatch(regVersions, ranges)
+
+      cb(null, [[name, has, loc, locMatch, regMatch, locs]])
+    })
+  }, cb)
+}
+
+function bestMatch (versions, ranges) {
+  return versions.filter(function (v) {
+    return !ranges.some(function (r) {
+      return !semver.satisfies(v, r)
+    })
+  }).sort(semver.compare).pop()
+}
+
+
+function readInstalled (dir, counter, parent, cb) {
+  var pkg, children, realpath
+
+  fs.realpath(dir, function (er, rp) {
+    realpath = rp
+    next()
+  })
+
+  readJson(path.resolve(dir, "package.json"), function (er, data) {
+    if (er) return cb() // not a package, probably.
+    counter[data.name] = counter[data.name] || 0
+    counter[data.name]++
+    pkg =
+      { _id: data._id
+      , name: data.name
+      , version: data.version
+      , dependencies: data.dependencies || {}
+      , optionalDependencies: data.optionalDependencies || {}
+      , devDependencies: data.devDependencies || {}
+      , bundledDependencies: data.bundledDependencies || []
+      , path: dir
+      , realPath: dir
+      , children: {}
+      , parent: parent
+      , family: Object.create(parent ? parent.family : null)
+      , unavoidable: false
+      , duplicate: false
+      }
+    if (parent) {
+      parent.children[data.name] = pkg
+      parent.family[data.name] = pkg
+    }
+    next()
+  })
+
+  fs.readdir(path.resolve(dir, "node_modules"), function (er, c) {
+    children = c || [] // error is ok, just means no children.
+    next()
+  })
+
+  function next () {
+    if (!children || !pkg || !realpath) return
+
+    // ignore devDependencies.  Just leave them where they are.
+    children = children.filter(function (c) {
+      return !pkg.devDependencies.hasOwnProperty(c)
+    })
+
+    pkg.realPath = realpath
+    if (pkg.realPath !== pkg.path) children = []
+    var d = path.resolve(dir, "node_modules")
+    asyncMap(children, function (child, cb) {
+      readInstalled(path.resolve(d, child), counter, pkg, cb)
+    }, function (er) {
+      cb(er, pkg, counter)
+    })
+  }
+}
+
+function whoDepends (pkg) {
+  var start = pkg.parent || pkg
+  return whoDepends_(pkg, [], start)
+}
+
+function whoDepends_ (pkg, who, test) {
+  if (test !== pkg &&
+      test.dependencies[pkg.name] &&
+      test.family[pkg.name] === pkg) {
+    who.push(test)
+  }
+  Object.keys(test.children).forEach(function (n) {
+    whoDepends_(pkg, who, test.children[n])
+  })
+  return who
+}
+
index 0a321b284a94fcaf86d348c95a842bdd9cf7a59f..5728f7343b4048653a4eca6c6c2f2eacad5cdb3e 100644 (file)
@@ -101,6 +101,8 @@ var commandCache = {}
               , "login": "adduser"
               , "add-user": "adduser"
               , "tst": "test"
+              , "find-dupes": "dedupe"
+              , "ddp": "dedupe"
               }
 
   , aliasNames = Object.keys(aliases)
@@ -116,6 +118,7 @@ var commandCache = {}
               , "prune"
               , "submodule"
               , "pack"
+              , "dedupe"
 
               , "rebuild"
               , "link"
@@ -308,28 +311,7 @@ function load (npm, cli, cb) {
         } catch (e) { 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")
-        , tag: npm.config.get("tag")
-        , ca: npm.config.get("ca")
-        , strictSSL: npm.config.get("strict-ssl")
-        , userAgent: npm.config.get("user-agent")
-        , E404: npm.E404
-        , EPUBLISHCONFLICT: npm.EPUBLISHCONFLICT
-        , log: log
-        , retries: npm.config.get("fetch-retries")
-        , 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")
-        })
+      npm.registry = new RegClient(npm.config)
 
       // save the token cookie in the config file
       if (npm.registry.couchLogin) {
@@ -378,15 +360,15 @@ function loadPrefix (npm, conf, cb) {
     }
   })
 
-  findPrefix(gp, function (er, gp) {
-    Object.defineProperty(npm, "globalPrefix",
-      { get : function () { return gp }
-      , set : function (r) { return gp = r }
-      , enumerable : true
-      })
-    // the prefix MUST exist, or else nothing works.
-    mkdir(gp, next)
-  })
+  gp = path.resolve(gp)
+  Object.defineProperty(npm, "globalPrefix",
+    { get : function () { return gp }
+    , set : function (r) { return gp = r }
+    , enumerable : true
+    })
+  // the prefix MUST exist, or else nothing works.
+  mkdir(gp, next)
+
 
   var i = 2
     , errState = null
index 51a9de767b37aefb59aae199f6b54a70a7760818..a84b59786040624b6177e17085db09c7a4902011 100644 (file)
@@ -2,7 +2,6 @@
 module.exports = publish
 
 var npm = require("./npm.js")
-  , registry = npm.registry
   , log = require("npmlog")
   , tar = require("./utils/tar.js")
   , path = require("path")
@@ -10,6 +9,8 @@ var npm = require("./npm.js")
   , fs = require("graceful-fs")
   , lifecycle = require("./utils/lifecycle.js")
   , chain = require("slide").chain
+  , Conf = require("npmconf").Conf
+  , RegClient = require("npm-registry-client")
 
 publish.usage = "npm publish <tarball>"
               + "\nnpm publish <folder>"
@@ -61,11 +62,11 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
   if (!data) return cb(new Error("no package.json file found"))
 
   // check for publishConfig hash
+  var registry = npm.registry
   if (data.publishConfig) {
-    Object.keys(data.publishConfig).forEach(function (k) {
-      log.info("publishConfig", k + "=" + data.publishConfig[k])
-      npm.config.set(k, data.publishConfig[k])
-    })
+    var pubConf = new Conf(npm.config)
+    pubConf.unshift(data.publishConfig)
+    registry = new RegClient(pubConf)
   }
 
   data._npmVersion = npm.version
@@ -77,10 +78,6 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
     ("This package has been marked as private\n"
     +"Remove the 'private' field from the package.json to publish it."))
 
-  regPublish(data, isRetry, arg, cachedir, cb)
-}
-
-function regPublish (data, isRetry, arg, cachedir, cb) {
   var tarball = cachedir + ".tgz"
   registry.publish(data, tarball, function (er) {
     if (er && er.code === "EPUBLISHCONFLICT"
index 68ede5f69986778747c977f658354edbfcf68a7a..7fabd69990669a9651eb08d94673451bf88f4336 100644 (file)
@@ -197,6 +197,12 @@ function errorHandler (er) {
               ,"Move it away, and try again."].join("\n"))
     break
 
+  case "ENEEDAUTH":
+    log.error("need auth", [er.message
+              ,"You need to authorize this machine using `npm adduser`"
+              ].join("\n"))
+    break
+
   case "ENOTSUP":
     if (er.required) {
       log.error("notsup", [er.message
index 6042abc5282bd981b2c4fe0e75ee88b791353ece..b98852066002a1952866a08c3eb85058d6f1756d 100644 (file)
@@ -65,9 +65,10 @@ function makeRequest (remote, fstr, headers) {
       "Auth required and none provided. Please run 'npm adduser'"))
   }
 
-  var proxy = npm.config.get( remote.protocol === "https:"
-                            ? "https-proxy"
-                            : "proxy")
+  var proxy
+  if (remote.protocol !== "https:" || !(proxy = npm.config.get("https-proxy"))) {
+    proxy = npm.config.get("proxy")
+  }
 
   var opts = { url: remote
              , proxy: proxy
index bc2c9598dbb0dabaac96c7a32fda29bab45a5184..c3ff85f593082d103ffa865c28e3cb5a5fefc0c9 100644 (file)
@@ -14,7 +14,6 @@ function findPrefix (p, cb_) {
   }
 
   p = path.resolve(p)
-  if (npm.config.get("global")) return cb(null, p)
   // if there's no node_modules folder, then
   // walk up until we hopefully find one.
   // if none anywhere, then use cwd.
index bdfd48165b6e5f0f04ef8e50f7634377ae782a67..592d83d4cca2ce52063be3cb5bb849c86927e857 100644 (file)
@@ -189,7 +189,7 @@ function printData (data, name, cb) {
     fields.forEach(function (f) {
       var d = cleanup(data[v][f])
       if (showVersions || showFields || typeof d !== "string") {
-        d = util.inspect(cleanup(data[v][f]), false, 5, true)
+        d = util.inspect(cleanup(data[v][f]), false, 5, npm.color)
       }
       if (f && showFields) f += " = "
       if (d.indexOf("\n") !== -1) d = "\n" + d
diff --git a/deps/npm/man/man1/dedupe.1 b/deps/npm/man/man1/dedupe.1
new file mode 100644 (file)
index 0000000..35b0d1d
--- /dev/null
@@ -0,0 +1,90 @@
+.\" Generated with Ronnjs 0.3.8
+.\" http://github.com/kapouer/ronnjs/
+.
+.TH "NPM\-DEDUPE" "1" "August 2012" "" ""
+.
+.SH "NAME"
+\fBnpm-dedupe\fR \-\- Reduce duplication
+.
+.SH "SYNOPSIS"
+.
+.nf
+npm dedupe [package names\.\.\.]
+.
+.fi
+.
+.SH "DESCRIPTION"
+Searches the local package tree and attempts to simplify the overall
+structure by moving dependencies further up the tree, where they can
+be more effectively shared by multiple dependent packages\.
+.
+.P
+For example, consider this dependency graph:
+.
+.IP "" 4
+.
+.nf
+a
++\-\- b <\-\- depends on c@1\.0\.x
+|   `\-\- c@1\.0\.3
+`\-\- d <\-\- depends on c@~1\.0\.9
+    `\-\- c@1\.0\.10
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In this case, \fBnpm help dedupe\fR will transform the tree to:
+.
+.IP "" 4
+.
+.nf
+a
++\-\- b
++\-\- d
+`\-\- c@1\.0\.10
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Because of the hierarchical nature of node\'s module lookup, b and d
+will both get their dependency met by the single c package at the root
+level of the tree\.
+.
+.P
+If a suitable version exists at the target location in the tree
+already, then it will be left untouched, but the other duplicates will
+be deleted\.
+.
+.P
+If no suitable version can be found, then a warning is printed, and
+nothing is done\.
+.
+.P
+If any arguments are supplied, then they are filters, and only the
+named packages will be touched\.
+.
+.P
+Note that this operation transforms the dependency tree, and may
+result in packages getting updated versions, perhaps from the npm
+registry\.
+.
+.P
+This feature is experimental, and may change in future versions\.
+.
+.SH "SEE ALSO"
+.
+.IP "\(bu" 4
+npm help ls
+.
+.IP "\(bu" 4
+npm help update
+.
+.IP "\(bu" 4
+npm help install
+.
+.IP "" 0
+
index ec2d9a9f33269813a061879faeb9917871dcf718..2f72291f9e980a66397fcb77a2de43f2f1987a62 100644 (file)
@@ -39,6 +39,9 @@
 .SH "npm help config"
  Manage the npm configuration file
 .
+.SH "npm help dedupe"
+ Reduce duplication
+.
 .SH "npm help deprecate"
  Deprecate a version of a package
 .
index 65db45c02ac5ba7a737baa527a958be2c5e8fa65..8808310e494baffd9e6631d7a34a5f411cb2ca84 100644 (file)
@@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
 .IP "" 4
 .
 .nf
-npm@1.1.49 /path/to/npm
+npm@1.1.55 /path/to/npm
 â””─┬ init\-package\-json@0\.0\.4
   â””── promzard@0\.1\.5
 .
index 522d451aa2d8b3a22ae042b1543d744458a14d54..c0253a1b4b3feb83b95fe3ef51442778ef4aa309 100644 (file)
@@ -14,7 +14,7 @@ npm <command> [args]
 .fi
 .
 .SH "VERSION"
-1.1.49
+1.1.55
 .
 .SH "DESCRIPTION"
 npm is the package manager for the Node JavaScript platform\.  It puts
index cdbccc90cda704a14276fcff71c24caf8d9a39f6..87072e4e34cc213f8e6e4aa35b76e148191fde00 100644 (file)
@@ -21,7 +21,7 @@ npm\.load(configObject, function (er, npm) {
 .fi
 .
 .SH "VERSION"
-1.1.49
+1.1.55
 .
 .SH "DESCRIPTION"
 This is the API documentation for npm\.
index cd7b12c1434a3d3baded606839e3feae20101a48..be037f0f21946f18ff95a955192408ea6a3e88a1 100644 (file)
@@ -283,7 +283,7 @@ function logout (cb) {
   , req = { uri: u, headers: h, json: true }
 
   request.del(req, function (er, res, data) {
-    if (er || res.statusCode !== 200) {
+    if (er || (res.statusCode !== 200 && res.statusCode !== 404)) {
       return cb(er, res, data)
     }
 
index a485486a8f1c887a3dea06ee03bc326f9a0f94a8..7d62b739f6b98dd57e298bf60b93fa548bbb713e 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "couch-login",
   "description": "A module for doing logged-in requests to a couchdb server",
-  "version": "0.1.9",
+  "version": "0.1.10",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/couch-login.git"
@@ -22,6 +22,6 @@
     "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.9",
-  "_from": "couch-login@latest"
+  "_id": "couch-login@0.1.10",
+  "_from": "couch-login@~0.1.9"
 }
diff --git a/deps/npm/node_modules/mkdirp/.gitignore.orig b/deps/npm/node_modules/mkdirp/.gitignore.orig
deleted file mode 100644 (file)
index 9303c34..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules/
-npm-debug.log
\ No newline at end of file
diff --git a/deps/npm/node_modules/mkdirp/.gitignore.rej b/deps/npm/node_modules/mkdirp/.gitignore.rej
deleted file mode 100644 (file)
index 69244ff..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
---- /dev/null
-+++ .gitignore
-@@ -0,0 +1,2 @@
-+node_modules/
-+npm-debug.log
\ No newline at end of file
diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js.orig b/deps/npm/node_modules/mkdirp/examples/pow.js.orig
deleted file mode 100644 (file)
index 7741462..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644 (file)
index 81e7f43..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- 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
index 874b31095a8140367423f8ac098b099336632270..fda6de8a2c2313676c3f28a0b4cd77a1bbfdff28 100644 (file)
@@ -27,18 +27,10 @@ function mkdirP (p, mode, f, made) {
                 });
                 break;
 
-            case 'EISDIR':
-            case 'EPERM':
-                // Operation not permitted or already is a dir.
-                // This is the error you get when trying to mkdir('c:/')
-                // on windows, or mkdir('/') on unix.  Make sure it's a
-                // dir by falling through to the EEXIST case.
-            case 'EROFS':
-                // a read-only file system.
-                // However, the dir could already exist, in which case
-                // the EROFS error will be obscuring a EEXIST!
-                // Fallthrough to that case.
-            case 'EEXIST':
+            // In the case of any other error, just see if there's a dir
+            // there already.  If so, then hooray!  If not, then something
+            // is borked.
+            default:
                 fs.stat(p, function (er2, stat) {
                     // if the stat fails, then that's super weird.
                     // let the original error be the failure reason.
@@ -46,10 +38,6 @@ function mkdirP (p, mode, f, made) {
                     else cb(null, made);
                 });
                 break;
-
-            default:
-                cb(er, made);
-                break;
         }
     });
 }
@@ -74,7 +62,10 @@ mkdirP.sync = function sync (p, mode, made) {
                 sync(p, mode, made);
                 break;
 
-            case 'EEXIST' :
+            // In the case of any other error, just see if there's a dir
+            // there already.  If so, then hooray!  If not, then something
+            // is borked.
+            default:
                 var stat;
                 try {
                     stat = fs.statSync(p);
@@ -84,9 +75,6 @@ mkdirP.sync = function sync (p, mode, made) {
                 }
                 if (!stat.isDirectory()) throw err0;
                 break;
-            default :
-                throw err0
-                break;
         }
     }
 
index f779658374ab237688367641c2b540c27497cb36..0d1eb988be03dceb19be74af2253bccd13be4297 100644 (file)
@@ -1,7 +1,7 @@
 {
   "name": "mkdirp",
   "description": "Recursively mkdir, like `mkdir -p`",
-  "version": "0.3.3",
+  "version": "0.3.4",
   "author": {
     "name": "James Halliday",
     "email": "mail@substack.net",
@@ -14,7 +14,7 @@
   ],
   "repository": {
     "type": "git",
-    "url": "git://github.com/substack/node-mkdirp.git"
+    "url": "http://github.com/substack/node-mkdirp.git"
   },
   "scripts": {
     "test": "tap test/*.js"
   "engines": {
     "node": "*"
   },
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_id": "mkdirp@0.3.3",
-  "dependencies": {},
-  "optionalDependencies": {},
-  "_engineSupported": true,
-  "_npmVersion": "1.1.24",
-  "_nodeVersion": "v0.7.10-pre",
-  "_defaultsLoaded": true,
-  "_from": "mkdirp@0.3"
+  "readme": "mkdirp\n======\n\nLike `mkdir -p`, but in node.js!\n\n[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)\n\nexample\n=======\n\npow.js\n------\n    var mkdirp = require('mkdirp');\n    \n    mkdirp('/tmp/foo/bar/baz', function (err) {\n        if (err) console.error(err)\n        else console.log('pow!')\n    });\n\nOutput\n    pow!\n\nAnd now /tmp/foo/bar/baz exists, huzzah!\n\nmethods\n=======\n\nvar mkdirp = require('mkdirp');\n\nmkdirp(dir, mode, cb)\n---------------------\n\nCreate a new directory and any necessary subdirectories at `dir` with octal\npermission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\n`cb(err, made)` fires with the error or the first directory `made`\nthat had to be created, if any.\n\nmkdirp.sync(dir, mode)\n----------------------\n\nSynchronously create a new directory and any necessary subdirectories at `dir`\nwith octal permission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\nReturns the first directory that had to be created, if any.\n\ninstall\n=======\n\nWith [npm](http://npmjs.org) do:\n\n    npm install mkdirp\n\nlicense\n=======\n\nMIT/X11\n",
+  "_id": "mkdirp@0.3.4",
+  "_from": "mkdirp@~0.3.3"
 }
index 89e71c0c5024ad3c41f947abc67057181a4480ec..1573fa92b21d5a85bc21e9850469d0319f818365 100644 (file)
@@ -15,6 +15,9 @@
       }],
       [ 'OS=="win"', {
         'libraries': [ '-l<(node_root_dir)/$(Configuration)/node.lib' ],
+        # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
+        # needs to have dll-interface to be used by clients of class 'node::ObjectWrap'
+        'msvs_disabled_warnings': [ 4251 ],
       }],
       [ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', {
         'cflags': [ '-fPIC' ],
index dc0a120b98edd30ef140b8703cbf6a26260dd44e..01abdd5a6290647ea66405c29c777fa54226fd26 100644 (file)
@@ -176,9 +176,13 @@ function build (gyp, argv, callback) {
       argv.push('/clp:Verbosity=minimal')
     }
 
-    // Turn off the Microsoft logo on Windows
     if (win) {
+      // Turn off the Microsoft logo on Windows
       argv.push('/nologo')
+
+      // Fix "warning MSB8012: TargetExt(.dll) does not match
+      // the Linker's OutputFile property value (.node)"
+      argv.push('/property:TargetExt=.node')
     }
 
     // Specify the build type, Release by default
index 26c8beb64d8d679cc70ad1f13868b958fa8622c4..58275ee5b3f95035d0537dd60845999dac7f0056 100644 (file)
@@ -83,6 +83,7 @@ proto.configDefs = {
   , proxy: String     // 'install'
   , nodedir: String   // 'configure'
   , loglevel: String  // everywhere
+  , python: String    // 'configure'
 }
 
 /**
index 7fa75a89850320ccf023a1ac27cd2357294c3936..ab5194150b7192dccef4e5f406e02deaa315e326 100644 (file)
@@ -10,7 +10,7 @@
     "bindings",
     "gyp"
   ],
-  "version": "0.6.5",
+  "version": "0.6.7",
   "installVersion": 9,
   "author": {
     "name": "Nathan Rajlich",
@@ -45,6 +45,6 @@
     "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| **Command**   | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build`       | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean`       | Removes any the `build` dir if it exists\n| `configure`   | Generates project build files for the current platform\n| `rebuild`     | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install`     | Installs node development header files for the given version\n| `list`        | Lists the currently installed node development file versions\n| `remove`      | Removes the node development header files for the 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.6.5",
+  "_id": "node-gyp@0.6.7",
   "_from": "node-gyp@~0.6.4"
 }
diff --git a/deps/npm/node_modules/node-uuid/.npmignore b/deps/npm/node_modules/node-uuid/.npmignore
deleted file mode 100644 (file)
index fd4f2b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-.DS_Store
diff --git a/deps/npm/node_modules/node-uuid/LICENSE.md b/deps/npm/node_modules/node-uuid/LICENSE.md
deleted file mode 100644 (file)
index bcdddf9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Copyright (c) 2010 Robert Kieffer
-
-Dual licensed under the [MIT](http://en.wikipedia.org/wiki/MIT_License) and [GPL](http://en.wikipedia.org/wiki/GNU_General_Public_License) licenses.
diff --git a/deps/npm/node_modules/node-uuid/README.md b/deps/npm/node_modules/node-uuid/README.md
deleted file mode 100644 (file)
index a44d9a7..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-# node-uuid
-
-Simple, fast generation of [RFC4122](http://www.ietf.org/rfc/rfc4122.txt) UUIDS.
-
-Features:
-
-* Generate RFC4122 version 1 or version 4 UUIDs
-* Runs in node.js and all browsers.
-* Cryptographically strong random # generation on supporting platforms
-* 1.1K minified and gzip'ed  (Want something smaller?  Check this [crazy shit](https://gist.github.com/982883) out! )
-* [Annotated source code](http://broofa.github.com/node-uuid/docs/uuid.html)
-
-## Getting Started
-
-Install it in your browser:
-
-```html
-<script src="uuid.js"></script>
-```
-
-Or in node.js:
-
-```
-npm install node-uuid
-```
-
-```javascript
-var uuid = require('node-uuid');
-```
-
-Then create some ids ...
-
-```javascript
-// Generate a v1 (time-based) id
-uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
-
-// Generate a v4 (random) id
-uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
-```
-
-## API
-
-### uuid.v1([`options` [, `buffer` [, `offset`]]])
-
-Generate and return a RFC4122 v1 (timestamp-based) UUID.
-
-* `options` - (Object) Optional uuid state to apply. Properties may include:
-
-  * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomnly generated ID.  See note 1.
-  * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence.  Default: An internally maintained clockseq is used.
-  * `msecs` - (Number | Date) Time in milliseconds since unix Epoch.  Default: The current time is used.
-  * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.
-
-* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
-* `offset` - (Number) Starting index in `buffer` at which to begin writing.
-
-Returns `buffer`, if specified, otherwise the string form of the UUID
-
-Notes:
-
-1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.)
-
-Example: Generate string UUID with fully-specified options
-
-```javascript
-uuid.v1({
-  node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
-  clockseq: 0x1234,
-  msecs: new Date('2011-11-01').getTime(),
-  nsecs: 5678
-});   // -> "710b962e-041c-11e1-9234-0123456789ab"
-```
-
-Example: In-place generation of two binary IDs
-
-```javascript
-// Generate two ids in an array
-var arr = new Array(32); // -> []
-uuid.v1(null, arr, 0);   // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15]
-uuid.v1(null, arr, 16);  // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15]
-
-// Optionally use uuid.unparse() to get stringify the ids
-uuid.unparse(buffer);    // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'
-uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'
-```
-
-### uuid.v4([`options` [, `buffer` [, `offset`]]])
-
-Generate and return a RFC4122 v4 UUID.
-
-* `options` - (Object) Optional uuid state to apply. Properties may include:
-
-  * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values
-  * `rng` - (Function) Random # generator to use.  Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values.
-
-* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.
-* `offset` - (Number) Starting index in `buffer` at which to begin writing.
-
-Returns `buffer`, if specified, otherwise the string form of the UUID
-
-Example: Generate string UUID with fully-specified options
-
-```javascript
-uuid.v4({
-  random: [
-    0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea,
-    0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36
-  ]
-});
-// -> "109156be-c4fb-41ea-b1b4-efe1671c5836"
-```
-
-Example: Generate two IDs in a single buffer
-
-```javascript
-var buffer = new Array(32); // (or 'new Buffer' in node.js)
-uuid.v4(null, buffer, 0);
-uuid.v4(null, buffer, 16);
-```
-
-### uuid.parse(id[, buffer[, offset]])
-### uuid.unparse(buffer[, offset])
-
-Parse and unparse UUIDs
-
-  * `id` - (String) UUID(-like) string
-  * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used
-  * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0
-
-Example parsing and unparsing a UUID string
-
-```javascript
-var bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> <Buffer 79 7f f0 43 11 eb 11 e1 80 d6 51 09 98 75 5d 10>
-var string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10'
-```
-
-### uuid.noConflict()
-
-(Browsers only) Set `uuid` property back to it's previous value.
-
-Returns the node-uuid object.
-
-Example:
-
-```javascript
-var myUuid = uuid.noConflict();
-myUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
-```
-
-## Deprecated APIs
-
-Support for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version.
-
-### uuid([format [, buffer [, offset]]])
-
-uuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary).
-
-### uuid.BufferClass
-
-The class of container created when generating binary uuid data if no buffer argument is specified.  This is expected to go away, with no replacement API.
-
-## Testing
-
-In node.js
-
-```
-> cd test
-> node uuid.js
-```
-
-In Browser
-
-```
-open test/test.html
-```
-
-### Benchmarking
-
-Requires node.js
-
-```
-npm install uuid uuid-js
-node test/benchmark.js
-```
-
-For a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark)
-
-For browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance).
-
-## Release notes
-
-v1.3.2:
-* Improve tests and handling of v1() options (Issue #24)
-* Expose RNG option to allow for perf testing with different generators
-
-v1.3:
-* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)!
-* Support for node.js crypto API
-* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code
diff --git a/deps/npm/node_modules/node-uuid/package.json b/deps/npm/node_modules/node-uuid/package.json
deleted file mode 100644 (file)
index 9df0da9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name"          : "node-uuid",
-  "description"   : "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
-  "url"           : "http://github.com/broofa/node-uuid",
-  "keywords"      : ["uuid", "guid", "rfc4122"],
-  "author"        : "Robert Kieffer <robert@broofa.com>",
-  "contributors"  : [
-    {"name": "Christoph Tavan <dev@tavan.de>", "github": "https://github.com/ctavan"}
-  ],
-  "dependencies"  : {},
-  "lib"           : ".",
-  "main"          : "./uuid.js",
-  "version"       : "1.3.3"
-}
diff --git a/deps/npm/node_modules/node-uuid/uuid.js b/deps/npm/node_modules/node-uuid/uuid.js
deleted file mode 100644 (file)
index 27f1d12..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-//     node-uuid/uuid.js
-//
-//     Copyright (c) 2010 Robert Kieffer
-//     Dual licensed under the MIT and GPL licenses.
-//     Documentation and details at https://github.com/broofa/node-uuid
-(function() {
-  var _global = this;
-
-  // Unique ID creation requires a high quality random # generator, but
-  // Math.random() does not guarantee "cryptographic quality".  So we feature
-  // detect for more robust APIs, normalizing each method to return 128-bits
-  // (16 bytes) of random data.
-  var mathRNG, nodeRNG, whatwgRNG;
-
-  // Math.random()-based RNG.  All platforms, very fast, unknown quality
-  var _rndBytes = new Array(16);
-  mathRNG = function() {
-    var r, b = _rndBytes, i = 0;
-
-    for (var i = 0, r; i < 16; i++) {
-      if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
-      b[i] = r >>> ((i & 0x03) << 3) & 0xff;
-    }
-
-    return b;
-  }
-
-  // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
-  // WebKit only (currently), moderately fast, high quality
-  if (_global.crypto && crypto.getRandomValues) {
-    var _rnds = new Uint32Array(4);
-    whatwgRNG = function() {
-      crypto.getRandomValues(_rnds);
-
-      for (var c = 0 ; c < 16; c++) {
-        _rndBytes[c] = _rnds[c >> 2] >>> ((c & 0x03) * 8) & 0xff;
-      }
-      return _rndBytes;
-    }
-  }
-
-  // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
-  // Node.js only, moderately fast, high quality
-  try {
-    var _rb = require('crypto').randomBytes;
-    nodeRNG = _rb && function() {
-      return _rb(16);
-    };
-  } catch (e) {}
-
-  // Select RNG with best quality
-  var _rng = nodeRNG || whatwgRNG || mathRNG;
-
-  // Buffer class to use
-  var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;
-
-  // Maps for number <-> hex string conversion
-  var _byteToHex = [];
-  var _hexToByte = {};
-  for (var i = 0; i < 256; i++) {
-    _byteToHex[i] = (i + 0x100).toString(16).substr(1);
-    _hexToByte[_byteToHex[i]] = i;
-  }
-
-  // **`parse()` - Parse a UUID into it's component bytes**
-  function parse(s, buf, offset) {
-    var i = (buf && offset) || 0, ii = 0;
-
-    buf = buf || [];
-    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(byte) {
-      if (ii < 16) { // Don't overflow!
-        buf[i + ii++] = _hexToByte[byte];
-      }
-    });
-
-    // Zero out remaining bytes if string was short
-    while (ii < 16) {
-      buf[i + ii++] = 0;
-    }
-
-    return buf;
-  }
-
-  // **`unparse()` - Convert UUID byte array (ala parse()) into a string**
-  function unparse(buf, offset) {
-    var i = offset || 0, bth = _byteToHex;
-    return  bth[buf[i++]] + bth[buf[i++]] +
-            bth[buf[i++]] + bth[buf[i++]] + '-' +
-            bth[buf[i++]] + bth[buf[i++]] + '-' +
-            bth[buf[i++]] + bth[buf[i++]] + '-' +
-            bth[buf[i++]] + bth[buf[i++]] + '-' +
-            bth[buf[i++]] + bth[buf[i++]] +
-            bth[buf[i++]] + bth[buf[i++]] +
-            bth[buf[i++]] + bth[buf[i++]];
-  }
-
-  // **`v1()` - Generate time-based UUID**
-  //
-  // Inspired by https://github.com/LiosK/UUID.js
-  // and http://docs.python.org/library/uuid.html
-
-  // random #'s we need to init node and clockseq
-  var _seedBytes = _rng();
-
-  // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
-  var _nodeId = [
-    _seedBytes[0] | 0x01,
-    _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
-  ];
-
-  // Per 4.2.2, randomize (14 bit) clockseq
-  var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
-
-  // Previous uuid creation time
-  var _lastMSecs = 0, _lastNSecs = 0;
-
-  // See https://github.com/broofa/node-uuid for API details
-  function v1(options, buf, offset) {
-    var i = buf && offset || 0;
-    var b = buf || [];
-
-    options = options || {};
-
-    var clockseq = options.clockseq != null ? options.clockseq : _clockseq;
-
-    // UUID timestamps are 100 nano-second units since the Gregorian epoch,
-    // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
-    // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
-    // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
-    var msecs = options.msecs != null ? options.msecs : new Date().getTime();
-
-    // Per 4.2.1.2, use count of uuid's generated during the current clock
-    // cycle to simulate higher resolution clock
-    var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1;
-
-    // Time since last uuid creation (in msecs)
-    var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
-
-    // Per 4.2.1.2, Bump clockseq on clock regression
-    if (dt < 0 && options.clockseq == null) {
-      clockseq = clockseq + 1 & 0x3fff;
-    }
-
-    // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
-    // time interval
-    if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
-      nsecs = 0;
-    }
-
-    // Per 4.2.1.2 Throw error if too many uuids are requested
-    if (nsecs >= 10000) {
-      throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
-    }
-
-    _lastMSecs = msecs;
-    _lastNSecs = nsecs;
-    _clockseq = clockseq;
-
-    // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
-    msecs += 12219292800000;
-
-    // `time_low`
-    var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
-    b[i++] = tl >>> 24 & 0xff;
-    b[i++] = tl >>> 16 & 0xff;
-    b[i++] = tl >>> 8 & 0xff;
-    b[i++] = tl & 0xff;
-
-    // `time_mid`
-    var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
-    b[i++] = tmh >>> 8 & 0xff;
-    b[i++] = tmh & 0xff;
-
-    // `time_high_and_version`
-    b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
-    b[i++] = tmh >>> 16 & 0xff;
-
-    // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
-    b[i++] = clockseq >>> 8 | 0x80;
-
-    // `clock_seq_low`
-    b[i++] = clockseq & 0xff;
-
-    // `node`
-    var node = options.node || _nodeId;
-    for (var n = 0; n < 6; n++) {
-      b[i + n] = node[n];
-    }
-
-    return buf ? buf : unparse(b);
-  }
-
-  // **`v4()` - Generate random UUID**
-
-  // See https://github.com/broofa/node-uuid for API details
-  function v4(options, buf, offset) {
-    // Deprecated - 'format' argument, as supported in v1.2
-    var i = buf && offset || 0;
-
-    if (typeof(options) == 'string') {
-      buf = options == 'binary' ? new BufferClass(16) : null;
-      options = null;
-    }
-    options = options || {};
-
-    var rnds = options.random || (options.rng || _rng)();
-
-    // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
-    rnds[6] = (rnds[6] & 0x0f) | 0x40;
-    rnds[8] = (rnds[8] & 0x3f) | 0x80;
-
-    // Copy bytes to buffer, if provided
-    if (buf) {
-      for (var ii = 0; ii < 16; ii++) {
-        buf[i + ii] = rnds[ii];
-      }
-    }
-
-    return buf || unparse(rnds);
-  }
-
-  // Export public API
-  var uuid = v4;
-  uuid.v1 = v1;
-  uuid.v4 = v4;
-  uuid.parse = parse;
-  uuid.unparse = unparse;
-  uuid.BufferClass = BufferClass;
-
-  // Export RNG options
-  uuid.mathRNG = mathRNG;
-  uuid.nodeRNG = nodeRNG;
-  uuid.whatwgRNG = whatwgRNG;
-
-  if (typeof(module) != 'undefined') {
-    // Play nice with node.js
-    module.exports = uuid;
-  } else {
-    // Play nice with browsers
-    var _previousRoot = _global.uuid;
-
-    // **`noConflict()` - (browser only) to reset global 'uuid' var**
-    uuid.noConflict = function() {
-      _global.uuid = _previousRoot;
-      return uuid;
-    }
-    _global.uuid = uuid;
-  }
-}());
index dbeb94422b4b6c7d0acd55242a102804d3fd00ce..4b180a029996252e3ffb16a04a2bac4443182c6c 100644 (file)
@@ -8,7 +8,7 @@ It handles all the caching and HTTP calls.
 
 ```javascript
 var RegClient = require('npm-registry-client')
-var client = new RegClient(options)
+var client = new RegClient(config)
 
 client.get("npm", "latest", 1000, function (er, data, raw, res) {
   // error is an error if there was a problem.
@@ -18,29 +18,43 @@ client.get("npm", "latest", 1000, function (er, data, raw, res) {
 })
 ```
 
-# Options
+# Configuration
+
+This program is designed to work with
+[npmconf](https://npmjs.org/package/npmconf), but you can also pass in
+a plain-jane object with the appropriate configs, and it'll shim it
+for you.  Any configuration thingie that has get/set/del methods will
+also be accepted.
 
 * `registry` **Required** {String} URL to the registry
 * `cache` **Required** {String} Path to the cache folder
-* `alwaysAuth` {Boolean} Auth even for GET requests.
+* `always-auth` {Boolean} Auth even for GET requests.
 * `auth` {String} A base64-encoded `username:password`
 * `email` {String} User's email address
 * `tag` {String} The default tag to use when publishing new packages.
   Default = `"latest"`
 * `ca` {String} Cerficate signing authority certificates to trust.
-* `strictSSL` {Boolean} Whether or not to be strict with SSL
+* `strict-ssl` {Boolean} Whether or not to be strict with SSL
   certificates.  Default = `true`
-* `userAgent` {String} User agent header to send.  Default =
+* `user-agent` {String} User agent header to send.  Default =
   `"node/{process.version}"`
 * `log` {Object} The logger to use.  Defaults to `require("npmlog")` if
   that works, otherwise logs are disabled.
-* `retries` {Number} Number of times to retry on GET failures.
+* `fetch-retries` {Number} Number of times to retry on GET failures.
   Default=2
-* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10
-* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.
+* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10
+* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.
   Default=10000 (10 seconds)
-* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.
+* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.
   Default=60000 (60 seconds)
+* `proxy` {URL} The url to proxy requests through.
+* `https-proxy` {URL} The url to proxy https requests through.
+  Defaults to be the same as `proxy` if unset.
+* `_auth` {String} The base64-encoded authorization header.
+* `username` `_password` {String} Username/password to use to generate
+  `_auth` if not supplied.
+* `_token` {Object} A token for use with
+  [couch-login](https://npmjs.org/package/couch-login)
 
 # client.request(method, where, [what], [etag], [nofollow], cb)
 
index 377f787f4eaa81e423ce2e651284ff155cf0c64a..8d321b869928c75828977fc5a433218ff8b67906 100644 (file)
@@ -19,78 +19,48 @@ try {
 
 function noop () {}
 
-function RegClient (options) {
+function RegClient (conf) {
+  // accept either a plain-jane object, or a npmconf object
+  // with a "get" method.
+  if (typeof conf.get !== 'function') {
+    var data = conf
+    conf = { get: function (k) { return data[k] }
+           , set: function (k, v) { data[k] = v }
+           , del: function (k) { delete data[k] } }
+  }
+
+  this.conf = conf
+
   // 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
+  var registry = conf.get('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 += '/'
+    registry = registry.href
+    if (registry.slice(-1) !== '/') {
+      registry += '/'
     }
+    this.conf.set('registry', registry)
   } else {
-    this.registry = null
+    registry = null
   }
 
-  this.retries = options.retries || 2
-  this.retryFactor = options.retryFactor || 10
-  this.retryMinTimeout = options.retryMinTimeout || 10000
-  this.retryMaxTimeout = options.retryMaxTimeout || 60000
-
-  this.cache = options.cache
-  if (!this.cache) throw new Error("Cache dir is required")
-
-  this.alwaysAuth = options.alwaysAuth || false
+  if (!conf.get('cache')) throw new Error("Cache dir is required")
 
-  this.auth = options.auth || null
-  if (this.auth) {
-    var a = new Buffer(this.auth, "base64").toString()
-    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) {
+  var auth = this.conf.get('_auth')
+  var alwaysAuth = this.conf.get('always-auth')
+  if (auth && !alwaysAuth && 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.couchLogin.proxy = this.proxy
-  }
-
-  this.email = options.email || null
-  this.defaultTag = options.tag || "latest"
-
-  this.ca = options.ca || null
-
-  this.strictSSL = options.strictSSL
-  if (this.strictSSL === undefined) this.strictSSL = true
-
-  this.userAgent = options.userAgent
-  if (this.userAgent === undefined) {
-    this.userAgent = 'node/' + process.version
+    var token = this.conf.get('_token')
+    this.couchLogin = new CouchLogin(registry, token)
+    this.couchLogin.proxy = this.conf.get('proxy')
   }
 
-  this.cacheMin = options.cacheMin || 0
-  this.cacheMax = options.cacheMax || Infinity
-
-  this.proxy = options.proxy
-  this.httpsProxy = options.httpsProxy || options.proxy
-
-  this.log = options.log || npmlog
+  this.log = conf.log || conf.get('log') || npmlog
 }
 
 require('fs').readdirSync(__dirname + "/lib").forEach(function (f) {
index f940ca1ca5e5b3793da294ba1fe820f78f7e0340..7106e444d7e7b1ba13a5e9cd4c6b1eb22a5b96b7 100644 (file)
@@ -1,18 +1,12 @@
-
 module.exports = adduser
 
-var uuid = require("node-uuid")
-  , crypto
-
-try {
-} catch (ex) {}
+var crypto = require('crypto')
 
 function sha (s) {
   return crypto.createHash("sha1").update(s).digest("hex")
 }
 
 function adduser (username, password, email, cb) {
-  if (!crypto) crypto = require("crypto")
 
   password = ("" + (password || "")).trim()
   if (!password) return cb(new Error("No password supplied."))
@@ -27,7 +21,7 @@ function adduser (username, password, email, cb) {
     "Sorry, ':' chars are not allowed in passwords.\n"+
     "See <https://issues.apache.org/jira/browse/COUCHDB-969> for why."))
 
-  var salt = uuid()
+  var salt = crypto.randomBytes(30).toString('hex')
     , userobj =
       { name : username
       , salt : salt
@@ -41,18 +35,18 @@ function adduser (username, password, email, cb) {
 
   // pluck off any other username/password/token.  it needs to be the
   // same as the user we're becoming now.  replace them on error.
-  var pre = { username: this.username
-            , password: this.password
-            , auth: this.auth
-            , token: this.token }
-
-  this.token = null
+  var pre = { username: this.conf.get('username')
+            , password: this.conf.get('_password')
+            , auth: this.conf.get('_auth')
+            , token: this.conf.get('_token') }
+
+  this.conf.del('_token')
+  this.conf.del('username')
+  this.conf.del('_auth')
+  this.conf.del('_password')
   if (this.couchLogin) {
     this.couchLogin.token = null
   }
-  this.username = null
-  this.password = null
-  this.auth = null
 
   cb = done.call(this, cb, pre)
 
@@ -72,13 +66,13 @@ function adduser (username, password, email, cb) {
     , function (error, data, json, response) {
         // if it worked, then we just created a new user, and all is well.
         // but if we're updating a current record, then it'll 409 first
-        if (error && !this.auth) {
+        if (error && !this.conf.get('_auth')) {
           // must be trying to re-auth on a new machine.
           // use this info as auth
           var b = new Buffer(username + ":" + password)
-          this.auth = b.toString("base64")
-          this.username = username
-          this.password = password
+          this.conf.set('_auth', b.toString("base64"))
+          this.conf.set('username', username)
+          this.conf.set('_password', password)
         }
 
         if (!error || !response || response.statusCode !== 409) {
@@ -114,16 +108,16 @@ function done (cb, pre) {
     }
 
     // there was some kind of error, re-instate previous auth/token/etc.
-    this.token = pre.token
+    this.conf.set('_token', pre.token)
     if (this.couchLogin) {
-      this.couchLogin.token = this.token
+      this.couchLogin.token = pre.token
       if (this.couchLogin.tokenSet) {
         this.couchLogin.tokenSet(pre.token)
       }
     }
-    this.username = pre.username
-    this.password = pre.password
-    this.auth = pre.auth
+    this.conf.set('username', pre.username)
+    this.conf.set('_password', pre.password)
+    this.conf.set('_auth', pre.auth)
 
     this.log.verbose("adduser", "back", [error, data, json])
     if (!error) {
index 835eb4ce5169e7462343689d53a0bf5f0d76c0d7..584a986b58097a6c909e5005d842d9a84d17e4b3 100644 (file)
@@ -12,10 +12,10 @@ function get (uri, timeout, nofollow, staleOk, cb) {
   if (typeof cb !== "function") cb = timeout, timeout = -1
   if (typeof cb !== "function") cb = version, version = null
 
-  timeout = Math.min(timeout, this.cacheMax)
-  timeout = Math.max(timeout, this.cacheMin)
+  timeout = Math.min(timeout, this.conf.get('cache-max') || 0)
+  timeout = Math.max(timeout, this.conf.get('cache-min') || Infinity)
 
-  if (!this.registry) timeout = Infinity
+  if (!this.conf.get('registry')) timeout = Infinity
 
   if ( process.env.COMP_CWORD !== undefined
     && process.env.COMP_LINE !== undefined
@@ -29,7 +29,7 @@ function get (uri, timeout, nofollow, staleOk, cb) {
     return requestAll.call(this, cb)
   }
 
-  var cache = path.join(this.cache, uri, ".cache.json")
+  var cache = path.join(this.conf.get('cache'), uri, ".cache.json")
   fs.stat(cache, function (er, stat) {
     if (!er) fs.readFile(cache, function (er, data) {
       try { data = JSON.parse(data) }
@@ -41,9 +41,9 @@ function get (uri, timeout, nofollow, staleOk, cb) {
 }
 
 function requestAll (cb) {
-  var cache = path.join(this.cache, "/-/all", ".cache.json")
+  var cache = path.join(this.conf.get('cache'), "/-/all", ".cache.json")
 
-  mkdir(path.join(this.cache, "-", "all"), function (er) {
+  mkdir(path.join(this.conf.get('cache'), "-", "all"), function (er) {
     fs.readFile(cache, function (er, data) {
       if (er) return requestAll_.call(this, 0, {}, cb)
       try {
@@ -74,7 +74,7 @@ function requestAll_ (c, data, cb) {
     uri = "/-/all"
   }
 
-  var cache = path.join(this.cache, "-/all", ".cache.json")
+  var cache = path.join(this.conf.get('cache'), "-/all", ".cache.json")
   this.request('GET', uri, function (er, updates, _, res) {
     if (er) return cb(er, data)
     var headers = res.headers
@@ -143,20 +143,20 @@ function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) {
 }
 
 function saveToCache (cache, data, saved) {
-  if (this.cacheStat) {
-    var cs = this.cacheStat
+  if (this._cacheStat) {
+    var cs = this._cacheStat
     return saveToCache_.call(this, cache, data, cs.uid, cs.gid, saved)
   }
-  fs.stat(this.cache, function (er, st) {
+  fs.stat(this.conf.get('cache'), function (er, st) {
     if (er) {
       return fs.stat(process.env.HOME || "", function (er, st) {
         // if this fails, oh well.
         if (er) return saved()
-        this.cacheStat = st
+        this._cacheStat = st
         return saveToCache.call(this, cache, data, saved)
       }.bind(this))
     }
-    this.cacheStat = st || { uid: null, gid: null }
+    this._cacheStat = st || { uid: null, gid: null }
     return saveToCache.call(this, cache, data, saved)
   }.bind(this))
 }
index 11aa599e617978664d670525b56e46ac87e3ce9f..b44b801b3a86733c93a68bfa7f75a4d0ed377354 100644 (file)
@@ -6,8 +6,14 @@ var path = require("path")
 
 function publish (data, tarball, cb) {
 
-  if (!this.email || !this.auth || !this.username) {
-    return cb(new Error("auth and email required for publishing"))
+  var email = this.conf.get('email')
+  var auth = this.conf.get('_auth')
+  var username = this.conf.get('username')
+
+  if (!email || !auth || !username) {
+    var er = new Error("auth and email required for publishing")
+    er.code = 'ENEEDAUTH'
+    return cb(er)
   }
 
   // add the dist-url to the data, pointing at the tarball.
@@ -15,7 +21,7 @@ function publish (data, tarball, cb) {
   // if the {version} is already there, then fail.
   // then:
   // PUT the data to {config.registry}/{data.name}/{data.version}
-  var registry = this.registry
+  var registry = this.conf.get('registry')
 
   var fullData =
     { _id : data.name
@@ -25,8 +31,8 @@ function publish (data, tarball, cb) {
     , versions : {}
     , readme: data.readme || ""
     , maintainers :
-      [ { name : this.username
-        , email : this.email
+      [ { name : username
+        , email : email
         }
       ]
     }
@@ -58,7 +64,7 @@ function publish (data, tarball, cb) {
     var dataURI = encodeURIComponent(data.name)
                 + "/" + encodeURIComponent(data.version)
 
-    var tag = data.tag || this.defaultTag || "latest"
+    var tag = data.tag || this.conf.get('tag') || "latest"
     dataURI += "/-tag/" + tag
 
     // let's see what versions are already published.
index 486226a712659199b0bb62ae4bcb230d99334c04..8d90572c6688049abf5d4dbaf0946419acda766f 100644 (file)
@@ -13,7 +13,8 @@ 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(
+  var registry = this.conf.get('registry')
+  if (!registry) return cb(new Error(
     "No registry url provided: " + method + " " + where))
 
   // Since there are multiple places where an error could occur,
@@ -29,13 +30,11 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
     return cb(new Error("favicon.ico isn't a package, it's a picture."))
   }
 
-  var registry = this.registry
-
   var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/
   , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
   , nu = where.match(adduserNew)
   , uc = where.match(adduserChange)
-  , isUpload = what || this.alwaysAuth
+  , isUpload = what || this.conf.get('always-auth')
   , isDel = method === "DELETE"
   , authRequired = isUpload && !nu || uc || isDel
 
@@ -62,27 +61,30 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   }
 
   var remote = url.parse(where)
-  , auth = this.auth
+  , auth = this.conf.get('_auth')
 
-  if (authRequired && !this.alwaysAuth) {
+  if (authRequired && !this.conf.get('always-auth')) {
     var couch = this.couchLogin
-    , token = couch && (this.token || couch.token)
+    , token = couch && (this.conf.get('_token') || couch.token)
     , validToken = token && couch.valid(token)
 
     if (!validToken) token = null
-    else this.token = token
+    else this.conf.set('_token', token)
 
     if (couch && !token) {
       // login to get a valid token
-      var a = { name: this.username, password: this.password }
+      var a = { name: this.conf.get('username'),
+                password: this.conf.get('_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_)
+        this.conf.set('_token', this.couchLogin.token)
+        return regRequest.call(this,
+                               method, where, what,
+                               etag, nofollow, cb_)
       }.bind(this))
     }
   }
@@ -101,11 +103,12 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
   // Tuned to spread 3 attempts over about a minute.
   // See formula at <https://github.com/tim-kos/node-retry>.
   var operation = retry.operation({
-    retries: this.retries,
-    factor: this.retryFactor,
-    minTimeout: this.retryMinTimeout,
-    maxTimeout: this.retryMaxTimeout
+    retries: this.conf.get('fetch-retries') || 2,
+    factor: this.conf.get('fetch-retry-factor'),
+    minTimeout: this.conf.get('fetch-retry-mintimeout') || 10000,
+    maxTimeout: this.conf.get('fetch-retry-maxtimeout') || 60000
   })
+
   var self = this
   operation.attempt(function (currentAttempt) {
     self.log.info("retry", "registry request attempt " + currentAttempt
@@ -118,8 +121,8 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
       var timeout = statusCode === 408
       var serverError = statusCode >= 500
       var statusRetry = !statusCode || timeout || serverError
-      if (reauth && this.auth && this.token) {
-        this.token = null
+      if (reauth && this.conf.get('_auth') && this.conf.get('_token')) {
+        this.conf.del('_token')
         this.couchLogin.token = null
         return regRequest.call(this, method, where, what, etag, nofollow, cb_)
       }
@@ -140,10 +143,12 @@ function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
     cb_.apply(null, arguments)
   }
 
+  var strict = this.conf.get('strict-ssl')
+  if (strict === undefined) strict = true
   var opts = { url: remote
              , method: method
-             , ca: this.ca
-             , strictSSL: this.strictSSL }
+             , ca: this.conf.get('ca')
+             , strictSSL: strict }
     , headers = opts.headers = {}
   if (etag) {
     this.log.verbose("etag", etag)
@@ -156,10 +161,12 @@ function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
 
   headers.accept = "application/json"
 
-  headers["user-agent"] = this.userAgent
+  headers["user-agent"] = this.conf.get('user-agent') ||
+                          'node/' + process.version
 
-  opts.proxy = remote.protocol === "https:"
-             ? this.httpsProxy : this.proxy
+  var p = this.conf.get('proxy')
+  var sp = this.conf.get('https-proxy') || p
+  opts.proxy = remote.protocol === "https:" ? sp : p
 
   // figure out wth 'what' is
   if (what) {
@@ -259,7 +266,7 @@ function requestDone (method, where, cb) {
         , caches = p.map(function (part) {
             return _ = path.join(_, part)
           }).map(function (cache) {
-            return path.join(this.cache, cache, ".cache.json")
+            return path.join(this.conf.get('cache'), cache, ".cache.json")
           }, this)
 
       // if the method is DELETE, then also remove the thing itself.
@@ -267,7 +274,7 @@ function requestDone (method, where, cb) {
       // That's what you get for deleting stuff.  Don't do that.
       if (method === "DELETE") {
         p = p.slice(0, p.indexOf("-rev"))
-        caches.push(path.join(this.cache, p.join("/")))
+        caches.push(path.join(this.conf.get('cache'), p.join("/")))
       }
 
       asyncMap(caches, rm, function () {})
index 36a66127e50b43b3d8060f269146efa59ba91d65..5b7ab4afe9059d4bebc45ee81f61cbea8bc1d7a9 100644 (file)
@@ -2,7 +2,7 @@
 module.exports = star
 
 function star (package, starred, cb) {
-  if (!this.username) return cb(new Error(
+  if (!this.conf.get('username')) return cb(new Error(
     "Must be logged in to star/unstar packages"))
 
   var users = {}
@@ -16,10 +16,10 @@ function star (package, starred, cb) {
 
     if (starred) {
       this.log.info("starring", fullData._id)
-      fullData.users[this.username] = true
+      fullData.users[this.conf.get('username')] = true
       this.log.verbose("starring", fullData)
     } else {
-      delete fullData.users[this.username]
+      delete fullData.users[this.conf.get('username')]
       this.log.info("unstarring", fullData._id)
       this.log.verbose("unstarring", fullData)
     }
index 709027af4cb00db054e9a3bc36fdf549c348f732..7ee3487908d3c0176cdc4c16f3d9d5de93fb70cc 100644 (file)
@@ -6,7 +6,7 @@
   },
   "name": "npm-registry-client",
   "description": "Client for the npm registry",
-  "version": "0.1.4",
+  "version": "0.2.5",
   "repository": {
     "url": "git://github.com/isaacs/npm-registry-client"
   },
@@ -15,7 +15,6 @@
     "test": "tap test/*.js"
   },
   "dependencies": {
-    "node-uuid": "~1.3.3",
     "request": "~2.9.202",
     "graceful-fs": "~1.1.8",
     "semver": "~1.0.14",
@@ -34,7 +33,7 @@
     "npmlog": ""
   },
   "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.1.4",
-  "_from": "npm-registry-client@latest"
+  "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(config)\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# Configuration\n\nThis program is designed to work with\n[npmconf](https://npmjs.org/package/npmconf), but you can also pass in\na plain-jane object with the appropriate configs, and it'll shim it\nfor you.  Any configuration thingie that has get/set/del methods will\nalso be accepted.\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `always-auth` {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* `strict-ssl` {Boolean} Whether or not to be strict with SSL\n  certificates.  Default = `true`\n* `user-agent` {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* `fetch-retries` {Number} Number of times to retry on GET failures.\n  Default=2\n* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10\n* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.\n  Default=10000 (10 seconds)\n* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.\n  Default=60000 (60 seconds)\n* `proxy` {URL} The url to proxy requests through.\n* `https-proxy` {URL} The url to proxy https requests through.\n  Defaults to be the same as `proxy` if unset.\n* `_auth` {String} The base64-encoded authorization header.\n* `username` `_password` {String} Username/password to use to generate\n  `_auth` if not supplied.\n* `_token` {Object} A token for use with\n  [couch-login](https://npmjs.org/package/couch-login)\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.2.5",
+  "_from": "npm-registry-client@~0.2.4"
 }
index 500abf29d95e0c40b234d3e907390fedeb5d0e94..8f0e63f721c2ef212ac005d0711fcdb87541186b 100644 (file)
@@ -5,9 +5,9 @@ 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
+    'fetch-retries': 6
+  , 'fetch-retry-mintimeout': 10
+  , 'fetch-retry-maxtimeout': 100
   , cache: __dirname + '/fixtures/cache'
   , registry: 'http://localhost:' + server.port })
 
index da4b4229072d2a9805fcdd855b7093ce71c2ab4e..41ba25142338c7c66809e4bc5ceb7ddeba7daee2 100644 (file)
@@ -9,6 +9,7 @@ var path = require('path')
 var nopt = require('nopt')
 var ini = require('ini')
 var Octal = configDefs.Octal
+var mkdirp = require('mkdirp')
 
 exports.load = load
 exports.Conf = Conf
@@ -174,18 +175,23 @@ Conf.prototype.save = function (where, cb) {
   then = then.bind(this)
   done = done.bind(this)
   this._saving ++
+
   var mode = where === 'user' ? 0600 : 0666
   if (!data.trim())
     fs.unlink(target.path, done)
   else {
-    fs.writeFile(target.path, data, 'utf8', function (er) {
+    mkdirp(path.dirname(target.path), function (er) {
       if (er)
         return then(er)
-      if (where === 'user' && myUid && myGid)
-        fs.chown(target.path, +myUid, +myGid, then)
-      else
-        then()
-    }.bind(this))
+      fs.writeFile(target.path, data, 'utf8', function (er) {
+        if (er)
+          return then(er)
+        if (where === 'user' && myUid && myGid)
+          fs.chown(target.path, +myUid, +myGid, then)
+        else
+          then()
+      })
+    })
   }
 
   function then (er) {
index 3a50fe9a4d2d5500ea0020f0a2f3d50e3d7496ab..8995ddfc04c75a3addfc7c3fe8fd043d6f87e5b9 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "npmconf",
-  "version": "0.0.6",
+  "version": "0.0.8",
   "description": "The config thing npm uses",
   "main": "npmconf.js",
   "directories": {
@@ -10,6 +10,8 @@
     "config-chain": "~1.1.1",
     "inherits": "~1.0.0",
     "once": "~1.1.1",
+    "mkdirp": "~0.3.3",
+    "osenv": "0.0.3",
     "nopt": "~2.0.0"
   },
   "devDependencies": {},
@@ -37,6 +39,6 @@
     "nopt": "~2.0.0"
   },
   "readme": "# npmconf\n\nThe config thing npm uses\n\nIf you are interested in interacting with the config settings that npm\nuses, then use this module.\n\nHowever, if you are writing a new Node.js program, and want\nconfiguration functionality similar to what npm has, but for your\nown thing, then I'd recommend using [rc](https://github.com/dominictarr/rc),\nwhich is probably what you want.\n\nIf I were to do it all over again, that's what I'd do for npm.  But,\nalas, there are many systems depending on many of the particulars of\nnpm's configuration setup, so it's not worth the cost of changing.\n\n## USAGE\n\n```javascript\nvar npmconf = require('npmconf')\n\n// pass in the cli options that you read from the cli\n// or whatever top-level configs you want npm to use for now.\nnpmconf.load({some:'configs'}, function (er, conf) {\n  // do stuff with conf\n  conf.get('some', 'cli') // 'configs'\n  conf.get('username') // 'joebobwhatevers'\n  conf.set('foo', 'bar', 'user')\n  conf.save('user', function (er) {\n    // foo = bar is now saved to ~/.npmrc or wherever\n  })\n})\n```\n",
-  "_id": "npmconf@0.0.6",
-  "_from": "npmconf@latest"
+  "_id": "npmconf@0.0.8",
+  "_from": "npmconf@~0.0.6"
 }
index 3e703bf9071b474ea0ecaf81a4c099eb69926011..b122b54afe4e8c4b48d4ad1bb93b94c382d32abe 100644 (file)
@@ -1,7 +1,7 @@
 {
   "name": "read-installed",
   "description": "Read all the installed packages in a folder, and return a tree structure with all the data.",
-  "version": "0.0.1",
+  "version": "0.0.2",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/read-installed"
@@ -27,6 +27,6 @@
     "url": "http://blog.izs.me/"
   },
   "readme": "# read-installed\n\nRead all the installed packages in a folder, and return a tree\nstructure with all the data.\n\nnpm uses this.\n\n## Usage\n\n```javascript\nvar readInstalled = require(\"read-installed\")\n// depth is optional, defaults to Infinity\nreadInstalled(folder, depth, function (er, data) {\n  ...\n})\n```\n",
-  "_id": "read-installed@0.0.1",
-  "_from": "read-installed"
+  "_id": "read-installed@0.0.2",
+  "_from": "read-installed@0"
 }
index be394225b87b5ba1567580dc45f46d6a604cad50..cb77dba33df95adee10894eba1a95674e98a5955 100644 (file)
@@ -286,6 +286,8 @@ function findUnmet (obj) {
                   +found.path+",\nwhich is version "+found.version
                   )
           found.invalid = true
+        } else {
+          found.extraneous = false
         }
         deps[d] = found
       }
index 42d06112729b42f9da7b3410fcbbed0e18cc2f4e..8e56b11e32e17252c1d4587dace17fb711e9f4e1 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "read-package-json",
-  "version": "0.1.3",
+  "version": "0.1.4",
   "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.1.3",
-  "_from": "read-package-json@~0.1.1"
+  "_id": "read-package-json@0.1.4",
+  "_from": "read-package-json@~0.1.3"
 }
index 837c6b7c4a8bbb6b6748e6f02ed43619ea1d275a..17e8b4320d6bf6e853581ebcb15d4a68cc610d41 100644 (file)
@@ -254,7 +254,7 @@ function mans (file, data, cb) {
 function mans_ (file, data, mans, cb) {
                 var m = data.directories && data.directories.man
                 data.man = mans.map(function (mf) {
-                                return path.resolve(m, mf)
+                                return path.resolve(path.dirname(file), m, mf)
                 })
                 return cb(null, data)
 }
index 01aa8e76bd48d2b651771679062cea44e4d09bd9..2edefdf473ee942c6a2e7d90fda70e6a0b20c61b 100644 (file)
@@ -33,6 +33,21 @@ Every option is optional.
 If silent is true, and the input is a TTY, then read will set raw
 mode, and read character by character.
 
+## COMPATIBILITY
+
+This module works sort of with node 0.6.  It does not work with node
+versions less than 0.6.  It is best on node 0.8.
+
+On node version 0.6, it will remove all listeners on the input
+stream's `data` and `keypress` events, because the readline module did
+not fully clean up after itself in that version of node, and did not
+make it possible to clean up after it in a way that has no potential
+for side effects.
+
+Additionally, some of the readline options (like `terminal`) will not
+function in versions of node before 0.8, because they were not
+implemented in the builtin readline module.
+
 ## CONTRIBUTING
 
 Patches welcome.
index 4b0e303f6cef5d2f1bc9bbd7ebb77bd33cec7868..4b8a422d9b34f0033a02965da4592f1ac17121d8 100644 (file)
@@ -23,7 +23,13 @@ function read (opts, cb) {
   var def = opts.default || ''
   var terminal = !!(opts.terminal || output.isTTY)
   var rlOpts = { input: input, output: output, terminal: terminal }
-  var rl = readline.createInterface(rlOpts)
+
+  if (process.version.match(/^v0\.6/)) {
+    var rl = readline.createInterface(rlOpts.input, rlOpts.output)
+  } else {
+    var rl = readline.createInterface(rlOpts)
+  }
+
   var prompt = (opts.prompt || '').trim() + ' '
   var silent = opts.silent
   var editDef = false
@@ -69,6 +75,13 @@ function read (opts, cb) {
   function done () {
     called = true
     rl.close()
+
+    if (process.version.match(/^v0\.6/)) {
+      rl.input.removeAllListeners('data')
+      rl.input.removeAllListeners('keypress')
+      rl.input.pause()
+    }
+
     clearTimeout(timer)
     output.mute()
     output.end()
index f0c3550fe10da52b1ec38cba8c605aa46065a422..7746618a129f823d9228c14b668c1ad651d38928 100644 (file)
@@ -63,6 +63,21 @@ function setIsTTY (isTTY) {
   })
 }
 
+Object.defineProperty(MuteStream.prototype, 'rows', {
+  get: function () {
+    return( this._dest ? this._dest.rows
+          : this._src ? this._src.rows
+          : undefined )
+  }, enumerable: true, configurable: true })
+
+Object.defineProperty(MuteStream.prototype, 'columns', {
+  get: function () {
+    return( this._dest ? this._dest.columns
+          : this._src ? this._src.columns
+          : undefined )
+  }, enumerable: true, configurable: true })
+
+
 MuteStream.prototype.pipe = function (dest) {
   this._dest = dest
   return Stream.prototype.pipe.call(this, dest)
index ff942b853e8ed1c6cac1f384fb26f4bd74dbdbb6..629b5be672256e8221985f512f52aaaf0a1456e3 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "mute-stream",
-  "version": "0.0.2",
+  "version": "0.0.3",
   "main": "mute.js",
   "directories": {
     "test": "test"
@@ -28,9 +28,6 @@
   "license": "BSD",
   "description": "Bytes go in, but they don't come out (when muted).",
   "readme": "# mute-stream\n\nBytes go in, but they don't come out (when muted).\n\nThis is a basic pass-through stream, but when muted, the bytes are\nsilently dropped, rather than being passed through.\n\n## Usage\n\n```javascript\nvar MuteStream = require('mute-stream')\n\nvar ms = new MuteStream(options)\n\nms.pipe(process.stdout)\nms.write('foo') // writes 'foo' to stdout\nms.mute()\nms.write('bar') // does not write 'bar'\nms.unmute()\nms.write('baz') // writes 'baz' to stdout\n\n// can also be used to mute incoming data\nvar ms = new MuteStream\ninput.pipe(ms)\n\nms.on('data', function (c) {\n  console.log('data: ' + c)\n})\n\ninput.emit('data', 'foo') // logs 'foo'\nms.mute()\ninput.emit('data', 'bar') // does not log 'bar'\nms.unmute()\ninput.emit('data', 'baz') // logs 'baz'\n```\n\n## Options\n\nAll options are optional.\n\n* `replace` Set to a string to replace each character with the\n  specified string when muted.  (So you can show `****` instead of the\n  password, for example.)\n\n## ms.mute()\n\nSet `muted` to `true`.  Turns `.write()` into a no-op.\n\n## ms.unmute()\n\nSet `muted` to `false`\n\n## ms.isTTY\n\nTrue if the pipe destination is a TTY, or if the incoming pipe source is\na TTY.\n\n## Other stream methods...\n\nThe other standard readable and writable stream methods are all\navailable.  The MuteStream object acts as a facade to its pipe source\nand destination.\n",
-  "_id": "mute-stream@0.0.2",
-  "dist": {
-    "shasum": "75d4466df24a57e80fec806bda88561cd0560d2d"
-  },
+  "_id": "mute-stream@0.0.3",
   "_from": "mute-stream@~0.0.2"
 }
index 473f82796960536cd93fac043d105aafd40e813c..2d1f6aed30156b6df045860856c82254fbadb0fa 100644 (file)
@@ -89,17 +89,29 @@ tap.test('outgoing', function (t) {
 tap.test('isTTY', function (t) {
   var str = new PassThrough
   str.isTTY = true
+  str.columns=80
+  str.rows=24
 
   var ms = new MS
   t.equal(ms.isTTY, false)
+  t.equal(ms.columns, undefined)
+  t.equal(ms.rows, undefined)
   ms.pipe(str)
   t.equal(ms.isTTY, true)
+  t.equal(ms.columns, 80)
+  t.equal(ms.rows, 24)
   str.isTTY = false
   t.equal(ms.isTTY, false)
+  t.equal(ms.columns, 80)
+  t.equal(ms.rows, 24)
   str.isTTY = true
   t.equal(ms.isTTY, true)
+  t.equal(ms.columns, 80)
+  t.equal(ms.rows, 24)
   ms.isTTY = false
   t.equal(ms.isTTY, false)
+  t.equal(ms.columns, 80)
+  t.equal(ms.rows, 24)
 
   ms = new MS
   t.equal(ms.isTTY, false)
index 79e5b7ce2c1fea989e15a3eb58ffb70b9d411e62..f76034e867a5fc975e93c4100b6f5e658e3540d2 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "read",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "main": "lib/read.js",
   "dependencies": {
     "mute-stream": "~0.0.2"
@@ -25,7 +25,7 @@
   "scripts": {
     "test": "tap test/*.js"
   },
-  "readme": "## read\n\nFor reading user input from stdin.\n\nSimilar to the `readline` builtin's `question()` method, but with a\nfew more features.\n\n## USAGE\n\n```javascript\nvar read = require(\"read\")\nread(options, callback)\n```\n\nThe callback gets called with either the user input, or the default\nspecified, or an error, as `callback(error, result, isDefault)`\nnode style.\n\n## OPTIONS\n\nEvery option is optional.\n\n* `prompt` What to write to stdout before reading input.\n* `silent` Don't echo the output as the user types it.\n* `replace` Replace silenced characters with the supplied character value.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n* `edit` Allow the user to edit the default value.\n* `terminal` Treat the output as a TTY, whether it is or not.\n* `stdin` Readable stream to get input data from. (default `process.stdin`)\n* `stdout` Writeable stream to write prompts to. (default: `process.stdout`)\n\nIf silent is true, and the input is a TTY, then read will set raw\nmode, and read character by character.\n\n## CONTRIBUTING\n\nPatches welcome.\n",
-  "_id": "read@1.0.3",
-  "_from": "read@~1"
+  "readme": "## read\n\nFor reading user input from stdin.\n\nSimilar to the `readline` builtin's `question()` method, but with a\nfew more features.\n\n## USAGE\n\n```javascript\nvar read = require(\"read\")\nread(options, callback)\n```\n\nThe callback gets called with either the user input, or the default\nspecified, or an error, as `callback(error, result, isDefault)`\nnode style.\n\n## OPTIONS\n\nEvery option is optional.\n\n* `prompt` What to write to stdout before reading input.\n* `silent` Don't echo the output as the user types it.\n* `replace` Replace silenced characters with the supplied character value.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n* `edit` Allow the user to edit the default value.\n* `terminal` Treat the output as a TTY, whether it is or not.\n* `stdin` Readable stream to get input data from. (default `process.stdin`)\n* `stdout` Writeable stream to write prompts to. (default: `process.stdout`)\n\nIf silent is true, and the input is a TTY, then read will set raw\nmode, and read character by character.\n\n## COMPATIBILITY\n\nThis module works sort of with node 0.6.  It does not work with node\nversions less than 0.6.  It is best on node 0.8.\n\nOn node version 0.6, it will remove all listeners on the input\nstream's `data` and `keypress` events, because the readline module did\nnot fully clean up after itself in that version of node, and did not\nmake it possible to clean up after it in a way that has no potential\nfor side effects.\n\nAdditionally, some of the readline options (like `terminal`) will not\nfunction in versions of node before 0.8, because they were not\nimplemented in the builtin readline module.\n\n## CONTRIBUTING\n\nPatches welcome.\n",
+  "_id": "read@1.0.4",
+  "_from": "read@~1.0.3"
 }
index c90c41036c73b372560a775e376fbec0ec5505ce..f5324b4aa68a6f420937355875d352e673ebf513 100644 (file)
@@ -5,6 +5,11 @@ if (process.argv[2] === 'child') {
   return child()
 }
 
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+  CLOSE = 'exit'
+}
+
 var spawn = require('child_process').spawn
 
 tap.test('basic', function (t) {
@@ -31,7 +36,7 @@ tap.test('basic', function (t) {
     console.error('result %j', c.toString())
   })
 
-  child.on('close', function () {
+  child.on(CLOSE, function () {
     result = JSON.parse(result)
     t.same(result, {"user":"a user","pass":"a password","verify":"a password","passMatch":true})
     t.equal(output, 'Username: (test-user) Password: (<default hidden>) Password again: (<default hidden>) ')
index 6f7644d2a97e903995c36ead917a97d02bc01bc8..f3335ac82371d890aff7b10b72f97bed7c20be53 100644 (file)
@@ -5,6 +5,11 @@ if (process.argv[2] === 'child') {
   return child()
 }
 
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+  CLOSE = 'exit'
+}
+
 var spawn = require('child_process').spawn
 
 tap.test('defaults', function (t) {
@@ -31,7 +36,7 @@ tap.test('defaults', function (t) {
     console.error('result %j', c.toString())
   })
 
-  child.on('close', function () {
+  child.on(CLOSE, function () {
     result = JSON.parse(result)
     t.same(result, {"user":"test-user","pass":"test-pass","verify":"test-pass","passMatch":true})
     t.equal(output, 'Username: (test-user) Password: (<default hidden>) Password again: (<default hidden>) ')
index 0d32dae8af99593c6d6b96517cf7a546f89a9768..2aaa586e45030ea2be281b4ad54224ec10ad755f 100644 (file)
@@ -1,6 +1,11 @@
 var tap = require('tap')
 var read = require('../lib/read.js')
 
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+  CLOSE = 'exit'
+}
+
 if (process.argv[2] === 'child') {
   return child()
 }
@@ -68,7 +73,7 @@ tap.test('many reads', function (t) {
     output += c
     console.error('' + c)
   })
-  child.on('close', function (c) {
+  child.on(CLOSE, function (c) {
     t.equal(output, expect)
     t.equal(n, 19)
     t.end()
index 8713a807ce1fff9806254baaad2fd0330db0e8ab..1a55ac50b812b24015c61a919d63b5daefa6fe3d 100644 (file)
@@ -151,7 +151,7 @@ The first argument can be either a url or an options object. The only required o
 * `headers` - http headers, defaults to {}
 * `body` - entity body for POST and PUT requests. Must be buffer or string.
 * `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.
-* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.
+* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.  Additionally, parses the response body as json.
 * `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.
 * `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.
 * `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.
diff --git a/deps/npm/node_modules/request/aws2.js b/deps/npm/node_modules/request/aws2.js
deleted file mode 100644 (file)
index eb683f7..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-var crypto = require('crypto')
-
-// The Authentication Header
-// 
-// The Amazon S3 REST API uses the standard HTTPAuthorization header to pass authentication information. (The name of the standard header is unfortunate because it carries authentication information, not authorization).Under the Amazon S3 authentication scheme, the Authorization header has the following form.
-// 
-// Authorization: AWS AWSAccessKeyId:Signature
-// 
-// Developers are issued an AWS Access Key ID and AWS SecretAccess Key when they register. For request authentication, theAWSAccessKeyId element identifies the secret key that was used to compute the signature, and (indirectly) the developer making the request.
-// 
-// The Signature element is the RFC 2104HMAC-SHA1 of selected elements from the request, and so theSignature part of the Authorization header will vary from request to request. If the request signature calculated by the system matches theSignature included with the request, then the requester will have demonstrated possession to the AWSSecret Access Key. The request will then be processed under the identity, and with the authority, of the developer to whom the key was issued.
-// 
-// Following is pseudo-grammar that illustrates the construction of the Authorization request header (\nmeans the Unicode code point U+000A commonly called newline).
-
-function authorizationHeader (accessKey) {
-  // Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
-  
-  var authorization = 'AWS' + " " + accessKey + ":" + signature()
-  
-  return authorization
-}
-
-// 
-
-function signature (secret, verb, md5, contenttype, date, amzheaders, bucket, path) {
-  // Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) );
-  
-  function encodeSignature (stringToSign) {
-    return crypto.createHash('sha1').update(stringToSign).digest('base64')
-  }
-  
-  // 
-  // StringToSign = HTTP-Verb + "\n" +
-  //  Content-MD5 + "\n" +
-  //  Content-Type + "\n" +
-  //  Date + "\n" +
-  //  CanonicalizedAmzHeaders +
-  //  CanonicalizedResource;
-  
-  function compileStringToSign () {
-    var s = 
-      verb + '\n'
-      (md5 || '') + '\n'
-      (contenttype || '') + '\n'
-      date.toUTCString() + '\n'
-      canonicalizeAmzHeaders(amzheaders) + 
-      canonicalizeResource()
-    return s
-  }
-  
-  // 
-  // CanonicalizedResource = [ "/" + Bucket ] +
-  //  <HTTP-Request-URI, from the protocol name up to the query string> +
-  //  [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"];
-  
-  function canonicalizeResource () {
-    return '/' + bucket + path
-  }
-  
-  // 
-  // CanonicalizedAmzHeaders = <described below>
-  // 
-  // HMAC-SHA1 is an algorithm defined by RFC 2104 (go to RFC 2104 - Keyed-Hashing for Message Authentication ). The algorithm takes as input two byte-strings: a key and a message. For Amazon S3 Request authentication, use your AWS Secret Access Key (YourSecretAccessKeyID) as the key, and the UTF-8 encoding of the StringToSign as the message. The output of HMAC-SHA1 is also a byte string, called the digest. The Signature request parameter is constructed by Base64 encoding this digest.
-  // Request Canonicalization for Signing
-  // 
-  // Recall that when the system receives an authenticated request, it compares the computed request signature with the signature provided in the request in StringToSign. For that reason, you must compute the signature using the same method used by Amazon S3. We call the process of putting a request in an agreed-upon form for signing "canonicalization".
-  
-}
-
-
-
-// Constructing the CanonicalizedResource Element
-// 
-// CanonicalizedResource represents the Amazon S3 resource targeted by the request. Construct it for a REST request as follows:
-// 
-// Launch Process
-// 
-// 1
-//  
-// 
-// Start with the empty string ("").
-// 
-// 2
-//  
-// 
-// If the request specifies a bucket using the HTTP Host header (virtual hosted-style), append the bucket name preceded by a "/" (e.g., "/bucketname"). For path-style requests and requests that don't address a bucket, do nothing. For more information on virtual hosted-style requests, see Virtual Hosting of Buckets.
-// 
-// 3
-//  
-// 
-// Append the path part of the un-decoded HTTP Request-URI, up-to but not including the query string.
-// 
-// 4
-//  
-// 
-// If the request addresses a sub-resource, like ?versioning, ?location, ?acl, ?torrent, ?lifecycle, or ?versionid append the sub-resource, its value if it has one, and the question mark. Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted by sub-resource name and separated by '&'. e.g. ?acl&versionId=value.
-// 
-// The list of sub-resources that must be included when constructing the CanonicalizedResource Element are: acl, lifecycle, location, logging, notification, partNumber, policy, requestPayment, torrent, uploadId, uploads, versionId, versioning, versions and website.
-// 
-// If the request specifies query string parameters overriding the response header values (see Get Object), append the query string parameters, and its values. When signing you do not encode these values. However, when making the request, you must encode these parameter values. The query string parameters in a GET request include response-content-type, response-content-language, response-expires, response-cache-control, response-content-disposition, response-content-encoding.
-// 
-// The delete query string parameter must be including when creating the CanonicalizedResource for a Multi-Object Delete request.
-// 
-// Elements of the CanonicalizedResource that come from the HTTP Request-URI should be signed literally as they appear in the HTTP request, including URL-Encoding meta characters.
-// 
-// The CanonicalizedResource might be different than the HTTP Request-URI. In particular, if your request uses the HTTP Host header to specify a bucket, the bucket does appear in the HTTP Request-URI. However, the CanonicalizedResource continues to include the bucket. Query string parameters might also appear in the Request-URI but are not included in CanonicalizedResource. For more information, see Virtual Hosting of Buckets.
-// Constructing the CanonicalizedAmzHeaders Element
-// 
-// To construct the CanonicalizedAmzHeaders part of StringToSign, select all HTTP request headers that start with 'x-amz-' (using a case-insensitive comparison) and use the following process.
-// 
-// CanonicalizedAmzHeaders Process
-// 1  Convert each HTTP header name to lower-case. For example, 'X-Amz-Date' becomes 'x-amz-date'.
-// 2  Sort the collection of headers lexicographically by header name.
-// 3  Combine header fields with the same name into one "header-name:comma-separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any white-space between values. For example, the two metadata headers 'x-amz-meta-username: fred' and 'x-amz-meta-username: barney' would be combined into the single header 'x-amz-meta-username: fred,barney'.
-// 4  "Unfold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding white-space (including new-line) by a single space.
-// 5  Trim any white-space around the colon in the header. For example, the header 'x-amz-meta-username: fred,barney' would become 'x-amz-meta-username:fred,barney'
-// 6  Finally, append a new-line (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string.
-// 
-// Positional versus Named HTTP Header StringToSign Elements
-// 
-// The first few header elements of StringToSign (Content-Type, Date, and Content-MD5) are positional in nature. StringToSign does not include the names of these headers, only their values from the request. In contrast, the 'x-amz-' elements are named; Both the header names and the header values appear in StringToSign.
-// 
-// If a positional header called for in the definition of StringToSign is not present in your request, (Content-Type or Content-MD5, for example, are optional for PUT requests, and meaningless for GET requests), substitute the empty string ("") in for that position.
-// Time Stamp Requirement
-// 
-// A valid time stamp (using either the HTTP Date header or an x-amz-date alternative) is mandatory for authenticated requests. Furthermore, the client time-stamp included with an authenticated request must be within 15 minutes of the Amazon S3 system time when the request is received. If not, the request will fail with the RequestTimeTooSkewed error status code. The intention of these restrictions is to limit the possibility that intercepted requests could be replayed by an adversary. For stronger protection against eavesdropping, use the HTTPS transport for authenticated requests.
-// 
-// Some HTTP client libraries do not expose the ability to set the Date header for a request. If you have trouble including the value of the 'Date' header in the canonicalized headers, you can set the time-stamp for the request using an 'x-amz-date' header instead. The value of the x-amz-date header must be in one of the RFC 2616 formats (http://www.ietf.org/rfc/rfc2616.txt). When an x-amz-date header is present in a request, the system will ignore any Date header when computing the request signature. Therefore, if you include the x-amz-date header, use the empty string for the Date when constructing the StringToSign. See the next section for an example.
index 2407a93492502d5c1cdab0cc36d52aede9699f80..dcdd5caab123fbc9e2091b6f0a90a179a4548804 100644 (file)
@@ -107,7 +107,7 @@ Request.prototype.init = function (options) {
   var self = this
   
   if (!options) options = {}
-  
+  if (process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG)) console.error('REQUEST', options)
   if (!self.pool && self.pool !== false) self.pool = globalPool
   self.dests = []
   self.__isRequestRequest = true
@@ -140,12 +140,11 @@ Request.prototype.init = function (options) {
 
     // do the HTTP CONNECT dance using koichik/node-tunnel
     if (http.globalAgent && self.uri.protocol === "https:") {
-      self.tunnel = true
       var tunnelFn = self.proxy.protocol === "http:"
                    ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
 
       var tunnelOptions = { proxy: { host: self.proxy.hostname
-                                   , port: +self.proxy.port 
+                                   , port: +self.proxy.port
                                    , proxyAuth: self.proxy.auth }
                           , ca: this.ca }
 
@@ -223,6 +222,18 @@ Request.prototype.init = function (options) {
     self.emit('error', error)
   }
 
+  self._parserErrorHandler = function (error) {
+    if (this.res) {
+      if (this.res.request) {
+        this.res.request.emit('error', error)
+      } else {
+        this.res.emit('error', error)
+      }
+    } else {
+      this._httpMessage.emit('error', error)
+    }
+  }
+
   if (options.form) {
     self.form(options.form)
   }
@@ -319,7 +330,7 @@ Request.prototype.init = function (options) {
   }
 
   self.once('pipe', function (src) {
-    if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.")
+    if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.")
     self.src = src
     if (isReadStream(src)) {
       if (!self.headers['content-type'] && !self.headers['Content-Type'])
@@ -367,6 +378,70 @@ Request.prototype.init = function (options) {
   })
 }
 
+// Must call this when following a redirect from https to http or vice versa
+// Attempts to keep everything as identical as possible, but update the
+// httpModule, Tunneling agent, and/or Forever Agent in use.
+Request.prototype._updateProtocol = function () {
+  var self = this
+  var protocol = self.uri.protocol
+
+  if (protocol === 'https:') {
+    // previously was doing http, now doing https
+    // if it's https, then we might need to tunnel now.
+    if (self.proxy) {
+      self.tunnel = true
+      var tunnelFn = self.proxy.protocol === 'http:'
+                   ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
+      var tunnelOptions = { proxy: { host: self.proxy.hostname
+                                   , post: +self.proxy.port
+                                   , proxyAuth: self.proxy.auth }
+                          , ca: self.ca }
+      self.agent = tunnelFn(tunnelOptions)
+      return
+    }
+
+    self.httpModule = https
+    switch (self.agentClass) {
+      case ForeverAgent:
+        self.agentClass = ForeverAgent.SSL
+        break
+      case http.Agent:
+        self.agentClass = https.Agent
+        break
+      default:
+        // nothing we can do.  Just hope for the best.
+        return
+    }
+
+    // if there's an agent, we need to get a new one.
+    if (self.agent) self.agent = self.getAgent()
+
+  } else {
+    if (log) log('previously https, now http')
+    // previously was doing https, now doing http
+    // stop any tunneling.
+    if (self.tunnel) self.tunnel = false
+    self.httpModule = http
+    switch (self.agentClass) {
+      case ForeverAgent.SSL:
+        self.agentClass = ForeverAgent
+        break
+      case https.Agent:
+        self.agentClass = http.Agent
+        break
+      default:
+        // nothing we can do.  just hope for the best
+        return
+    }
+
+    // if there's an agent, then get a new one.
+    if (self.agent) {
+      self.agent = null
+      self.agent = self.getAgent()
+    }
+  }
+}
+
 Request.prototype.getAgent = function () {
   var Agent = this.agentClass
   var options = {}
@@ -392,7 +467,11 @@ Request.prototype.getAgent = function () {
     poolKey += this.host + ':' + this.port
   }
 
-  if (options.ca) {
+  // ca option is only relevant if proxy or destination are https
+  var proxy = this.proxy
+  if (typeof proxy === 'string') proxy = url.parse(proxy)
+  var caRelevant = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:'
+  if (options.ca && caRelevant) {
     if (poolKey) poolKey += ':'
     poolKey += options.ca
   }
@@ -402,6 +481,9 @@ Request.prototype.getAgent = function () {
     return this.httpModule.globalAgent
   }
 
+  // we're using a stored agent.  Make sure it's protocol-specific
+  poolKey = this.uri.protocol + poolKey
+
   // already generated an agent for this setting
   if (this.pool[poolKey]) return this.pool[poolKey]
 
@@ -410,25 +492,28 @@ Request.prototype.getAgent = function () {
 
 Request.prototype.start = function () {
   var self = this
-  
+
   if (self._aborted) return
-  
+
   self._started = true
   self.method = self.method || 'GET'
   self.href = self.uri.href
   if (log) log('%method %href', self)
-  
+
   if (self.src && self.src.stat && self.src.stat.size) {
     self.headers['content-length'] = self.src.stat.size
   }
   if (self._aws) {
     self.aws(self._aws, true)
   }
-  
+
   self.req = self.httpModule.request(self, function (response) {
+    if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) {
+      response.connection.once('error', self._parserErrorHandler)
+    }
     if (self._aborted) return
     if (self._paused) response.pause()
-    
+
     self.response = response
     response.request = self
     response.toJSON = toJSON
@@ -446,7 +531,7 @@ Request.prototype.start = function () {
       clearTimeout(self.timeoutTimer)
       self.timeoutTimer = null
     }  
-    
+
     var addCookie = function (cookie) {
       if (self._jar) self._jar.add(new Cookie(cookie))
       else cookieJar.add(new Cookie(cookie))
@@ -470,7 +555,15 @@ Request.prototype.start = function () {
       if (!isUrl.test(response.headers.location)) {
         response.headers.location = url.resolve(self.uri.href, response.headers.location)
       }
-      self.uri = response.headers.location
+
+      var uriPrev = self.uri
+      self.uri = url.parse(response.headers.location)
+
+      // handle the case where we change protocol from https to http or vice versa
+      if (self.uri.protocol !== uriPrev.protocol) {
+        self._updateProtocol()
+      }
+
       self.redirects.push(
         { statusCode : response.statusCode
         , redirectUri: response.headers.location 
@@ -540,7 +633,7 @@ Request.prototype.start = function () {
             if (self.encoding === null) {
               response.body = body
             } else {
-              response.body = body.toString()
+              response.body = body.toString(self.encoding)
             }
           } else if (buffer.length) {
             response.body = buffer.join('')
@@ -584,7 +677,9 @@ Request.prototype.start = function () {
   self.req.on('drain', function() {
     self.emit('drain')
   })
-  
+  self.on('end', function() {
+    self.req.connection.removeListener('error', self._parserErrorHandler)
+  })
   self.emit('request', self.req)
 }
 
@@ -659,10 +754,12 @@ Request.prototype.multipart = function (multipart) {
     self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary;
   }
 
-  console.log('boundary >> ' + self.boundary)
-
   if (!multipart.forEach) throw new Error('Argument error, options.multipart.')
 
+  if (self.preambleCRLF) {
+    self.body.push(new Buffer('\r\n'))
+  }
+  
   multipart.forEach(function (part) {
     var body = part.body
     if(body == null) throw Error('Body attribute missing in multipart.')
@@ -747,6 +844,7 @@ Request.prototype.oauth = function (_oauth) {
       // skip 
     } else {
       delete oa['oauth_'+i]
+      delete oa[i]
     }
   }
   this.headers.Authorization = 
@@ -861,16 +959,25 @@ function request (uri, options, callback) {
 
 module.exports = request
 
-request.defaults = function (options) {
+request.initParams = initParams;
+
+request.defaults = function (options, requester) {
   var def = function (method) {
     var d = function (uri, opts, callback) {
       var params = initParams(uri, opts, callback);
       for (var i in options) {
         if (params.options[i] === undefined) params.options[i] = options[i]
       }
-      return method(params.options, params.callback)
+      if(typeof requester === 'function') {
+        if(method === request) {
+          method = requester;
+        } else {
+          params.options._requester = requester;
+        }
+      }
+      return method(params.options, params.callback);
     }
-    return d
+    return d;
   }
   var de = def(request)
   de.get = def(request.get)
@@ -920,6 +1027,9 @@ request.head = function (uri, options, callback) {
 request.del = function (uri, options, callback) {
   var params = initParams(uri, options, callback);
   params.options.method = 'DELETE'
+  if(typeof params.options._requester === 'function') {
+    request = params.options._requester;
+  }
   return request(params.uri || null, params.options, params.callback)
 }
 request.jar = function () {
index 6796f5dff694ec8cd282626d7a85419f9703c85b..05d31444949ff2ea294c2a73bb643b099a4580a9 100644 (file)
   "scripts": {
     "test": "node tests/run.js"
   },
-  "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n  npm install request\n</pre>\n\nOr from source:\n\n<pre>\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n  if (!error && response.statusCode == 200) {\n    console.log(body) // Print the google web page.\n  }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    if (req.method === 'PUT') {\n      req.pipe(request.put('http://mysite.com/doodle.png'))\n    } else if (req.method === 'GET' || req.method === 'HEAD') {\n      request.get('http://mysite.com/doodle.png').pipe(resp)\n    } \n  }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    var x = request('http://mysite.com/doodle.png')\n    req.pipe(x)\n    x.pipe(resp)\n  }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    r.get('http://google.com/doodle.png').pipe(resp)\n  }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n  , oauth =\n    { callback: 'http://mysite.com/callback/'\n    , consumer_key: CONSUMER_KEY\n    , consumer_secret: CONSUMER_SECRET\n    }\n  , url = 'https://api.twitter.com/oauth/request_token'\n  ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n  // Assume by some stretch of magic you aquired the verifier\n  var access_token = qs.parse(body)\n    , oauth = \n      { consumer_key: CONSUMER_KEY\n      , consumer_secret: CONSUMER_SECRET\n      , token: access_token.oauth_token\n      , verifier: VERIFIER\n      , token_secret: access_token.oauth_token_secret\n      }\n    , url = 'https://api.twitter.com/oauth/access_token'\n    ;\n  request.post({url:url, oauth:oauth}, function (e, r, body) {\n    var perm_token = qs.parse(body)\n      , oauth = \n        { consumer_key: CONSUMER_KEY\n        , consumer_secret: CONSUMER_SECRET\n        , token: perm_token.oauth_token\n        , token_secret: perm_token.oauth_token_secret\n        }\n      , url = 'https://api.twitter.com/1/users/show.json?'\n      , params = \n        { screen_name: perm_token.screen_name\n        , user_id: perm_token.user_id\n        }\n      ;\n    url += qs.stringify(params)\n    request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n      console.log(user)\n    })\n  })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options)  \n  \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n  var request = require('request')\n    , rand = Math.floor(Math.random()*100000000).toString()\n    ;\n  request(\n    { method: 'PUT'\n    , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n    , multipart: \n      [ { 'content-type': 'application/json'\n        ,  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n        }\n      , { body: 'I am an attachment' }\n      ] \n    }\n  , function (error, response, body) {\n      if(response.statusCode == 201){\n        console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n      } else {\n        console.log('error: '+ response.statusCode)\n        console.log(body)\n      }\n    }\n  )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n  request('http://images.google.com')\n})\n```\n",
+  "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n  npm install request\n</pre>\n\nOr from source:\n\n<pre>\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n  if (!error && response.statusCode == 200) {\n    console.log(body) // Print the google web page.\n  }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    if (req.method === 'PUT') {\n      req.pipe(request.put('http://mysite.com/doodle.png'))\n    } else if (req.method === 'GET' || req.method === 'HEAD') {\n      request.get('http://mysite.com/doodle.png').pipe(resp)\n    } \n  }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    var x = request('http://mysite.com/doodle.png')\n    req.pipe(x)\n    x.pipe(resp)\n  }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n  if (req.url === '/doodle.png') {\n    r.get('http://google.com/doodle.png').pipe(resp)\n  }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n  , oauth =\n    { callback: 'http://mysite.com/callback/'\n    , consumer_key: CONSUMER_KEY\n    , consumer_secret: CONSUMER_SECRET\n    }\n  , url = 'https://api.twitter.com/oauth/request_token'\n  ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n  // Assume by some stretch of magic you aquired the verifier\n  var access_token = qs.parse(body)\n    , oauth = \n      { consumer_key: CONSUMER_KEY\n      , consumer_secret: CONSUMER_SECRET\n      , token: access_token.oauth_token\n      , verifier: VERIFIER\n      , token_secret: access_token.oauth_token_secret\n      }\n    , url = 'https://api.twitter.com/oauth/access_token'\n    ;\n  request.post({url:url, oauth:oauth}, function (e, r, body) {\n    var perm_token = qs.parse(body)\n      , oauth = \n        { consumer_key: CONSUMER_KEY\n        , consumer_secret: CONSUMER_SECRET\n        , token: perm_token.oauth_token\n        , token_secret: perm_token.oauth_token_secret\n        }\n      , url = 'https://api.twitter.com/1/users/show.json?'\n      , params = \n        { screen_name: perm_token.screen_name\n        , user_id: perm_token.user_id\n        }\n      ;\n    url += qs.stringify(params)\n    request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n      console.log(user)\n    })\n  })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.  Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options)  \n  \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n  var request = require('request')\n    , rand = Math.floor(Math.random()*100000000).toString()\n    ;\n  request(\n    { method: 'PUT'\n    , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n    , multipart: \n      [ { 'content-type': 'application/json'\n        ,  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n        }\n      , { body: 'I am an attachment' }\n      ] \n    }\n  , function (error, response, body) {\n      if(response.statusCode == 201){\n        console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n      } else {\n        console.log('error: '+ response.statusCode)\n        console.log(body)\n      }\n    }\n  )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n  request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n  request('http://images.google.com')\n})\n```\n",
   "_id": "request@2.9.203",
   "dist": {
-    "shasum": "f4c8f35b61b4d6621cb287bb1a1be6002b0bbe4a"
+    "shasum": "baf55a9b2ccfcca405cfcc0b104edf8b2681eeef"
   },
-  "_from": "request@~2.9"
+  "_from": "git://github.com/isaacs/request"
 }
index 921f51204089f7fa8d13c1d722a574f59fc9f7b9..5b7cb511f7102da12255ed29ee70da14847e902c 100644 (file)
@@ -51,11 +51,15 @@ exports.createPostValidator = function (text) {
     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()
+      if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) {
+        var boundary = req.headers['content-type'].split('boundary=')[1];
+        text = text.replace(/__BOUNDARY__/g, boundary);
+      }
+      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;
index e3fc75d97075c0c2176f2584fa25230f599055e8..a624397d7c5bec338a0def3267573a42c0f8abeb 100644 (file)
@@ -30,6 +30,11 @@ var tests =
     , encoding: null
     , expectBody: new Buffer("TESTING!")
     }
+  , testGetEncoding :
+    { resp : server.createGetResponse(new Buffer('efa3bfcea9e29883', 'hex'))
+    , encoding: 'hex'
+    , expectBody: "efa3bfcea9e29883"
+    }
   , testGetJSON :
      { resp : server.createGetResponse('{"test":true}', 'application/json')
      , json : true
@@ -50,7 +55,39 @@ var tests =
     , method: "PUT"
     , json: {foo: 'bar'}
     }
-
+  , testPutMultipart :
+    { resp: server.createPostValidator(
+        '--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
+  , testPutMultipartPreambleCRLF :
+    { resp: server.createPostValidator(
+        '\r\n--__BOUNDARY__\r\n' +
+        'content-type: text/html\r\n' +
+        '\r\n' +
+        '<html><body>Oh hi.</body></html>' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
+        'Oh hi.' +
+        '\r\n--__BOUNDARY__--'
+        )
+    , method: "PUT"
+    , preambleCRLF: true
+    , multipart:
+      [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+      , {'body': 'Oh hi.'}
+      ]
+    }
   }
 
 s.listen(s.port, function () {
index 6c8b58fa692d3f29c42d84bfe02552551431f198..479abf2338e326cb5fe3052aec039624600ba008 100644 (file)
@@ -61,8 +61,39 @@ s.listen(s.port, 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()
   });
 
+  s.on('/get_custom', function(req, resp) {
+    assert.equal(req.headers.foo, 'bar');
+    assert.equal(req.headers.x, 'y');
+    resp.writeHead(200, {'Content-Type': 'text/plain'});
+    resp.end();
+  });
+
+  // test custom request handler function
+  var defaultRequest = request.defaults({
+    headers:{foo:"bar"}
+    , body: 'TESTING!'
+  }, function(uri, options, callback) {
+    var params = request.initParams(uri, options, callback);
+    options = params.options;
+    options.headers.x = 'y';
+
+    return request(params.uri, params.options, params.callback);
+  });
+
+  var msg = 'defaults test failed. head request should throw earlier';
+  assert.throws(function() {
+    defaultRequest.head(s.url + '/get_custom', function(e, r, b) {
+      throw new Error(msg);
+    });
+    counter+=1;
+  }, msg);
+
+  defaultRequest.get(s.url + '/get_custom', 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-follow-all-303.js b/deps/npm/node_modules/request/tests/test-follow-all-303.js
new file mode 100644 (file)
index 0000000..5eec497
--- /dev/null
@@ -0,0 +1,30 @@
+var request = require('request');
+var http = require('http');
+var requests = 0;
+var assert = require('assert');
+
+var server = http.createServer(function (req, res) {
+  console.error(req.method, req.url);
+  requests ++;
+
+  if (req.method === 'POST') {
+    console.error('send 303');
+    res.setHeader('location', req.url);
+    res.statusCode = 303;
+    res.end('try again, i guess\n');
+  } else {
+    console.error('send 200')
+    res.end('ok: ' + requests);
+  }
+});
+server.listen(6767);
+
+request.post({ url: 'http://localhost:6767/foo',
+               followAllRedirects: true,
+               form: { foo: 'bar' } }, function (er, req, body) {
+  if (er) throw er;
+  assert.equal(body, 'ok: 2');
+  assert.equal(requests, 2);
+  console.error('ok - ' + process.version);
+  server.close();
+});
diff --git a/deps/npm/node_modules/request/tests/test-follow-all.js b/deps/npm/node_modules/request/tests/test-follow-all.js
new file mode 100644 (file)
index 0000000..4dbde61
--- /dev/null
@@ -0,0 +1,35 @@
+var request = require('request');
+var http = require('http');
+var requests = 0;
+var assert = require('assert');
+
+var server = http.createServer(function (req, res) {
+  requests ++;
+
+  // redirect everything 3 times, no matter what.
+  var c = req.headers.cookie;
+
+  if (!c) c = 0;
+  else c = +c.split('=')[1] || 0;
+
+  if (c > 3) {
+    res.end('ok: '+requests);
+    return;
+  }
+
+  res.setHeader('set-cookie', 'c=' + (c + 1));
+  res.setHeader('location', req.url);
+  res.statusCode = 302;
+  res.end('try again, i guess\n');
+});
+server.listen(6767);
+
+request.post({ url: 'http://localhost:6767/foo',
+               followAllRedirects: true,
+               form: { foo: 'bar' } }, function (er, req, body) {
+  if (er) throw er;
+  assert.equal(body, 'ok: 5');
+  assert.equal(requests, 5);
+  console.error('ok - ' + process.version);
+  server.close();
+});
index f53fc14a8d929e54687bbb6bf33985c160b2d7e2..470b68ddd70f11e8654ced863e997d7d93cf99d5 100644 (file)
@@ -52,13 +52,13 @@ var tests =
     }
   , testPutMultipart :
     { resp: server.createPostValidator(
-        '--frontier\r\n' +
+        '--__BOUNDARY__\r\n' +
         'content-type: text/html\r\n' +
         '\r\n' +
         '<html><body>Oh hi.</body></html>' +
-        '\r\n--frontier\r\n\r\n' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
         'Oh hi.' +
-        '\r\n--frontier--'
+        '\r\n--__BOUNDARY__--'
         )
     , method: "PUT"
     , multipart:
index df7330b39d8dfff9da8ec20a3971e55c15ed5832..58e7db93f7c23dcce5627b144ce006b5f46d0b10 100644 (file)
@@ -44,13 +44,13 @@ var tests =
     }
   , testPutMultipart :
     { resp: server.createPostValidator(
-        '--frontier\r\n' +
+        '--__BOUNDARY__\r\n' +
         'content-type: text/html\r\n' +
         '\r\n' +
         '<html><body>Oh hi.</body></html>' +
-        '\r\n--frontier\r\n\r\n' +
+        '\r\n--__BOUNDARY__\r\n\r\n' +
         'Oh hi.' +
-        '\r\n--frontier--'
+        '\r\n--__BOUNDARY__--'
         )
     , method: "PUT"
     , multipart:
index 8354f6d8d2120be2bb9644d9712225a10d1fc712..5ddb311625b84178c036e6de1108f9c0d50b1247 100644 (file)
@@ -50,13 +50,13 @@ var tests =
       }
     , testPutMultipart :
       { resp: server.createPostValidator(
-          '--frontier\r\n' +
+          '--__BOUNDARY__\r\n' +
           'content-type: text/html\r\n' +
           '\r\n' +
           '<html><body>Oh hi.</body></html>' +
-          '\r\n--frontier\r\n\r\n' +
+          '\r\n--__BOUNDARY__\r\n\r\n' +
           'Oh hi.' +
-          '\r\n--frontier--'
+          '\r\n--__BOUNDARY__--'
           )
       , method: "PUT"
       , multipart:
diff --git a/deps/npm/node_modules/request/tests/test-protocol-changing-redirect.js b/deps/npm/node_modules/request/tests/test-protocol-changing-redirect.js
new file mode 100644 (file)
index 0000000..f74e196
--- /dev/null
@@ -0,0 +1,60 @@
+var server = require('./server')
+  , assert = require('assert')
+  , request = require('../main.js')
+
+
+var s = server.createServer()
+var ss = server.createSSLServer()
+var sUrl = 'http://localhost:' + s.port
+var ssUrl = 'https://localhost:' + ss.port
+
+s.listen(s.port, bouncy(s, ssUrl))
+ss.listen(ss.port, bouncy(ss, sUrl))
+
+var hits = {}
+var expect = {}
+var pending = 0
+function bouncy (s, server) { return function () {
+
+  var redirs = { a: 'b'
+               , b: 'c'
+               , c: 'd'
+               , d: 'e'
+               , e: 'f'
+               , f: 'g'
+               , g: 'h'
+               , h: 'end' }
+
+  var perm = true
+  Object.keys(redirs).forEach(function (p) {
+    var t = redirs[p]
+
+    // switch type each time
+    var type = perm ? 301 : 302
+    perm = !perm
+    s.on('/' + p, function (req, res) {
+      res.writeHead(type, { location: server + '/' + t })
+      res.end()
+    })
+  })
+
+  s.on('/end', function (req, res) {
+    var h = req.headers['x-test-key']
+    hits[h] = true
+    pending --
+    if (pending === 0) done()
+  })
+}}
+
+for (var i = 0; i < 5; i ++) {
+  pending ++
+  var val = 'test_' + i
+  expect[val] = true
+  request({ url: (i % 2 ? sUrl : ssUrl) + '/a'
+          , headers: { 'x-test-key': val } })
+}
+
+function done () {
+  assert.deepEqual(hits, expect)
+  process.exit(0)
+}
diff --git a/deps/npm/node_modules/request/tests/test-s3.js b/deps/npm/node_modules/request/tests/test-s3.js
deleted file mode 100644 (file)
index 5f59c4a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
index 58131b9bbaad2388ea900b4f34a10d01617c862c..51e2126f85407e72c9dbfc6b622d9fce401b6aa3 100644 (file)
@@ -32,9 +32,10 @@ squid.stdout.on('data', function (c) {
 })
 
 squid.on('exit', function (c) {
-  console.error('exit '+c)
+  console.error('squid: exit '+c)
   if (c && !ready) {
     console.error('squid must be installed to run this test.')
+    console.error('skipping this test. please install squid and run again if you need to test tunneling.')
     c = null
     hadError = null
     process.exit(0)
@@ -49,8 +50,9 @@ squid.on('exit', function (c) {
 
 setTimeout(function F () {
   if (!ready) return setTimeout(F, 100)
-  request({ uri: 'https://registry.npmjs.org/request/'
+  request({ uri: 'https://registry.npmjs.org/'
           , proxy: 'http://localhost:3128'
+          , strictSSL: true
           , ca: ca
           , json: true }, function (er, body) {
     hadError = er
index 453786c5e7bcc800474ff6e8b54b81bd5d383033..469c130e898842a467454efbad2ff015a3681b46 100644 (file)
@@ -188,6 +188,7 @@ function createSecureSocket(options, cb) {
   TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
     // 0 is dummy port for v0.6
     var secureSocket = tls.connect(0, mergeOptions({}, self.options, {
+      servername: options.host,
       socket: socket
     }));
     cb(secureSocket);
index d0b4d7be7c0a8b7d63f54a9e094821f4e458ece1..71a77aba69ac19af246ae34df39f4ef3ca9afccb 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "version": "1.1.49",
+  "version": "1.1.55",
   "name": "npm",
   "publishConfig": {
     "proprietary-attribs": false
@@ -41,7 +41,6 @@
     "graceful-fs": "~1.1.1",
     "minimatch": "~0.2.6",
     "nopt": "~2.0",
-    "node-uuid": "~1.3",
     "rimraf": "2",
     "request": "~2.9",
     "which": "1",
@@ -50,7 +49,7 @@
     "block-stream": "*",
     "inherits": "1",
     "mkdirp": "~0.3.3",
-    "read": "~1.0.3",
+    "read": "~1.0.4",
     "lru-cache": "~2.0.0",
     "node-gyp": "~0.6.4",
     "fstream-npm": "0.1",
@@ -59,7 +58,7 @@
     "chownr": "0",
     "npmlog": "0",
     "ansi": "~0.1.2",
-    "npm-registry-client": "~0.1.4",
+    "npm-registry-client": "~0.2.4",
     "read-package-json": "~0.1.3",
     "read-installed": "0",
     "glob": "~3.1.12",
@@ -79,7 +78,6 @@
     "graceful-fs",
     "minimatch",
     "nopt",
-    "node-uuid",
     "rimraf",
     "request",
     "which",
     "tap": "~0.2.5"
   },
   "engines": {
-    "node": ">=0.8",
+    "node": ">=0.6",
     "npm": "1"
   },
   "scripts": {
diff --git a/deps/npm/test/tap/publish-config.js b/deps/npm/test/tap/publish-config.js
new file mode 100644 (file)
index 0000000..ac8c94a
--- /dev/null
@@ -0,0 +1,41 @@
+var test = require('tap').test
+var fs = require('fs')
+var pkg = process.env.npm_config_tmp || '/tmp'
+pkg += '/npm-test-publish-config'
+
+require('mkdirp').sync(pkg)
+
+fs.writeFileSync(pkg + '/package.json', JSON.stringify({
+  name: 'npm-test-publish-config',
+  version: '1.2.3',
+  publishConfig: { registry: 'http://localhost:13370' }
+}), 'utf8')
+
+var spawn = require('child_process').spawn
+var npm = require.resolve('../../bin/npm-cli.js')
+var node = process.execPath
+
+console.error('pkg=%j', pkg)
+
+test(function (t) {
+  var child
+  require('http').createServer(function (req, res) {
+    t.pass('got request on the fakey fake registry')
+    t.end()
+    this.close()
+    res.statusCode = 500
+    res.end('{"error":"sshhh. naptime nao. \\^O^/ <(YAWWWWN!)"}')
+    child.kill()
+  }).listen(13370, function () {
+    t.pass('server is listening')
+
+    // don't much care about listening to the child's results
+    // just wanna make sure it hits the server we just set up.
+    //
+    // there are plenty of other tests to verify that publish
+    // itself functions normally.
+    child = spawn(node, [npm, 'publish'], {
+      cwd: pkg
+    })
+  })
+})