<p>This function should not be used programmatically. Instead, just refer
to the <code>npm.bin</code> member.</p>
</div>
-<p id="footer">bin — npm@1.1.44</p>
+<p id="footer">bin — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">bugs — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/index.html">index(1)</a></li></ul>
</div>
-<p id="footer">commands — npm@1.1.44</p>
+<p id="footer">commands — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../api/npm.html">npm(3)</a></li></ul>
</div>
-<p id="footer">config — npm@1.1.44</p>
+<p id="footer">config — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">deprecate — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">docs — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">edit — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p>
</div>
-<p id="footer">explore — npm@1.1.44</p>
+<p id="footer">explore — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The silent parameter is not neccessary not used, but it may in the future.</p>
</div>
-<p id="footer">help-search — npm@1.1.44</p>
+<p id="footer">help-search — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p><a href="../doc/json.html">json(1)</a></p>
</div>
-<p id="footer">init — npm@1.1.44</p>
+<p id="footer">init — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
installed or when an error has been encountered.</p>
</div>
-<p id="footer">install — npm@1.1.44</p>
+<p id="footer">install — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">link — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>For a list of all the available command-line configs, see <code>npm help config</code></p>
</div>
-<p id="footer">load — npm@1.1.44</p>
+<p id="footer">load — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
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 — npm@1.1.44</p>
+<p id="footer">ls — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.44</p>
+<p>1.1.45</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre>
</div>
-<p id="footer">npm — npm@1.1.44</p>
+<p id="footer">npm — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If the 'packages' parameter is left out, npm will check all packages.</p>
</div>
-<p id="footer">outdated — npm@1.1.44</p>
+<p id="footer">outdated — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">owner — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>If no arguments are supplied, then npm packs the current package folder.</p>
</div>
-<p id="footer">pack — npm@1.1.44</p>
+<p id="footer">pack — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">prefix — npm@1.1.44</p>
+<p id="footer">prefix — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Extraneous packages are packages that are not listed on the parent
package's dependencies list.</p>
</div>
-<p id="footer">prune — npm@1.1.44</p>
+<p id="footer">prune — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">publish — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>See <code>npm help build</code></p>
</div>
-<p id="footer">rebuild — npm@1.1.44</p>
+<p id="footer">rebuild — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">restart — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically.</p>
</div>
-<p id="footer">root — npm@1.1.44</p>
+<p id="footer">root — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">run-script — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
and doesn't try to read your mind (it doesn't do any verb tense matching or the
like).</p>
</div>
-<p id="footer">search — npm@1.1.44</p>
+<p id="footer">search — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when the shrinkwrap has
been saved.</p>
</div>
-<p id="footer">shrinkwrap — npm@1.1.44</p>
+<p id="footer">shrinkwrap — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">start — npm@1.1.44</p>
+<p id="footer">start — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run stop on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">stop — npm@1.1.44</p>
+<p id="footer">stop — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li>npm help json</li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.44</p>
+<p id="footer">submodule — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
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 — npm@1.1.44</p>
+<p id="footer">tag — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>npm can run tests on multiple packages. Just specify multiple packages
in the <code>packages</code> parameter.</p>
</div>
-<p id="footer">test — npm@1.1.44</p>
+<p id="footer">test — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>Finally, 'callback' is a function that will be called when all packages have been
uninstalled or when an error has been encountered.</p>
</div>
-<p id="footer">uninstall — npm@1.1.44</p>
+<p id="footer">uninstall — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">unpublish — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p>
</div>
-<p id="footer">update — npm@1.1.44</p>
+<p id="footer">update — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
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 — npm@1.1.44</p>
+<p id="footer">version — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>corresponding to the list of fields selected.</p>
</div>
-<p id="footer">view — npm@1.1.44</p>
+<p id="footer">view — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p>This function is not useful programmatically</p>
</div>
-<p id="footer">whoami — npm@1.1.44</p>
+<p id="footer">whoami — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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> — npm@1.1.44</p>
+<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">adduser — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">bin — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">bugs — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">build — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/install.html">install(1)</a></li></ul>
</div>
-<p id="footer">bundle — npm@1.1.44</p>
+<p id="footer">bundle — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">cache — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">changelog — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">coding-style — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">completion — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">config — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">deprecate — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">developers — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">disputes — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">docs — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">edit — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">explore — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">faq — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">folders — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">help-search — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">help — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<p> Display npm username</p>
</div>
-<p id="footer">index — npm@1.1.44</p>
+<p id="footer">index — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">init — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">install — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">json — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">link — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
nested packages will <em>also</em> show the paths to the specified packages.
For example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
-<pre><code>npm@1.1.44 /path/to/npm
+<pre><code>npm@1.1.45 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5</code></pre>
<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 — npm@1.1.44</p>
+<p id="footer">list — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<h2 id="VERSION">VERSION</h2>
-<p>1.1.44</p>
+<p>1.1.45</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<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 — npm@1.1.44</p>
+<p id="footer">npm — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">outdated — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">owner — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">pack — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">prefix — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">prune — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">publish — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">rebuild — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">registry — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">removing-npm — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">restart — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">root — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">run-script — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">scripts — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">search — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li></ul>
</div>
-<p id="footer">semver — npm@1.1.44</p>
+<p id="footer">semver — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">shrinkwrap — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">star — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">start — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">stop — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul>
</div>
-<p id="footer">submodule — npm@1.1.44</p>
+<p id="footer">submodule — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">tag — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">test — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">uninstall — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">unpublish — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">update — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">version — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">view — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
<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 — npm@1.1.44</p>
+<p id="footer">whoami — npm@1.1.45</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
function readUsername (c, u, cb) {
read({prompt: "Username: ", default: c.u}, function (er, un) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ // make sure it's valid. we have to do this here, because
+ // couchdb will only ever say "bad password" with a 401 when
+ // you try to PUT a _users record that the validate_doc_update
+ // rejects for *any* reason.
+
+ if (!un) {
+ return readUsername(c, u, cb)
+ }
+
+ if (un !== un.toLowerCase()) {
+ log.warn('Username must be lowercase')
+ return readUsername(c, u, cb)
+ }
+
+ if (un !== encodeURIComponent(un)) {
+ log.warn('Username may not contain non-url-safe chars')
+ return readUsername(c, u, cb)
+ }
+
+ if (un.charAt(0) === '.') {
+ log.warn('Username may not start with "."')
+ return readUsername(c, u, cb)
+ }
+
c.changed = c.u !== un
u.u = un
cb(er)
return cb()
}
read({prompt: "Password: ", silent: true}, function (er, pw) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ if (!pw) {
+ return readPassword(c, u, cb)
+ }
+
+ if (pw.match(/['!:@"]/)) {
+ log.warn('Sorry, passwords cannot contain these characters: \'!:@"')
+ return readPassword(c, u, cb)
+ }
+
u.p = pw
cb(er)
})
function readEmail (c, u, cb) {
read({prompt: "Email: ", default: c.e}, function (er, em) {
+ if (er) {
+ return cb(er.message === "cancelled" ? er.message : er)
+ }
+
+ if (!em) {
+ return readEmail(c, u, cb)
+ }
+
+ if (!em.match(/^.+@.+\..+$/)) {
+ log.warn('Email must be an email address')
+ return readEmail(c, u, cb)
+ }
+
u.e = em
cb(er)
})
// save the token cookie in the config file
if (npm.registry.couchLogin) {
- npm.registry.couchLogin.tokenSet = function (tok, cb) {
+ npm.registry.couchLogin.tokenSet = function (tok) {
ini.set("_token", JSON.stringify(tok), "user")
// ignore save error. best effort.
ini.save("user", function () {})
function errorHandler (er) {
+ var printStack = false
// console.error("errorHandler", er)
if (!ini.resolved) {
// logging won't work unless we pretend that it's ready
var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
if (m && !er.code) er.code = m
- var didStack = false
switch (er.code) {
case "ECONNREFUSED":
log.error("", er)
log.error("", ["\nIf you are behind a proxy, please make sure that the"
,"'proxy' config is set properly. See: 'npm help config'"
].join("\n"))
+ printStack = true
break
case "EACCES":
log.error("", er)
log.error("", ["\nPlease try running this command again as root/Administrator."
].join("\n"))
+ printStack = true
break
case "ELIFECYCLE":
} // else passthrough
default:
- didStack = true
log.error("", er.stack || er.message || er)
log.error("", ["If you need help, you may report this log at:"
," <http://github.com/isaacs/npm/issues>"
,"or email it to:"
," <npm-@googlegroups.com>"
].join("\n"))
+ printStack = false
break
}
].forEach(function (k) {
var v = er[k]
if (k === "stack") {
- if (didStack) return
+ if (!printStack) return
if (!v) v = er.message
}
if (!v) return
+ "published version\n"
+ "'npm ls' to inspect current package/dependency versions"
-function version (args, cb) {
- if (args.length !== 1) return cb(version.usage)
+function version (args, silent, cb_) {
+ if (typeof cb_ !== "function") cb_ = silent, silent = false
+ if (args.length !== 1) return cb_(version.usage)
fs.readFile(path.join(process.cwd(), "package.json"), function (er, data) {
if (er) {
log.error("version", "No package.json found")
- return cb(er)
+ return cb_(er)
}
try {
data = JSON.parse(data)
} catch (er) {
log.error("version", "Bad package.json data")
- return cb(er)
+ return cb_(er)
}
var newVer = semver.valid(args[0])
if (!newVer) newVer = semver.inc(data.version, args[0])
- if (!newVer) return cb(version.usage)
- if (data.version === newVer) return cb(new Error("Version not changed"))
+ if (!newVer) return cb_(version.usage)
+ if (data.version === newVer) return cb_(new Error("Version not changed"))
data.version = newVer
fs.stat(path.join(process.cwd(), ".git"), function (er, s) {
+ function cb (er) {
+ if (!er && !silent) console.log("v" + newVer)
+ cb_(er)
+ }
+
var doGit = !er && s.isDirectory()
if (!doGit) return write(data, cb)
else checkGit(data, cb)
.IP "" 4
.
.nf
-npm@1.1.44 /path/to/npm
+npm@1.1.45 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.
.fi
.
.SH "VERSION"
-1.1.44
+1.1.45
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
.fi
.
.SH "VERSION"
-1.1.44
+1.1.45
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
var request = require('request')
, url = require('url')
, crypto = require('crypto')
+, YEAR = (1000 * 60 * 60 * 24 * 365)
module.exports = CouchLogin
if (tok === 'anonymous') tok = NaN
this.token = tok
this.couch = url.format(couch)
+
+ this.maxAge = YEAR
}
CouchLogin.prototype =
delete sc['max-age']
}
+ // expire the session after 1 year, even if couch won't.
+ if (!sc.hasOwnProperty('expires')) {
+ sc.expires = Date.now() + YEAR
+ }
+
+ if (!isNaN(this.maxAge)) {
+ sc.expires = Math.min(sc.expires, Date.now() + this.maxAge)
+ }
+
this.token = sc
if (this.tokenSet) this.tokenSet(this.token)
}
}
function valid (token) {
- var d = token && token.expires
- return token && token.expires > Date.now()
+ if (!token) return false
+ if (!token.hasOwnProperty('expires')) return true
+ return token.expires > Date.now()
}
function sha (s) {
},
"name": "couch-login",
"description": "A module for doing logged-in requests to a couchdb server",
- "version": "0.1.6",
+ "version": "0.1.8",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/couch-login.git"
"tap": "~0.2.4"
},
"readme": "# couch-login\n\nThis module lets you log into couchdb to get a session token, then make\nrequests using that session. It is basically just a thin wrapper around\n[@mikeal's request module](https://github.com/mikeal/request).\n\nThis is handy if you want a user to take actions in a couchdb database\non behalf of a user, without having to store their couchdb username and\npassword anywhere. (You do need to store the AuthSession token\nsomewhere, though.)\n\n## Usage\n\n```javascript\nvar CouchLogin = require('couch-login')\n\n// Nothing about this module is http-server specific of course.\n// You could also use it to do authenticated requests against\n// a couchdb using sessions and storing the token somewhere else.\n\nhttp.createServer(function (req, res) {\n var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')\n\n // .. look up the token in the user's session or whatever ..\n // Look at couch.decorate(req, res) for more on doing that\n // automatically, below.\n\n if (sessionToken) {\n // this user already logged in.\n couch.token = sessionToken\n\n // now we can do things on their behalf, like:\n // 1. View their session info.\n // like doing request.get({ uri: couch + '/_session', ... })\n // but with the cookie and whatnot\n\n couch.get('/_session', function (er, resp, data) {\n // er = some kind of communication error.\n // resp = response object from the couchdb request.\n // data = parsed JSON response body.\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // now we have the session info, we know who this user is.\n // hitting couchdb for this on every request is kinda costly,\n // so maybe you should store the username wherever you're storing\n // the sessionToken. RedSess is a good util for this, if you're\n // into redis. And if you're not into redis, you're crazy,\n // because it is awesome.\n\n // now let's get the user record.\n // note that this will 404 for anyone other than the user,\n // unless they're a server admin.\n couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)\n\n // PUTs and DELETEs will also use their session, of course, so\n // your validate_doc_update's will see their info in userCtx\n })\n\n } else {\n // don't have a sessionToken.\n // get a username and password from the post body or something.\n // maybe redirect to a /login page or something to ask for that.\n var login = { name: name, password: password }\n couch.login(login, function (er, resp, data) {\n // again, er is an error, resp is the response obj, data is the json\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // the data is something like\n // {\"ok\":true,\"name\":\"testuser\",\"roles\":[]}\n // and couch.token is the token you'll need to save somewhere.\n\n // at this point, you can start making authenticated requests to\n // couchdb, or save data in their session, or do whatever it is\n // that you need to do.\n\n res.statusCode = 200\n res.write(\"Who's got two thumbs and just logged you into couch?\\n\")\n setTimeout(function () {\n res.end(\"THIS GUY!\")\n }, 500)\n })\n }\n})\n```\n\n## Class: CouchLogin\n### new CouchLogin(couchdbUrl, token)\n\nCreate a new CouchLogin object bound to the couchdb url.\n\nIn addition to these, the `get`, `post`, `put`, and `del` methods all\nproxy to the associated method on [request](https://github.com/mikeal/request).\n\nHowever, as you'll note in the example above, only the pathname portion\nof the url is required. Urls will be appended to the couchdb url passed\ninto the constructor.\n\nIf you have to talk to more than one couchdb, then you'll need more than\none CouchLogin object, for somewhat obvious reasons.\n\nAll callbacks get called with the following arguments, which are exactly\nidentical to the arguments passed to a `request` callback.\n\n* `er` {Error | null} Set if a communication error happens.\n* `resp` {HTTP Response} The response from the request to couchdb\n* `data` {Object} The parsed JSON data from couch\n\nIf the token is the string \"anonymous\", then it will not attempt to log\nin before making requests. If the token is not \"anonymous\", then it\nmust be an object with the appropriate fields.\n\n### couch.token\n\n* {Object}\n\nAn object representing the couchdb session token. (Basically just a\ncookie and a timeout.)\n\nIf the token has already timed out, then setting it will have no effect.\n\n### couch.tokenSet\n\nIf set, this method is called whenever the token is saved.\n\nFor example, you could assign a function to this method to save the\ntoken into a redis session, a cookie, or in some other database.\n\nTakes a callback which should be called when the token is saved.\n\n### couch.tokenGet\n\nIf set, this method is called to look up the token on demand.\n\nThe inverse of couch.tokenSet. Takes a callback which is called with\nthe `cb(er || null, token)`.\n\n### couch.tokenDel\n\nIf set, this method is called to delete the token when it should be\ndiscarded.\n\nRelated to tokenGet and tokenSet. Takes a callback which should be\ncalled when the token is deleted.\n\n### couch.anonymous()\n\nReturn a new CouchLogin object that points at the same couchdb server,\nbut doesn't try to log in before making requests.\n\nThis is handy for situations where the user is not logged in at the\nmoment, but a request needs to be made anyway, and does not require\nauthorization.\n\n### couch.login(auth, callback)\n\n* `auth` {Object} The login details\n * `name` {String}\n * `password` {String}\n* `callback` {Function}\n\nWhen the callback is called, the `couch.token` will already have been\nset (assuming it worked!), so subsequent requests will be done as that\nuser.\n\n### couch.get(path, callback)\n\nGET the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.del(path, callback)\n\nDELETE the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.post(path, data, callback)\n\nPOST the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.put(path, data, callback)\n\nPUT the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.changePass(newAuth, callback)\n\nMust already be logged in. Updates the `_users` document with new salt\nand hash, and re-logs in with the new credentials. Callback is called\nwith the same arguments as login, or the first step of the process that\nfailed.\n\n### couch.signup(userData, callback)\n\nCreate a new user account. The userData must contain at least a `name`\nand `password` field. Any additional data will be copied to the user\nrecord. The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and\n`date` fields are generated.\n\nAlso signs in as the newly created user, on successful account creation.\n\n### couch.deleteAccount(name, callback)\n\nDeletes a user account. If not logged in as the user, or a server\nadmin, then the request will fail.\n\nNote that this immediately invalidates any session tokens for the\ndeleted user account. If you are deleting the user's record, then you\nought to follow this with `couch.logout(callback)` so that it won't try\nto re-use the invalid session.\n\n### couch.logout(callback)\n\nDelete the session out of couchdb. This makes the token permanently\ninvalid, and deletes it.\n\n### couch.decorate(req, res)\n\nSet up `req.couch` and `res.couch` as references to this couch login\ninstance.\n\nAdditionall, if `req.session` or `res.session` is set, then it'll call\n`session.get('couch_token', cb)` as the tokenGet method,\n`session.set('couch_token', token, cb)` as the tokenSet method, and\n`session.del('couch_token', cb)` as the tokenDel method.\n\nThis works really nice with\n[RedSess](https://github.com/isaacs/redsess).\n",
- "_id": "couch-login@0.1.6",
+ "_id": "couch-login@0.1.8",
"_from": "couch-login@~0.1.6"
}
var auth = { name: 'testuser', password: 'test' }
, newAuth = { name: 'testuser', password: 'asdfasdf' }
-, couch = new CouchLogin('https://isaacs-staging.couch.xxx/')
+, couch = new CouchLogin('https://isaacs-staging.iriscouch.com/')
, u = '/_users/org.couchdb.user:' + auth.name
, userRecordMarker
# promzard
+A prompting wizard for building files from specialized PromZard modules.
+Used by `npm init`.
+
A reimplementation of @SubStack's
[prompter](https://github.com/substack/node-prompter), which does not
use AST traversal.
"url": "http://blog.izs.me/"
},
"name": "promzard",
- "description": "A reimplementation of @SubStack's [prompter](https://github.com/substack/node-prompter), which does not use AST traversal.",
- "version": "0.1.5",
+ "description": "prompting wizardly",
+ "version": "0.2.0",
"repository": {
"url": "git://github.com/isaacs/promzard"
},
"dependencies": {
- "read": "0"
+ "read": "1"
},
"devDependencies": {
"tap": "~0.2.5"
"scripts": {
"test": "tap test/*.js"
},
- "readme": "# promzard\n\nA reimplementation of @SubStack's\n[prompter](https://github.com/substack/node-prompter), which does not\nuse AST traversal.\n\nFrom another point of view, it's a reimplementation of\n[@Marak](https://github.com/marak)'s\n[wizard](https://github.com/Marak/wizard) which doesn't use schemas.\n\nThe goal is a nice drop-in enhancement for `npm init`.\n\n## Usage\n\n```javascript\nvar promzard = require('promzard')\npromzard(inputFile, optionalContextAdditions, function (er, data) {\n // .. you know what you doing ..\n})\n```\n\nIn the `inputFile` you can have something like this:\n\n```javascript\nvar fs = require('fs')\nmodule.exports = {\n \"greeting\": prompt(\"Who shall you greet?\", \"world\", function (who) {\n return \"Hello, \" + who\n }),\n \"filename\": __filename,\n \"directory\": function (cb) {\n fs.readdir(__dirname, cb)\n }\n}\n```\n\nWhen run, promzard will display the prompts and resolve the async\nfunctions in order, and then either give you an error, or the resolved\ndata, ready to be dropped into a JSON file or some other place.\n\n\n### promzard(inputFile, ctx, callback)\n\nThe inputFile is just a node module. You can require() things, set\nmodule.exports, etc. Whatever that module exports is the result, and it\nis walked over to call any functions as described below.\n\nThe only caveat is that you must give PromZard the full absolute path\nto the module (you can get this via Node's `require.resolve`.) Also,\nthe `prompt` function is injected into the context object, so watch out.\n\nWhatever you put in that `ctx` will of course also be available in the\nmodule. You can get quite fancy with this, passing in existing configs\nand so on.\n\n### Class: promzard.PromZard(file, ctx)\n\nJust like the `promzard` function, but the EventEmitter that makes it\nall happen. Emits either a `data` event with the data, or a `error`\nevent if it blows up.\n\nIf `error` is emitted, then `data` never will be.\n\n### prompt(...)\n\nIn the promzard input module, you can call the `prompt` function.\nThis prompts the user to input some data. The arguments are interpreted\nbased on type:\n\n1. `string` The first string encountered is the prompt. The second is\n the default value.\n2. `function` A transformer function which receives the data and returns\n something else. More than meets the eye.\n3. `object` The `prompt` member is the prompt, the `default` member is\n the default value, and the `transform` is the transformer.\n\nWhatever the final value is, that's what will be put on the resulting\nobject.\n\n### Functions\n\nIf there are any functions on the promzard input module's exports, then\npromzard will call each of them with a callback. This way, your module\ncan do asynchronous actions if necessary to validate or ascertain\nwhatever needs verification.\n\nThe functions are called in the context of the ctx object, and are given\na single argument, which is a callback that should be called with either\nan error, or the result to assign to that spot.\n\nIn the async function, you can also call prompt() and return the result\nof the prompt in the callback.\n\nFor example, this works fine in a promzard module:\n\n```\nexports.asyncPrompt = function (cb) {\n fs.stat(someFile, function (er, st) {\n // if there's an error, no prompt, just error\n // otherwise prompt and use the actual file size as the default\n cb(er, prompt('file size', st.size))\n })\n}\n```\n\nYou can also return other async functions in the async function\ncallback. Though that's a bit silly, it could be a handy way to reuse\nfunctionality in some cases.\n\n### Sync vs Async\n\nThe `prompt()` function is not synchronous, though it appears that way.\nIt just returns a token that is swapped out when the data object is\nwalked over asynchronously later, and returns a token.\n\nFor that reason, prompt() calls whose results don't end up on the data\nobject are never shown to the user. For example, this will only prompt\nonce:\n\n```\nexports.promptThreeTimes = prompt('prompt me once', 'shame on you')\nexports.promptThreeTimes = prompt('prompt me twice', 'um....')\nexports.promptThreeTimes = prompt('you cant prompt me again')\n```\n\n### Isn't this exactly the sort of 'looks sync' that you said was bad about other libraries?\n\nYeah, sorta. I wouldn't use promzard for anything more complicated than\na wizard that spits out prompts to set up a config file or something.\nMaybe there are other use cases I haven't considered.\n",
- "_id": "promzard@0.1.5",
- "_from": "promzard@~0.1.5"
+ "readme": "# promzard\n\nA prompting wizard for building files from specialized PromZard modules.\nUsed by `npm init`.\n\nA reimplementation of @SubStack's\n[prompter](https://github.com/substack/node-prompter), which does not\nuse AST traversal.\n\nFrom another point of view, it's a reimplementation of\n[@Marak](https://github.com/marak)'s\n[wizard](https://github.com/Marak/wizard) which doesn't use schemas.\n\nThe goal is a nice drop-in enhancement for `npm init`.\n\n## Usage\n\n```javascript\nvar promzard = require('promzard')\npromzard(inputFile, optionalContextAdditions, function (er, data) {\n // .. you know what you doing ..\n})\n```\n\nIn the `inputFile` you can have something like this:\n\n```javascript\nvar fs = require('fs')\nmodule.exports = {\n \"greeting\": prompt(\"Who shall you greet?\", \"world\", function (who) {\n return \"Hello, \" + who\n }),\n \"filename\": __filename,\n \"directory\": function (cb) {\n fs.readdir(__dirname, cb)\n }\n}\n```\n\nWhen run, promzard will display the prompts and resolve the async\nfunctions in order, and then either give you an error, or the resolved\ndata, ready to be dropped into a JSON file or some other place.\n\n\n### promzard(inputFile, ctx, callback)\n\nThe inputFile is just a node module. You can require() things, set\nmodule.exports, etc. Whatever that module exports is the result, and it\nis walked over to call any functions as described below.\n\nThe only caveat is that you must give PromZard the full absolute path\nto the module (you can get this via Node's `require.resolve`.) Also,\nthe `prompt` function is injected into the context object, so watch out.\n\nWhatever you put in that `ctx` will of course also be available in the\nmodule. You can get quite fancy with this, passing in existing configs\nand so on.\n\n### Class: promzard.PromZard(file, ctx)\n\nJust like the `promzard` function, but the EventEmitter that makes it\nall happen. Emits either a `data` event with the data, or a `error`\nevent if it blows up.\n\nIf `error` is emitted, then `data` never will be.\n\n### prompt(...)\n\nIn the promzard input module, you can call the `prompt` function.\nThis prompts the user to input some data. The arguments are interpreted\nbased on type:\n\n1. `string` The first string encountered is the prompt. The second is\n the default value.\n2. `function` A transformer function which receives the data and returns\n something else. More than meets the eye.\n3. `object` The `prompt` member is the prompt, the `default` member is\n the default value, and the `transform` is the transformer.\n\nWhatever the final value is, that's what will be put on the resulting\nobject.\n\n### Functions\n\nIf there are any functions on the promzard input module's exports, then\npromzard will call each of them with a callback. This way, your module\ncan do asynchronous actions if necessary to validate or ascertain\nwhatever needs verification.\n\nThe functions are called in the context of the ctx object, and are given\na single argument, which is a callback that should be called with either\nan error, or the result to assign to that spot.\n\nIn the async function, you can also call prompt() and return the result\nof the prompt in the callback.\n\nFor example, this works fine in a promzard module:\n\n```\nexports.asyncPrompt = function (cb) {\n fs.stat(someFile, function (er, st) {\n // if there's an error, no prompt, just error\n // otherwise prompt and use the actual file size as the default\n cb(er, prompt('file size', st.size))\n })\n}\n```\n\nYou can also return other async functions in the async function\ncallback. Though that's a bit silly, it could be a handy way to reuse\nfunctionality in some cases.\n\n### Sync vs Async\n\nThe `prompt()` function is not synchronous, though it appears that way.\nIt just returns a token that is swapped out when the data object is\nwalked over asynchronously later, and returns a token.\n\nFor that reason, prompt() calls whose results don't end up on the data\nobject are never shown to the user. For example, this will only prompt\nonce:\n\n```\nexports.promptThreeTimes = prompt('prompt me once', 'shame on you')\nexports.promptThreeTimes = prompt('prompt me twice', 'um....')\nexports.promptThreeTimes = prompt('you cant prompt me again')\n```\n\n### Isn't this exactly the sort of 'looks sync' that you said was bad about other libraries?\n\nYeah, sorta. I wouldn't use promzard for anything more complicated than\na wizard that spits out prompts to set up a config file or something.\nMaybe there are other use cases I haven't considered.\n",
+ "_id": "promzard@0.2.0",
+ "_from": "promzard@~0.2.0"
}
}}(cb).bind(this)
}
- read({ prompt: prompt + ': ' , default: def }, cb)
+ read({ prompt: prompt + ':' , default: def }, cb)
}
var test = require('tap').test;
var promzard = require('../');
+if (process.argv[2] === 'child') {
+ return child()
+}
+
test('exports', function (t) {
- t.plan(1);
-
- var ctx = { tmpdir : '/tmp' }
- var file = __dirname + '/exports.input';
- promzard(file, ctx, function (err, output) {
- t.same(
- {
- a : 3,
- b : '!2b',
- c : {
- x : 55,
- y : '/tmp/y/file.txt',
- }
- },
- output
- );
- });
-
- setTimeout(function () {
- process.stdin.emit('data', '\n');
- }, 100);
-
- setTimeout(function () {
- process.stdin.emit('data', '55\n');
- }, 200);
+ t.plan(1);
+
+ var spawn = require('child_process').spawn
+ var child = spawn(process.execPath, [__filename, 'child'])
+
+ var output = ''
+ child.stderr.on('data', function (c) {
+ output += c
+ })
+
+ setTimeout(function () {
+ child.stdin.write('\n');
+ }, 100)
+ setTimeout(function () {
+ child.stdin.write('55\n');
+ }, 200)
+
+ child.on('close', function () {
+ console.error('output=%j', output)
+ output = JSON.parse(output)
+ t.same({
+ a : 3,
+ b : '!2b',
+ c : {
+ x : 55,
+ y : '/tmp/y/file.txt',
+ }
+ }, output);
+ t.end()
+ })
});
+
+function child () {
+ var ctx = { tmpdir : '/tmp' }
+ var file = __dirname + '/exports.input';
+
+ promzard(file, ctx, function (err, output) {
+ console.error(JSON.stringify(output))
+ });
+}
var test = require('tap').test;
var promzard = require('../');
var fs = require('fs')
+var file = __dirname + '/fn.input';
+
+var expect = {
+ a : 3,
+ b : '!2B...',
+ c : {
+ x : 5500,
+ y : '/tmp/y/file.txt',
+ }
+}
+expect.a_function = fs.readFileSync(file, 'utf8')
+expect.asyncPrompt = 'async prompt'
+
+if (process.argv[2] === 'child') {
+ return child()
+}
test('prompt callback param', function (t) {
- t.plan(1);
-
- var ctx = { tmpdir : '/tmp' }
- var file = __dirname + '/fn.input';
- promzard(file, ctx, function (err, output) {
- var expect =
- {
- a : 3,
- b : '!2B...',
- c : {
- x : 5500,
- y : '/tmp/y/file.txt',
- }
- }
- expect.a_function = fs.readFileSync(file, 'utf8')
- expect.asyncPrompt = 'async prompt'
- t.same(
- output,
- expect
- );
- });
-
- setTimeout(function () {
- process.stdin.emit('data', '\n');
- }, 100);
-
- setTimeout(function () {
- process.stdin.emit('data', '55\n');
- }, 200);
-
- setTimeout(function () {
- process.stdin.emit('data', 'async prompt')
- }, 300)
-});
+ t.plan(1);
+
+ var spawn = require('child_process').spawn
+ var child = spawn(process.execPath, [__filename, 'child'])
+
+ var output = ''
+ child.stderr.on('data', function (c) {
+ output += c
+ })
+
+ child.on('close', function () {
+ console.error('output=%j', output)
+ output = JSON.parse(output)
+ t.same(output, expect);
+ t.end()
+ })
+
+ setTimeout(function () {
+ child.stdin.write('\n')
+ }, 100)
+ setTimeout(function () {
+ child.stdin.write('55\n')
+ }, 150)
+ setTimeout(function () {
+ child.stdin.write('async prompt\n')
+ }, 200)
+})
+
+function child () {
+ var ctx = { tmpdir : '/tmp' }
+ var file = __dirname + '/fn.input';
+ promzard(file, ctx, function (err, output) {
+ console.error(JSON.stringify(output))
+ })
+}
{
"name": "init-package-json",
- "version": "0.0.4",
+ "version": "0.0.5",
"main": "init-package-json.js",
"scripts": {
"test": "tap test/*.js"
"url": "http://blog.izs.me/"
},
"license": "BSD",
- "description": "A node module to get your node module started.",
+ "description": "A node module to get your node module started",
"dependencies": {
- "promzard": "~0.1.5",
- "read": "~0.1.0",
+ "promzard": "~0.2.0",
+ "read": "~1.0.1",
"read-package-json": "0",
"semver": "~1.0.14"
},
"start"
],
"readme": "# init-package-json\n\nA node module to get your node module started.\n\n## Usage\n\n```javascript\nvar init = require('init-package-json')\nvar path = require('path')\n\n// a path to a promzard module. In the event that this file is\n// not found, one will be provided for you.\nvar initFile = path.resolve(process.env.HOME, '.npm-init')\n\n// the dir where we're doin stuff.\nvar dir = process.cwd()\n\n// extra stuff that gets put into the PromZard module's context.\n// In npm, this is the resolved config object. Exposed as 'config'\n// Optional.\nvar configData = { some: 'extra stuff' }\n\n// Any existing stuff from the package.json file is also exposed in the\n// PromZard module as the `package` object. There will also be free\n// vars for:\n// * `filename` path to the package.json file\n// * `basename` the tip of the package dir\n// * `dirname` the parent of the package dir\n\ninit(dir, initFile, configData, function (er, data) {\n // the data's already been written to {dir}/package.json\n // now you can do stuff with it\n})\n```\n\nOr from the command line:\n\n```\n$ npm-init\n```\n\nSee [PromZard](https://github.com/isaacs/promzard) for details about\nwhat can go in the config file.\n",
- "_id": "init-package-json@0.0.4",
+ "_id": "init-package-json@0.0.5",
"_from": "init-package-json@0"
}
* ["Hello World" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)
* [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)
* [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)
- * ['"binding.gyp" files out in the wild' wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)
+ * [*"binding.gyp" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)
Commands
`node-gyp` responds to the following commands:
- * `build` - Invokes `make`/`msbuild.exe` and builds the native addon
- * `clean` - Removes any generated project files and the `out` dir
- * `configure` - Generates project build files for the current platform
- * `rebuild` - Runs "clean", "configure" and "build" all at once
- * `install` - Installs node development files for the given version.
- * `list` - Lists the currently installed node development file versions
- * `remove` - Removes a node development files for a given version
+| **Command** | **Description**
+|:--------------|:---------------------------------------------------------------
+| `build` | Invokes `make`/`msbuild.exe` and builds the native addon
+| `clean` | Removes any the `build` dir if it exists
+| `configure` | Generates project build files for the current platform
+| `rebuild` | Runs "clean", "configure" and "build" all in a row
+| `install` | Installs node development header files for the given version
+| `list` | Lists the currently installed node development file versions
+| `remove` | Removes the node development header files for the given version
License
*/
var prog = gyp()
+var completed = false
prog.parseArgv(process.argv)
if (prog.todo.length === 0) {
}
}
-// start running the given commands!
-var completed = false
-run()
-
function run () {
- if (prog.todo.length === 0) {
+ var command = prog.todo.shift()
+ if (!command) {
// done!
completed = true
log.info('ok')
return
}
- var command = prog.todo.shift()
-
- // is this an alias?
- if (command in prog.aliases) {
- command = prog.aliases[command]
- }
- prog.commands[command](prog.argv.slice(), function (err) {
+ prog.commands[command.name](command.args, function (err) {
if (err) {
- log.error(command + ' error', err.stack)
+ log.error(command.name + ' error')
+ log.error('stack', err.stack)
+ errorMessage()
log.error('not ok')
return process.exit(1)
}
- if (command == 'list') {
+ if (command.name == 'list') {
var versions = arguments[1]
if (versions.length > 0) {
versions.forEach(function (version) {
process.on('exit', function (code) {
if (!completed && !code) {
log.error('Completion callback never invoked!')
- log.error('This is a bug in `node-gyp`, please file an Issue:')
- log.error('', ' https://github.com/TooTallNate/node-gyp/issues')
- log.error('not ok')
+ issueMessage()
process.exit(6)
}
})
process.on('uncaughtException', function (err) {
- log.error('UNCAUGHT EXCEPTION', err.stack)
- log.error('This is a bug in `node-gyp`, please file an Issue:')
- log.error('', ' https://github.com/TooTallNate/node-gyp/issues')
- log.error('not ok')
+ log.error('UNCAUGHT EXCEPTION')
+ log.error('stack', err.stack)
+ issueMessage()
process.exit(7)
})
+
+function errorMessage () {
+ // copied from npm's lib/util/error-handler.js
+ var os = require('os')
+ log.error('System', os.type() + ' ' + os.release())
+ log.error('command', process.argv
+ .map(JSON.stringify).join(' '))
+ log.error('cwd', process.cwd())
+ log.error('node -v', process.version)
+ log.error('node-gyp -v', 'v' + prog.package.version)
+}
+
+function issueMessage () {
+ errorMessage()
+ log.error('', [ 'This is a bug in `node-gyp`.'
+ , 'Please file an Issue:'
+ , ' <https://github.com/TooTallNate/node-gyp/issues>'
+ ].join('\n'))
+}
+
+// start running the given commands!
+run()
buildType = 'Release'
}
- log.verbose('build type:', buildType)
- log.verbose('architecture:', arch)
- log.verbose('node dev dir:', nodeDir)
+ log.verbose('build type', buildType)
+ log.verbose('architecture', arch)
+ log.verbose('node dev dir', nodeDir)
if (win) {
findSolutionFile()
}
function symlinkNodeBinding () {
- var buildDir = path.join('build', buildType, '*.node')
+ var source, target
+ var buildDir = 'build/' + buildType + '/*.node'
log.verbose('globbing for files', buildDir)
glob(buildDir, function (err, nodeFiles) {
if (err) return callback(err)
+ log.silly('symlink', 'linking files', nodeFiles)
function link () {
var file = nodeFiles.shift()
if (!file) {
// no more files to link... done!
return callback()
}
- var dest = path.join('build', path.basename(file))
- log.info('symlink', 'creating link %j pointing to %j', file, dest)
- var rel = path.relative('build', file)
- log.verbose('symlink data', rel)
- fs.symlink(rel, dest, 'file', function (err) {
+ if (win) {
+ // windows requires absolute paths for junctions
+ source = path.resolve('build', path.basename(file))
+ target = path.resolve(file)
+ } else {
+ // on unix, use only relative paths since they're nice
+ source = path.join('build', path.basename(file))
+ target = path.relative('build', file)
+ }
+ log.info('symlink', 'creating %s "%s" pointing to "%s"', win ? 'junction' : 'symlink', source, target)
+ fs.symlink(target, source, 'junction', function (err) {
if (err) {
if (err.code === 'EEXIST') {
log.verbose('destination already exists; deleting', dest)
// permission to create the dev dir. As a fallback, make the tmpdir() be
// the dev dir for this installation. This is not ideal, but at least
// the compilation will succeed...
- gyp.devDir = path.resolve(osenv.tmpdir(), '.node-gyp')
+ var tmpdir = osenv.tmpdir()
+ gyp.devDir = path.resolve(tmpdir, '.node-gyp')
log.warn(err.code, 'user "%s" does not have permission to create dev dir "%s"', osenv.user(), devDir)
log.warn(err.code, 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir)
+ if (process.cwd() == tmpdir) {
+ log.verbose('tmpdir == cwd', 'automatically will remove dev files after to save disk space')
+ gyp.todo.push({ name: 'remove', args: argv })
+ }
gyp.commands.install(argv, cb)
} else {
cb(err)
this.opts = nopt(this.configDefs, this.shorthands, argv)
this.argv = this.opts.argv.remain.slice()
- var commands = []
- this.argv.slice().forEach(function (arg) {
- if (arg in this.commands || arg in this.aliases) {
- this.argv.splice(this.argv.indexOf(arg), 1)
- commands.push(arg)
+ var commands = this.todo = []
+
+ // create a copy of the argv array with aliases mapped
+ var argv = this.argv.map(function (arg) {
+ // is this an alias?
+ if (arg in this.aliases) {
+ arg = this.aliases[arg]
}
+ return arg
}, this)
- this.todo = commands
+ // process the mapped args into "command" objects ("name" and "args" props)
+ argv.slice().forEach(function (arg) {
+ if (arg in this.commands) {
+ var args = argv.splice(0, argv.indexOf(arg))
+ argv.shift()
+ if (commands.length > 0) {
+ commands[commands.length - 1].args = args
+ }
+ commands.push({ name: arg, args: [] })
+ }
+ }, this)
+ if (commands.length > 0) {
+ commands[commands.length - 1].args = argv.splice(0)
+ }
// support for inheriting config env variables from npm
var npm_config_prefix = 'npm_config_'
function rebuild (gyp, argv, callback) {
- // first "clean"
- gyp.commands.clean([], function (err) {
- if (err) {
- // don't bail
- log.info('rebuild clean failed', err.stack);
- }
-
- gyp.commands.configure([], function (err) {
- if (err) return callback(err);
- gyp.commands.build([], callback);
- });
- });
+ gyp.todo.push(
+ { name: 'clean', args: [] }
+ , { name: 'configure', args: [] }
+ , { name: 'build', args: [] }
+ )
+ process.nextTick(callback)
}
"bindings",
"gyp"
],
- "version": "0.5.8",
+ "version": "0.6.1",
"installVersion": 9,
"author": {
"name": "Nathan Rajlich",
"fstream": "~0.1.13",
"minimatch": "0.2",
"mkdirp": "0.3",
- "nopt": "1",
+ "nopt": "2",
"npmlog": "0",
"osenv": "0",
"request": "2.9",
"engines": {
"node": ">= 0.6.0"
},
- "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n * On Unix:\n * `python`\n * `make`\n * A proper C/C++ compiler toolchain, like GCC\n * On Windows:\n * [Python][windows-python] ([`v2.7.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n * Microsoft Visual C++ ([Express][msvc] version works well)\n * For 64-bit builds of node and native modules you will _also_ need the [Windows 7 64-bit SDK][win7sdk]\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n \"targets\": [\n {\n \"target_name\": \"binding\",\n \"sources\": [ \"src/binding.cc\" ]\n }\n ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * ['\"binding.gyp\" files out in the wild' wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n * `build` - Invokes `make`/`msbuild.exe` and builds the native addon\n * `clean` - Removes any generated project files and the `out` dir\n * `configure` - Generates project build files for the current platform\n * `rebuild` - Runs \"clean\", \"configure\" and \"build\" all at once\n * `install` - Installs node development files for the given version.\n * `list` - Lists the currently installed node development file versions\n * `remove` - Removes a node development files for a given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n",
- "_id": "node-gyp@0.5.8",
+ "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 <nathan@tootallnate.net>\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.1",
"dist": {
- "shasum": "2e6cdb28159c9bdd3fe484c7db81f119ee17e594"
+ "shasum": "6b380fd3fbf21c0dc99147a5f99fd8fc8f79c794"
},
- "_from": "node-gyp@~0.5"
+ "_from": "node-gyp@latest"
}
--- /dev/null
+#!/usr/bin/env node
+
+//process.env.DEBUG_NOPT = 1
+
+// my-program.js
+var nopt = require("../lib/nopt")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , knownOpts = { "foo" : [String, null]
+ , "bar" : [Stream, Number]
+ , "baz" : path
+ , "bloo" : [ "big", "medium", "small" ]
+ , "flag" : Boolean
+ , "pick" : Boolean
+ }
+ , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
+ , "b7" : ["--bar", "7"]
+ , "m" : ["--bloo", "medium"]
+ , "p" : ["--pick"]
+ , "f" : ["--flag", "true"]
+ , "g" : ["--flag"]
+ , "s" : "--flag"
+ }
+ // everything is optional.
+ // knownOpts and shorthands default to {}
+ // arg list defaults to process.argv
+ // slice defaults to 2
+ , parsed = nopt(knownOpts, shortHands, process.argv, 2)
+
+console.log("parsed =\n"+ require("util").inspect(parsed))
// now data is full
clean(data, types, exports.typeDefs)
data.argv = {remain:remain,cooked:cooked,original:original}
- data.argv.toString = function () {
+ Object.defineProperty(data.argv, 'toString', { value: function () {
return this.original.map(JSON.stringify).join(" ")
- }
+ }, enumerable: false })
return data
}
args[i] = "--"
break
}
+ var hadEq = false
if (arg.charAt(0) === "-") {
if (arg.indexOf("=") !== -1) {
+ hadEq = true
var v = arg.split("=")
arg = v.shift()
v = v.join("=")
}
}
arg = arg.replace(/^-+/, "")
- var no = false
+ var no = null
while (arg.toLowerCase().indexOf("no-") === 0) {
no = !no
arg = arg.substr(3)
var val
, la = args[i + 1]
- var isBool = no ||
+ var isBool = typeof no === 'boolean' ||
types[arg] === Boolean ||
Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 ||
+ (typeof types[arg] === 'undefined' && !hadEq) ||
(la === "false" &&
(types[arg] === null ||
Array.isArray(types[arg]) && ~types[arg].indexOf(null)))
"-no-body-can-do-the-boogaloo-like-I-do"
,{"body-can-do-the-boogaloo-like-I-do":false}, []]
,["we are -no-strangers-to-love "+
- "--you-know the-rules --and so-do-i "+
+ "--you-know=the-rules --and=so-do-i "+
"---im-thinking-of=a-full-commitment "+
"--no-you-would-get-this-from-any-other-guy "+
"--no-gonna-give-you-up "+
,["--nullstream false"
,{nullstream:null}
,[]]
- ,["--notadate 2011-01-25"
+ ,["--notadate=2011-01-25"
,{notadate: "2011-01-25"}
,[]]
,["--date 2011-01-25"
-{ "name" : "nopt"
-, "version" : "1.0.10"
-, "description" : "Option parsing for Node, supporting types, shorthands, etc. Used by npm."
-, "author" : "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)"
-, "main" : "lib/nopt.js"
-, "scripts" : { "test" : "node lib/nopt.js" }
-, "repository" : "http://github.com/isaacs/nopt"
-, "bin" : "./bin/nopt.js"
-, "license" :
- { "type" : "MIT"
- , "url" : "https://github.com/isaacs/nopt/raw/master/LICENSE" }
-, "dependencies" : { "abbrev" : "1" }}
+{
+ "name": "nopt",
+ "version": "2.0.0",
+ "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "main": "lib/nopt.js",
+ "scripts": {
+ "test": "node lib/nopt.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/isaacs/nopt"
+ },
+ "bin": {
+ "nopt": "./bin/nopt.js"
+ },
+ "license": {
+ "type": "MIT",
+ "url": "https://github.com/isaacs/nopt/raw/master/LICENSE"
+ },
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "readme": "If you want to write an option parser, and have it be good, there are\ntwo ways to do it. The Right Way, and the Wrong Way.\n\nThe Wrong Way is to sit down and write an option parser. We've all done\nthat.\n\nThe Right Way is to write some complex configurable program with so many\noptions that you go half-insane just trying to manage them all, and put\nit off with duct-tape solutions until you see exactly to the core of the\nproblem, and finally snap and write an awesome option parser.\n\nIf you want to write an option parser, don't write an option parser.\nWrite a package manager, or a source control system, or a service\nrestarter, or an operating system. You probably won't end up with a\ngood one of those, but if you don't give up, and you are relentless and\ndiligent enough in your procrastination, you may just end up with a very\nnice option parser.\n\n## USAGE\n\n // my-program.js\n var nopt = require(\"nopt\")\n , Stream = require(\"stream\").Stream\n , path = require(\"path\")\n , knownOpts = { \"foo\" : [String, null]\n , \"bar\" : [Stream, Number]\n , \"baz\" : path\n , \"bloo\" : [ \"big\", \"medium\", \"small\" ]\n , \"flag\" : Boolean\n , \"pick\" : Boolean\n , \"many\" : [String, Array]\n }\n , shortHands = { \"foofoo\" : [\"--foo\", \"Mr. Foo\"]\n , \"b7\" : [\"--bar\", \"7\"]\n , \"m\" : [\"--bloo\", \"medium\"]\n , \"p\" : [\"--pick\"]\n , \"f\" : [\"--flag\"]\n }\n // everything is optional.\n // knownOpts and shorthands default to {}\n // arg list defaults to process.argv\n // slice defaults to 2\n , parsed = nopt(knownOpts, shortHands, process.argv, 2)\n console.log(parsed)\n\nThis would give you support for any of the following:\n\n```bash\n$ node my-program.js --foo \"blerp\" --no-flag\n{ \"foo\" : \"blerp\", \"flag\" : false }\n\n$ node my-program.js ---bar 7 --foo \"Mr. Hand\" --flag\n{ bar: 7, foo: \"Mr. Hand\", flag: true }\n\n$ node my-program.js --foo \"blerp\" -f -----p\n{ foo: \"blerp\", flag: true, pick: true }\n\n$ node my-program.js -fp --foofoo\n{ foo: \"Mr. Foo\", flag: true, pick: true }\n\n$ node my-program.js --foofoo -- -fp # -- stops the flag parsing.\n{ foo: \"Mr. Foo\", argv: { remain: [\"-fp\"] } }\n\n$ node my-program.js --blatzk 1000 -fp # unknown opts are ok.\n{ blatzk: 1000, flag: true, pick: true }\n\n$ node my-program.js --blatzk true -fp # but they need a value\n{ blatzk: true, flag: true, pick: true }\n\n$ node my-program.js --no-blatzk -fp # unless they start with \"no-\"\n{ blatzk: false, flag: true, pick: true }\n\n$ node my-program.js --baz b/a/z # known paths are resolved.\n{ baz: \"/Users/isaacs/b/a/z\" }\n\n# if Array is one of the types, then it can take many\n# values, and will always be an array. The other types provided\n# specify what types are allowed in the list.\n\n$ node my-program.js --many 1 --many null --many foo\n{ many: [\"1\", \"null\", \"foo\"] }\n\n$ node my-program.js --many foo\n{ many: [\"foo\"] }\n```\n\nRead the tests at the bottom of `lib/nopt.js` for more examples of\nwhat this puppy can do.\n\n## Types\n\nThe following types are supported, and defined on `nopt.typeDefs`\n\n* String: A normal string. No parsing is done.\n* path: A file system path. Gets resolved against cwd if not absolute.\n* url: A url. If it doesn't parse, it isn't accepted.\n* Number: Must be numeric.\n* Date: Must parse as a date. If it does, and `Date` is one of the options,\n then it will return a Date object, not a string.\n* Boolean: Must be either `true` or `false`. If an option is a boolean,\n then it does not need a value, and its presence will imply `true` as\n the value. To negate boolean flags, do `--no-whatever` or `--whatever\n false`\n* NaN: Means that the option is strictly not allowed. Any value will\n fail.\n* Stream: An object matching the \"Stream\" class in node. Valuable\n for use when validating programmatically. (npm uses this to let you\n supply any WriteStream on the `outfd` and `logfd` config options.)\n* Array: If `Array` is specified as one of the types, then the value\n will be parsed as a list of options. This means that multiple values\n can be specified, and that the value will always be an array.\n\nIf a type is an array of values not on this list, then those are\nconsidered valid values. For instance, in the example above, the\n`--bloo` option can only be one of `\"big\"`, `\"medium\"`, or `\"small\"`,\nand any other value will be rejected.\n\nWhen parsing unknown fields, `\"true\"`, `\"false\"`, and `\"null\"` will be\ninterpreted as their JavaScript equivalents, and numeric values will be\ninterpreted as a number.\n\nYou can also mix types and values, or multiple types, in a list. For\ninstance `{ blah: [Number, null] }` would allow a value to be set to\neither a Number or null. When types are ordered, this implies a\npreference, and the first type that can be used to properly interpret\nthe value will be used.\n\nTo define a new type, add it to `nopt.typeDefs`. Each item in that\nhash is an object with a `type` member and a `validate` method. The\n`type` member is an object that matches what goes in the type list. The\n`validate` method is a function that gets called with `validate(data,\nkey, val)`. Validate methods should assign `data[key]` to the valid\nvalue of `val` if it can be handled properly, or return boolean\n`false` if it cannot.\n\nYou can also call `nopt.clean(data, types, typeDefs)` to clean up a\nconfig object and remove its invalid properties.\n\n## Error Handling\n\nBy default, nopt outputs a warning to standard error when invalid\noptions are found. You can change this behavior by assigning a method\nto `nopt.invalidHandler`. This method will be called with\nthe offending `nopt.invalidHandler(key, val, types)`.\n\nIf no `nopt.invalidHandler` is assigned, then it will console.error\nits whining. If it is assigned to boolean `false` then the warning is\nsuppressed.\n\n## Abbreviations\n\nYes, they are supported. If you define options like this:\n\n```javascript\n{ \"foolhardyelephants\" : Boolean\n, \"pileofmonkeys\" : Boolean }\n```\n\nThen this will work:\n\n```bash\nnode program.js --foolhar --pil\nnode program.js --no-f --pileofmon\n# etc.\n```\n\n## Shorthands\n\nShorthands are a hash of shorter option names to a snippet of args that\nthey expand to.\n\nIf multiple one-character shorthands are all combined, and the\ncombination does not unambiguously match any other option or shorthand,\nthen they will be broken up into their constituent parts. For example:\n\n```json\n{ \"s\" : [\"--loglevel\", \"silent\"]\n, \"g\" : \"--global\"\n, \"f\" : \"--force\"\n, \"p\" : \"--parseable\"\n, \"l\" : \"--long\"\n}\n```\n\n```bash\nnpm ls -sgflp\n# just like doing this:\nnpm ls --loglevel silent --global --force --long --parseable\n```\n\n## The Rest of the args\n\nThe config object returned by nopt is given a special member called\n`argv`, which is an object with the following fields:\n\n* `remain`: The remaining args after all the parsing has occurred.\n* `original`: The args as they originally appeared.\n* `cooked`: The args after flags and shorthands are expanded.\n\n## Slicing\n\nNode programs are called with more or less the exact argv as it appears\nin C land, after the v8 and node-specific options have been plucked off.\nAs such, `argv[0]` is always `node` and `argv[1]` is always the\nJavaScript program being run.\n\nThat's usually not very useful to you. So they're sliced off by\ndefault. If you want them, then you can pass in `0` as the last\nargument, or any other number that you'd like to slice off the start of\nthe list.\n",
+ "_id": "nopt@2.0.0",
+ "_from": "nopt@latest"
+}
test/fixtures/cache
+node_modules
+npm-debug.log
-Copyright (c) Isaac Z. Schlueter
+Copyright (c) Isaac Z. Schlueter ("Author")
All rights reserved.
The BSD License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
+
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
+
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
, date: new Date().toISOString()
}
- cb = done.call(this, 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
+ if (this.couchLogin) {
+ this.couchLogin.token = null
+ }
+ this.username = null
+ this.password = null
+ this.auth = null
+
+ cb = done.call(this, cb, pre)
+
+ var logObj = Object.keys(userobj).map(function (k) {
+ if (k === 'salt' || k === 'password_sha') return [k, 'XXXXX']
+ return [k, userobj[k]]
+ }).reduce(function (s, kv) {
+ s[kv[0]] = kv[1]
+ return s
+ }, {})
+
+ this.log.verbose("adduser", "before first PUT", logObj)
- this.log.verbose("adduser", "before first PUT", userobj)
this.request('PUT'
, '/-/user/org.couchdb.user:'+encodeURIComponent(username)
, userobj
// use this info as auth
var b = new Buffer(username + ":" + password)
this.auth = b.toString("base64")
+ this.username = username
+ this.password = password
}
if (!error || !response || response.statusCode !== 409) {
userobj[k] = data[k]
}
})
- this.log.verbose("adduser", "userobj", userobj)
+ this.log.verbose("adduser", "userobj", logObj)
this.request('PUT'
, '/-/user/org.couchdb.user:'+encodeURIComponent(username)
+ "/-rev/" + userobj._rev
}.bind(this))
}
-function done (cb) {
+function done (cb, pre) {
return function (error, data, json, response) {
if (!error && (!response || response.statusCode === 201)) {
return cb(error, data, json, response)
}
+
+ // there was some kind of error, re-instate previous auth/token/etc.
+ this.token = pre.token
+ if (this.couchLogin) {
+ this.couchLogin.token = this.token
+ if (this.couchLogin.tokenSet) {
+ this.couchLogin.tokenSet(pre.token)
+ }
+ }
+ this.username = pre.username
+ this.password = pre.password
+ this.auth = pre.auth
+
this.log.verbose("adduser", "back", [error, data, json])
if (!error) {
error = new Error( (response && response.statusCode || "") + " "+
},
"name": "npm-registry-client",
"description": "Client for the npm registry",
- "version": "0.0.11",
+ "version": "0.1.2",
"repository": {
"url": "git://github.com/isaacs/npm-registry-client"
},
},
"license": "BSD",
"readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `retries` {Number} Number of times to retry on GET failures.\n Default=2\n* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10\n* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.\n Default=10000 (10 seconds)\n* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default=60000 (60 seconds)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n",
- "_id": "npm-registry-client@0.0.11",
+ "_id": "npm-registry-client@0.1.2",
"_from": "npm-registry-client@0"
}
--- /dev/null
+npm-debug.log
+node_modules
+## read
+
For reading user input from stdin.
+Similar to the `readline` builtin's `question()` method, but with a
+few more features.
+
## USAGE
```javascript
```
The callback gets called with either the user input, or the default
-specified, or an error, in the traditional `callback(error, result)`
+specified, or an error, as `callback(error, result, isDefault)`
node style.
## OPTIONS
* `prompt` What to write to stdout before reading input.
* `silent` Don't echo the output as the user types it.
-* `num` Max number of chars to read from terminal.
* `timeout` Number of ms to wait for user input before giving up.
* `default` The default value if the user enters nothing.
+* `edit` Allow the user to edit the default value.
+* `terminal` Treat the output as a TTY, whether it is or not.
+* `stdin` Readable stream to get input data from. (default `process.stdin`)
+* `stdout` Writeable stream to write prompts to. (default: `process.stdout`)
-If silent is true, or num is set, and the input is a TTY,
-then read will set raw mode, and read character by character.
-
-At this time, backspace and arrow keys are not supported very well.
-It's probably not too hard to add support for this, perhaps using node's
-built-in readline module.
+If silent is true, and the input is a TTY, then read will set raw
+mode, and read character by character.
## CONTRIBUTING
Patches welcome.
-
-## BUGS
-
-In node 0.6.0 through 0.6.5, you must explicitly call
-`process.stdin.destroy()` or `process.exit()` when you know that your
-program is done reading, or else it will keep the event loop running
-forever.
-
-See: <https://github.com/joyent/node/issues/2257>
read({prompt: "Username: ", default: "test-user" }, function (er, user) {
read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
- read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) {
- read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
- console.error({user: user,
- pass: pass,
- verify: pass2,
- four:four,
- passMatch: (pass === pass2)})
- console.error("If the program doesn't end right now,\n"
- +"then you may be experiencing this bug:\n"
- +"https://github.com/joyent/node/issues/2257")
- })
+ read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+ console.error({user: user,
+ pass: pass,
+ verify: pass2,
+ passMatch: (pass === pass2)})
+ console.error("the program should exit now")
})
})
})
module.exports = read
-var buffer = ""
- , tty = require("tty")
- , StringDecoder = require("string_decoder").StringDecoder
+var readline = require('readline')
+var Mute = require('mute-stream')
-function raw (mode) {
- if (process.stdin.setRawMode) {
- if (process.stdin.isTTY) {
- process.stdin.setRawMode(mode)
- }
- return
+function read (opts, cb) {
+ if (opts.num) {
+ throw new Error('read() no longer accepts a char number limit')
}
- // old style
- try {
- tty.setRawMode(mode)
- } catch (e) {}
-}
-
-function read (opts, cb) {
- if (!cb) cb = opts, opts = {}
+ var input = opts.input || process.stdin
+ var output = opts.output || process.stdout
+ var m = new Mute()
+ m.pipe(output)
+ output = m
+ var def = opts.default || ''
+ var terminal = !!(opts.terminal || output.isTTY)
+ var rlOpts = { input: input, output: output, terminal: terminal }
+ var rl = readline.createInterface(rlOpts)
+ var prompt = (opts.prompt || '').trim() + ' '
+ var silent = opts.silent
+ var editDef = false
+ var timeout = opts.timeout
+
+ if (def) {
+ if (silent) {
+ prompt += '(<default hidden>) '
+ } else if (opts.edit) {
+ editDef = true
+ } else {
+ prompt += '(' + def + ') '
+ }
+ }
- var p = opts.prompt || ""
- , def = opts.default
- , silent = opts.silent
- , timeout = opts.timeout
- , num = opts.num || null
+ output.unmute()
+ rl.setPrompt(prompt)
+ rl.prompt()
+ if (silent) {
+ output.mute()
+ } else if (editDef) {
+ rl.line = def
+ rl.cursor = def.length
+ rl._refreshLine()
+ }
- if (p && def) p += "("+(silent ? "<default hidden>" : def)+") "
+ var called = false
+ rl.on('line', onLine)
+ rl.on('error', onError)
- // switching into raw mode is a little bit painful.
- // avoid if possible.
- var r = silent || num ? rawRead : normalRead
- if (r === rawRead && !process.stdin.isTTY) r = normalRead
+ rl.on('SIGINT', function () {
+ rl.close()
+ onError(new Error('canceled'))
+ })
+ var timer
if (timeout) {
- cb = (function (cb) {
- var called = false
- var t = setTimeout(function () {
- raw(false)
- process.stdout.write("\n")
- if (def) done(null, def)
- else done(new Error("timeout"))
- }, timeout)
-
- function done (er, data) {
- clearTimeout(t)
- if (called) return
- // stop reading!
- stdin.pause()
- called = true
- cb(er, data)
- }
-
- return done
- })(cb)
+ timer = setTimeout(function () {
+ onError(new Error('timed out'))
+ }, timeout)
}
- if (p && !process.stdout.write(p)) {
- process.stdout.on("drain", function D () {
- process.stdout.removeListener("drain", D)
- r(def, timeout, silent, num, cb)
- })
- } else {
- process.nextTick(function () {
- r(def, timeout, silent, num, cb)
- })
+ function done () {
+ called = true
+ rl.close()
+ clearTimeout(timer)
+ output.mute()
}
-}
-
-function normalRead (def, timeout, silent, num, cb) {
- var stdin = process.openStdin()
- , val = ""
- , decoder = new StringDecoder("utf8")
-
- stdin.resume()
- stdin.on("error", cb)
- stdin.on("data", function D (chunk) {
- // get the characters that are completed.
- val += buffer + decoder.write(chunk)
- buffer = ""
-
- // \r has no place here.
- val = val.replace(/\r/g, "")
- if (val.indexOf("\n") !== -1) {
- // pluck off any delims at the beginning.
- if (val !== "\n") {
- var i, l
- for (i = 0, l = val.length; i < l; i ++) {
- if (val.charAt(i) !== "\n") break
- }
- if (i !== 0) val = val.substr(i)
- }
-
- // hack. if we get the number of chars, just pretend there was a delim
- if (num > 0 && val.length >= num) {
- val = val.substr(0, num) + "\n" + val.substr(num)
- }
-
- // buffer whatever might have come *after* the delimter
- var delimIndex = val.indexOf("\n")
- if (delimIndex !== -1) {
- buffer = val.substr(delimIndex)
- val = val.substr(0, delimIndex)
- } else {
- buffer = ""
- }
-
- stdin.pause()
- stdin.removeListener("data", D)
- stdin.removeListener("error", cb)
+ function onError (er) {
+ if (called) return
+ done()
+ return cb(er)
+ }
- // read(1) trims
- val = val.trim() || def
- cb(null, val)
+ function onLine (line) {
+ if (called) return
+ if (silent && terminal) {
+ output.unmute()
+ output.write('\r\n')
}
- })
-}
-
-function rawRead (def, timeout, silent, num, cb) {
- var stdin = process.openStdin()
- , val = ""
- , decoder = new StringDecoder
-
- raw(true)
- stdin.resume()
- stdin.on("error", cb)
- stdin.on("data", function D (c) {
- // \r is my enemy.
- var s = decoder.write(c).replace(/\r/g, "\n")
- var i = 0
-
- LOOP: while (c = s.charAt(i++)) switch (c) {
- case "\u007f": // backspace
- val = val.substr(0, val.length - 1)
- if (!silent) process.stdout.write('\b \b')
- break
-
- case "\u0004": // EOF
- case "\n":
- raw(false)
- stdin.removeListener("data", D)
- stdin.removeListener("error", cb)
- val = val.trim() || def
- process.stdout.write("\n")
- stdin.pause()
- return cb(null, val)
-
- case "\u0003": case "\0": // ^C or other signal abort
- raw(false)
- stdin.removeListener("data", D)
- stdin.removeListener("error", cb)
- stdin.pause()
- return cb(new Error("cancelled"))
-
- default: // just a normal char
- val += buffer + c
- buffer = ""
- if (!silent) process.stdout.write(c)
-
- // explicitly process a delim if we have enough chars
- // and stop the processing.
- if (num && val.length >= num) D("\n")
- break LOOP
+ done()
+ // truncate the \n at the end.
+ line = line.replace(/\r?\n$/, '')
+ var isDefault = !!(editDef && line === def)
+ if (def && !line) {
+ isDefault = true
+ line = def
}
- })
+ cb(null, line, isDefault)
+ }
}
--- /dev/null
+Copyright (c) Isaac Z. Schlueter ("Author")
+All rights reserved.
+
+The BSD License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- /dev/null
+# mute-stream
+
+Bytes go in, but they don't come out (when muted).
+
+This is a basic pass-through stream, but when muted, the bytes are
+silently dropped, rather than being passed through.
+
+## Usage
+
+```javascript
+var MuteStream = require('mute-stream')
+
+var ms = new MuteStream
+
+ms.pipe(process.stdout)
+ms.write('foo') // writes 'foo' to stdout
+ms.mute()
+ms.write('bar') // does not write 'bar'
+ms.unmute()
+ms.write('baz') // writes 'baz' to stdout
+
+// can also be used to mute incoming data
+var ms = new MuteStream
+input.pipe(ms)
+
+ms.on('data', function (c) {
+ console.log('data: ' + c)
+})
+
+input.emit('data', 'foo') // logs 'foo'
+ms.mute()
+input.emit('data', 'bar') // does not log 'bar'
+ms.unmute()
+input.emit('data', 'baz') // logs 'baz'
+```
+
+## ms.mute()
+
+Set `muted` to `true`. Turns `.write()` into a no-op.
+
+## ms.unmute()
+
+Set `muted` to `false`
+
+## ms.isTTY
+
+True if the pipe destination is a TTY, or if the incoming pipe source is
+a TTY.
+
+## Other stream methods...
+
+The other standard readable and writable stream methods are all
+available. The MuteStream object acts as a facade to its pipe source
+and destination.
--- /dev/null
+var Stream = require('stream')
+
+module.exports = MuteStream
+
+// var out = new MuteStream(process.stdout)
+// argument auto-pipes
+function MuteStream (dest) {
+ Stream.apply(this)
+ this.writable = this.readable = true
+ this.muted = false
+ this.on('pipe', this._onpipe)
+}
+
+MuteStream.prototype = Object.create(Stream.prototype)
+
+Object.defineProperty(MuteStream.prototype, 'constructor', {
+ value: MuteStream,
+ enumerable: false
+})
+
+MuteStream.prototype.mute = function () {
+ this.muted = true
+}
+
+MuteStream.prototype.unmute = function () {
+ this.muted = false
+}
+
+Object.defineProperty(MuteStream.prototype, '_onpipe', {
+ value: onPipe,
+ enumerable: false,
+ writable: true,
+ configurable: true
+})
+
+function onPipe (src) {
+ this._src = src
+}
+
+Object.defineProperty(MuteStream.prototype, 'isTTY', {
+ get: getIsTTY,
+ set: setIsTTY,
+ enumerable: true,
+ configurable: true
+})
+
+function getIsTTY () {
+ return( (this._dest) ? this._dest.isTTY
+ : (this._src) ? this._src.isTTY
+ : false
+ )
+}
+
+// basically just get replace the getter/setter with a regular value
+function setIsTTY (isTTY) {
+ Object.defineProperty(this, 'isTTY', {
+ value: isTTY,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ })
+}
+
+MuteStream.prototype.pipe = function (dest) {
+ this._dest = dest
+ return Stream.prototype.pipe.call(this, dest)
+}
+
+MuteStream.prototype.pause = function () {
+ if (this._src) return this._src.pause()
+}
+
+MuteStream.prototype.resume = function () {
+ if (this._src) return this._src.resume()
+}
+
+MuteStream.prototype.write = function (c) {
+ if (this.muted) return true
+ this.emit('data', c)
+}
+
+MuteStream.prototype.end = function (c) {
+ if (!this.muted) this.emit('data', c)
+ this.emit('end')
+}
+
+function proxy (fn) { return function () {
+ var d = this._dest
+ var s = this._src
+ if (d && d[fn]) d[fn].apply(d, arguments)
+ if (s && s[fn]) s[fn].apply(s, arguments)
+}}
+
+MuteStream.prototype.destroy = proxy('destroy')
+MuteStream.prototype.destroySoon = proxy('destroySoon')
+MuteStream.prototype.close = proxy('close')
--- /dev/null
+{
+ "name": "mute-stream",
+ "version": "0.0.1",
+ "main": "mute.js",
+ "directories": {
+ "test": "test"
+ },
+ "devDependencies": {
+ "tap": "~0.2.5"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/mute-stream"
+ },
+ "keywords": [
+ "mute",
+ "stream",
+ "pipe"
+ ],
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "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\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## 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.1",
+ "_from": "mute-stream@0"
+}
--- /dev/null
+var Stream = require('stream')
+var tap = require('tap')
+var MS = require('../mute.js')
+
+// some marker objects
+var END = {}
+var PAUSE = {}
+var RESUME = {}
+
+function PassThrough () {
+ Stream.call(this)
+ this.readable = this.writable = true
+}
+
+PassThrough.prototype = Object.create(Stream.prototype, {
+ constructor: {
+ value: PassThrough
+ },
+ write: {
+ value: function (c) {
+ this.emit('data', c)
+ }
+ },
+ end: {
+ value: function (c) {
+ if (c) this.write(c)
+ this.emit('end')
+ }
+ },
+ pause: {
+ value: function () {
+ this.emit('pause')
+ }
+ },
+ resume: {
+ value: function () {
+ this.emit('resume')
+ }
+ }
+})
+
+tap.test('incoming', function (t) {
+ var ms = new MS
+ var str = new PassThrough
+ str.pipe(ms)
+
+ var expect = ['foo', 'boo', END]
+ ms.on('data', function (c) {
+ t.equal(c, expect.shift())
+ })
+ ms.on('end', function () {
+ t.equal(END, expect.shift())
+ t.end()
+ })
+ str.write('foo')
+ ms.mute()
+ str.write('bar')
+ ms.unmute()
+ str.write('boo')
+ ms.mute()
+ str.write('blaz')
+ str.end('grelb')
+})
+
+tap.test('outgoing', function (t) {
+ var ms = new MS
+ var str = new PassThrough
+ ms.pipe(str)
+
+ var expect = ['foo', 'boo', END]
+ str.on('data', function (c) {
+ t.equal(c, expect.shift())
+ })
+ str.on('end', function () {
+ t.equal(END, expect.shift())
+ t.end()
+ })
+
+ ms.write('foo')
+ ms.mute()
+ ms.write('bar')
+ ms.unmute()
+ ms.write('boo')
+ ms.mute()
+ ms.write('blaz')
+ ms.end('grelb')
+})
+
+tap.test('isTTY', function (t) {
+ var str = new PassThrough
+ str.isTTY = true
+
+ var ms = new MS
+ t.equal(ms.isTTY, false)
+ ms.pipe(str)
+ t.equal(ms.isTTY, true)
+ str.isTTY = false
+ t.equal(ms.isTTY, false)
+ str.isTTY = true
+ t.equal(ms.isTTY, true)
+ ms.isTTY = false
+ t.equal(ms.isTTY, false)
+
+ ms = new MS
+ t.equal(ms.isTTY, false)
+ str.pipe(ms)
+ t.equal(ms.isTTY, true)
+ str.isTTY = false
+ t.equal(ms.isTTY, false)
+ str.isTTY = true
+ t.equal(ms.isTTY, true)
+ ms.isTTY = false
+ t.equal(ms.isTTY, false)
+
+ t.end()
+})
+
+tap.test('pause/resume incoming', function (t) {
+ var str = new PassThrough
+ var ms = new MS
+ str.on('pause', function () {
+ t.equal(PAUSE, expect.shift())
+ })
+ str.on('resume', function () {
+ t.equal(RESUME, expect.shift())
+ })
+ var expect = [PAUSE, RESUME, PAUSE, RESUME]
+ str.pipe(ms)
+ ms.pause()
+ ms.resume()
+ ms.pause()
+ ms.resume()
+ t.equal(expect.length, 0, 'saw all events')
+ t.end()
+})
{
"name": "read",
- "version": "0.1.0",
+ "version": "1.0.1",
"main": "lib/read.js",
- "dependencies": {},
+ "dependencies": {
+ "mute-stream": "0"
+ },
"devDependencies": {
"tap": "*"
},
"engines": {
- "node": ">=0.6"
+ "node": ">=0.8"
},
"author": {
"name": "Isaac Z. Schlueter",
"scripts": {
"test": "tap test/*.js"
},
- "readme": "For reading user input from stdin.\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, in the traditional `callback(error, result)`\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* `num` Max number of chars to read from terminal.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n\nIf silent is true, or num is set, and the input is a TTY,\nthen read will set raw mode, and read character by character.\n\nAt this time, backspace and arrow keys are not supported very well.\nIt's probably not too hard to add support for this, perhaps using node's\nbuilt-in readline module.\n\n## CONTRIBUTING\n\nPatches welcome.\n\n## BUGS\n\nIn node 0.6.0 through 0.6.5, you must explicitly call\n`process.stdin.destroy()` or `process.exit()` when you know that your\nprogram is done reading, or else it will keep the event loop running\nforever.\n\nSee: <https://github.com/joyent/node/issues/2257>\n",
- "_id": "read@0.1.0",
- "_from": "read@0"
+ "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* `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.1",
+ "_from": "read@latest"
}
tap.test('basic', function (t) {
var child = spawn(process.execPath, [__filename, 'child'])
var output = ''
+ var write = child.stdin.write.bind(child.stdin)
child.stdout.on('data', function (c) {
console.error('data %s', c)
output += c
if (output.match(/Username: \(test-user\) $/)) {
- child.stdin.write('a user\n')
+ process.nextTick(write.bind(null, 'a user\n'))
} else if (output.match(/Password: \(<default hidden>\) $/)) {
- child.stdin.write('a password\n')
- } else if (output.match(/characters: $/)) {
- child.stdin.write('asdf\n')
+ process.nextTick(write.bind(null, 'a password\n'))
} else if (output.match(/Password again: \(<default hidden>\) $/)) {
- child.stdin.write('a password\n')
+ process.nextTick(write.bind(null, 'a password\n'))
+ } else {
+ console.error('prompts done, output=%j', output)
}
})
var result = ''
child.stderr.on('data', function (c) {
result += c
+ console.error('result %j', c.toString())
})
child.on('close', function () {
result = JSON.parse(result)
- t.same(result, {"user":"a user","pass":"a password","verify":"a password","four":"asdf","passMatch":true})
- t.equal(output, 'Username: (test-user) Password: (<default hidden>) Enter 4 characters: Password again: (<default hidden>) ')
+ t.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>) ')
t.end()
})
})
function child () {
read({prompt: "Username: ", default: "test-user" }, function (er, user) {
read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
- read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) {
- read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
- console.error(JSON.stringify({user: user,
- pass: pass,
- verify: pass2,
- four:four,
- passMatch: (pass === pass2)}))
- })
+ read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+ console.error(JSON.stringify({user: user,
+ pass: pass,
+ verify: pass2,
+ passMatch: (pass === pass2)}))
})
})
})
--- /dev/null
+var tap = require('tap')
+var read = require('../lib/read.js')
+
+if (process.argv[2] === 'child') {
+ return child()
+}
+
+var spawn = require('child_process').spawn
+
+tap.test('defaults', function (t) {
+ var child = spawn(process.execPath, [__filename, 'child'])
+ var output = ''
+ var write = child.stdin.write.bind(child.stdin)
+ child.stdout.on('data', function (c) {
+ console.error('data %s', c)
+ output += c
+ if (output.match(/Username: \(test-user\) $/)) {
+ process.nextTick(write.bind(null, '\n'))
+ } else if (output.match(/Password: \(<default hidden>\) $/)) {
+ process.nextTick(write.bind(null, '\n'))
+ } else if (output.match(/Password again: \(<default hidden>\) $/)) {
+ process.nextTick(write.bind(null, '\n'))
+ } else {
+ console.error('prompts done, output=%j', output)
+ }
+ })
+
+ var result = ''
+ child.stderr.on('data', function (c) {
+ result += c
+ console.error('result %j', c.toString())
+ })
+
+ 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>) ')
+ t.end()
+ })
+})
+
+function child () {
+ read({prompt: "Username: ", default: "test-user" }, function (er, user) {
+ read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
+ read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+ console.error(JSON.stringify({user: user,
+ pass: pass,
+ verify: pass2,
+ passMatch: (pass === pass2)}))
+ })
+ })
+ })
+}
{
- "version": "1.1.44",
+ "version": "1.1.45",
"name": "npm",
"publishConfig": {
"proprietary-attribs": false
"abbrev": "1",
"graceful-fs": "~1.1.1",
"minimatch": "~0.2",
- "nopt": "1",
+ "nopt": "~2.0",
"node-uuid": "~1.3",
"proto-list": "1",
"rimraf": "2",
"block-stream": "*",
"inherits": "1",
"mkdirp": "~0.3.3",
- "read": "0",
+ "read": "~1",
"lru-cache": "~1.1.0",
- "node-gyp": "~0.5",
+ "node-gyp": "~0.6.1",
"fstream-npm": "0.1",
"uid-number": "0",
"archy": "0",