@@ -3,18 +3,95 @@ <h2 id="synopsis">SYNOPSIS</h2>
<pre><code>npm update [-g] [&lt;name&gt; [&lt;name&gt; ...]]
</code></pre><h2 id="description">DESCRIPTION</h2>
<p>This command will update all the packages listed to the latest version
(specified by the <code>tag</code> config).</p>
(specified by the <code>tag</code> config), respecting semver.</p>
<p>It will also install missing packages. As with all commands that install
packages, the <code>--dev</code> flag will cause <code>devDependencies</code> to be processed
as well.</p>
<p>If the <code>-g</code> flag is specified, this command will update globally installed
packages.</p>
<p>If no package name is specified, all packages in the specified location (global
or local) will be updated.</p>
<p>As of <code>npm@2.6.1</code>, the <code>npm update</code> will only inspect top-level packages.
Prior versions of <code>npm</code> would also recursively inspect all dependencies.
To get the old behavior, use <code>npm --depth 9999 update</code>, but be warned that
simultaneous asynchronous update of all packages, including <code>npm</code> itself
and packages that <code>npm</code> depends on, often causes problems up to and including
the uninstallation of <code>npm</code> itself.</p>
<p>To restore a missing <code>npm</code>, use the command:</p>
<pre><code>curl -L https://npmjs.com/install.sh | sh
</code></pre><h2 id="examples">EXAMPLES</h2>
<p>IMPORTANT VERSION NOTE: these examples assume <code>npm@2.6.1</code> or later. For
older versions of <code>npm</code>, you must specify <code>--depth 0</code> to get the behavior
described below.</p>
<p>For the examples below, assume that the current package is <code>app</code> and it depends
on dependencies, <code>dep1</code> (<code>dep2</code>, .. etc.). The published versions of <code>dep1</code> are:</p>
<pre><code>{
dist-tags: { latest: &quot;1.2.2&quot; },
versions: { &quot;1.2.2&quot;,
&quot;1.2.1&quot;,
&quot;1.2.0&quot;,
&quot;1.1.2&quot;,
&quot;1.1.1&quot;,
&quot;1.0.0&quot;,
&quot;0.4.1&quot;,
&quot;0.4.0&quot;,
&quot;0.2.0&quot;
}
}
</code></pre><h3 id="caret-dependencies">Caret Dependencies</h3>
<p>If <code>app</code>&#39;s <code>package.json</code> contains:</p>
<pre><code>dependencies: {
dep1: &quot;^1.1.1&quot;
}
</code></pre><p>Then <code>npm update</code> will install <code>dep1@1.2.2</code>, because <code>1.2.2</code> is <code>latest</code> and
<code>1.2.2</code> satisfies <code>^1.1.1</code>.</p>
<h3 id="tilde-dependencies">Tilde Dependencies</h3>
<p>However, if <code>app</code>&#39;s <code>package.json</code> contains:</p>
<pre><code>dependencies: {
dep1: &quot;~1.1.1&quot;
}
</code></pre><p>In this case, running <code>npm update</code> will install <code>dep1@1.1.2</code>. Even though the <code>latest</code>
tag points to <code>1.2.2</code>, this version does not satisfy <code>~1.1.1</code>, which is equivalent
to <code>&gt;=1.1.1 &lt;1.2.0</code>. So the highest-sorting version that satisfies <code>~1.1.1</code> is used,
which is <code>1.1.2</code>.</p>
<h3 id="caret-dependencies-below-1-0-0">Caret Dependencies below 1.0.0</h3>
<p>Suppose <code>app</code> has a caret dependency on a version below <code>1.0.0</code>, for example:</p>
<pre><code>dependencies: {
dep1: &quot;^0.2.0&quot;
}
</code></pre><p><code>npm update</code> will install <code>dep1@0.2.0</code>, because there are no other
versions which satisfy <code>^0.2.0</code>.</p>
<p>If the dependence were on <code>^0.4.0</code>:</p>
<pre><code>dependencies: {
dep1: &quot;^0.4.0&quot;
}
</code></pre><p>Then <code>npm update</code> will install <code>dep1@0.4.1</code>, because that is the highest-sorting
version that satisfies <code>^0.4.0</code> (<code>&gt;= 0.4.0 &lt;0.5.0</code>)</p>
<h3 id="recording-updates-with-save-">Recording Updates with <code>--save</code></h3>
<p>When you want to update a package and save the new version as
the minimum required dependency in <code>package.json</code>, you can use
<code>npm update --save</code>. For example if <code>package.json</code> contains</p>
<pre><code>dependencies: {
dep1: &quot;^1.1.1&quot;
}
</code></pre><p>Then <code>npm update --save</code> will install <code>dep1@1.2.2</code> (i.e., <code>latest</code>),
and <code>package.json</code> will be modified:</p>
<pre><code>dependencies: {
dep1: &quot;^1.2.2&quot;
}
</code></pre><p>Note that <code>npm</code> will only write an updated version to <code>package.json</code>
if it installs a new package.</p>
<h3 id="updating-globally-installed-packages">Updating Globally-Installed Packages</h3>
<p><code>npm update -g</code> will apply the <code>update</code> action to each globally- installed
package that is <code>outdated</code> -- that is, has a version that is different from
<code>latest</code>.</p>
<p>NOTE: If a package has been upgraded to a version newer than <code>latest</code>, it will
be <em>downgraded</em>.</p>
<h2 id="see-also">SEE ALSO</h2>
<ul>
<li><a href="../cli/npm-install.html">npm-install(1)</a></li>
<li><a href="../cli/npm-outdated.html">npm-outdated(1)</a></li>
<li><a href="../cli/npm-shrinkwrap.html">npm-shrinkwrap(1)</a></li>
<li><a href="../misc/npm-registry.html">npm-registry(7)</a></li>
<li><a href="../files/npm-folders.html">npm-folders(5)</a></li>
<li><a href="../cli/npm-ls.html">npm-ls(1)</a></li>
@@ -8,8 +8,10 @@ <h2 id="synopsis">SYNOPSIS</h2>
valid second argument to semver.inc (one of &quot;patch&quot;, &quot;minor&quot;, &quot;major&quot;,
&quot;prepatch&quot;, &quot;preminor&quot;, &quot;premajor&quot;, &quot;prerelease&quot;). In the second case,
the existing version will be incremented by 1 in the specified field.</p>
<p>If run in a git repo, it will also create a version commit and tag, and
fail if the repo is not clean.</p>
<p>If run in a git repo, it will also create a version commit and tag, and fail if
the repo is not clean. This behavior is controlled by <code>git-tag-version</code> (see
below), and can be disabled on the command line by running <code>npm
--no-git-tag-version version</code></p>
<p>If supplied with <code>--message</code> (shorthand: <code>-m</code>) config option, npm will
use it as a commit message when creating a version commit. If the
<code>message</code> config contains <code>%s</code> then that will be replaced with the
@@ -26,10 +28,18 @@ <h2 id="synopsis">SYNOPSIS</h2>
2048-bit RSA key, ID 6C481CF6, created 2010-08-31

Enter passphrase:
</code></pre><h2 id="see-also">SEE ALSO</h2>
</code></pre><h2 id="configuration">CONFIGURATION</h2>
<h3 id="git-tag-version">git-tag-version</h3>
<ul>
<li>Default: true</li>
<li>Type: Boolean</li>
</ul>
<p>Commit and tag the version change.</p>
<h2 id="see-also">SEE ALSO</h2>
<ul>
<li><a href="../cli/npm-init.html">npm-init(1)</a></li>
<li><a href="../files/package.json.html">package.json(5)</a></li>
<li><a href="../misc/semver.html">semver(7)</a></li>
<li><a href="../misc/config.html">config(7)</a></li>
</ul>

@@ -2,7 +2,7 @@ <h1><a href="../cli/npm.html">npm</a></h1> <p>javascript package manager</p>
<h2 id="synopsis">SYNOPSIS</h2>
<pre><code>npm &lt;command&gt; [args]
</code></pre><h2 id="version">VERSION</h2>
<p>2.3.0</p>
<p>2.8.4</p>
<h2 id="description">DESCRIPTION</h2>
<p>npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
@@ -99,15 +99,15 @@ <h2 id="contributions">CONTRIBUTIONS</h2>
the issues list or ask on the mailing list.</p>
<ul>
<li><a href="http://github.com/npm/npm/issues">http://github.com/npm/npm/issues</a></li>
<li><a href="&#x6d;&#x61;&#x69;&#x6c;&#x74;&#111;&#x3a;&#x6e;&#112;&#109;&#45;&#64;&#x67;&#x6f;&#x6f;&#x67;&#108;&#101;&#x67;&#x72;&#x6f;&#117;&#x70;&#115;&#x2e;&#99;&#111;&#x6d;">&#x6e;&#112;&#109;&#45;&#64;&#x67;&#x6f;&#x6f;&#x67;&#108;&#101;&#x67;&#x72;&#x6f;&#117;&#x70;&#115;&#x2e;&#99;&#111;&#x6d;</a></li>
<li><a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#x3a;&#x6e;&#112;&#109;&#45;&#x40;&#x67;&#x6f;&#x6f;&#103;&#108;&#x65;&#x67;&#x72;&#111;&#x75;&#x70;&#115;&#46;&#x63;&#111;&#109;">&#x6e;&#112;&#109;&#45;&#x40;&#x67;&#x6f;&#x6f;&#103;&#108;&#x65;&#x67;&#x72;&#111;&#x75;&#x70;&#115;&#46;&#x63;&#111;&#109;</a></li>
</ul>
<h2 id="bugs">BUGS</h2>
<p>When you find issues, please report them:</p>
<ul>
<li>web:
<a href="http://github.com/npm/npm/issues">http://github.com/npm/npm/issues</a></li>
<li>email:
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#58;&#x6e;&#x70;&#x6d;&#45;&#x40;&#103;&#111;&#x6f;&#x67;&#x6c;&#x65;&#x67;&#x72;&#111;&#117;&#112;&#115;&#46;&#99;&#x6f;&#109;">&#x6e;&#x70;&#x6d;&#45;&#x40;&#103;&#111;&#x6f;&#x67;&#x6c;&#x65;&#x67;&#x72;&#111;&#117;&#112;&#115;&#46;&#99;&#x6f;&#109;</a></li>
<a href="&#x6d;&#97;&#x69;&#x6c;&#116;&#111;&#58;&#x6e;&#112;&#109;&#45;&#x40;&#x67;&#x6f;&#111;&#x67;&#x6c;&#101;&#x67;&#x72;&#111;&#x75;&#x70;&#115;&#46;&#99;&#x6f;&#x6d;">&#x6e;&#112;&#109;&#45;&#x40;&#x67;&#x6f;&#111;&#x67;&#x6c;&#101;&#x67;&#x72;&#111;&#x75;&#x70;&#115;&#46;&#99;&#x6f;&#x6d;</a></li>
</ul>
<p>Be sure to include <em>all</em> of the output from the npm command that didn&#39;t work
as expected. The <code>npm-debug.log</code> file is also helpful to provide.</p>
@@ -117,7 +117,7 @@ <h2 id="author">AUTHOR</h2>
<p><a href="http://blog.izs.me/">Isaac Z. Schlueter</a> ::
<a href="https://github.com/isaacs/">isaacs</a> ::
<a href="http://twitter.com/izs">@izs</a> ::
<a href="&#109;&#x61;&#105;&#x6c;&#x74;&#111;&#58;&#105;&#64;&#x69;&#x7a;&#x73;&#46;&#x6d;&#101;">&#105;&#64;&#x69;&#x7a;&#x73;&#46;&#x6d;&#101;</a></p>
<a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#x69;&#x40;&#x69;&#x7a;&#115;&#x2e;&#x6d;&#x65;">&#x69;&#x40;&#x69;&#x7a;&#115;&#x2e;&#x6d;&#x65;</a></p>
<h2 id="see-also">SEE ALSO</h2>
<ul>
<li><a href="../cli/npm-help.html">npm-help(1)</a></li>
@@ -52,7 +52,7 @@ <h2 id="bugs">bugs</h2>
issues should be reported. These are helpful for people who encounter issues
with your package.</p>
<p>It should look like this:</p>
<pre><code>{ &quot;url&quot; : &quot;http://github.com/owner/project/issues&quot;
<pre><code>{ &quot;url&quot; : &quot;https://github.com/owner/project/issues&quot;
, &quot;email&quot; : &quot;project@hostname.com&quot;
}
</code></pre><p>You can specify either one or both values. If you want to provide only a url,
@@ -78,7 +78,7 @@ <h2 id="people-fields-author-contributors">people fields: author, contributors</
, &quot;url&quot; : &quot;http://barnyrubble.tumblr.com/&quot;
}
</code></pre><p>Or you can shorten that all into a single string, and npm will parse it for you:</p>
<pre><code>&quot;Barney Rubble &lt;b@rubble.com&gt; (http://barnyrubble.tumblr.com/)
<pre><code>&quot;Barney Rubble &lt;b@rubble.com&gt; (http://barnyrubble.tumblr.com/)&quot;
</code></pre><p>Both email and url are optional either way.</p>
<p>npm also sets a top-level &quot;maintainers&quot; field with your npm user info.</p>
<h2 id="files">files</h2>
@@ -150,7 +150,7 @@ <h2 id="bin">bin</h2>
<h2 id="directories">directories</h2>
<p>The CommonJS <a href="http://wiki.commonjs.org/wiki/Packages/1.0">Packages</a> spec details a
few ways that you can indicate the structure of your package using a <code>directories</code>
object. If you look at <a href="http://registry.npmjs.org/npm/latest">npm&#39;s package.json</a>,
object. If you look at <a href="https://registry.npmjs.org/npm/latest">npm&#39;s package.json</a>,
you&#39;ll see that it has directories for doc, lib, and man.</p>
<p>In the future, this information may be used in other creative ways.</p>
<h3 id="directories-lib">directories.lib</h3>
@@ -175,17 +175,26 @@ <h2 id="repository">repository</h2>
<p>Do it like this:</p>
<pre><code>&quot;repository&quot; :
{ &quot;type&quot; : &quot;git&quot;
, &quot;url&quot; : &quot;http://github.com/npm/npm.git&quot;
, &quot;url&quot; : &quot;https://github.com/npm/npm.git&quot;
}

&quot;repository&quot; :
{ &quot;type&quot; : &quot;svn&quot;
, &quot;url&quot; : &quot;http://v8.googlecode.com/svn/trunk/&quot;
, &quot;url&quot; : &quot;https://v8.googlecode.com/svn/trunk/&quot;
}
</code></pre><p>The URL should be a publicly available (perhaps read-only) url that can be handed
directly to a VCS program without any modification. It should not be a url to an
html project page that you put in your browser. It&#39;s for computers.</p>
<h2 id="scripts">scripts</h2>
<p>For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same
shortcut syntax you use for <code>npm install</code>:</p>
<pre><code>&quot;repository&quot;: &quot;npm/npm&quot;

&quot;repository&quot;: &quot;gist:11081aaa281&quot;

&quot;repository&quot;: &quot;bitbucket:example/repo&quot;

&quot;repository&quot;: &quot;gitlab:another/repo&quot;
</code></pre><h2 id="scripts">scripts</h2>
<p>The &quot;scripts&quot; property is a dictionary containing script commands that are run
at various times in the lifecycle of your package. The key is the lifecycle
event, and the value is the command to run at that point.</p>
@@ -325,18 +334,23 @@ <h2 id="peerdependencies">peerDependencies</h2>
<p>For example:</p>
<pre><code>{
&quot;name&quot;: &quot;tea-latte&quot;,
&quot;version&quot;: &quot;1.3.5&quot;
&quot;version&quot;: &quot;1.3.5&quot;,
&quot;peerDependencies&quot;: {
&quot;tea&quot;: &quot;2.x&quot;
}
}
</code></pre><p>This ensures your package <code>tea-latte</code> can be installed <em>along</em> with the second
major version of the host package <code>tea</code> only. The host package is automatically
installed if needed. <code>npm install tea-latte</code> could possibly yield the following
dependency graph:</p>
major version of the host package <code>tea</code> only. <code>npm install tea-latte</code> could
possibly yield the following dependency graph:</p>
<pre><code>├── tea-latte@1.3.5
└── tea@2.2.0
</code></pre><p>Trying to install another plugin with a conflicting requirement will cause an
</code></pre><p><strong>NOTE: npm versions 1 and 2 will automatically install <code>peerDependencies</code> if
they are not explicitly depended upon higher in the dependency tree. In the
next major version of npm (npm@3), this will no longer be the case. You will
receive a warning that the peerDependency is not installed instead.</strong> The
behavior in npms 1 &amp; 2 was frequently confusing and could easily put you into
dependency hell, a situation that npm is designed to avoid as much as possible.</p>
<p>Trying to install another plugin with a conflicting requirement will cause an
error. For this reason, make sure your plugin requirement is as broad as
possible, and not to lock it down to specific patch versions.</p>
<p>Assuming the host complies with <a href="http://semver.org/">semver</a>, only changes in
@@ -385,15 +399,15 @@ <h2 id="engines">engines</h2>
</code></pre><p>Note that, unless the user has set the <code>engine-strict</code> config flag, this
field is advisory only.</p>
<h2 id="enginestrict">engineStrict</h2>
<p><strong>NOTE: This feature is deprecated and will be removed in npm 3.0.0.</strong></p>
<p>If you are sure that your module will <em>definitely not</em> run properly on
versions of Node/npm other than those specified in the <code>engines</code> object,
then you can set <code>&quot;engineStrict&quot;: true</code> in your package.json file.
This will override the user&#39;s <code>engine-strict</code> config setting.</p>
<p>Please do not do this unless you are really very very sure. If your
engines object is something overly restrictive, you can quite easily and
inadvertently lock yourself into obscurity and prevent your users from
updating to new versions of Node. Consider this choice carefully. If
people abuse it, it will be removed in a future version of npm.</p>
updating to new versions of Node. Consider this choice carefully.</p>
<h2 id="os">os</h2>
<p>You can specify which operating systems your
module will run on:</p>
@@ -52,7 +52,7 @@ <h2 id="bugs">bugs</h2>
issues should be reported. These are helpful for people who encounter issues
with your package.</p>
<p>It should look like this:</p>
<pre><code>{ &quot;url&quot; : &quot;http://github.com/owner/project/issues&quot;
<pre><code>{ &quot;url&quot; : &quot;https://github.com/owner/project/issues&quot;
, &quot;email&quot; : &quot;project@hostname.com&quot;
}
</code></pre><p>You can specify either one or both values. If you want to provide only a url,
@@ -78,7 +78,7 @@ <h2 id="people-fields-author-contributors">people fields: author, contributors</
, &quot;url&quot; : &quot;http://barnyrubble.tumblr.com/&quot;
}
</code></pre><p>Or you can shorten that all into a single string, and npm will parse it for you:</p>
<pre><code>&quot;Barney Rubble &lt;b@rubble.com&gt; (http://barnyrubble.tumblr.com/)
<pre><code>&quot;Barney Rubble &lt;b@rubble.com&gt; (http://barnyrubble.tumblr.com/)&quot;
</code></pre><p>Both email and url are optional either way.</p>
<p>npm also sets a top-level &quot;maintainers&quot; field with your npm user info.</p>
<h2 id="files">files</h2>
@@ -150,7 +150,7 @@ <h2 id="bin">bin</h2>
<h2 id="directories">directories</h2>
<p>The CommonJS <a href="http://wiki.commonjs.org/wiki/Packages/1.0">Packages</a> spec details a
few ways that you can indicate the structure of your package using a <code>directories</code>
object. If you look at <a href="http://registry.npmjs.org/npm/latest">npm&#39;s package.json</a>,
object. If you look at <a href="https://registry.npmjs.org/npm/latest">npm&#39;s package.json</a>,
you&#39;ll see that it has directories for doc, lib, and man.</p>
<p>In the future, this information may be used in other creative ways.</p>
<h3 id="directories-lib">directories.lib</h3>
@@ -175,17 +175,26 @@ <h2 id="repository">repository</h2>
<p>Do it like this:</p>
<pre><code>&quot;repository&quot; :
{ &quot;type&quot; : &quot;git&quot;
, &quot;url&quot; : &quot;http://github.com/npm/npm.git&quot;
, &quot;url&quot; : &quot;https://github.com/npm/npm.git&quot;
}

&quot;repository&quot; :
{ &quot;type&quot; : &quot;svn&quot;
, &quot;url&quot; : &quot;http://v8.googlecode.com/svn/trunk/&quot;
, &quot;url&quot; : &quot;https://v8.googlecode.com/svn/trunk/&quot;
}
</code></pre><p>The URL should be a publicly available (perhaps read-only) url that can be handed
directly to a VCS program without any modification. It should not be a url to an
html project page that you put in your browser. It&#39;s for computers.</p>
<h2 id="scripts">scripts</h2>
<p>For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same
shortcut syntax you use for <code>npm install</code>:</p>
<pre><code>&quot;repository&quot;: &quot;npm/npm&quot;

&quot;repository&quot;: &quot;gist:11081aaa281&quot;

&quot;repository&quot;: &quot;bitbucket:example/repo&quot;

&quot;repository&quot;: &quot;gitlab:another/repo&quot;
</code></pre><h2 id="scripts">scripts</h2>
<p>The &quot;scripts&quot; property is a dictionary containing script commands that are run
at various times in the lifecycle of your package. The key is the lifecycle
event, and the value is the command to run at that point.</p>
@@ -325,18 +334,23 @@ <h2 id="peerdependencies">peerDependencies</h2>
<p>For example:</p>
<pre><code>{
&quot;name&quot;: &quot;tea-latte&quot;,
&quot;version&quot;: &quot;1.3.5&quot;
&quot;version&quot;: &quot;1.3.5&quot;,
&quot;peerDependencies&quot;: {
&quot;tea&quot;: &quot;2.x&quot;
}
}
</code></pre><p>This ensures your package <code>tea-latte</code> can be installed <em>along</em> with the second
major version of the host package <code>tea</code> only. The host package is automatically
installed if needed. <code>npm install tea-latte</code> could possibly yield the following
dependency graph:</p>
major version of the host package <code>tea</code> only. <code>npm install tea-latte</code> could
possibly yield the following dependency graph:</p>
<pre><code>├── tea-latte@1.3.5
└── tea@2.2.0
</code></pre><p>Trying to install another plugin with a conflicting requirement will cause an
</code></pre><p><strong>NOTE: npm versions 1 and 2 will automatically install <code>peerDependencies</code> if
they are not explicitly depended upon higher in the dependency tree. In the
next major version of npm (npm@3), this will no longer be the case. You will
receive a warning that the peerDependency is not installed instead.</strong> The
behavior in npms 1 &amp; 2 was frequently confusing and could easily put you into
dependency hell, a situation that npm is designed to avoid as much as possible.</p>
<p>Trying to install another plugin with a conflicting requirement will cause an
error. For this reason, make sure your plugin requirement is as broad as
possible, and not to lock it down to specific patch versions.</p>
<p>Assuming the host complies with <a href="http://semver.org/">semver</a>, only changes in
@@ -385,15 +399,15 @@ <h2 id="engines">engines</h2>
</code></pre><p>Note that, unless the user has set the <code>engine-strict</code> config flag, this
field is advisory only.</p>
<h2 id="enginestrict">engineStrict</h2>
<p><strong>NOTE: This feature is deprecated and will be removed in npm 3.0.0.</strong></p>
<p>If you are sure that your module will <em>definitely not</em> run properly on
versions of Node/npm other than those specified in the <code>engines</code> object,
then you can set <code>&quot;engineStrict&quot;: true</code> in your package.json file.
This will override the user&#39;s <code>engine-strict</code> config setting.</p>
<p>Please do not do this unless you are really very very sure. If your
engines object is something overly restrictive, you can quite easily and
inadvertently lock yourself into obscurity and prevent your users from
updating to new versions of Node. Consider this choice carefully. If
people abuse it, it will be removed in a future version of npm.</p>
updating to new versions of Node. Consider this choice carefully.</p>
<h2 id="os">os</h2>
<p>You can specify which operating systems your
module will run on:</p>
@@ -5,6 +5,8 @@ <h2 id="command-line-documentation">Command Line Documentation</h2>
<p>Using npm on the command line</p>
<h3 id="npm-1-"><a href="cli/npm.html">npm(1)</a></h3>
<p>javascript package manager</p>
<h3 id="npm-access-1-"><a href="cli/npm-access.html">npm-access(1)</a></h3>
<p>Set access level on published packages</p>
<h3 id="npm-adduser-1-"><a href="cli/npm-adduser.html">npm-adduser(1)</a></h3>
<p>Add a registry user account</p>
<h3 id="npm-bin-1-"><a href="cli/npm-bin.html">npm-bin(1)</a></h3>
@@ -25,6 +27,8 @@ <h3 id="npm-dedupe-1-"><a href="cli/npm-dedupe.html">npm-dedupe(1)</a></h3>
<p>Reduce duplication</p>
<h3 id="npm-deprecate-1-"><a href="cli/npm-deprecate.html">npm-deprecate(1)</a></h3>
<p>Deprecate a version of a package</p>
<h3 id="npm-dist-tag-1-"><a href="cli/npm-dist-tag.html">npm-dist-tag(1)</a></h3>
<p>Modify package distribution tags</p>
<h3 id="npm-docs-1-"><a href="cli/npm-docs.html">npm-docs(1)</a></h3>
<p>Docs for a package in a web browser maybe</p>
<h3 id="npm-edit-1-"><a href="cli/npm-edit.html">npm-edit(1)</a></h3>
@@ -41,6 +45,8 @@ <h3 id="npm-install-1-"><a href="cli/npm-install.html">npm-install(1)</a></h3>
<p>Install a package</p>
<h3 id="npm-link-1-"><a href="cli/npm-link.html">npm-link(1)</a></h3>
<p>Symlink a package folder</p>
<h3 id="npm-logout-1-"><a href="cli/npm-logout.html">npm-logout(1)</a></h3>
<p>Log out of the registry</p>
<h3 id="npm-ls-1-"><a href="cli/npm-ls.html">npm-ls(1)</a></h3>
<p>List installed packages</p>
<h3 id="npm-outdated-1-"><a href="cli/npm-outdated.html">npm-outdated(1)</a></h3>
@@ -1,6 +1,6 @@
<h1><a href="../misc/npm-config.html">npm-config</a></h1> <p>More than you probably want to know about npm configuration</p>
<h2 id="description">DESCRIPTION</h2>
<p>npm gets its configuration values from 6 sources, in this priority:</p>
<p>npm gets its configuration values from the following sources, sorted by priority:</p>
<h3 id="command-line-flags">Command Line Flags</h3>
<p>Putting <code>--foo bar</code> on the command line sets the <code>foo</code> configuration
parameter to <code>&quot;bar&quot;</code>. A <code>--</code> argument tells the cli parser to stop
@@ -42,7 +42,6 @@ <h2 id="shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</h2
<li><code>-m</code>: <code>--message</code></li>
<li><code>-p</code>, <code>--porcelain</code>: <code>--parseable</code></li>
<li><code>-reg</code>: <code>--registry</code></li>
<li><code>-v</code>: <code>--version</code></li>
<li><code>-f</code>: <code>--force</code></li>
<li><code>-desc</code>: <code>--description</code></li>
<li><code>-S</code>: <code>--save</code></li>
@@ -81,6 +80,15 @@ <h2 id="shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</h2
<pre><code>npm config set foo:port 80
</code></pre><p>See <a href="../files/package.json.html">package.json(5)</a> for more information.</p>
<h2 id="config-settings">Config Settings</h2>
<h3 id="access">access</h3>
<ul>
<li>Default: <code>restricted</code></li>
<li>Type: Access</li>
</ul>
<p>When publishing scoped packages, the access level defaults to <code>restricted</code>. If
you want your scoped package to be publicly viewable (and installable) set
<code>--access=public</code>. The only valid values for <code>access</code> are <code>public</code> and
<code>restricted</code>. Unscoped packages <em>always</em> have an access level of <code>public</code>.</p>
<h3 id="always-auth">always-auth</h3>
<ul>
<li>Default: false</li>
@@ -187,8 +195,12 @@ <h3 id="depth">depth</h3>
<li>Default: Infinity</li>
<li>Type: Number</li>
</ul>
<p>The depth to go when recursing directories for <code>npm ls</code> and
<code>npm cache ls</code>.</p>
<p>The depth to go when recursing directories for <code>npm ls</code>,
<code>npm cache ls</code>, and <code>npm outdated</code>.</p>
<p>For <code>npm outdated</code>, a setting of <code>Infinity</code> will be treated as <code>0</code>
since that gives more useful information. To show the outdated status
of all packages and dependents, use a large integer value,
e.g., <code>npm outdated --depth 9999</code></p>
<h3 id="description">description</h3>
<ul>
<li>Default: true</li>
@@ -313,6 +325,16 @@ <h3 id="https-proxy">https-proxy</h3>
<p>A proxy to use for outgoing https requests. If the <code>HTTPS_PROXY</code> or
<code>https_proxy</code> or <code>HTTP_PROXY</code> or <code>http_proxy</code> environment variables are set,
proxy settings will be honored by the underlying <code>request</code> library.</p>
<h3 id="if-present">if-present</h3>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
</ul>
<p>If true, npm will not exit with an error code when <code>run-script</code> is invoked for
a script that isn&#39;t defined in the <code>scripts</code> section of <code>package.json</code>. This
option can be used when it&#39;s desirable to optionally run a script when it&#39;s
present and fail if the script fails. This is useful, for example, when running
scripts that may only apply for some builds in an otherwise generic CI setup.</p>
<h3 id="ignore-scripts">ignore-scripts</h3>
<ul>
<li>Default: false</li>
@@ -354,7 +376,7 @@ <h3 id="init-license">init-license</h3>
<p>The value <code>npm init</code> should use by default for the package license.</p>
<h3 id="init-version">init-version</h3>
<ul>
<li>Default: &quot;0.0.0&quot;</li>
<li>Default: &quot;1.0.0&quot;</li>
<li>Type: semver</li>
</ul>
<p>The value that <code>npm init</code> should use by default for the package
@@ -572,7 +594,7 @@ <h3 id="save-prefix">save-prefix</h3>
</ul>
<p>Configure how versions of packages installed to a package.json file via
<code>--save</code> or <code>--save-dev</code> get prefixed.</p>
<p>For example if a package has version <code>1.2.3</code>, by default it&#39;s version is
<p>For example if a package has version <code>1.2.3</code>, by default its version is
set to <code>^1.2.3</code> which allows minor upgrades for that package, but after
<code>npm config set save-prefix=&#39;~&#39;</code> it would be set to <code>~1.2.3</code> which only allows
patch upgrades.</p>
@@ -738,7 +760,6 @@ <h3 id="viewer">viewer</h3>
<h2 id="see-also">SEE ALSO</h2>
<ul>
<li><a href="../cli/npm-config.html">npm-config(1)</a></li>
<li><a href="../misc/npm-config.html">npm-config(7)</a></li>
<li><a href="../files/npmrc.html">npmrc(5)</a></li>
<li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li>
<li><a href="../files/npm-folders.html">npm-folders(5)</a></li>
@@ -2,7 +2,7 @@ <h1><a href="../misc/npm-disputes.html">npm-disputes</a></h1> <p>Handling Module
<h2 id="synopsis">SYNOPSIS</h2>
<ol>
<li>Get the author email with <code>npm owner ls &lt;pkgname&gt;</code></li>
<li>Email the author, CC <a href="&#109;&#x61;&#x69;&#x6c;&#x74;&#x6f;&#x3a;&#115;&#117;&#x70;&#x70;&#x6f;&#x72;&#116;&#64;&#110;&#x70;&#x6d;&#x6a;&#115;&#46;&#99;&#x6f;&#x6d;">&#115;&#117;&#x70;&#x70;&#x6f;&#x72;&#116;&#64;&#110;&#x70;&#x6d;&#x6a;&#115;&#46;&#99;&#x6f;&#x6d;</a></li>
<li>Email the author, CC <a href="&#x6d;&#97;&#x69;&#108;&#116;&#x6f;&#58;&#115;&#x75;&#x70;&#112;&#111;&#114;&#x74;&#64;&#x6e;&#112;&#109;&#106;&#115;&#46;&#99;&#x6f;&#x6d;">&#115;&#x75;&#x70;&#112;&#111;&#114;&#x74;&#64;&#x6e;&#112;&#109;&#106;&#115;&#46;&#99;&#x6f;&#x6d;</a></li>
<li>After a few weeks, if there&#39;s no resolution, we&#39;ll sort it out.</li>
</ol>
<p>Don&#39;t squat on package names. Publish code or move out of the way.</p>
@@ -40,12 +40,12 @@ <h2 id="description">DESCRIPTION</h2>
owner (Bob).</li>
<li>Joe emails Bob, explaining the situation <strong>as respectfully as
possible</strong>, and what he would like to do with the module name. He
adds the npm support staff <a href="&#x6d;&#x61;&#x69;&#x6c;&#x74;&#111;&#58;&#115;&#117;&#x70;&#112;&#111;&#114;&#x74;&#64;&#110;&#x70;&#109;&#x6a;&#x73;&#46;&#x63;&#111;&#x6d;">&#115;&#117;&#x70;&#112;&#111;&#114;&#x74;&#64;&#110;&#x70;&#109;&#x6a;&#x73;&#46;&#x63;&#111;&#x6d;</a> to the CC list of
adds the npm support staff <a href="&#109;&#x61;&#x69;&#x6c;&#x74;&#x6f;&#x3a;&#x73;&#117;&#112;&#x70;&#x6f;&#x72;&#x74;&#x40;&#x6e;&#x70;&#109;&#x6a;&#115;&#x2e;&#99;&#x6f;&#x6d;">&#x73;&#117;&#112;&#x70;&#x6f;&#x72;&#x74;&#x40;&#x6e;&#x70;&#109;&#x6a;&#115;&#x2e;&#99;&#x6f;&#x6d;</a> to the CC list of
the email. Mention in the email that Bob can run <code>npm owner add
joe foo</code> to add Joe as an owner of the <code>foo</code> package.</li>
<li>After a reasonable amount of time, if Bob has not responded, or if
Bob and Joe can&#39;t come to any sort of resolution, email support
<a href="&#109;&#97;&#105;&#108;&#116;&#x6f;&#58;&#115;&#x75;&#x70;&#112;&#x6f;&#114;&#x74;&#64;&#x6e;&#112;&#x6d;&#106;&#115;&#x2e;&#99;&#111;&#x6d;">&#115;&#x75;&#x70;&#112;&#x6f;&#114;&#x74;&#64;&#x6e;&#112;&#x6d;&#106;&#115;&#x2e;&#99;&#111;&#x6d;</a> and we&#39;ll sort it out. (&quot;Reasonable&quot; is
<a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#115;&#117;&#112;&#112;&#111;&#114;&#116;&#64;&#110;&#112;&#x6d;&#106;&#x73;&#x2e;&#x63;&#111;&#x6d;">&#115;&#117;&#112;&#112;&#111;&#114;&#116;&#64;&#110;&#112;&#x6d;&#106;&#x73;&#x2e;&#x63;&#111;&#x6d;</a> and we&#39;ll sort it out. (&quot;Reasonable&quot; is
usually at least 4 weeks, but extra time is allowed around common
holidays.)</li>
</ol>
@@ -225,7 +225,7 @@ <h2 id="i-get-econnrefused-a-lot-what-s-up-">I get ECONNREFUSED a lot. What&#39
<p>To check if the registry is down, open up
<a href="https://registry.npmjs.org/">https://registry.npmjs.org/</a> in a web browser. This will also tell
you if you are just unable to access the internet for some reason.</p>
<p>If the registry IS down, let us know by emailing <a href="&#x6d;&#97;&#x69;&#x6c;&#116;&#x6f;&#58;&#115;&#x75;&#x70;&#112;&#111;&#114;&#x74;&#64;&#110;&#x70;&#x6d;&#106;&#115;&#x2e;&#x63;&#111;&#x6d;">&#115;&#x75;&#x70;&#112;&#111;&#114;&#x74;&#64;&#110;&#x70;&#x6d;&#106;&#115;&#x2e;&#x63;&#111;&#x6d;</a>
<p>If the registry IS down, let us know by emailing <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#111;&#x3a;&#x73;&#117;&#112;&#112;&#x6f;&#114;&#116;&#x40;&#110;&#112;&#109;&#x6a;&#x73;&#x2e;&#99;&#x6f;&#109;">&#x73;&#117;&#112;&#112;&#x6f;&#114;&#116;&#x40;&#110;&#112;&#109;&#x6a;&#x73;&#x2e;&#99;&#x6f;&#109;</a>
or posting an issue at <a href="https://github.com/npm/npm/issues">https://github.com/npm/npm/issues</a>. If it&#39;s
down for the world (and not just on your local network) then we&#39;re
probably already being pinged about it.</p>
@@ -5,6 +5,8 @@ <h2 id="command-line-documentation">Command Line Documentation</h2>
<p>Using npm on the command line</p>
<h3 id="npm-1-"><a href="../cli/npm.html">npm(1)</a></h3>
<p>javascript package manager</p>
<h3 id="npm-access-1-"><a href="../cli/npm-access.html">npm-access(1)</a></h3>
<p>Set access level on published packages</p>
<h3 id="npm-adduser-1-"><a href="../cli/npm-adduser.html">npm-adduser(1)</a></h3>
<p>Add a registry user account</p>
<h3 id="npm-bin-1-"><a href="../cli/npm-bin.html">npm-bin(1)</a></h3>
@@ -25,6 +27,8 @@ <h3 id="npm-dedupe-1-"><a href="../cli/npm-dedupe.html">npm-dedupe(1)</a></h3>
<p>Reduce duplication</p>
<h3 id="npm-deprecate-1-"><a href="../cli/npm-deprecate.html">npm-deprecate(1)</a></h3>
<p>Deprecate a version of a package</p>
<h3 id="npm-dist-tag-1-"><a href="../cli/npm-dist-tag.html">npm-dist-tag(1)</a></h3>
<p>Modify package distribution tags</p>
<h3 id="npm-docs-1-"><a href="../cli/npm-docs.html">npm-docs(1)</a></h3>
<p>Docs for a package in a web browser maybe</p>
<h3 id="npm-edit-1-"><a href="../cli/npm-edit.html">npm-edit(1)</a></h3>
@@ -41,6 +45,8 @@ <h3 id="npm-install-1-"><a href="../cli/npm-install.html">npm-install(1)</a></h3
<p>Install a package</p>
<h3 id="npm-link-1-"><a href="../cli/npm-link.html">npm-link(1)</a></h3>
<p>Symlink a package folder</p>
<h3 id="npm-logout-1-"><a href="../cli/npm-logout.html">npm-logout(1)</a></h3>
<p>Log out of the registry</p>
<h3 id="npm-ls-1-"><a href="../cli/npm-ls.html">npm-ls(1)</a></h3>
<p>List installed packages</p>
<h3 id="npm-outdated-1-"><a href="../cli/npm-outdated.html">npm-outdated(1)</a></h3>
@@ -30,41 +30,23 @@ <h2 id="description">DESCRIPTION</h2>
run-script &lt;pkg&gt; &lt;stage&gt;</code>. <em>Pre</em> and <em>post</em> commands with matching
names will be run for those as well (e.g. <code>premyscript</code>, <code>myscript</code>,
<code>postmyscript</code>).</p>
<h2 id="note-install-scripts-are-an-antipattern">NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN</h2>
<p><strong>tl;dr</strong> Don&#39;t use <code>install</code>. Use a <code>.gyp</code> file for compilation, and
<code>prepublish</code> for anything else.</p>
<p>You should almost never have to explicitly set a <code>preinstall</code> or
<code>install</code> script. If you are doing this, please consider if there is
another option.</p>
<p>The only valid use of <code>install</code> or <code>preinstall</code> scripts is for
compilation which must be done on the target architecture. In early
versions of node, this was often done using the <code>node-waf</code> scripts, or
a standalone <code>Makefile</code>, and early versions of npm required that it be
explicitly set in package.json. This was not portable, and harder to
do properly.</p>
<p>In the current version of node, the standard way to do this is using a
<code>.gyp</code> file. If you have a file with a <code>.gyp</code> extension in the root
of your package, then npm will run the appropriate <code>node-gyp</code> commands
automatically at install time. This is the only officially supported
method for compiling binary addons, and does not require that you add
anything to your package.json file.</p>
<p>If you have to do other things before your package is used, in a way
<h2 id="common-uses">COMMON USES</h2>
<p>If you need to perform operations on your package before it is used, in a way
that is not dependent on the operating system or architecture of the
target system, then use a <code>prepublish</code> script instead. This includes
target system, use a <code>prepublish</code> script. This includes
tasks such as:</p>
<ul>
<li>Compile CoffeeScript source code into JavaScript.</li>
<li>Create minified versions of JavaScript source code.</li>
<li>Compiling CoffeeScript source code into JavaScript.</li>
<li>Creating minified versions of JavaScript source code.</li>
<li>Fetching remote resources that your package will use.</li>
</ul>
<p>The advantage of doing these things at <code>prepublish</code> time instead of
<code>preinstall</code> or <code>install</code> time is that they can be done once, in a
single place, and thus greatly reduce complexity and variability.
<p>The advantage of doing these things at <code>prepublish</code> time is that they can be done once, in a
single place, thus reducing complexity and variability.
Additionally, this means that:</p>
<ul>
<li>You can depend on <code>coffee-script</code> as a <code>devDependency</code>, and thus
your users don&#39;t need to have it installed.</li>
<li>You don&#39;t need to include the minifiers in your package, reducing
<li>You don&#39;t need to include minifiers in your package, reducing
the size for your users.</li>
<li>You don&#39;t need to rely on your users having <code>curl</code> or <code>wget</code> or
other system tools on the target machines.</li>
@@ -185,6 +167,11 @@ <h2 id="best-practices">BEST PRACTICES</h2>
<li>Don&#39;t prefix your script commands with &quot;sudo&quot;. If root permissions
are required for some reason, then it&#39;ll fail with that error, and
the user will sudo the npm command in question.</li>
<li>Don&#39;t use <code>install</code>. Use a <code>.gyp</code> file for compilation, and <code>prepublish</code>
for anything else. You should almost never have to explicitly set a
preinstall or install script. If you are doing this, please consider if
there is another option. The only valid use of <code>install</code> or <code>preinstall</code>
scripts is for compilation which must be done on the target architecture.</li>
</ul>
<h2 id="see-also">SEE ALSO</h2>
<ul>
@@ -83,7 +83,7 @@ <h3 id="prerelease-tags">Prerelease Tags</h3>
<h4 id="prerelease-identifiers">Prerelease Identifiers</h4>
<p>The method <code>.inc</code> takes an additional <code>identifier</code> string argument that
will append the value of the string as a prerelease identifier:</p>
<pre><code class="lang-`javascript">&gt; semver.inc(&#39;1.2.3&#39;, &#39;pre&#39;, &#39;beta&#39;)
<pre><code class="lang-javascript">&gt; semver.inc(&#39;1.2.3&#39;, &#39;pre&#39;, &#39;beta&#39;)
&#39;1.2.4-beta.0&#39;
</code></pre>
<p>command-line example:</p>
@@ -208,6 +208,9 @@ <h2 id="functions">Functions</h2>
increments it.</li>
</ul>
</li>
<li><code>major(v)</code>: Return the major version number.</li>
<li><code>minor(v)</code>: Return the minor version number.</li>
<li><code>patch(v)</code>: Return the patch version number.</li>
</ul>
<h3 id="comparison">Comparison</h3>
<ul>
@@ -0,0 +1,123 @@
var assert = require("assert")
var resolve = require("path").resolve
var url = require("url")

var log = require("npmlog")
var readPackageJson = require("read-package-json")

var mapToRegistry = require("./utils/map-to-registry.js")
var npa = require("npm-package-arg")
var npm = require("./npm.js")

module.exports = access

access.usage = "npm access public [<package>]"
+ "\nnpm access restricted [<package>]"
+ "\nnpm access add <read-only|read-write> <entity> [<package>]"
+ "\nnpm access rm <entity> [<package>]"
+ "\nnpm access ls [<package>]"
+ "\nnpm access edit [<package>]"

access.completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv.length === 2) {
return cb(null, ["public", "restricted", "add", "rm", "ls", "edit"])
}

switch (argv[2]) {
case "public":
case "restricted":
case "ls":
case "edit":
return cb(new Error("unimplemented: packages you can change"))
case "add":
if (argv.length === 3) return cb(null, ["read-only", "read-write"])

return cb(new Error("unimplemented: entities and packages"))
case "rm":
return cb(new Error("unimplemented: entities and packages"))
default:
return cb(new Error(argv[2]+" not recognized"))
}
}

function access (args, cb) {
var cmd = args.shift()
switch (cmd) {
case "public": case "restricted": return changeAccess(args, cmd, cb)
case "add": case "set": return add(args, cb)
case "rm": case "del": case "clear": return rm(args, cb)
case "list": case "sl": case "ls": return ls(args, cb)
case "edit": case "ed": return edit(args, cb)
default: return cb("Usage:\n"+access.usage)
}
}

function changeAccess (args, level, cb) {
assert(Array.isArray(args), "changeAccess requires args be an array")
assert(
["public", "restricted"].indexOf(level) !== -1,
"access level must be either 'public' or 'restricted'"
)
assert(typeof cb === "function", "changeAccess requires a callback")

var p = (args.shift() || "").trim()
if (!p) return getCurrentPackage(level, cb)
changeAccess_(p, level, cb)
}

function getCurrentPackage (level, cb) {
var here = resolve(npm.prefix, "package.json")
log.verbose("setPackageLevel", "here", here)

readPackageJson(here, function (er, data) {
if (er) return cb(er)

if (!data.name) {
return cb(new Error("Package must be named"))
}

changeAccess_(data.name, level, cb)
})
}

function changeAccess_ (name, level, cb) {
log.verbose("changeAccess", "name", name, "level", level)
mapToRegistry(name, npm.config, function (er, uri, auth, base) {
if (er) return cb(er)

var data = npa(name)
if (!data.scope) {
var msg = "Sorry, you can't change the access level of unscoped packages."
log.error("access", msg)
return cb(new Error(msg))
}

// name must be scoped, so escape separator
name = name.replace("/", "%2f")
// FIXME: mapToRegistry still isn't generic enough SIGH
uri = url.resolve(base, "-/package/"+name+"/access")
var params = {
level : level,
auth : auth
}

npm.registry.access(uri, params, cb)
})
}

function add (args, cb) {
return cb(new Error("npm access add isn't implemented yet!"))
}

function rm (args, cb) {
return cb(new Error("npm access rm isn't implemented yet!"))
}

function ls (args, cb) {
return cb(new Error("npm access ls isn't implemented yet!"))
}

function edit (args, cb) {
return cb(new Error("npm edit ls isn't implemented yet!"))
}
@@ -135,7 +135,8 @@ function save (c, u, cb) {
if (scope.charAt(0) !== "@") scope = "@" + scope

var scopedRegistry = npm.config.get(scope + ":registry")
if (scopedRegistry) uri = scopedRegistry
var cliRegistry = npm.config.get("registry", "cli")
if (scopedRegistry && !cliRegistry) uri = scopedRegistry
}

var params = {
@@ -13,14 +13,9 @@ var npm = require("./npm.js")
, mapToRegistry = require("./utils/map-to-registry.js")

bugs.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
mapToRegistry("-/short", npm.config, function (er, uri, auth) {
if (er) return cb(er)

npm.registry.get(uri, { timeout : 60000, auth : auth }, function (er, list) {
return cb(null, list || [])
})
})
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}

function bugs (args, cb) {
@@ -85,20 +85,26 @@ function linkStuff (pkg, folder, global, didRB, cb) {
// if it's global, and folder is in {prefix}/node_modules,
// then bins are in {prefix}/bin
// otherwise, then bins are in folder/../.bin
var parent = pkg.name[0] === "@" ? path.dirname(path.dirname(folder)) : path.dirname(folder)
, gnm = global && npm.globalDir
, gtop = parent === gnm

log.verbose("linkStuff", [global, gnm, gtop, parent])
log.info("linkStuff", pkg._id)

shouldWarn(pkg, folder, global, function() {
asyncMap( [linkBins, linkMans, !didRB && rebuildBundles]
, function (fn, cb) {
if (!fn) return cb()
log.verbose(fn.name, pkg._id)
fn(pkg, folder, parent, gtop, cb)
}, cb)
var parent = pkg.name[0] === '@' ? path.dirname(path.dirname(folder)) : path.dirname(folder)
var gnm = global && npm.globalDir
var gtop = parent === gnm

log.info('linkStuff', pkg._id)
log.silly('linkStuff', pkg._id, 'has', parent, 'as its parent node_modules')
if (global) log.silly('linkStuff', pkg._id, 'is part of a global install')
if (gnm) log.silly('linkStuff', pkg._id, 'is installed into a global node_modules')
if (gtop) log.silly('linkStuff', pkg._id, 'is installed into the top-level global node_modules')

shouldWarn(pkg, folder, global, function () {
asyncMap(
[linkBins, linkMans, !didRB && rebuildBundles],
function (fn, cb) {
if (!fn) return cb()
log.verbose(fn.name, pkg._id)
fn(pkg, folder, parent, gtop, cb)
},
cb
)
})
}

@@ -239,8 +245,9 @@ function linkMans (pkg, folder, parent, gtop, cb) {
var stem = parseMan[1]
var sxn = parseMan[2]
var bn = path.basename(stem)
var manSrc = path.resolve(folder, man)
var manDest = path.join(manRoot, "man" + sxn, bn)

linkIfExists(man, manDest, gtop && folder, cb)
linkIfExists(manSrc, manDest, gtop && folder, cb)
}, cb)
}
@@ -76,7 +76,6 @@ var npm = require("./npm.js")
, addLocal = require("./cache/add-local.js")
, addRemoteTarball = require("./cache/add-remote-tarball.js")
, addRemoteGit = require("./cache/add-remote-git.js")
, maybeGithub = require("./cache/maybe-github.js")
, inflight = require("inflight")
, realizePackageSpecifier = require("realize-package-specifier")
, npa = require("npm-package-arg")
@@ -135,9 +134,7 @@ function read (name, ver, forceBypass, cb) {

var root = cachedPackageRoot({name : name, version : ver})
function c (er, data) {
log.silly("cache", "addNamed cb", name+"@"+ver)
if (er) log.verbose("cache", "addNamed error for", name+"@"+ver, er)

if (data) deprCheck(data)

return cb(er, data)
@@ -298,10 +295,8 @@ function add (args, where, cb) {
})
break
case "git":
addRemoteGit(p.spec, false, cb)
break
case "github":
maybeGithub(p.spec, cb)
case "hosted":
addRemoteGit(p.rawSpec, cb)
break
default:
if (p.name) return addNamed(p.name, p.spec, null, cb)
@@ -34,20 +34,23 @@ function addNamed (name, version, data, cb_) {
assert(typeof cb_ === "function", "must have callback")

var key = name + "@" + version
log.verbose("addNamed", key)
log.silly("addNamed", key)

function cb (er, data) {
if (data && !data._fromGithub) data._from = key
cb_(er, data)
}

log.silly("addNamed", "semver.valid", semver.valid(version))
log.silly("addNamed", "semver.validRange", semver.validRange(version))
var fn = ( semver.valid(version, true) ? addNameVersion
: semver.validRange(version, true) ? addNameRange
: addNameTag
)
fn(name, version, data, cb)
if (semver.valid(version, true)) {
log.verbose('addNamed', JSON.stringify(version), 'is a plain semver version for', name)
addNameVersion(name, version, data, cb)
} else if (semver.validRange(version, true)) {
log.verbose('addNamed', JSON.stringify(version), 'is a valid semver range for', name)
addNameRange(name, version, data, cb)
} else {
log.verbose('addNamed', JSON.stringify(version), 'is being treated as a dist-tag for', name)
addNameTag(name, version, data, cb)
}
}

function addNameTag (name, tag, data, cb) {

Large diffs are not rendered by default.

@@ -19,8 +19,8 @@ function addRemoteTarball (u, pkgData, shasum, auth, cb_) {
function cb (er, data) {
if (data) {
data._from = u
data._shasum = data._shasum || shasum
data._resolved = u
data._shasum = data._shasum || shasum
}
cb_(er, data)
}
@@ -24,6 +24,7 @@ function CachingRegistryClient (config) {
// swizzle in our custom cache invalidation logic
this._request = this.request
this.request = this._invalidatingRequest
this.get = get
}
inherits(CachingRegistryClient, RegistryClient)

@@ -42,7 +43,7 @@ CachingRegistryClient.prototype._invalidatingRequest = function (uri, params, cb
// thinking that it didn't work when it did.
// Note that failure is an acceptable option here, since the only
// result will be a stale cache for some helper commands.
client.log.verbose("request", "invalidating", invalidated, "on", method)
log.verbose("request", "invalidating", invalidated, "on", method)
return rimraf(invalidated, function () {
cb.apply(undefined, args)
})
@@ -52,7 +53,7 @@ CachingRegistryClient.prototype._invalidatingRequest = function (uri, params, cb
})
}

CachingRegistryClient.prototype.get = function get (uri, params, cb) {
function get (uri, params, cb) {
assert(typeof uri === "string", "must pass registry URI to get")
assert(params && typeof params === "object", "must pass params to get")
assert(typeof cb === "function", "must pass callback to get")
@@ -68,7 +69,10 @@ CachingRegistryClient.prototype.get = function get (uri, params, cb) {

// If the GET is part of a write operation (PUT or DELETE), then
// skip past the cache entirely, but still save the results.
if (uri.match(/\?write=true$/)) return get_.call(this, uri, cachePath, params, cb)
if (uri.match(/\?write=true$/)) {
log.verbose("get", "GET as part of write; not caching result")
return get_.call(this, uri, cachePath, params, cb)
}

var client = this
fs.stat(cachePath, function (er, stat) {
@@ -170,6 +174,7 @@ function get_ (uri, cachePath, params, cb) {
}

function saveToCache (cachePath, data, saved) {
log.verbose("get", "saving", data.name, "to", cachePath)
getCacheStat(function (er, st) {
mkdirp(path.dirname(cachePath), function (er, made) {
if (er) return saved()

This file was deleted.

@@ -1,82 +1,86 @@
module.exports = updateIndex

var fs = require("graceful-fs")
, assert = require("assert")
, path = require("path")
, mkdir = require("mkdirp")
, chownr = require("chownr")
, url = require("url")
, npm = require("../npm.js")
, log = require("npmlog")
, cacheFile = require("npm-cache-filename")
, getCacheStat = require("./get-stat.js")
var fs = require('graceful-fs')
var assert = require('assert')
var path = require('path')
var mkdir = require('mkdirp')
var chownr = require('chownr')
var npm = require('../npm.js')
var log = require('npmlog')
var cacheFile = require('npm-cache-filename')
var getCacheStat = require('./get-stat.js')
var mapToRegistry = require('../utils/map-to-registry.js')

/* /-/all is special.
* It uses timestamp-based caching and partial updates,
* because it is a monster.
*/
function updateIndex (uri, params, cb) {
assert(typeof uri === "string", "must pass registry URI to updateIndex")
assert(params && typeof params === "object", "must pass params to updateIndex")
assert(typeof cb === "function", "must pass callback to updateIndex")

var parsed = url.parse(uri)
assert(
parsed.protocol === "http:" || parsed.protocol === "https:",
"must have a URL that starts with http: or https:"
)

var cacheBase = cacheFile(npm.config.get("cache"))(uri)
var cachePath = path.join(cacheBase, ".cache.json")
log.info("updateIndex", cachePath)

getCacheStat(function (er, st) {
function updateIndex (staleness, cb) {
assert(typeof cb === 'function', 'must pass callback to updateIndex')

mapToRegistry('-/all', npm.config, function (er, uri, auth) {
if (er) return cb(er)

mkdir(cacheBase, function (er, made) {
if (er) return cb(er)
var params = {
timeout: staleness,
follow: true,
staleOk: true,
auth: auth
}
var cacheBase = cacheFile(npm.config.get('cache'))(uri)
var cachePath = path.join(cacheBase, '.cache.json')
log.info('updateIndex', cachePath)

fs.readFile(cachePath, function (er, data) {
if (er) return updateIndex_(uri, params, 0, {}, cachePath, cb)
getCacheStat(function (er, st) {
if (er) return cb(er)

try {
data = JSON.parse(data)
}
catch (ex) {
fs.writeFile(cachePath, "{}", function (er) {
if (er) return cb(new Error("Broken cache."))
mkdir(cacheBase, function (er, made) {
if (er) return cb(er)

return updateIndex_(uri, params, 0, {}, cachePath, cb)
fs.readFile(cachePath, function (er, data) {
if (er) {
log.warn('', 'Building the local index for the first time, please be patient')
return updateIndex_(uri, params, {}, cachePath, cb)
}

chownr(made || cachePath, st.uid, st.gid, function (er) {
if (er) return cb(er)

try {
data = JSON.parse(data)
} catch (ex) {
fs.writeFile(cachePath, '{}', function (er) {
if (er) return cb(new Error('Broken cache.'))

log.warn('', 'Building the local index for the first time, please be patient')
return updateIndex_(uri, params, {}, cachePath, cb)
})
}

var t = +data._updated || 0
// use the cache and update in the background if it's not too old
if (Date.now() - t < 60000) {
cb(null, data)
cb = function () {}
}

if (t === 0) {
log.warn('', 'Building the local index for the first time, please be patient')
} else {
log.verbose('updateIndex', 'Cached search data present with timestamp', t)
uri += '/since?stale=update_after&startkey=' + t
}
updateIndex_(uri, params, data, cachePath, cb)
})
}
var t = +data._updated || 0
chownr(made || cachePath, st.uid, st.gid, function (er) {
if (er) return cb(er)

updateIndex_(uri, params, t, data, cachePath, cb)
})
})
})
})
}

function updateIndex_ (uri, params, t, data, cachePath, cb) {
// use the cache and update in the background if it's not too old
if (Date.now() - t < 60000) {
cb(null, data)
cb = function () {}
}

var full
if (t === 0) {
log.warn("", "Building the local index for the first time, please be patient")
full = url.resolve(uri, "/-/all")
}
else {
full = url.resolve(uri, "/-/all/since?stale=update_after&startkey=" + t)
}

npm.registry.request(full, params, function (er, updates, _, res) {
function updateIndex_ (all, params, data, cachePath, cb) {
log.silly('update-index', 'fetching', all)
npm.registry.request(all, params, function (er, updates, _, res) {
if (er) return cb(er, data)

var headers = res.headers
@@ -0,0 +1,16 @@
var assert = require("assert")

var toNerfDart = require("./nerf-dart.js")

module.exports = clearCredentialsByURI

function clearCredentialsByURI (uri) {
assert(uri && typeof uri === "string", "registry URL is required")

var nerfed = toNerfDart(uri)

this.del(nerfed + ":_authToken", "user")
this.del(nerfed + ":_password", "user")
this.del(nerfed + ":username", "user")
this.del(nerfed + ":email", "user")
}
@@ -74,8 +74,10 @@ function load () {
loading = true

cb = once(function (er, conf) {
if (!er)
if (!er) {
exports.loaded = conf
loading = false
}
loadCbs.forEach(function (fn) {
fn(er, conf)
})
@@ -152,10 +154,17 @@ function load_(builtin, rc, cli, cb) {
// annoying humans and their expectations!
if (conf.get("prefix")) {
var etc = path.resolve(conf.get("prefix"), "etc")
defaults.globalconfig = path.resolve(etc, "npmrc")
defaults.globalignorefile = path.resolve(etc, "npmignore")
mkdirp(etc, function (err) {
defaults.globalconfig = path.resolve(etc, "npmrc")
defaults.globalignorefile = path.resolve(etc, "npmignore")
afterUserContinuation()
})
} else {
afterUserContinuation()
}
}

function afterUserContinuation() {
conf.addFile(conf.get("globalconfig"), "global")

// move the builtin into the conf stack now.
@@ -220,6 +229,7 @@ Conf.prototype.setUser = require("./set-user.js")
Conf.prototype.findPrefix = require("./find-prefix.js")
Conf.prototype.getCredentialsByURI = require("./get-credentials-by-uri.js")
Conf.prototype.setCredentialsByURI = require("./set-credentials-by-uri.js")
Conf.prototype.clearCredentialsByURI = require("./clear-credentials-by-uri.js")

Conf.prototype.loadExtras = function(cb) {
this.setUser(function(er) {
@@ -24,20 +24,14 @@ try {
exports.Umask = Umask
function Umask () {}
function validateUmask (data, k, val) {
return umask.validate (data, k, val)
return umask.validate(data, k, val)
}

function validateSemver (data, k, val) {
if (!semver.valid(val)) return false
data[k] = semver.valid(val)
}

function validateTag (data, k, val) {
val = ("" + val).trim()
if (!val || semver.validRange(val)) return false
data[k] = val
}

function validateStream (data, k, val) {
if (!(val instanceof Stream)) return false
data[k] = val
@@ -47,10 +41,6 @@ nopt.typeDefs.semver = { type: semver, validate: validateSemver }
nopt.typeDefs.Stream = { type: Stream, validate: validateStream }
nopt.typeDefs.Umask = { type: Umask, validate: validateUmask }

// Don't let --tag=1.2.3 ever be a thing
var tag = {}
nopt.typeDefs.tag = { type: tag, validate: validateTag }

nopt.invalidHandler = function (k, val, type) {
log.warn("invalid config", k + "=" + JSON.stringify(val))

@@ -60,9 +50,6 @@ nopt.invalidHandler = function (k, val, type) {
}

switch (type) {
case tag:
log.warn("invalid config", "Tag must not be a SemVer range")
break
case Umask:
log.warn("invalid config", "Must be umask, octal number in range 0000..0777")
break
@@ -119,7 +106,9 @@ Object.defineProperty(exports, "defaults", {get: function () {
}

defaults = {
"always-auth" : false
access : null
, "always-auth" : false

, "bin-links" : true
, browser : null

@@ -158,6 +147,7 @@ Object.defineProperty(exports, "defaults", {get: function () {
, group : process.platform === "win32" ? 0
: process.env.SUDO_GID || (process.getgid && process.getgid())
, heading: "npm"
, "if-present": false
, "ignore-scripts": false
, "init-module": path.resolve(home, ".npm-init.js")
, "init-author-name" : ""
@@ -228,7 +218,8 @@ Object.defineProperty(exports, "defaults", {get: function () {
}})

exports.types =
{ "always-auth" : Boolean
{ access : [null, "restricted", "public"]
, "always-auth" : Boolean
, "bin-links": Boolean
, browser : [null, String]
, ca: [null, String, Array]
@@ -259,6 +250,7 @@ exports.types =
, "https-proxy" : [null, url]
, "user-agent" : String
, "heading": String
, "if-present": Boolean
, "ignore-scripts": Boolean
, "init-module": path
, "init-author-name" : String
@@ -272,7 +264,7 @@ exports.types =
// local-address must be listed as an IP for a local network interface
// must be IPv4 due to node bug
, "local-address" : getLocalAddresses()
, loglevel : ["silent","error","warn","http","info","verbose","silly"]
, loglevel : ["silent", "error", "warn", "http", "info", "verbose", "silly"]
, logstream : Stream
, long : Boolean
, message: String
@@ -284,7 +276,7 @@ exports.types =
, prefix: path
, production: Boolean
, "proprietary-attribs": Boolean
, proxy : [null, url]
, proxy : [null, false, url] // allow proxy to be disabled explicitly
, "rebuild-bundle" : Boolean
, registry : [null, url]
, rollback : Boolean
@@ -307,7 +299,7 @@ exports.types =
, "sign-git-tag": Boolean
, spin: ["always", Boolean]
, "strict-ssl": Boolean
, tag : tag
, tag : String
, tmp : path
, unicode : Boolean
, "unsafe-perm" : Boolean
@@ -9,8 +9,12 @@ function loadCAFile(cafilePath, cb) {
fs.readFile(cafilePath, "utf8", afterCARead.bind(this))

function afterCARead(er, cadata) {
if (er)

if (er) {
// previous cafile no longer exists, so just continue on gracefully
if (er.code === 'ENOENT') return cb()
return cb(er)
}

var delim = "-----END CERTIFICATE-----"
var output
@@ -314,11 +314,28 @@ function readInstalled (dir, counter, parent, cb) {
})

fs.readdir(path.resolve(dir, "node_modules"), function (er, c) {
children = c || [] // error is ok, just means no children.
children = children.filter(function (p) {
return !p.match(/^[\._-]/)
})
next()
children = children || [] // error is ok, just means no children.
// check if there are scoped packages.
asyncMap(c || [], function (child, cb) {
if (child.indexOf('@') === 0) {
fs.readdir(path.resolve(dir, "node_modules", child), function (er, scopedChildren) {
// error is ok, just means no children.
(scopedChildren || []).forEach(function (sc) {
children.push(path.join(child, sc))
})
cb()
})
} else {
children.push(child)
cb()
}
}, function (er) {
if (er) return cb(er)
children = children.filter(function (p) {
return !p.match(/^[\._-]/)
})
next();
});
})

function next () {
@@ -0,0 +1,151 @@
module.exports = distTag

var log = require("npmlog")
var npa = require("npm-package-arg")
var semver = require("semver")

var npm = require("./npm.js")
var mapToRegistry = require("./utils/map-to-registry.js")
var readLocalPkg = require("./utils/read-local-package.js")

distTag.usage = "npm dist-tag add <pkg>@<version> [<tag>]"
+ "\nnpm dist-tag rm <pkg> <tag>"
+ "\nnpm dist-tag ls [<pkg>]"

distTag.completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv.length === 2) {
return cb(null, ["add", "rm", "ls"])
}

switch (argv[2]) {
default:
return cb()
}
}

function distTag (args, cb) {
var cmd = args.shift()
switch (cmd) {
case "add": case "a": case "set": case "s":
return add(args[0], args[1], cb)
case "rm": case "r": case "del": case "d": case "remove":
return remove(args[1], args[0], cb)
case "ls": case "l": case "sl": case "list":
return list(args[0], cb)
default:
return cb("Usage:\n"+distTag.usage)
}
}

function add (spec, tag, cb) {
var thing = npa(spec || "")
var pkg = thing.name
var version = thing.rawSpec
var t = (tag || npm.config.get("tag")).trim()

log.verbose("dist-tag add", t, "to", pkg+"@"+version)

if (!pkg || !version || !t) return cb("Usage:\n"+distTag.usage)

if (semver.validRange(t)) {
var er = new Error("Tag name must not be a valid SemVer range: " + t)
return cb(er)
}

fetchTags(pkg, function (er, tags) {
if (er) return cb(er)

if (tags[t] === version) {
log.warn("dist-tag add", t, "is already set to version", version)
return cb()
}
tags[t] = version

mapToRegistry(pkg, npm.config, function (er, uri, auth, base) {
var params = {
package : pkg,
distTag : t,
version : version,
auth : auth
}

npm.registry.distTags.add(base, params, function (er) {
if (er) return cb(er)

console.log("+"+t+": "+pkg+"@"+version)
cb()
})
})
})
}

function remove (tag, pkg, cb) {
log.verbose("dist-tag del", tag, "from", pkg)

fetchTags(pkg, function (er, tags) {
if (er) return cb(er)

if (!tags[tag]) {
log.info("dist-tag del", tag, "is not a dist-tag on", pkg)
return cb(new Error(tag+" is not a dist-tag on "+pkg))
}

var version = tags[tag]
delete tags[tag]

mapToRegistry(pkg, npm.config, function (er, uri, auth, base) {
var params = {
package : pkg,
distTag : tag,
auth : auth
}

npm.registry.distTags.rm(base, params, function (er) {
if (er) return cb(er)

console.log("-"+tag+": "+pkg+"@"+version)
cb()
})
})
})
}

function list (pkg, cb) {
if (!pkg) return readLocalPkg(function (er, pkg) {
if (er) return cb(er)
if (!pkg) return cb(distTag.usage)
list(pkg, cb)
})

fetchTags(pkg, function (er, tags) {
if (er) {
log.error("dist-tag ls", "Couldn't get dist-tag data for", pkg)
return cb(er)
}
var msg = Object.keys(tags).map(function (k) {
return k+": "+tags[k]
}).sort().join("\n")
console.log(msg)
cb(er, tags)
})
}

function fetchTags (pkg, cb) {
mapToRegistry(pkg, npm.config, function (er, uri, auth, base) {
if (er) return cb(er)

var params = {
package : pkg,
auth : auth
}
npm.registry.distTags.fetch(base, params, function (er, tags) {
if (er) return cb(er)
if (!tags || !Object.keys(tags).length) {
return cb(new Error("No dist-tags found for " + pkg))
}

cb(null, tags)
})
})
}
@@ -11,13 +11,9 @@ var npm = require("./npm.js")
, mapToRegistry = require("./utils/map-to-registry.js")

docs.completion = function (opts, cb) {
mapToRegistry("/-/short", npm.config, function (er, uri, auth) {
if (er) return cb(er)

npm.registry.get(uri, { timeout : 60000, auth : auth }, function (er, list) {
return cb(null, list || [])
})
})
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}

function url (json) {
@@ -59,19 +59,23 @@ function help (args, cb) {
var manroot = path.resolve(__dirname, "..", "man")

// legacy
if (section === "global")
section = "folders"
else if (section === "json")
section = "package.json"
if (section === "global") section = "folders"
else if (section === "json") section = "package.json"

// find either /section.n or /npm-section.n
var f = "+(npm-" + section + "|" + section + ").[0-9]"
var compext = "\\.+(gz|bz2|lzma|[FYzZ]|xz)$"
var f = "+(npm-" + section + "|" + section + ").[0-9]?(" + compext + ")"
return glob(manroot + "/*/" + f, function (er, mans) {
if (er)
return cb(er)
if (er) return cb(er)

if (!mans.length) return npm.commands["help-search"](args, cb)

if (!mans.length)
return npm.commands["help-search"](args, cb)
mans = mans.map(function (man) {
var ext = path.extname(man)
if (man.match(new RegExp(compext))) man = path.basename(man, ext)

return man
})

viewMan(pickMan(mans, pref), cb)
})
@@ -17,7 +17,7 @@ function init (args, cb) {
if (!initJson.yes(npm.config)) {
console.log(
["This utility will walk you through creating a package.json file."
,"It only covers the most common items, and tries to guess sane defaults."
,"It only covers the most common items, and tries to guess sensible defaults."
,""
,"See `npm help json` for definitive documentation on these fields"
,"and exactly what they do."

Large diffs are not rendered by default.

@@ -8,7 +8,6 @@ var npm = require("./npm.js")
, asyncMap = require("slide").asyncMap
, chain = require("slide").chain
, path = require("path")
, rm = require("./utils/gently-rm.js")
, build = require("./build.js")
, npa = require("npm-package-arg")

@@ -128,20 +127,17 @@ function linkPkg (folder, cb_) {
return cb(er)
}
var target = path.resolve(npm.globalDir, d.name)
rm(target, function (er) {
symlink(me, target, false, true, function (er) {
if (er) return cb(er)
symlink(me, target, function (er) {
log.verbose("link", "build target", target)
// also install missing dependencies.
npm.commands.install(me, [], function (er) {
if (er) return cb(er)
log.verbose("link", "build target", target)
// also install missing dependencies.
npm.commands.install(me, [], function (er) {
// build the global stuff. Don't run *any* scripts, because
// install command already will have done that.
build([target], true, build._noLC, true, function (er) {
if (er) return cb(er)
// build the global stuff. Don't run *any* scripts, because
// install command already will have done that.
build([target], true, build._noLC, true, function (er) {
if (er) return cb(er)
resultPrinter(path.basename(me), me, target, cb)
})
resultPrinter(path.basename(me), me, target, cb)
})
})
})
@@ -0,0 +1,40 @@
module.exports = logout

var dezalgo = require("dezalgo")
var log = require("npmlog")

var npm = require("./npm.js")
var mapToRegistry = require("./utils/map-to-registry.js")

logout.usage = "npm logout [--registry] [--scope]"

function logout (args, cb) {
npm.spinner.start()
cb = dezalgo(cb)

mapToRegistry("/", npm.config, function (err, uri, auth, normalized) {
if (err) return cb(err)

if (auth.token) {
log.verbose("logout", "clearing session token for", normalized)
npm.registry.logout(normalized, { auth: auth }, function (err) {
if (err) return cb(err)

npm.config.clearCredentialsByURI(normalized)
npm.spinner.stop()
npm.config.save("user", cb)
})
}
else if (auth.username || auth.password) {
log.verbose("logout", "clearing user credentials for", normalized)
npm.config.clearCredentialsByURI(normalized)
npm.spinner.stop()
npm.config.save("user", cb)
}
else {
cb(new Error(
"Not logged in to", normalized + ",", "so can't log out."
))
}
})
}
@@ -40,6 +40,7 @@ function ls (args, silent, cb) {
var opt = { depth: depth, log: log.warn, dev: true }
readInstalled(dir, opt, function (er, data) {
pruneNestedExtraneous(data)
filterByEnv(data)
var bfs = bfsify(data, args)
, lite = getLite(bfs)

@@ -88,6 +89,21 @@ function pruneNestedExtraneous (data, visited) {
}
}

function filterByEnv (data) {
var dev = npm.config.get("dev")
var production = npm.config.get("production")
if (dev === production) return
var dependencies = {}
var devDependencies = data.devDependencies || []
Object.keys(data.dependencies).forEach(function (name) {
var keys = Object.keys(devDependencies)
if (production && keys.indexOf(name) !== -1) return
if (dev && keys.indexOf(name) === -1) return
dependencies[name] = data.dependencies[name]
})
data.dependencies = dependencies
}

function alphasort (a, b) {
a = a.toLowerCase()
b = b.toLowerCase()
@@ -11,9 +11,6 @@ if (typeof WScript !== "undefined") {
}


// monkey-patch support for 0.6 child processes
require('child-process-close')

var EventEmitter = require("events").EventEmitter
, npm = module.exports = new EventEmitter()
, npmconf = require("./config/core.js")
@@ -66,7 +63,9 @@ var commandCache = {}
, "i" : "install"
, "isntall" : "install"
, "up" : "update"
, "upgrade" : "update"
, "c" : "config"
, "dist-tags" : "dist-tag"
, "info" : "view"
, "show" : "view"
, "find" : "search"
@@ -109,8 +108,10 @@ var commandCache = {}
, "stars"
, "tag"
, "adduser"
, "logout"
, "unpublish"
, "owner"
, "access"
, "deprecate"
, "shrinkwrap"

@@ -131,6 +132,7 @@ var commandCache = {}
, "prefix"
, "bin"
, "whoami"
, "dist-tag"

, "test"
, "stop"
@@ -220,7 +222,7 @@ Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
})

return commandCache[a]
}, enumerable: fullList.indexOf(c) !== -1 })
}, enumerable: fullList.indexOf(c) !== -1, configurable: true })

// make css-case commands callable via camelCase as well
if (c.match(/\-([a-z])/)) {
@@ -35,24 +35,33 @@ var path = require("path")
, mapToRegistry = require("./utils/map-to-registry.js")
, npa = require("npm-package-arg")
, readInstalled = require("read-installed")
, long = npm.config.get("long")
, log = require("npmlog")

function outdated (args, silent, cb) {
if (typeof cb !== "function") cb = silent, silent = false
var dir = path.resolve(npm.dir, "..")

// default depth for `outdated` is 0 (cf. `ls`)
if (npm.config.get("depth") === Infinity) npm.config.set("depth", 0)

outdated_(args, dir, {}, 0, function (er, list) {
if (!list) list = []
if (er || silent || list.length === 0) return cb(er, list)
if (npm.config.get("json")) {
console.log(makeJSON(list))
} else if (npm.config.get("parseable")) {
console.log(makeParseable(list))
} else {
var outList = list.map(makePretty)
var outTable = [[ "Package"
, "Current"
, "Wanted"
, "Latest"
, "Location"
]].concat(outList)
var outHead = [ "Package"
, "Current"
, "Wanted"
, "Latest"
, "Location"
]
if (long) outHead.push("Package Type")
var outTable = [outHead].concat(outList)

if (npm.color) {
outTable[0] = outTable[0].map(function(heading) {
@@ -69,13 +78,14 @@ function outdated (args, silent, cb) {
})
}

// [[ dir, dep, has, want, latest ]]
// [[ dir, dep, has, want, latest, type ]]
function makePretty (p) {
var dep = p[1]
, dir = path.resolve(p[0], "node_modules", dep)
, has = p[2]
, want = p[3]
, latest = p[4]
, type = p[6]

if (!npm.config.get("global")) {
dir = path.relative(process.cwd(), dir)
@@ -87,12 +97,14 @@ function makePretty (p) {
, latest
, dirToPrettyLocation(dir)
]
if (long) columns[5] = type

if (npm.color) {
columns[0] = color[has === want ? "yellow" : "red"](columns[0]) // dep
columns[2] = color.green(columns[2]) // want
columns[3] = color.magenta(columns[3]) // latest
columns[4] = color.brightBlack(columns[4]) // dir
if (long) columns[5] = color.brightBlack(columns[5]) // type
}

return columns
@@ -111,17 +123,22 @@ function dirToPrettyLocation (dir) {

function makeParseable (list) {
return list.map(function (p) {

var dep = p[1]
, dir = path.resolve(p[0], "node_modules", dep)
, has = p[2]
, want = p[3]
, latest = p[4]
, type = p[6]

return [ dir
var out = [ dir
, dep + "@" + want
, (has ? (dep + "@" + has) : "MISSING")
, dep + "@" + latest
].join(":")
]
if (long) out.push(type)

return out.join(":")
}).join(os.EOL)
}

@@ -137,6 +154,7 @@ function makeJSON (list) {
, latest: p[4]
, location: dir
}
if (long) out[p[1]].type = p[6]
})
return JSON.stringify(out, null, 2)
}
@@ -154,13 +172,23 @@ function outdated_ (args, dir, parentHas, depth, cb) {
return cb(null, [])
}
var deps = null
var types = {}
readJson(path.resolve(dir, "package.json"), function (er, d) {
d = d || {}
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
deps = (er) ? true : (d.dependencies || {})
if (!er) {
Object.keys(deps).forEach(function (k) {
types[k] = "dependencies"
})
}

if (npm.config.get("save-dev")) {
deps = d.devDependencies || {}
Object.keys(deps).forEach(function (k) {
types[k] = "devDependencies"
})

return next()
}

@@ -174,6 +202,9 @@ function outdated_ (args, dir, parentHas, depth, cb) {

if (npm.config.get("save-optional")) {
deps = d.optionalDependencies || {}
Object.keys(deps).forEach(function (k) {
types[k] = "optionalDependencies"
})
return next()
}

@@ -186,6 +217,7 @@ function outdated_ (args, dir, parentHas, depth, cb) {
Object.keys(d.devDependencies || {}).forEach(function (k) {
if (!(k in parentHas)) {
deps[k] = d.devDependencies[k]
types[k] = "devDependencies"
}
})
}
@@ -236,12 +268,14 @@ function outdated_ (args, dir, parentHas, depth, cb) {
// if has[dep] !== shouldHave[dep], then cb with the data
// otherwise dive into the folder
asyncMap(Object.keys(deps), function (dep, cb) {
shouldUpdate(args, dir, dep, has, deps[dep], depth, cb)
if (!long) return shouldUpdate(args, dir, dep, has, deps[dep], depth, cb)

shouldUpdate(args, dir, dep, has, deps[dep], depth, cb, types[dep])
}, cb)
}
}

function shouldUpdate (args, dir, dep, has, req, depth, cb) {
function shouldUpdate (args, dir, dep, has, req, depth, cb, type) {
// look up the most recent version.
// if that's what we already have, or if it's not on the args list,
// then dive into it. Otherwise, cb() with the data.
@@ -260,15 +294,17 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
}

function doIt (wanted, latest) {
cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req ]])
}

if (args.length && args.indexOf(dep) === -1) {
return skip()
if (!long) {
return cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req]])
}
cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req, type]])
}

if (npa(req).type === "git")
if (args.length && args.indexOf(dep) === -1) return skip()
var parsed = npa(req)
if (parsed.type === "git" || (parsed.hosted && parsed.hosted.type === "github")) {
return doIt("git", "git")
}

// search for the latest package
mapToRegistry(dep, npm.config, function (er, uri, auth) {
@@ -318,10 +354,12 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {

if (!curr || dFromUrl && cFromUrl && d._from !== curr.from
|| d.version !== curr.version
|| d.version !== l.version)
|| d.version !== l.version) {
doIt(d.version, l.version)
else
}
else {
skip()
}
}
}
}
@@ -6,8 +6,8 @@ owner.usage = "npm owner add <username> <pkg>"

var npm = require("./npm.js")
, log = require("npmlog")
, readJson = require("read-package-json")
, mapToRegistry = require("./utils/map-to-registry.js")
, readLocalPkg = require("./utils/read-local-package.js")

owner.completion = function (opts, cb) {
var argv = opts.conf.argv.remain
@@ -26,12 +26,9 @@ owner.completion = function (opts, cb) {
var byUser, theUser
switch (argv[2]) {
case "ls":
if (argv.length > 3) return cb()
return mapToRegistry("-/short", npm.config, function (er, uri, auth) {
if (er) return cb(er)

npm.registry.get(uri, { auth : auth }, cb)
})
// FIXME: there used to be registry completion here, but it stopped
// making sense somewhere around 50,000 packages on the registry
return cb()

case "rm":
if (argv.length > 3) {
@@ -252,14 +249,6 @@ function mutate (pkg, user, mutation, cb) {
}
}

function readLocalPkg (cb) {
if (npm.config.get("global")) return cb()
var path = require("path")
readJson(path.resolve(npm.prefix, "package.json"), function (er, d) {
return cb(er, d && d.name)
})
}

function unknown (action, cb) {
cb("Usage: \n" + owner.usage)
}
@@ -12,10 +12,13 @@ var npm = require("./npm.js")
, mapToRegistry = require("./utils/map-to-registry.js")
, cachedPackageRoot = require("./cache/cached-package-root.js")
, createReadStream = require("graceful-fs").createReadStream
, npa = require("npm-package-arg")
, semver = require('semver')

publish.usage = "npm publish <tarball>"
+ "\nnpm publish <folder>"
publish.usage = "npm publish <tarball> [--tag <tagname>]"
+ "\nnpm publish <folder> [--tag <tagname>]"
+ "\n\nPublishes '.' if no argument supplied"
+ "\n\nSets tag `latest` if no --tag specified"

publish.completion = function (opts, cb) {
// publish can complete to a folder with a package.json
@@ -33,6 +36,13 @@ function publish (args, isRetry, cb) {
if (args.length !== 1) return cb(publish.usage)

log.verbose("publish", args)

var t = npm.config.get('tag').trim()
if (semver.validRange(t)) {
var er = new Error("Tag name must not be a valid SemVer range: " + t)
return cb(er)
}

var arg = args[0]
// if it's a local folder, then run the prepublish there, first.
readJson(path.resolve(arg, "package.json"), function (er, data) {
@@ -121,6 +131,16 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
auth : auth
}

// registry-frontdoor cares about the access level, which is only
// configurable for scoped packages
if (config.get("access")) {
if (!npa(data.name).scope && config.get("access") === "restricted") {
return cb(new Error("Can't restrict access to unscoped packages."))
}

params.access = config.get("access")
}

registry.publish(registryBase, params, function (er) {
if (er && er.code === "EPUBLISHCONFLICT" &&
npm.config.get("force") && !isRetry) {
@@ -15,14 +15,9 @@ var npm = require("./npm.js")
, npa = require("npm-package-arg")

repo.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
mapToRegistry("/-/short", npm.config, function (er, uri) {
if (er) return cb(er)

npm.registry.get(uri, { timeout : 60000 }, function (er, list) {
return cb(null, list || [])
})
})
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}

function repo (args, cb) {
@@ -84,39 +84,64 @@ function runScript (args, cb) {

function list(cb) {
var json = path.join(npm.localPrefix, "package.json")
var cmdList = [ "publish", "install", "uninstall"
, "test", "stop", "start", "restart"
].reduce(function (l, p) {
return l.concat(["pre" + p, p, "post" + p])
}, [])
return readJson(json, function(er, d) {
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) d = {}
var scripts = Object.keys(d.scripts || {})
var allScripts = Object.keys(d.scripts || {})
var scripts = []
var runScripts = []
allScripts.forEach(function (script) {
if (cmdList.indexOf(script) !== -1) scripts.push(script)
else runScripts.push(script)
})

if (log.level === "silent") {
return cb(null, scripts)
return cb(null, allScripts)
}

if (npm.config.get("json")) {
console.log(JSON.stringify(d.scripts || {}, null, 2))
return cb(null, scripts)
return cb(null, allScripts)
}

if (npm.config.get("parseable")) {
allScripts.forEach(function(script) {
console.log(script + ":" + d.scripts[script])
})
return cb(null, allScripts)
}

var s = ":"
var prefix = ""
if (!npm.config.get("parseable")) {
s = "\n "
prefix = " "
console.log("Available scripts in the %s package:", d.name)
var s = "\n "
var prefix = " "
if (scripts.length) {
console.log("Lifecycle scripts included in %s:", d.name)
}
scripts.forEach(function(script) {
console.log(prefix + script + s + d.scripts[script])
})
return cb(null, scripts)
if (!scripts.length && runScripts.length) {
console.log("Scripts available in %s via `npm run-script`:", d.name)
}
else if (runScripts.length) {
console.log("\navailable via `npm run-script`:")
}
runScripts.forEach(function(script) {
console.log(prefix + script + s + d.scripts[script])
})
return cb(null, allScripts)
})
}

function run (pkg, wd, cmd, args, cb) {
if (!pkg.scripts) pkg.scripts = {}

var cmds
if (cmd === "restart") {
if (cmd === "restart" && !pkg.scripts.restart) {
cmds = [
"prestop", "stop", "poststop",
"restart",
@@ -134,6 +159,8 @@ function run (pkg, wd, cmd, args, cb) {
log.verbose("run-script using default platform env: env (Unix)")
pkg.scripts[cmd] = "env"
}
} else if (npm.config.get("if-present")) {
return cb(null);
} else {
return cb(new Error("missing script: " + cmd))
}
@@ -162,8 +189,7 @@ function run (pkg, wd, cmd, args, cb) {
function joinArgs (args) {
var joinedArgs = ""
args.forEach(function(arg) {
if (arg.match(/[ '"]/)) arg = '"' + arg.replace(/"/g, '\\"') + '"'
joinedArgs += " " + arg
joinedArgs += ' "' + arg.replace(/"/g, '\\"') + '"'
})
return joinedArgs
}
@@ -3,7 +3,6 @@ module.exports = exports = search

var npm = require("./npm.js")
, columnify = require("columnify")
, mapToRegistry = require("./utils/map-to-registry.js")
, updateIndex = require("./cache/update-index.js")

search.usage = "npm search [some search terms ...]"
@@ -35,19 +34,24 @@ function search (args, silent, staleness, cb) {
if (typeof cb !== "function") cb = silent, silent = false

var searchopts = npm.config.get("searchopts")
, searchexclude = npm.config.get("searchexclude")
var searchexclude = npm.config.get("searchexclude")

if (typeof searchopts !== "string") searchopts = ""
searchopts = searchopts.split(/\s+/)
if (typeof searchexclude === "string") {
searchexclude = searchexclude.split(/\s+/)
} else searchexclude = []
var opts = searchopts.concat(args).map(function (s) {
return s.toLowerCase()
}).filter(function (s) { return s })

if (typeof searchexclude === "string") {
searchexclude = searchexclude.split(/\s+/)
} else {
searchexclude = []
}
searchexclude = searchexclude.map(function (s) {
return s.toLowerCase()
})
getFilteredData( staleness, opts, searchexclude, function (er, data) {

getFilteredData(staleness, opts, searchexclude, function (er, data) {
// now data is the list of data that we want to show.
// prettify and print it, and then provide the raw
// data to the cb.
@@ -58,19 +62,9 @@ function search (args, silent, staleness, cb) {
}

function getFilteredData (staleness, args, notArgs, cb) {
mapToRegistry("-/all", npm.config, function (er, uri, auth) {
updateIndex(staleness, function (er, data) {
if (er) return cb(er)

var params = {
timeout : staleness,
follow : true,
staleOk : true,
auth : auth
}
updateIndex(uri, params, function (er, data) {
if (er) return cb(er)
return cb(null, filter(data, args, notArgs))
})
return cb(null, filter(data, args, notArgs))
})
}

@@ -20,6 +20,12 @@ function shrinkwrap (args, silent, cb) {
log.warn("shrinkwrap", "doesn't take positional args")
}

// https://github.com/npm/npm/issues/7641
// introduced because `npm ls` can now show dev and prod depenednecy
// trees separately
if (npm.config.get("dev")) {
npm.config.set("production", true)
}
npm.commands.ls([], true, function (er, _, pkginfo) {
if (er) return cb(er)
shrinkwrap_(pkginfo, silent, npm.config.get("dev"), cb)
@@ -45,7 +51,7 @@ function shrinkwrap_ (pkginfo, silent, dev, cb) {
return
}

log.warn("shrinkwrap", "Excluding devDependency: %s", dep)
log.warn("shrinkwrap", "Excluding devDependency: %s", dep, data.dependencies)
delete pkginfo.dependencies[dep]
})
}
@@ -10,17 +10,9 @@ star.usage = "npm star <package> [pkg, pkg, ...]\n"
+ "npm unstar <package> [pkg, pkg, ...]"

star.completion = function (opts, cb) {
mapToRegistry("-/short", npm.config, function (er, uri, auth) {
if (er) return cb(er)

var params = {
timeout : 60000,
auth : auth
}
npm.registry.get(uri, params, function (er, list) {
return cb(null, list || [])
})
})
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}

function star (args, cb) {
@@ -9,6 +9,17 @@ var npm = require("./npm.js")
function stars (args, cb) {
npm.commands.whoami([], true, function (er, username) {
var name = args.length === 1 ? args[0] : username

if (er) {
if (er.code === 'ENEEDAUTH' && !name) {
var needAuth = new Error("'npm stars' on your own user account requires auth")
needAuth.code = 'ENEEDAUTH'
return cb(needAuth)
}

if (er.code !== 'ENEEDAUTH') return cb(er)
}

mapToRegistry("", npm.config, function (er, uri, auth) {
if (er) return cb(er)

@@ -9,6 +9,7 @@ var npm = require("./npm.js")
, mapToRegistry = require("./utils/map-to-registry.js")
, npa = require("npm-package-arg")
, semver = require("semver")
, log = require("npmlog")

function tag (args, cb) {
var thing = npa(args.shift() || "")
@@ -25,6 +26,8 @@ function tag (args, cb) {
return cb(er)
}

log.warn("tag", "This command is deprecated. Use `npm dist-tag` instead.")

mapToRegistry(project, npm.config, function (er, uri, auth) {
if (er) return cb(er)

@@ -5,6 +5,7 @@ var readJson = require("read-package-json")
, gentlyRm = require("./utils/gently-rm.js")
, npm = require("./npm.js")
, path = require("path")
, isInside = require("path-is-inside")
, lifecycle = require("./utils/lifecycle.js")
, asyncMap = require("slide").asyncMap
, chain = require("slide").chain
@@ -23,12 +24,12 @@ function unbuild_ (silent) { return function (folder, cb_) {
cb_(er, path.relative(npm.root, folder))
}
folder = path.resolve(folder)
var base = isInside(folder, npm.prefix) ? npm.prefix : folder
delete build._didBuild[folder]
log.verbose("unbuild", folder.substr(npm.prefix.length + 1))
readJson(path.resolve(folder, "package.json"), function (er, pkg) {
// if no json, then just trash it, but no scripts or whatever.
if (er) return gentlyRm(folder, false, npm.prefix, cb)
readJson.cache.del(folder)
if (er) return gentlyRm(folder, false, base, cb)
chain
( [ [lifecycle, pkg, "preuninstall", folder, false, true]
, [lifecycle, pkg, "uninstall", folder, false, true]
@@ -38,7 +39,7 @@ function unbuild_ (silent) { return function (folder, cb_) {
}
, [rmStuff, pkg, folder]
, [lifecycle, pkg, "postuninstall", folder, false, true]
, [gentlyRm, folder, false, npm.prefix] ]
, [gentlyRm, folder, false, base] ]
, cb )
})
}}
@@ -51,8 +52,6 @@ function rmStuff (pkg, folder, cb) {
, gnm = npm.dir
, top = gnm === parent

readJson.cache.del(path.resolve(folder, "package.json"))

log.verbose("unbuild rmStuff", pkg._id, "from", gnm)
if (!top) log.verbose("unbuild rmStuff", "in", parent)
asyncMap([rmBins, rmMans], function (fn, cb) {
@@ -28,12 +28,11 @@ function uninstall (args, cb) {
if (args.length) return uninstall_(args, nm, cb)

// remove this package from the global space, if it's installed there
if (npm.config.get("global")) return cb(uninstall.usage)
readJson(path.resolve(npm.prefix, "package.json"), function (er, pkg) {
readJson(path.resolve(npm.localPrefix, "package.json"), function (er, pkg) {
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er) return cb(uninstall.usage)
uninstall_( [pkg.name]
, npm.dir
, npm.globalDir
, cb )
})

@@ -22,10 +22,26 @@ update.completion = npm.commands.outdated.completion

function update (args, cb) {
npm.commands.outdated(args, true, function (er, outdated) {
log.info("outdated", "updating", outdated)
if (er) return cb(er)

asyncMap(outdated, function (ww, cb) {
var wanted = outdated.filter(function (ww) {
var dep = ww[1]
var current = ww[2]
var wanted = ww[3]
var latest = ww[4]
if (current === wanted && wanted !== latest) {
log.verbose(
'outdated',
'not updating', dep,
"because it's currently at the maximum version that matches its specified semver range"
)
}
return current !== wanted
})
if (wanted.length === 0) return cb()

log.info('outdated', 'updating', wanted)
asyncMap(wanted, function (ww, cb) {
// [[ dir, dep, has, want, req ]]
var where = ww[0]
, dep = ww[1]
@@ -21,10 +21,10 @@ if type complete &>/dev/null; then
2>/dev/null)) || return $?
IFS="$si"
}
complete -F _npm_completion npm
complete -o default -F _npm_completion npm
elif type compdef &>/dev/null; then
_npm_completion() {
si=$IFS
local si=$IFS
compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
@@ -287,6 +287,7 @@ function errorHandler (er) {
case "ECONNRESET":
case "ENOTFOUND":
case "ETIMEDOUT":
case "EAI_FAIL":
log.error("network", [er.message
,"This is most likely not a problem with npm itself"
,"and is related to network connectivity."
@@ -304,11 +305,15 @@ function errorHandler (er) {
break

case "ETARGET":
log.error("notarget", [er.message
var msg = [er.message
,"This is most likely not a problem with npm itself."
,"In most cases you or one of your dependencies are requesting"
,"a package version that doesn't exist."
].join("\n"))
]
if (er.parent) {
msg.push("\nIt was specified as a dependency of '"+er.parent+"'\n")
}
log.error("notarget", msg.join("\n"))
break

case "ENOTSUP":
@@ -350,7 +355,7 @@ function errorHandler (er) {
default:
log.error("", er.message || er)
log.error("", ["", "If you need help, you may report this error at:"
," <http://github.com/npm/npm/issues>"
," <https://github.com/npm/npm/issues>"
].join("\n"))
break
}