diff options
author | isaacs <i@izs.me> | 2012-02-24 18:52:17 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-02-24 18:52:17 -0800 |
commit | ca0986fbd1a8ade47f3160853a257b6ae83a2151 (patch) | |
tree | 7a86f9b6ff5b046d800fab15d51d220b2b3b476e | |
parent | e004721b482198fb9558f920f8101b27fb0bcb7c (diff) | |
download | node-new-ca0986fbd1a8ade47f3160853a257b6ae83a2151.tar.gz |
Update npm to 1.1.2
133 files changed, 1862 insertions, 509 deletions
diff --git a/deps/npm/AUTHORS b/deps/npm/AUTHORS index 42263ec8df..b1b915af67 100644 --- a/deps/npm/AUTHORS +++ b/deps/npm/AUTHORS @@ -52,3 +52,5 @@ Gautham Pai <buzypi@gmail.com> David Trejo <david.daniel.trejo@gmail.com> Paul Vorbach <paul@vorb.de> George Ornbo <george@shapeshed.com> +Tim Oxley <secoif@gmail.com> +Tyler Green <tyler.green2@gmail.com> diff --git a/deps/npm/bin/npm-cli.js b/deps/npm/bin/npm-cli.js index e0b9f20bb8..f29437093e 100755 --- a/deps/npm/bin/npm-cli.js +++ b/deps/npm/bin/npm-cli.js @@ -49,6 +49,13 @@ if (conf.version) { return } +if (conf.versions) { + var v = process.versions + v.npm = npm.version + console.log(v) + return +} + log.info("npm@"+npm.version, "using") log.info("node@"+process.version, "using") diff --git a/deps/npm/bin/npm.cmd b/deps/npm/bin/npm.cmd index bac9e5f1c4..7720e20529 100644 --- a/deps/npm/bin/npm.cmd +++ b/deps/npm/bin/npm.cmd @@ -1,6 +1,6 @@ :: Created by npm, please don't edit manually.
-@IF EXIST "%~dp0"\"node.exe" (
- "%~dp0"\"node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
+@IF EXIST "%~dp0\node.exe" (
+ "%~dp0\node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
) ELSE (
- node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
-)
\ No newline at end of file + node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
+)
diff --git a/deps/npm/doc/api/ls.md b/deps/npm/doc/api/ls.md index a6c0a13821..ed890ff146 100644 --- a/deps/npm/doc/api/ls.md +++ b/deps/npm/doc/api/ls.md @@ -21,6 +21,12 @@ It will print out extraneous, missing, and invalid packages. If the silent parameter is set to true, nothing will be output to the screen, but the data will still be returned. +Callback is provided an error if one occurred, the full data about which +packages are installed and which dependencies they will receive, and a +"lite" data object which just shows which versions are installed where. +Note that the full data object is a circular structure, so care must be +taken if it is serialized to JSON. + ## CONFIGURATION ### long diff --git a/deps/npm/doc/api/shrinkwrap.md b/deps/npm/doc/api/shrinkwrap.md new file mode 100644 index 0000000000..6584d6a0da --- /dev/null +++ b/deps/npm/doc/api/shrinkwrap.md @@ -0,0 +1,20 @@ +npm-shrinkwrap(3) -- programmatically generate package shrinkwrap file +==================================================== + +## SYNOPSIS + + npm.commands.shrinkwrap(args, [silent,] callback) + +## DESCRIPTION + +This acts much the same ways as shrinkwrapping on the command-line. + +This command does not take any arguments, but 'args' must be defined. +Beyond that, if any arguments are passed in, npm will politely warn that it +does not take positional arguments. + +If the 'silent' parameter is set to true, nothing will be output to the screen, +but the shrinkwrap file will still be written. + +Finally, 'callback' is a function that will be called when the shrinkwrap has +been saved. diff --git a/deps/npm/doc/cli/config.md b/deps/npm/doc/cli/config.md index 9b3da04c65..9d90f4024e 100644 --- a/deps/npm/doc/cli/config.md +++ b/deps/npm/doc/cli/config.md @@ -372,6 +372,17 @@ The value `npm init` should use by default for the package author's email. The value `npm init` should use by default for the package author's homepage. +### json + +* Default: false +* Type: Boolean + +Whether or not to output JSON data, rather than the normal output. + +This feature is currently experimental, and the output data structures +for many commands is either not implemented in JSON yet, or subject to +change. Only the output from `npm ls --json` is currently valid. + ### link * Default: false @@ -682,6 +693,16 @@ If true, output the npm version and exit successfully. Only relevant when specified explicitly on the command line. +### versions + +* Default: false +* Type: boolean + +If true, output the npm version as well as node's `process.versions` +hash, and exit successfully. + +Only relevant when specified explicitly on the command line. + ### viewer * Default: "man" on Posix, "browser" on Windows diff --git a/deps/npm/doc/cli/index.md b/deps/npm/doc/cli/index.md index 5a9b99be19..ee88f3d8f3 100644 --- a/deps/npm/doc/cli/index.md +++ b/deps/npm/doc/cli/index.md @@ -170,6 +170,10 @@ npm-index(1) -- Index of all npm documentation The semantic versioner for npm +## npm-shrinkwrap(1) + + Lock down dependency versions + ## npm-star(1) Mark your favorite packages @@ -323,6 +327,10 @@ npm-index(1) -- Index of all npm documentation Search for packages +## npm-shrinkwrap(3) + + programmatically generate package shrinkwrap file + ## npm-start(3) Start a package diff --git a/deps/npm/doc/cli/install.md b/deps/npm/doc/cli/install.md index 22eb8234e7..903844a413 100644 --- a/deps/npm/doc/cli/install.md +++ b/deps/npm/doc/cli/install.md @@ -14,7 +14,9 @@ npm-install(1) -- Install a package ## DESCRIPTION -This command installs a package, and any packages that it depends on. +This command installs a package, and any packages that it depends on. If the +package has a shrinkwrap file, the installation of dependencies will be driven +by that. See npm-shrinkwrap(1). A `package` is: @@ -199,3 +201,4 @@ affects a real use-case, it will be investigated. * npm-folders(1) * npm-tag(1) * npm-rm(1) +* npm-shrinkwrap(1) diff --git a/deps/npm/doc/cli/list.md b/deps/npm/doc/cli/list.md index 596349a815..93d86cd838 100644 --- a/deps/npm/doc/cli/list.md +++ b/deps/npm/doc/cli/list.md @@ -22,6 +22,13 @@ When run as `ll` or `la`, it shows extended information by default. ## CONFIGURATION +### json + +* Default: false +* Type: Boolean + +Show information in JSON format. + ### long * Default: false diff --git a/deps/npm/doc/cli/shrinkwrap.md b/deps/npm/doc/cli/shrinkwrap.md new file mode 100644 index 0000000000..3b60b13f7f --- /dev/null +++ b/deps/npm/doc/cli/shrinkwrap.md @@ -0,0 +1,171 @@ +npm-shrinkwrap(1) -- Lock down dependency versions +===================================================== + +## SYNOPSIS + + npm shrinkwrap + +## DESCRIPTION + +This command locks down the versions of a package's dependencies so that you can +control exactly which versions of each dependency will be used when your package +is installed. + +By default, "npm install" recursively installs the target's dependencies (as +specified in package.json), choosing the latest available version that satisfies +the dependency's semver pattern. In some situations, particularly when shipping +software where each change is tightly managed, it's desirable to fully specify +each version of each dependency recursively so that subsequent builds and +deploys do not inadvertently pick up newer versions of a dependency that satisfy +the semver pattern. Specifying specific semver patterns in each dependency's +package.json would facilitate this, but that's not always possible or desirable, +as when another author owns the npm package. It's also possible to check +dependencies directly into source control, but that may be undesirable for other +reasons. + +As an example, consider package A: + + { + "name": "A", + "version": "0.1.0", + "dependencies": { + "B": "<0.1.0" + } + } + +package B: + + { + "name": "B", + "version": "0.0.1", + "dependencies": { + "C": "<0.1.0" + } + } + +and package C: + + { + "name": "C, + "version": "0.0.1" + } + +If these are the only versions of A, B, and C available in the registry, then +a normal "npm install A" will install: + + A@0.1.0 + `-- B@0.0.1 + `-- C@0.0.1 + +However, if B@0.0.2 is published, then a fresh "npm install A" will install: + + A@0.1.0 + `-- B@0.0.2 + `-- C@0.0.1 + +assuming the new version did not modify B's dependencies. Of course, the new +version of B could include a new version of C and any number of new +dependencies. If such changes are undesirable, the author of A could specify a +dependency on B@0.0.1. However, if A's author and B's author are not the same +person, there's no way for A's author to say that he or she does not want to +pull in newly published versions of C when B hasn't changed at all. + +In this case, A's author can run + + npm shrinkwrap + +This generates npm-shrinkwrap.json, which will look something like this: + + { + "name": "A", + "version": "0.1.0", + "dependencies": { + "B": { + "version": "0.0.1", + "dependencies": { + "C": { + "version": "0.1.0" + } + } + } + } + } + +The shrinkwrap command has locked down the dependencies based on what's +currently installed in node_modules. When "npm install" installs a package with +a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than +package.json files) completely drives the installation of that package and all +of its dependencies (recursively). So now the author publishes A@0.1.0, and +subsequent installs of this package will use B@0.0.1 and C@0.1.0, regardless the +dependencies and versions listed in A's, B's, and C's package.json files. + + +### Using shrinkwrapped packages + +Using a shrinkwrapped package is no different than using any other package: you +can "npm install" it by hand, or add a dependency to your package.json file and +"npm install" it. + +### Building shrinkwrapped packages + +To shrinkwrap an existing package: + +1. Run "npm install" in the package root to install the current versions of all + dependencies. +2. Validate that the package works as expected with these versions. +3. Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish your + package. + +To add or update a dependency in a shrinkwrapped package: + +1. Run "npm install" in the package root to install the current versions of all + dependencies. +2. Add or update dependencies. "npm install" each new or updated package + individually and then update package.json. Note that they must be + explicitly named in order to be installed: running `npm install` with + no arguments will merely reproduce the existing shrinkwrap. +3. Validate that the package works as expected with the new dependencies. +4. Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and publish your + package. + +You can use npm-outdated(1) to view dependencies with newer versions available. + +### Other Notes + +Since "npm shrinkwrap" uses the locally installed packages to construct the +shrinkwrap file, devDependencies will be included if and only if you've +installed them already when you make the shrinkwrap. + +A shrinkwrap file must be consistent with the package's package.json file. "npm +shrinkwrap" will fail if required dependencies are not already installed, since +that would result in a shrinkwrap that wouldn't actually work. Similarly, the +command will fail if there are extraneous packages (not referenced by +package.json), since that would indicate that package.json is not correct. + +If shrinkwrapped package A depends on shrinkwrapped package B, B's shrinkwrap +will not be used as part of the installation of A. However, because A's +shrinkwrap is constructed from a valid installation of B and recursively +specifies all dependencies, the contents of B's shrinkwrap will implicitly be +included in A's shrinkwrap. + +### Caveats + +Shrinkwrap files only lock down package versions, not actual package contents. +While discouraged, a package author can republish an existing version of a +package, causing shrinkwrapped packages using that version to pick up different +code than they were before. If you want to avoid any risk that a byzantine +author replaces a package you're using with code that breaks your application, +you could modify the shrinkwrap file to use git URL references rather than +version numbers so that npm always fetches all packages from git. + +If you wish to lock down the specific bytes included in a package, for +example to have 100% confidence in being able to reproduce a deployment +or build, then you ought to check your dependencies into source control, +or pursue some other mechanism that can verify contents rather than +versions. + +## SEE ALSO + +* npm-install(1) +* npm-json(1) +* npm-list(1) diff --git a/deps/npm/html/api/bin.html b/deps/npm/html/api/bin.html index 53a93ac7b9..f532874a08 100644 --- a/deps/npm/html/api/bin.html +++ b/deps/npm/html/api/bin.html @@ -19,7 +19,7 @@ <p>This function should not be used programmatically. Instead, just refer to the <code>npm.bin</code> member.</p> </div> -<p id="footer">bin — npm@1.1.1</p> +<p id="footer">bin — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/bugs.html b/deps/npm/html/api/bugs.html index d090d16229..75479a4d8c 100644 --- a/deps/npm/html/api/bugs.html +++ b/deps/npm/html/api/bugs.html @@ -25,7 +25,7 @@ optional version number.</p> <p>This command will launch a browser, so this command may not be the most friendly for programmatic use.</p> </div> -<p id="footer">bugs — npm@1.1.1</p> +<p id="footer">bugs — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/commands.html b/deps/npm/html/api/commands.html index 1e895fe4e0..26febd8a15 100644 --- a/deps/npm/html/api/commands.html +++ b/deps/npm/html/api/commands.html @@ -28,7 +28,7 @@ usage, or <code>man 3 npm-<command></code> for programmatic usage.</p> <ul><li><a href="../doc/index.html">index(1)</a></li></ul> </div> -<p id="footer">commands — npm@1.1.1</p> +<p id="footer">commands — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/config.html b/deps/npm/html/api/config.html index 12cd0fb38b..df58adec27 100644 --- a/deps/npm/html/api/config.html +++ b/deps/npm/html/api/config.html @@ -33,7 +33,7 @@ functions instead.</p> <ul><li><a href="../api/npm.html">npm(3)</a></li></ul> </div> -<p id="footer">config — npm@1.1.1</p> +<p id="footer">config — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/deprecate.html b/deps/npm/html/api/deprecate.html index 36a7955d6b..ea1298af54 100644 --- a/deps/npm/html/api/deprecate.html +++ b/deps/npm/html/api/deprecate.html @@ -30,7 +30,7 @@ install the package.</p></li></ul> <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../api/unpublish.html">unpublish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul> </div> -<p id="footer">deprecate — npm@1.1.1</p> +<p id="footer">deprecate — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/docs.html b/deps/npm/html/api/docs.html index 59b6739bbb..14214d7bea 100644 --- a/deps/npm/html/api/docs.html +++ b/deps/npm/html/api/docs.html @@ -25,7 +25,7 @@ optional version number.</p> <p>This command will launch a browser, so this command may not be the most friendly for programmatic use.</p> </div> -<p id="footer">docs — npm@1.1.1</p> +<p id="footer">docs — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/edit.html b/deps/npm/html/api/edit.html index 594f471175..21ff933415 100644 --- a/deps/npm/html/api/edit.html +++ b/deps/npm/html/api/edit.html @@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p> <p>Since this command opens an editor in a new process, be careful about where and how this is used.</p> </div> -<p id="footer">edit — npm@1.1.1</p> +<p id="footer">edit — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/explore.html b/deps/npm/html/api/explore.html index 3fb6e73f16..8c02a51fee 100644 --- a/deps/npm/html/api/explore.html +++ b/deps/npm/html/api/explore.html @@ -24,7 +24,7 @@ sure to use <code>npm rebuild <pkg></code> if you make any changes.</p> <p>The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p> </div> -<p id="footer">explore — npm@1.1.1</p> +<p id="footer">explore — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/help-search.html b/deps/npm/html/api/help-search.html index 750ec89b14..37068ac2c3 100644 --- a/deps/npm/html/api/help-search.html +++ b/deps/npm/html/api/help-search.html @@ -32,7 +32,7 @@ Name of the file that matched</li></ul> <p>The silent parameter is not neccessary not used, but it may in the future.</p> </div> -<p id="footer">help-search — npm@1.1.1</p> +<p id="footer">help-search — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/init.html b/deps/npm/html/api/init.html index 32b6567e61..f07d214860 100644 --- a/deps/npm/html/api/init.html +++ b/deps/npm/html/api/init.html @@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p> <p><a href="../doc/json.html">json(1)</a></p> </div> -<p id="footer">init — npm@1.1.1</p> +<p id="footer">init — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/install.html b/deps/npm/html/api/install.html index 6414fbed49..bdcac428c4 100644 --- a/deps/npm/html/api/install.html +++ b/deps/npm/html/api/install.html @@ -25,7 +25,7 @@ the name of a package to be installed.</p> <p>Finally, 'callback' is a function that will be called when all packages have been installed or when an error has been encountered.</p> </div> -<p id="footer">install — npm@1.1.1</p> +<p id="footer">install — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/link.html b/deps/npm/html/api/link.html index dd093e5f42..86e377a212 100644 --- a/deps/npm/html/api/link.html +++ b/deps/npm/html/api/link.html @@ -39,7 +39,7 @@ npm.commands.link('redis', cb) # link-install the package</code></pre> <p>Now, any changes to the redis package will be reflected in the package in the current working directory</p> </div> -<p id="footer">link — npm@1.1.1</p> +<p id="footer">link — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/load.html b/deps/npm/html/api/load.html index 5fb4294320..b2a1a9d163 100644 --- a/deps/npm/html/api/load.html +++ b/deps/npm/html/api/load.html @@ -32,7 +32,7 @@ config object.</p> <p>For a list of all the available command-line configs, see <code>npm help config</code></p> </div> -<p id="footer">load — npm@1.1.1</p> +<p id="footer">load — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/ls.html b/deps/npm/html/api/ls.html index d79428c263..159d9c2283 100644 --- a/deps/npm/html/api/ls.html +++ b/deps/npm/html/api/ls.html @@ -28,6 +28,12 @@ like with any other command, such as <code>global</code> to list global packages <p>If the silent parameter is set to true, nothing will be output to the screen, but the data will still be returned.</p> +<p>Callback is provided an error if one occurred, the full data about which +packages are installed and which dependencies they will receive, and a +"lite" data object which just shows which versions are installed where. +Note that the full data object is a circular structure, so care must be +taken if it is serialized to JSON.</p> + <h2 id="CONFIGURATION">CONFIGURATION</h2> <h3 id="long">long</h3> @@ -53,7 +59,7 @@ project.</p> This means that if a submodule a same dependency as a parent module, then the dependency will only be output once.</p> </div> -<p id="footer">ls — npm@1.1.1</p> +<p id="footer">ls — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/npm.html b/deps/npm/html/api/npm.html index f21710a98f..3e923fc488 100644 --- a/deps/npm/html/api/npm.html +++ b/deps/npm/html/api/npm.html @@ -24,7 +24,7 @@ npm.load(configObject, function (er, npm) { <h2 id="VERSION">VERSION</h2> -<p>1.1.1</p> +<p>1.1.2</p> <h2 id="DESCRIPTION">DESCRIPTION</h2> @@ -91,7 +91,7 @@ method names. Use the <code>npm.deref</code> method to find the real name.</p> <pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre> </div> -<p id="footer">npm — npm@1.1.1</p> +<p id="footer">npm — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/outdated.html b/deps/npm/html/api/outdated.html index 06eea3426b..4febbeb392 100644 --- a/deps/npm/html/api/outdated.html +++ b/deps/npm/html/api/outdated.html @@ -19,7 +19,7 @@ currently outdated.</p> <p>If the 'packages' parameter is left out, npm will check all packages.</p> </div> -<p id="footer">outdated — npm@1.1.1</p> +<p id="footer">outdated — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/owner.html b/deps/npm/html/api/owner.html index 16199b9f7d..d7708b1716 100644 --- a/deps/npm/html/api/owner.html +++ b/deps/npm/html/api/owner.html @@ -34,7 +34,7 @@ that is not implemented at this time.</p> <ul><li><a href="../api/publish.html">publish(3)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul> </div> -<p id="footer">owner — npm@1.1.1</p> +<p id="footer">owner — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/pack.html b/deps/npm/html/api/pack.html index 06da5452a6..4b6b9dad84 100644 --- a/deps/npm/html/api/pack.html +++ b/deps/npm/html/api/pack.html @@ -25,7 +25,7 @@ overwritten the second time.</p> <p>If no arguments are supplied, then npm packs the current package folder.</p> </div> -<p id="footer">pack — npm@1.1.1</p> +<p id="footer">pack — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/prefix.html b/deps/npm/html/api/prefix.html index a7f2367a1b..b159e67677 100644 --- a/deps/npm/html/api/prefix.html +++ b/deps/npm/html/api/prefix.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically</p> </div> -<p id="footer">prefix — npm@1.1.1</p> +<p id="footer">prefix — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/prune.html b/deps/npm/html/api/prune.html index 4ee3074db3..09c9456bdb 100644 --- a/deps/npm/html/api/prune.html +++ b/deps/npm/html/api/prune.html @@ -23,7 +23,7 @@ <p>Extraneous packages are packages that are not listed on the parent package's dependencies list.</p> </div> -<p id="footer">prune — npm@1.1.1</p> +<p id="footer">prune — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/publish.html b/deps/npm/html/api/publish.html index 1e512bf0dc..4d57cdec5b 100644 --- a/deps/npm/html/api/publish.html +++ b/deps/npm/html/api/publish.html @@ -32,7 +32,7 @@ the registry. Overwrites when the "force" environment variable is set.</p> <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../api/owner.html">owner(3)</a></li></ul> </div> -<p id="footer">publish — npm@1.1.1</p> +<p id="footer">publish — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/rebuild.html b/deps/npm/html/api/rebuild.html index 3bef149872..5a16961981 100644 --- a/deps/npm/html/api/rebuild.html +++ b/deps/npm/html/api/rebuild.html @@ -22,7 +22,7 @@ the new binary. If no 'packages' parameter is specify, every package will be reb <p>See <code>npm help build</code></p> </div> -<p id="footer">rebuild — npm@1.1.1</p> +<p id="footer">rebuild — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/restart.html b/deps/npm/html/api/restart.html index 19c93b2f83..5baee5750c 100644 --- a/deps/npm/html/api/restart.html +++ b/deps/npm/html/api/restart.html @@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p> <ul><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul> </div> -<p id="footer">restart — npm@1.1.1</p> +<p id="footer">restart — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/root.html b/deps/npm/html/api/root.html index c8340dd812..bfad92bb02 100644 --- a/deps/npm/html/api/root.html +++ b/deps/npm/html/api/root.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically.</p> </div> -<p id="footer">root — npm@1.1.1</p> +<p id="footer">root — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/run-script.html b/deps/npm/html/api/run-script.html index 32cf0b5e71..df45596906 100644 --- a/deps/npm/html/api/run-script.html +++ b/deps/npm/html/api/run-script.html @@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p> <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../api/test.html">test(3)</a></li><li><a href="../api/start.html">start(3)</a></li><li><a href="../api/restart.html">restart(3)</a></li><li><a href="../api/stop.html">stop(3)</a></li></ul> </div> -<p id="footer">run-script — npm@1.1.1</p> +<p id="footer">run-script — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/search.html b/deps/npm/html/api/search.html index 40bd527da4..ac0cbd3937 100644 --- a/deps/npm/html/api/search.html +++ b/deps/npm/html/api/search.html @@ -32,7 +32,7 @@ excluded term (the "searchexclude" config). The search is case insensitive and doesn't try to read your mind (it doesn't do any verb tense matching or the like).</p> </div> -<p id="footer">search — npm@1.1.1</p> +<p id="footer">search — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/shrinkwrap.html b/deps/npm/html/api/shrinkwrap.html new file mode 100644 index 0000000000..1a4ef61327 --- /dev/null +++ b/deps/npm/html/api/shrinkwrap.html @@ -0,0 +1,61 @@ +<!doctype html> +<html> + <title>shrinkwrap</title> + <meta http-equiv="content-type" value="text/html;utf-8"> + <link rel="stylesheet" type="text/css" href="./style.css"> + + <body> + <div id="wrapper"> +<h1><a href="../api/shrinkwrap.html">shrinkwrap</a></h1> <p>programmatically generate package shrinkwrap file</p> + +<h2 id="SYNOPSIS">SYNOPSIS</h2> + +<pre><code>npm.commands.shrinkwrap(args, [silent,] callback)</code></pre> + +<h2 id="DESCRIPTION">DESCRIPTION</h2> + +<p>This acts much the same ways as shrinkwrapping on the command-line.</p> + +<p>This command does not take any arguments, but 'args' must be defined. +Beyond that, if any arguments are passed in, npm will politely warn that it +does not take positional arguments.</p> + +<p>If the 'silent' parameter is set to true, nothing will be output to the screen, +but the shrinkwrap file will still be written.</p> + +<p>Finally, 'callback' is a function that will be called when the shrinkwrap has +been saved.</p> +</div> +<p id="footer">shrinkwrap — npm@1.1.2</p> +<script> +;(function () { +var wrapper = document.getElementById("wrapper") +var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0) + .filter(function (el) { + return el.parentNode === wrapper + && el.tagName.match(/H[1-6]/) + && el.id + }) +var l = 2 + , toc = document.createElement("ul") +toc.innerHTML = els.map(function (el) { + var i = el.tagName.charAt(1) + , out = "" + while (i > l) { + out += "<ul>" + l ++ + } + while (i < l) { + out += "</ul>" + l -- + } + out += "<li><a href='#" + el.id + "'>" + + ( el.innerText || el.text || el.innerHTML) + + "</a>" + return out +}).join("\n") +toc.id = "toc" +document.body.appendChild(toc) +})() +</script> +</body></html> diff --git a/deps/npm/html/api/start.html b/deps/npm/html/api/start.html index 186fa29f04..6830137e9d 100644 --- a/deps/npm/html/api/start.html +++ b/deps/npm/html/api/start.html @@ -19,7 +19,7 @@ <p>npm can run tests on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">start — npm@1.1.1</p> +<p id="footer">start — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/stop.html b/deps/npm/html/api/stop.html index e1fa932744..d6ddfa9be9 100644 --- a/deps/npm/html/api/stop.html +++ b/deps/npm/html/api/stop.html @@ -19,7 +19,7 @@ <p>npm can run stop on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">stop — npm@1.1.1</p> +<p id="footer">stop — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/submodule.html b/deps/npm/html/api/submodule.html index 11e1b9fa2f..401514d92d 100644 --- a/deps/npm/html/api/submodule.html +++ b/deps/npm/html/api/submodule.html @@ -33,7 +33,7 @@ dependencies into the submodule folder.</p> <ul><li>npm help json</li><li>git help submodule</li></ul> </div> -<p id="footer">submodule — npm@1.1.1</p> +<p id="footer">submodule — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/tag.html b/deps/npm/html/api/tag.html index 1901d48b79..1c21554e2e 100644 --- a/deps/npm/html/api/tag.html +++ b/deps/npm/html/api/tag.html @@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be used. For more information about how to set this config, check <code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p> </div> -<p id="footer">tag — npm@1.1.1</p> +<p id="footer">tag — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/test.html b/deps/npm/html/api/test.html index 925febe402..51bd2647e3 100644 --- a/deps/npm/html/api/test.html +++ b/deps/npm/html/api/test.html @@ -22,7 +22,7 @@ true.</p> <p>npm can run tests on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">test — npm@1.1.1</p> +<p id="footer">test — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/uninstall.html b/deps/npm/html/api/uninstall.html index 1f2e3a1c1d..98dc686111 100644 --- a/deps/npm/html/api/uninstall.html +++ b/deps/npm/html/api/uninstall.html @@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p> <p>Finally, 'callback' is a function that will be called when all packages have been uninstalled or when an error has been encountered.</p> </div> -<p id="footer">uninstall — npm@1.1.1</p> +<p id="footer">uninstall — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/unpublish.html b/deps/npm/html/api/unpublish.html index d027eee271..2179840ead 100644 --- a/deps/npm/html/api/unpublish.html +++ b/deps/npm/html/api/unpublish.html @@ -26,7 +26,7 @@ is what is meant.</p> <p>If no version is specified, or if all versions are removed then the root package entry is removed from the registry entirely.</p> </div> -<p id="footer">unpublish — npm@1.1.1</p> +<p id="footer">unpublish — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/update.html b/deps/npm/html/api/update.html index 14bb8da376..6383e2a453 100644 --- a/deps/npm/html/api/update.html +++ b/deps/npm/html/api/update.html @@ -18,7 +18,7 @@ <p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p> </div> -<p id="footer">update — npm@1.1.1</p> +<p id="footer">update — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/version.html b/deps/npm/html/api/version.html index 44f4d01bcb..9a4fcae34c 100644 --- a/deps/npm/html/api/version.html +++ b/deps/npm/html/api/version.html @@ -24,7 +24,7 @@ fail if the repo is not clean.</p> parameter. The difference, however, is this function will fail if it does not have exactly one element. The only element should be a version number.</p> </div> -<p id="footer">version — npm@1.1.1</p> +<p id="footer">version — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/view.html b/deps/npm/html/api/view.html index 4975351cb1..5303658156 100644 --- a/deps/npm/html/api/view.html +++ b/deps/npm/html/api/view.html @@ -99,7 +99,7 @@ the field name.</p> <p>corresponding to the list of fields selected.</p> </div> -<p id="footer">view — npm@1.1.1</p> +<p id="footer">view — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/api/whoami.html b/deps/npm/html/api/whoami.html index a425d41fc5..b1321a0e43 100644 --- a/deps/npm/html/api/whoami.html +++ b/deps/npm/html/api/whoami.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically</p> </div> -<p id="footer">whoami — npm@1.1.1</p> +<p id="footer">whoami — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/README.html b/deps/npm/html/doc/README.html index 5138289880..3aefa2d108 100644 --- a/deps/npm/html/doc/README.html +++ b/deps/npm/html/doc/README.html @@ -267,7 +267,7 @@ will no doubt tell you to put the output in a gist or email.</p> <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul> </div> -<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.1</p> +<p id="footer"><a href="../doc/README.html">README</a> — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/adduser.html b/deps/npm/html/doc/adduser.html index 6d2cb691ba..2af866e3a5 100644 --- a/deps/npm/html/doc/adduser.html +++ b/deps/npm/html/doc/adduser.html @@ -39,7 +39,7 @@ authorize on a new machine.</p> <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li></ul> </div> -<p id="footer">adduser — npm@1.1.1</p> +<p id="footer">adduser — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/bin.html b/deps/npm/html/doc/bin.html index 3a1a17bb50..21b1a57f67 100644 --- a/deps/npm/html/doc/bin.html +++ b/deps/npm/html/doc/bin.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">bin — npm@1.1.1</p> +<p id="footer">bin — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/bugs.html b/deps/npm/html/doc/bugs.html index d0e57b2fa7..78a8b00326 100644 --- a/deps/npm/html/doc/bugs.html +++ b/deps/npm/html/doc/bugs.html @@ -36,7 +36,7 @@ config param.</p> <ul><li><a href="../doc/docs.html">docs(1)</a></li><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul> </div> -<p id="footer">bugs — npm@1.1.1</p> +<p id="footer">bugs — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/build.html b/deps/npm/html/doc/build.html index 510d0092e2..fc1df5db3d 100644 --- a/deps/npm/html/doc/build.html +++ b/deps/npm/html/doc/build.html @@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul> <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul> </div> -<p id="footer">build — npm@1.1.1</p> +<p id="footer">build — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/bundle.html b/deps/npm/html/doc/bundle.html index 3f7a758e13..744496d240 100644 --- a/deps/npm/html/doc/bundle.html +++ b/deps/npm/html/doc/bundle.html @@ -20,7 +20,7 @@ install packages into the local space.</p> <ul><li><a href="../doc/install.html">install(1)</a></li></ul> </div> -<p id="footer">bundle — npm@1.1.1</p> +<p id="footer">bundle — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cache.html b/deps/npm/html/doc/cache.html index 5ba4c5970f..da793c4689 100644 --- a/deps/npm/html/doc/cache.html +++ b/deps/npm/html/doc/cache.html @@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p> <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li></ul> </div> -<p id="footer">cache — npm@1.1.1</p> +<p id="footer">cache — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/changelog.html b/deps/npm/html/doc/changelog.html index 541bbbf59b..1ff71c16e1 100644 --- a/deps/npm/html/doc/changelog.html +++ b/deps/npm/html/doc/changelog.html @@ -34,7 +34,7 @@ <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li></ul> </div> -<p id="footer">changelog — npm@1.1.1</p> +<p id="footer">changelog — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/coding-style.html b/deps/npm/html/doc/coding-style.html index 89646e93dd..6b33e6c5e5 100644 --- a/deps/npm/html/doc/coding-style.html +++ b/deps/npm/html/doc/coding-style.html @@ -191,7 +191,7 @@ set to anything."</p> <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">coding-style — npm@1.1.1</p> +<p id="footer">coding-style — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/completion.html b/deps/npm/html/doc/completion.html index baa40da0d7..07427aef4c 100644 --- a/deps/npm/html/doc/completion.html +++ b/deps/npm/html/doc/completion.html @@ -33,7 +33,7 @@ completions based on the arguments.</p> <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">completion — npm@1.1.1</p> +<p id="footer">completion — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/config.html b/deps/npm/html/doc/config.html index f822ce0f76..301ff3c8ea 100644 --- a/deps/npm/html/doc/config.html +++ b/deps/npm/html/doc/config.html @@ -331,6 +331,16 @@ from packages when building tarballs.</p> <p>The value <code>npm init</code> should use by default for the package author's homepage.</p> +<h3 id="json">json</h3> + +<ul><li>Default: false</li><li>Type: Boolean</li></ul> + +<p>Whether or not to output JSON data, rather than the normal output.</p> + +<p>This feature is currently experimental, and the output data structures +for many commands is either not implemented in JSON yet, or subject to +change. Only the output from <code>npm ls --json</code> is currently valid.</p> + <h3 id="link">link</h3> <ul><li>Default: false</li><li>Type: Boolean</li></ul> @@ -601,6 +611,15 @@ this value. Thus, the defaults are <code>0755</code> and <code>0644</code> resp <p>Only relevant when specified explicitly on the command line.</p> +<h3 id="versions">versions</h3> + +<ul><li>Default: false</li><li>Type: boolean</li></ul> + +<p>If true, output the npm version as well as node's <code>process.versions</code> +hash, and exit successfully.</p> + +<p>Only relevant when specified explicitly on the command line.</p> + <h3 id="viewer">viewer</h3> <ul><li>Default: "man" on Posix, "browser" on Windows</li><li>Type: path</li></ul> @@ -623,7 +642,7 @@ then answer "no" to any prompt.</p> <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">config — npm@1.1.1</p> +<p id="footer">config — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/deprecate.html b/deps/npm/html/doc/deprecate.html index fd9426b85c..e0e410e1e3 100644 --- a/deps/npm/html/doc/deprecate.html +++ b/deps/npm/html/doc/deprecate.html @@ -29,7 +29,7 @@ something like this:</p> <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul> </div> -<p id="footer">deprecate — npm@1.1.1</p> +<p id="footer">deprecate — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/developers.html b/deps/npm/html/doc/developers.html index 16afb59212..406f342891 100644 --- a/deps/npm/html/doc/developers.html +++ b/deps/npm/html/doc/developers.html @@ -150,7 +150,7 @@ from a fresh checkout.</p> <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li></ul> </div> -<p id="footer">developers — npm@1.1.1</p> +<p id="footer">developers — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/disputes.html b/deps/npm/html/doc/disputes.html index ffbfb007c4..ab7ba2173c 100644 --- a/deps/npm/html/doc/disputes.html +++ b/deps/npm/html/doc/disputes.html @@ -80,7 +80,7 @@ license statement)</li><li>Illegal content.</li></ol> <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul> </div> -<p id="footer">disputes — npm@1.1.1</p> +<p id="footer">disputes — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/docs.html b/deps/npm/html/doc/docs.html index 4313781420..2a1bc68d41 100644 --- a/deps/npm/html/doc/docs.html +++ b/deps/npm/html/doc/docs.html @@ -37,7 +37,7 @@ config param.</p> <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li></ul> </div> -<p id="footer">docs — npm@1.1.1</p> +<p id="footer">docs — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/edit.html b/deps/npm/html/doc/edit.html index 9e723ddd72..7f62e2915c 100644 --- a/deps/npm/html/doc/edit.html +++ b/deps/npm/html/doc/edit.html @@ -37,7 +37,7 @@ or <code>"notepad"</code> on Windows.</li><li>Type: path</li></ul> <ul><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/explore.html">explore(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">edit — npm@1.1.1</p> +<p id="footer">edit — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/explore.html b/deps/npm/html/doc/explore.html index d95de7c2a7..1e5d24adda 100644 --- a/deps/npm/html/doc/explore.html +++ b/deps/npm/html/doc/explore.html @@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul> <ul><li><a href="../doc/submodule.html">submodule(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/edit.html">edit(1)</a></li><li><a href="../doc/rebuild.html">rebuild(1)</a></li><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul> </div> -<p id="footer">explore — npm@1.1.1</p> +<p id="footer">explore — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/faq.html b/deps/npm/html/doc/faq.html index 17442ad43b..4a8cb1aeaa 100644 --- a/deps/npm/html/doc/faq.html +++ b/deps/npm/html/doc/faq.html @@ -241,7 +241,7 @@ We'll have someone kick it or something.</p> <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul> </div> -<p id="footer">faq — npm@1.1.1</p> +<p id="footer">faq — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/folders.html b/deps/npm/html/doc/folders.html index 4967a890e7..0533ed5163 100644 --- a/deps/npm/html/doc/folders.html +++ b/deps/npm/html/doc/folders.html @@ -205,7 +205,7 @@ cannot be found elsewhere. See <code><a href="../doc/json.html">json(1)</a></co <ul><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/pack.html">pack(1)</a></li><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li></ul> </div> -<p id="footer">folders — npm@1.1.1</p> +<p id="footer">folders — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/help-search.html b/deps/npm/html/doc/help-search.html index f28ebaf345..f7504c4dc3 100644 --- a/deps/npm/html/doc/help-search.html +++ b/deps/npm/html/doc/help-search.html @@ -38,7 +38,7 @@ where the terms were found in the documentation.</p> <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/help.html">help(1)</a></li></ul> </div> -<p id="footer">help-search — npm@1.1.1</p> +<p id="footer">help-search — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/help.html b/deps/npm/html/doc/help.html index 72429e4644..7c27afa600 100644 --- a/deps/npm/html/doc/help.html +++ b/deps/npm/html/doc/help.html @@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p> <ul><li><a href="../doc/npm.html">npm(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/help-search.html">help-search(1)</a></li><li><a href="../doc/index.html">index(1)</a></li></ul> </div> -<p id="footer">help — npm@1.1.1</p> +<p id="footer">help — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/index.html b/deps/npm/html/doc/index.html index 21a6f8ad0a..e34ecde4b2 100644 --- a/deps/npm/html/doc/index.html +++ b/deps/npm/html/doc/index.html @@ -178,6 +178,10 @@ <p> The semantic versioner for npm</p> +<h2 id="npm-shrinkwrap-1"><a href="../doc/shrinkwrap.html">shrinkwrap(1)</a></h2> + +<p> Lock down dependency versions</p> + <h2 id="npm-star-1"><a href="../doc/star.html">star(1)</a></h2> <p> Mark your favorite packages</p> @@ -332,6 +336,10 @@ <p> Search for packages</p> +<h2 id="npm-shrinkwrap-3"><a href="../api/shrinkwrap.html">shrinkwrap(3)</a></h2> + +<p> programmatically generate package shrinkwrap file</p> + <h2 id="npm-start-3"><a href="../api/start.html">start(3)</a></h2> <p> Start a package</p> @@ -376,7 +384,7 @@ <p> Display npm username</p> </div> -<p id="footer">index — npm@1.1.1</p> +<p id="footer">index — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/init.html b/deps/npm/html/doc/init.html index 7ecabfba75..c483eedf03 100644 --- a/deps/npm/html/doc/init.html +++ b/deps/npm/html/doc/init.html @@ -29,7 +29,7 @@ without a really good reason to do so.</p> <ul><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.1</p> +<p id="footer">init — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/install.html b/deps/npm/html/doc/install.html index fe833e368c..7521efb563 100644 --- a/deps/npm/html/doc/install.html +++ b/deps/npm/html/doc/install.html @@ -21,7 +21,9 @@ npm install <name>@<version range></code></pre> <h2 id="DESCRIPTION">DESCRIPTION</h2> -<p>This command installs a package, and any packages that it depends on.</p> +<p>This command installs a package, and any packages that it depends on. If the +package has a shrinkwrap file, the installation of dependencies will be driven +by that. See <a href="../doc/shrinkwrap.html">shrinkwrap(1)</a>.</p> <p>A <code>package</code> is:</p> @@ -132,9 +134,9 @@ affects a real use-case, it will be investigated.</p> <h2 id="SEE-ALSO">SEE ALSO</h2> -<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></ul> +<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.1</p> +<p id="footer">install — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/json.html b/deps/npm/html/doc/json.html index e428654f4b..26fbaf86e0 100644 --- a/deps/npm/html/doc/json.html +++ b/deps/npm/html/doc/json.html @@ -436,7 +436,7 @@ overridden.</p> <ul><li><a href="../doc/semver.html">semver(1)</a></li><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/version.html">version(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/rm.html">rm(1)</a></li></ul> </div> -<p id="footer">json — npm@1.1.1</p> +<p id="footer">json — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/link.html b/deps/npm/html/doc/link.html index 5b4ca3c0ef..618b7e18bc 100644 --- a/deps/npm/html/doc/link.html +++ b/deps/npm/html/doc/link.html @@ -58,7 +58,7 @@ installation target into your project's <code>node_modules</code> folder.</p> <ul><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">link — npm@1.1.1</p> +<p id="footer">link — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/list.html b/deps/npm/html/doc/list.html index 56e3bbf0a7..98eb8ec1df 100644 --- a/deps/npm/html/doc/list.html +++ b/deps/npm/html/doc/list.html @@ -29,6 +29,12 @@ like with any other command, such as <code>-g</code> to list global packages.</p <h2 id="CONFIGURATION">CONFIGURATION</h2> +<h3 id="json">json</h3> + +<ul><li>Default: false</li><li>Type: Boolean</li></ul> + +<p>Show information in JSON format.</p> + <h3 id="long">long</h3> <ul><li>Default: false</li><li>Type: Boolean</li></ul> @@ -52,7 +58,7 @@ project.</p> <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/link.html">link(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/update.html">update(1)</a></li></ul> </div> -<p id="footer">list — npm@1.1.1</p> +<p id="footer">list — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/npm.html b/deps/npm/html/doc/npm.html index b2b1b888e0..8fb1d5e68e 100644 --- a/deps/npm/html/doc/npm.html +++ b/deps/npm/html/doc/npm.html @@ -14,7 +14,7 @@ <h2 id="VERSION">VERSION</h2> -<p>1.1.1</p> +<p>1.1.2</p> <h2 id="DESCRIPTION">DESCRIPTION</h2> @@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p> <ul><li><a href="../doc/help.html">help(1)</a></li><li><a href="../doc/faq.html">faq(1)</a></li><li><a href="../doc/README.html">README</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/index.html">index(1)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul> </div> -<p id="footer">npm — npm@1.1.1</p> +<p id="footer">npm — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/outdated.html b/deps/npm/html/doc/outdated.html index 3cca6b96b5..7cfd6c5299 100644 --- a/deps/npm/html/doc/outdated.html +++ b/deps/npm/html/doc/outdated.html @@ -21,7 +21,7 @@ packages are currently outdated.</p> <ul><li><a href="../doc/update.html">update(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li></ul> </div> -<p id="footer">outdated — npm@1.1.1</p> +<p id="footer">outdated — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/owner.html b/deps/npm/html/doc/owner.html index 4a2875fc0d..de4d40501b 100644 --- a/deps/npm/html/doc/owner.html +++ b/deps/npm/html/doc/owner.html @@ -34,7 +34,7 @@ that is not implemented at this time.</p> <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul> </div> -<p id="footer">owner — npm@1.1.1</p> +<p id="footer">owner — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/pack.html b/deps/npm/html/doc/pack.html index 7f41e048d2..9d86e1c035 100644 --- a/deps/npm/html/doc/pack.html +++ b/deps/npm/html/doc/pack.html @@ -29,7 +29,7 @@ overwritten the second time.</p> <ul><li><a href="../doc/cache.html">cache(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">pack — npm@1.1.1</p> +<p id="footer">pack — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/prefix.html b/deps/npm/html/doc/prefix.html index ec0504d24a..823bdc132e 100644 --- a/deps/npm/html/doc/prefix.html +++ b/deps/npm/html/doc/prefix.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/root.html">root(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">prefix — npm@1.1.1</p> +<p id="footer">prefix — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/prune.html b/deps/npm/html/doc/prune.html index 2567cda7e4..666e875414 100644 --- a/deps/npm/html/doc/prune.html +++ b/deps/npm/html/doc/prune.html @@ -25,7 +25,7 @@ package's dependencies list.</p> <ul><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul> </div> -<p id="footer">prune — npm@1.1.1</p> +<p id="footer">prune — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/publish.html b/deps/npm/html/doc/publish.html index a7666b703a..4285c43313 100644 --- a/deps/npm/html/doc/publish.html +++ b/deps/npm/html/doc/publish.html @@ -29,7 +29,7 @@ the registry. Overwrites when the "--force" flag is set.</p> <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/tag.html">tag(1)</a></li></ul> </div> -<p id="footer">publish — npm@1.1.1</p> +<p id="footer">publish — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/rebuild.html b/deps/npm/html/doc/rebuild.html index 89ea256624..e73b242086 100644 --- a/deps/npm/html/doc/rebuild.html +++ b/deps/npm/html/doc/rebuild.html @@ -25,7 +25,7 @@ the new binary.</p> <ul><li><a href="../doc/build.html">build(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul> </div> -<p id="footer">rebuild — npm@1.1.1</p> +<p id="footer">rebuild — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/registry.html b/deps/npm/html/doc/registry.html index 54778cf49b..3eaef2e85f 100644 --- a/deps/npm/html/doc/registry.html +++ b/deps/npm/html/doc/registry.html @@ -97,7 +97,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/disputes.html">disputes(1)</a></li></ul> </div> -<p id="footer">registry — npm@1.1.1</p> +<p id="footer">registry — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/removing-npm.html b/deps/npm/html/doc/removing-npm.html index 84ecc6a813..e0a3a56bf8 100644 --- a/deps/npm/html/doc/removing-npm.html +++ b/deps/npm/html/doc/removing-npm.html @@ -58,7 +58,7 @@ modules. To track those down, you can do the following:</p> <ul><li><a href="../doc/README.html">README</a></li><li><a href="../doc/rm.html">rm(1)</a></li><li><a href="../doc/prune.html">prune(1)</a></li></ul> </div> -<p id="footer">removing-npm — npm@1.1.1</p> +<p id="footer">removing-npm — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/restart.html b/deps/npm/html/doc/restart.html index d7f48d46f7..5e007b2810 100644 --- a/deps/npm/html/doc/restart.html +++ b/deps/npm/html/doc/restart.html @@ -24,7 +24,7 @@ the "start" script.</p> <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul> </div> -<p id="footer">restart — npm@1.1.1</p> +<p id="footer">restart — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/root.html b/deps/npm/html/doc/root.html index e84946989a..16312383e9 100644 --- a/deps/npm/html/doc/root.html +++ b/deps/npm/html/doc/root.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/prefix.html">prefix(1)</a></li><li><a href="../doc/bin.html">bin(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">root — npm@1.1.1</p> +<p id="footer">root — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/run-script.html b/deps/npm/html/doc/run-script.html index 3eff1c7e38..04dcb48708 100644 --- a/deps/npm/html/doc/run-script.html +++ b/deps/npm/html/doc/run-script.html @@ -23,7 +23,7 @@ called directly, as well.</p> <ul><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul> </div> -<p id="footer">run-script — npm@1.1.1</p> +<p id="footer">run-script — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/scripts.html b/deps/npm/html/doc/scripts.html index efded27085..d4aa6668af 100644 --- a/deps/npm/html/doc/scripts.html +++ b/deps/npm/html/doc/scripts.html @@ -164,7 +164,7 @@ will sudo the npm command in question.</li></ul> <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/developers.html">developers(1)</a></li><li><a href="../doc/install.html">install(1)</a></li></ul> </div> -<p id="footer">scripts — npm@1.1.1</p> +<p id="footer">scripts — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/search.html b/deps/npm/html/doc/search.html index 2e94b6bea1..7f02fd198a 100644 --- a/deps/npm/html/doc/search.html +++ b/deps/npm/html/doc/search.html @@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p> <ul><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/view.html">view(1)</a></li></ul> </div> -<p id="footer">search — npm@1.1.1</p> +<p id="footer">search — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/semver.html b/deps/npm/html/doc/semver.html index a9e25c1f3d..5fd52470de 100644 --- a/deps/npm/html/doc/semver.html +++ b/deps/npm/html/doc/semver.html @@ -104,7 +104,7 @@ that satisfies the range, or null if none of them do.</li></ul> <ul><li><a href="../doc/json.html">json(1)</a></li></ul> </div> -<p id="footer">semver — npm@1.1.1</p> +<p id="footer">semver — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/shrinkwrap.html b/deps/npm/html/doc/shrinkwrap.html new file mode 100644 index 0000000000..1acaf8c6c9 --- /dev/null +++ b/deps/npm/html/doc/shrinkwrap.html @@ -0,0 +1,204 @@ +<!doctype html> +<html> + <title>shrinkwrap</title> + <meta http-equiv="content-type" value="text/html;utf-8"> + <link rel="stylesheet" type="text/css" href="./style.css"> + + <body> + <div id="wrapper"> +<h1><a href="../doc/shrinkwrap.html">shrinkwrap</a></h1> <p>Lock down dependency versions</p> + +<h2 id="SYNOPSIS">SYNOPSIS</h2> + +<pre><code>npm shrinkwrap</code></pre> + +<h2 id="DESCRIPTION">DESCRIPTION</h2> + +<p>This command locks down the versions of a package's dependencies so that you can +control exactly which versions of each dependency will be used when your package +is installed.</p> + +<p>By default, "npm install" recursively installs the target's dependencies (as +specified in package.json), choosing the latest available version that satisfies +the dependency's semver pattern. In some situations, particularly when shipping +software where each change is tightly managed, it's desirable to fully specify +each version of each dependency recursively so that subsequent builds and +deploys do not inadvertently pick up newer versions of a dependency that satisfy +the semver pattern. Specifying specific semver patterns in each dependency's +package.json would facilitate this, but that's not always possible or desirable, +as when another author owns the npm package. It's also possible to check +dependencies directly into source control, but that may be undesirable for other +reasons.</p> + +<p>As an example, consider package A:</p> + +<pre><code>{ + "name": "A", + "version": "0.1.0", + "dependencies": { + "B": "<0.1.0" + } +}</code></pre> + +<p>package B:</p> + +<pre><code>{ + "name": "B", + "version": "0.0.1", + "dependencies": { + "C": "<0.1.0" + } +}</code></pre> + +<p>and package C:</p> + +<pre><code>{ + "name": "C, + "version": "0.0.1" +}</code></pre> + +<p>If these are the only versions of A, B, and C available in the registry, then +a normal "npm install A" will install:</p> + +<pre><code>A@0.1.0 +`-- B@0.0.1 + `-- C@0.0.1</code></pre> + +<p>However, if B@0.0.2 is published, then a fresh "npm install A" will install:</p> + +<pre><code>A@0.1.0 +`-- B@0.0.2 + `-- C@0.0.1</code></pre> + +<p>assuming the new version did not modify B's dependencies. Of course, the new +version of B could include a new version of C and any number of new +dependencies. If such changes are undesirable, the author of A could specify a +dependency on B@0.0.1. However, if A's author and B's author are not the same +person, there's no way for A's author to say that he or she does not want to +pull in newly published versions of C when B hasn't changed at all.</p> + +<p>In this case, A's author can run</p> + +<pre><code>npm shrinkwrap</code></pre> + +<p>This generates npm-shrinkwrap.json, which will look something like this:</p> + +<pre><code>{ + "name": "A", + "version": "0.1.0", + "dependencies": { + "B": { + "version": "0.0.1", + "dependencies": { + "C": { + "version": "0.1.0" + } + } + } + } +}</code></pre> + +<p>The shrinkwrap command has locked down the dependencies based on what's +currently installed in node_modules. When "npm install" installs a package with +a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than +package.json files) completely drives the installation of that package and all +of its dependencies (recursively). So now the author publishes A@0.1.0, and +subsequent installs of this package will use B@0.0.1 and C@0.1.0, regardless the +dependencies and versions listed in A's, B's, and C's package.json files.</p> + +<h3 id="Using-shrinkwrapped-packages">Using shrinkwrapped packages</h3> + +<p>Using a shrinkwrapped package is no different than using any other package: you +can "npm install" it by hand, or add a dependency to your package.json file and +"npm install" it.</p> + +<h3 id="Building-shrinkwrapped-packages">Building shrinkwrapped packages</h3> + +<p>To shrinkwrap an existing package:</p> + +<ol><li>Run "npm install" in the package root to install the current versions of all +dependencies.</li><li>Validate that the package works as expected with these versions.</li><li>Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish your +package.</li></ol> + +<p>To add or update a dependency in a shrinkwrapped package:</p> + +<ol><li>Run "npm install" in the package root to install the current versions of all +dependencies.</li><li>Add or update dependencies. "npm install" each new or updated package +individually and then update package.json. Note that they must be +explicitly named in order to be installed: running <code>npm install</code> with +no arguments will merely reproduce the existing shrinkwrap.</li><li>Validate that the package works as expected with the new dependencies.</li><li>Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and publish your +package.</li></ol> + +<p>You can use <a href="../doc/outdated.html">outdated(1)</a> to view dependencies with newer versions available.</p> + +<h3 id="Other-Notes">Other Notes</h3> + +<p>Since "npm shrinkwrap" uses the locally installed packages to construct the +shrinkwrap file, devDependencies will be included if and only if you've +installed them already when you make the shrinkwrap.</p> + +<p>A shrinkwrap file must be consistent with the package's package.json file. "npm +shrinkwrap" will fail if required dependencies are not already installed, since +that would result in a shrinkwrap that wouldn't actually work. Similarly, the +command will fail if there are extraneous packages (not referenced by +package.json), since that would indicate that package.json is not correct.</p> + +<p>If shrinkwrapped package A depends on shrinkwrapped package B, B's shrinkwrap +will not be used as part of the installation of A. However, because A's +shrinkwrap is constructed from a valid installation of B and recursively +specifies all dependencies, the contents of B's shrinkwrap will implicitly be +included in A's shrinkwrap.</p> + +<h3 id="Caveats">Caveats</h3> + +<p>Shrinkwrap files only lock down package versions, not actual package contents. +While discouraged, a package author can republish an existing version of a +package, causing shrinkwrapped packages using that version to pick up different +code than they were before. If you want to avoid any risk that a byzantine +author replaces a package you're using with code that breaks your application, +you could modify the shrinkwrap file to use git URL references rather than +version numbers so that npm always fetches all packages from git.</p> + +<p>If you wish to lock down the specific bytes included in a package, for +example to have 100% confidence in being able to reproduce a deployment +or build, then you ought to check your dependencies into source control, +or pursue some other mechanism that can verify contents rather than +versions.</p> + +<h2 id="SEE-ALSO">SEE ALSO</h2> + +<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.2</p> +<script> +;(function () { +var wrapper = document.getElementById("wrapper") +var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0) + .filter(function (el) { + return el.parentNode === wrapper + && el.tagName.match(/H[1-6]/) + && el.id + }) +var l = 2 + , toc = document.createElement("ul") +toc.innerHTML = els.map(function (el) { + var i = el.tagName.charAt(1) + , out = "" + while (i > l) { + out += "<ul>" + l ++ + } + while (i < l) { + out += "</ul>" + l -- + } + out += "<li><a href='#" + el.id + "'>" + + ( el.innerText || el.text || el.innerHTML) + + "</a>" + return out +}).join("\n") +toc.id = "toc" +document.body.appendChild(toc) +})() +</script> +</body></html> diff --git a/deps/npm/html/doc/star.html b/deps/npm/html/doc/star.html index 139344be39..a5e1ec3d45 100644 --- a/deps/npm/html/doc/star.html +++ b/deps/npm/html/doc/star.html @@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p> <ul><li><a href="../doc/view.html">view(1)</a></li><li><a href="../doc/whoami.html">whoami(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul> </div> -<p id="footer">star — npm@1.1.1</p> +<p id="footer">star — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/start.html b/deps/npm/html/doc/start.html index b595fbd044..27d0749571 100644 --- a/deps/npm/html/doc/start.html +++ b/deps/npm/html/doc/start.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul> </div> -<p id="footer">start — npm@1.1.1</p> +<p id="footer">start — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/stop.html b/deps/npm/html/doc/stop.html index 7df5594d48..25cd52132e 100644 --- a/deps/npm/html/doc/stop.html +++ b/deps/npm/html/doc/stop.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/test.html">test(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li></ul> </div> -<p id="footer">stop — npm@1.1.1</p> +<p id="footer">stop — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/submodule.html b/deps/npm/html/doc/submodule.html index a97ec2fcc1..031c0df102 100644 --- a/deps/npm/html/doc/submodule.html +++ b/deps/npm/html/doc/submodule.html @@ -33,7 +33,7 @@ dependencies into the submodule folder.</p> <ul><li><a href="../doc/json.html">json(1)</a></li><li>git help submodule</li></ul> </div> -<p id="footer">submodule — npm@1.1.1</p> +<p id="footer">submodule — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/tag.html b/deps/npm/html/doc/tag.html index d2cc26bb0d..090aac22cd 100644 --- a/deps/npm/html/doc/tag.html +++ b/deps/npm/html/doc/tag.html @@ -21,7 +21,7 @@ <ul><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">tag — npm@1.1.1</p> +<p id="footer">tag — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/test.html b/deps/npm/html/doc/test.html index b70c1c433c..e8f4f37c1f 100644 --- a/deps/npm/html/doc/test.html +++ b/deps/npm/html/doc/test.html @@ -23,7 +23,7 @@ true.</p> <ul><li><a href="../doc/run-script.html">run-script(1)</a></li><li><a href="../doc/scripts.html">scripts(1)</a></li><li><a href="../doc/start.html">start(1)</a></li><li><a href="../doc/restart.html">restart(1)</a></li><li><a href="../doc/stop.html">stop(1)</a></li></ul> </div> -<p id="footer">test — npm@1.1.1</p> +<p id="footer">test — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/uninstall.html b/deps/npm/html/doc/uninstall.html index 69e4431e10..46e6f303b2 100644 --- a/deps/npm/html/doc/uninstall.html +++ b/deps/npm/html/doc/uninstall.html @@ -22,7 +22,7 @@ on its behalf.</p> <ul><li><a href="../doc/prune.html">prune(1)</a></li><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/config.html">config(1)</a></li></ul> </div> -<p id="footer">uninstall — npm@1.1.1</p> +<p id="footer">uninstall — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/unpublish.html b/deps/npm/html/doc/unpublish.html index 6a4207eb39..0d33a1ca6d 100644 --- a/deps/npm/html/doc/unpublish.html +++ b/deps/npm/html/doc/unpublish.html @@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p> <ul><li><a href="../doc/deprecate.html">deprecate(1)</a></li><li><a href="../doc/publish.html">publish(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li><li><a href="../doc/owner.html">owner(1)</a></li></ul> </div> -<p id="footer">unpublish — npm@1.1.1</p> +<p id="footer">unpublish — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/update.html b/deps/npm/html/doc/update.html index 589a3ad88c..96b229c60b 100644 --- a/deps/npm/html/doc/update.html +++ b/deps/npm/html/doc/update.html @@ -23,7 +23,7 @@ <ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/outdated.html">outdated(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/folders.html">folders(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul> </div> -<p id="footer">update — npm@1.1.1</p> +<p id="footer">update — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/version.html b/deps/npm/html/doc/version.html index 04e5c81231..42a107e56a 100644 --- a/deps/npm/html/doc/version.html +++ b/deps/npm/html/doc/version.html @@ -31,7 +31,7 @@ will use it as a commit message when creating a version commit.</p> <ul><li><a href="../doc/init.html">init(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/semver.html">semver(1)</a></li></ul> </div> -<p id="footer">version — npm@1.1.1</p> +<p id="footer">version — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/view.html b/deps/npm/html/doc/view.html index 0f29556b61..c15841e701 100644 --- a/deps/npm/html/doc/view.html +++ b/deps/npm/html/doc/view.html @@ -88,7 +88,7 @@ the field name.</p> <ul><li><a href="../doc/search.html">search(1)</a></li><li><a href="../doc/registry.html">registry(1)</a></li><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/docs.html">docs(1)</a></li></ul> </div> -<p id="footer">view — npm@1.1.1</p> +<p id="footer">view — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/whoami.html b/deps/npm/html/doc/whoami.html index d5ba7e5f13..e4b70b4af6 100644 --- a/deps/npm/html/doc/whoami.html +++ b/deps/npm/html/doc/whoami.html @@ -20,7 +20,7 @@ <ul><li><a href="../doc/config.html">config(1)</a></li><li><a href="../doc/adduser.html">adduser(1)</a></li></ul> </div> -<p id="footer">whoami — npm@1.1.1</p> +<p id="footer">whoami — npm@1.1.2</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 211a6612ed..b493775c1d 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -3,12 +3,14 @@ // // See doc/install.md for more description -// Managing "family" lists... -// every time we dive into a deeper node_modules folder, the "family" -// list that gets passed along uses the previous "family" list as -// it's __proto__. Any "resolved precise dependency" things that aren't -// already on this object get added, and then that's passed to the next -// generation of installation. +// Managing contexts... +// there's a lot of state associated with an "install" operation, including +// packages that are already installed, parent packages, current shrinkwrap, and +// so on. We maintain this state in a "context" object that gets passed around. +// every time we dive into a deeper node_modules folder, the "family" list that +// gets passed along uses the previous "family" list as its __proto__. Any +// "resolved precise dependency" things that aren't already on this object get +// added, and then that's passed to the next generation of installation. module.exports = install @@ -20,7 +22,9 @@ install.usage = "npm install <tarball file>" + "\nnpm install <pkg>@<version>" + "\nnpm install <pkg>@<version range>" + "\n\nCan specify one or more: npm install ./foo.tgz bar@stable /some/folder" - + "\nInstalls dependencies in ./package.json if no argument supplied" + + "\nIf no argument is supplied and ./npm-shrinkwrap.json is " + + "\npresent, installs dependencies specified in the shrinkwrap." + + "\nOtherwise, installs dependencies from ./package.json." install.completion = function (opts, cb) { // install can complete to a folder with a package.json, or any package. @@ -109,33 +113,107 @@ function install (args, cb_) { // or install current folder globally if (!args.length) { if (npm.config.get("global")) args = ["."] - else return readJson( path.resolve(where, "package.json") - , { dev: !npm.config.get("production") } - , function (er, data) { + else return readDependencies( null + , where + , { dev: !npm.config.get("production") } + , function (er, data) { if (er) return log.er(cb, "Couldn't read dependencies.")(er) var deps = Object.keys(data.dependencies || {}) log.verbose([where, deps], "where, deps") - var family = {} - , ancestors = {} - family[data.name] = ancestors[data.name] = data.version + var context = { family: {} + , ancestors: {} + , explicit: false + , parent: data + , wrap: null } + context.family[data.name] = context.ancestors[data.name] = data.version installManyTop(deps.map(function (dep) { var target = data.dependencies[dep] , parsed = url.parse(target.replace(/^git\+/, "git")) target = dep + "@" + target return target - }), where, family, ancestors, false, data, cb) + }), where, context, cb) }) } // initial "family" is the name:version of the root, if it's got - // a pacakge.json file. + // a package.json file. readJson(path.resolve(where, "package.json"), function (er, data) { if (er) data = null - var family = {} - , ancestors = {} - if (data) family[data.name] = ancestors[data.name] = data.version + var context = { family: {} + , ancestors: {} + , explicit: true + , parent: data + , wrap: null } + if (data) { + context.family[data.name] = context.ancestors[data.name] = data.version + } var fn = npm.config.get("global") ? installMany : installManyTop - fn(args, where, family, ancestors, true, data, cb) + fn(args, where, context, cb) + }) + }) +} + +// reads dependencies for the package at "where". There are several cases, +// depending on our current state and the package's configuration: +// +// 1. If "context" is specified, then we examine the context to see if there's a +// shrinkwrap there. In that case, dependencies are read from the shrinkwrap. +// 2. Otherwise, if an npm-shrinkwrap.json file is present, dependencies are +// read from there. +// 3. Otherwise, dependencies come from package.json. +// +// Regardless of which case we fall into, "cb" is invoked with a first argument +// describing the full package (as though readJson had been used) but with +// "dependencies" read as described above. The second argument to "cb" is the +// shrinkwrap to use in processing this package's dependencies, which may be +// "wrap" (in case 1) or a new shrinkwrap (in case 2). +function readDependencies (context, where, opts, cb) { + var wrap = context ? context.wrap : null + + readJson( path.resolve(where, "package.json") + , opts + , function (er, data) { + if (er) return cb(er) + + if (wrap) { + log.verbose([where, wrap], "readDependencies: using existing wrap") + var rv = {} + Object.keys(data).forEach(function (key) { + rv[key] = data[key] + }) + rv.dependencies = {} + Object.keys(wrap).forEach(function (key) { + rv.dependencies[key] = wrap[key].version + }) + log.verbose([rv.dependencies], "readDependencies: returned deps") + return cb(null, rv, wrap) + } + + var wrapfile = path.resolve(where, "npm-shrinkwrap.json") + + fs.readFile(wrapfile, "utf8", function (er, wrapjson) { + if (er) { + log.verbose("readDependencies: using package.json deps") + return cb(null, data, null) + } + + try { + var newwrap = JSON.parse(wrapjson) + } catch (ex) { + return cb(ex) + } + + log.info(wrapfile, "using shrinkwrap file") + var rv = {} + Object.keys(data).forEach(function (key) { + rv[key] = data[key] + }) + rv.dependencies = {} + Object.keys(newwrap.dependencies).forEach(function (key) { + rv.dependencies[key] = newwrap.dependencies[key].version + }) + log.verbose([rv.dependencies], "readDependencies: returned deps") + return cb(null, rv, newwrap.dependencies) }) }) } @@ -187,8 +265,10 @@ function save (where, installed, tree, pretty, cb) { // Outputting *all* the installed modules is a bit confusing, // because the length of the path does not make it clear // that the submodules are not immediately require()able. -// TODO: Show the complete tree, ls-style. +// TODO: Show the complete tree, ls-style, but only if --long is provided function prettify (tree, installed) { + // XXX This should match the data structure provided by npm ls --json + if (npm.config.get("json")) return JSON.stringify(tree, null, 2) if (npm.config.get("parseable")) return parseable(installed) return Object.keys(tree).map(function (p) { p = tree[p] @@ -255,10 +335,9 @@ function treeify (installed) { // just like installMany, but also add the existing packages in // where/node_modules to the family object. -function installManyTop (what, where, family, ancestors, explicit, parent, cb_) { - +function installManyTop (what, where, context, cb_) { function cb (er, d) { - if (explicit || er) return cb_(er, d) + if (context.explicit || er) return cb_(er, d) // since this wasn't an explicit install, let's build the top // folder, so that `npm install` also runs the lifecycle scripts. npm.commands.build([where], false, true, function (er) { @@ -266,7 +345,7 @@ function installManyTop (what, where, family, ancestors, explicit, parent, cb_) }) } - if (explicit) return next() + if (context.explicit) return next() readJson(path.join(where, "package.json"), function (er, data) { if (er) return next(er) @@ -275,21 +354,21 @@ function installManyTop (what, where, family, ancestors, explicit, parent, cb_) function next (er) { if (er) return cb(er) - installManyTop_(what, where, family, ancestors, explicit, parent, cb) + installManyTop_(what, where, context, cb) } } -function installManyTop_ (what, where, family, ancestors, explicit, parent, cb) { +function installManyTop_ (what, where, context, cb) { var nm = path.resolve(where, "node_modules") - , names = explicit + , names = context.explicit ? what.map(function (w) { return w.split(/@/).shift() }) : [] fs.readdir(nm, function (er, pkgs) { - if (er) return installMany(what, where, family, ancestors, explicit, parent, cb) + if (er) return installMany(what, where, context, cb) pkgs = pkgs.filter(function (p) { return !p.match(/^[\._-]/) - && (!explicit || names.indexOf(p) === -1) + && (!context.explicit || names.indexOf(p) === -1) }) asyncMap(pkgs.map(function (p) { return path.resolve(nm, p, "package.json") @@ -302,36 +381,44 @@ function installManyTop_ (what, where, family, ancestors, explicit, parent, cb) // add all the existing packages to the family list. // however, do not add to the ancestors list. packages.forEach(function (p) { - family[p[0]] = p[1] + context.family[p[0]] = p[1] }) - return installMany(what, where, family, ancestors, explicit, parent, cb) + return installMany(what, where, context, cb) }) }) } -function installMany (what, where, family, ancestors, explicit, parent, cb) { - // 'npm install foo' should install the version of foo - // that satisfies the dep in the current folder. - // This will typically return immediately, since we already read - // this file family, and it'll be cached. - readJson(path.resolve(where, "package.json"), function (er, data) { +function installMany (what, where, context, cb) { + // readDependencies takes care of figuring out whether the list of + // dependencies we'll iterate below comes from an existing shrinkwrap from a + // parent level, a new shrinkwrap at this level, or package.json at this + // level, as well as which shrinkwrap (if any) our dependencies should use. + readDependencies(context, where, {}, function (er, data, wrap) { if (er) data = {} - d = data.dependencies || {} var parent = data + var d = data.dependencies || {} + + // if we're explicitly installing "what" into "where", then the shrinkwrap + // for "where" doesn't apply. This would be the case if someone were adding + // a new package to a shrinkwrapped package. (data.dependencies will not be + // used here except to indicate what packages are already present, so + // there's no harm in using that.) + if (context.explicit) wrap = null + // what is a list of things. // resolve each one. asyncMap( what - , targetResolver(where, family, ancestors, explicit, d, parent) + , targetResolver(where, context, d) , function (er, targets) { if (er) return cb(er) // each target will be a data object corresponding // to a package, folder, or whatever that is in the cache now. - var newPrev = Object.create(family) - , newAnc = Object.create(ancestors) + var newPrev = Object.create(context.family) + , newAnc = Object.create(context.ancestors) newAnc[data.name] = data.version targets.forEach(function (t) { @@ -343,17 +430,25 @@ function installMany (what, where, family, ancestors, explicit, parent, cb) { }) asyncMap(targets, function (target, cb) { log(target._id, "installOne") - installOne(target, where, newPrev, newAnc, parent, cb) + var newWrap = wrap ? wrap[target.name].dependencies || {} : null + var newContext = { family: newPrev + , ancestors: newAnc + , parent: parent + , explicit: false + , wrap: newWrap } + installOne(target, where, newContext, cb) }, cb) }) }) } -function targetResolver (where, family, ancestors, explicit, deps, parent) { - var alreadyInstalledManually = explicit ? [] : null +function targetResolver (where, context, deps) { + var alreadyInstalledManually = context.explicit ? [] : null , nm = path.resolve(where, "node_modules") + , parent = context.parent + , wrap = context.wrap - if (!explicit) fs.readdir(nm, function (er, inst) { + if (!context.explicit) fs.readdir(nm, function (er, inst) { if (er) return alreadyInstalledManually = [] asyncMap(inst, function (pkg, cb) { readJson(path.resolve(nm, pkg, "package.json"), function (er, d) { @@ -381,11 +476,29 @@ function targetResolver (where, family, ancestors, explicit, deps, parent) { return cb(null, []) } - if (family[what] && semver.satisfies(family[what], deps[what] || "")) { - return cb(null, []) + // check for a version installed higher in the tree. + // If installing from a shrinkwrap, it must match exactly. + if (context.family[what]) { + if (wrap && wrap[what].version == context.family[what]) { + log.verbose("using existing "+what+" (matches shrinkwrap)") + return cb(null, []) + } + + if (!wrap && semver.satisfies(context.family[what], deps[what] || "")) { + log.verbose("using existing "+what+" (no shrinkwrap)") + return cb(null, []) + } } - if (deps[what]) { + if (wrap) { + name = what.split(/@/).shift() + if (wrap[name]) { + log.verbose("shrinkwrap: resolving "+what+" to "+wrap[name].version) + what = name + "@" + wrap[name].version + } else { + log.verbose("shrinkwrap: skipping "+what+" (not in shrinkwrap)") + } + } else if (deps[what]) { what = what + "@" + deps[what] } @@ -395,7 +508,7 @@ function targetResolver (where, family, ancestors, explicit, deps, parent) { log.warn(what, "optional dependency failed, continuing") return cb(null, []) } - if (!er && data && family[data.name] === data.version) { + if (!er && data && context.family[data.name] === data.version) { return cb(null, []) } return cb(er, data) @@ -405,20 +518,21 @@ function targetResolver (where, family, ancestors, explicit, deps, parent) { // we've already decided to install this. if anything's in the way, // then uninstall it first. -function installOne (target, where, family, ancestors, parent, cb) { +function installOne (target, where, context, cb) { // the --link flag makes this a "link" command if it's at the // the top level. if (where === npm.prefix && npm.config.get("link") && !npm.config.get("global")) { - return localLink(target, where, family, ancestors, parent, cb) + return localLink(target, where, context, cb) } - installOne_(target, where, family, ancestors, parent, cb) + installOne_(target, where, context, cb) } -function localLink (target, where, family, ancestors, parent, cb) { +function localLink (target, where, context, cb) { log.verbose(target._id, "try to link") var jsonFile = path.resolve( npm.dir, target.name , "package.json" ) + , parent = context.parent readJson(jsonFile, function (er, data) { if (er || data._id === target._id) { @@ -440,7 +554,7 @@ function localLink (target, where, family, ancestors, parent, cb) { } else { log.verbose(target._id, "install locally (no link)") - installOne_(target, where, family, ancestors, parent, cb) + installOne_(target, where, context, cb) } }) } @@ -464,18 +578,19 @@ function resultList (target, where, parentId) { , parentId && prettyWhere ] } -function installOne_ (target, where, family, ancestors, parent, cb) { +function installOne_ (target, where, context, cb) { var nm = path.resolve(where, "node_modules") , targetFolder = path.resolve(nm, target.name) , prettyWhere = relativize(where, process.cwd() + "/x") + , parent = context.parent if (prettyWhere === ".") prettyWhere = null chain ( [ [checkEngine, target] - , [checkCycle, target, ancestors] + , [checkCycle, target, context.ancestors] , [checkGit, targetFolder] - , [write, target, targetFolder, family, ancestors] ] + , [write, target, targetFolder, context] ] , function (er, d) { log.verbose(target._id, "installOne cb") if (er) return cb(er) @@ -559,10 +674,11 @@ function checkGit_ (folder, cb) { }) } -function write (target, targetFolder, family, ancestors, cb_) { +function write (target, targetFolder, context, cb_) { var up = npm.config.get("unsafe-perm") , user = up ? null : npm.config.get("user") , group = up ? null : npm.config.get("group") + , family = context.family function cb (er, data) { // cache.unpack returns the data object, and all we care about @@ -586,23 +702,33 @@ function write (target, targetFolder, family, ancestors, cb_) { // up until this point, since we really don't care about it. , function (er) { if (er) return cb(er) - var deps = Object.keys(target.dependencies || {}) - installMany(deps.filter(function (d) { - // prefer to not install things that are satisfied by - // something in the "family" list. - return !semver.satisfies(family[d], target.dependencies[d]) - }).map(function (d) { - var t = target.dependencies[d] - , parsed = url.parse(t.replace(/^git\+/, "git")) - t = d + "@" + t - return t - }), targetFolder, family, ancestors, false, target, function (er, d) { - log.verbose(targetFolder, "about to build") - if (er) return cb(er) - npm.commands.build( [targetFolder] - , npm.config.get("global") - , true - , function (er) { return cb(er, d) }) + + // before continuing to installing dependencies, check for a shrinkwrap. + readDependencies(context, targetFolder, {}, function (er, data, wrap) { + var deps = Object.keys(data.dependencies || {}) + var newcontext = { family: family + , ancestors: context.ancestors + , parent: target + , explicit: false + , wrap: wrap } + installMany(deps.filter(function (d) { + // prefer to not install things that are satisfied by + // something in the "family" list, unless we're installing + // from a shrinkwrap. + return wrap || !semver.satisfies(family[d], data.dependencies[d]) + }).map(function (d) { + var t = data.dependencies[d] + , parsed = url.parse(t.replace(/^git\+/, "git")) + t = d + "@" + t + return t + }), targetFolder, newcontext, function (er, d) { + log.verbose(targetFolder, "about to build") + if (er) return cb(er) + npm.commands.build( [targetFolder] + , npm.config.get("global") + , true + , function (er) { return cb(er, d) }) + }) }) - } ) + }) } diff --git a/deps/npm/lib/link.js b/deps/npm/lib/link.js index fea6606666..3049884cab 100644 --- a/deps/npm/lib/link.js +++ b/deps/npm/lib/link.js @@ -141,6 +141,7 @@ function resultPrinter (pkg, src, dest, rp, cb) { var where = relativize(dest, path.resolve(process.cwd(),"x")) rp = (rp || "").trim() src = (src || "").trim() + // XXX If --json is set, then look up the data from the package.json if (npm.config.get("parseable")) { return parseableOutput(dest, rp || src, cb) } @@ -150,6 +151,9 @@ function resultPrinter (pkg, src, dest, rp, cb) { } function parseableOutput (dest, rp, cb) { + // XXX this should match ls --parseable and install --parseable + // look up the data from package.json, format it the same way. + // // link is always effectively "long", since it doesn't help much to // *just* print the target folder. // However, we don't actually ever read the version number, so diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js index 6bf0617c30..a4ffc331a3 100644 --- a/deps/npm/lib/ls.js +++ b/deps/npm/lib/ls.js @@ -26,13 +26,83 @@ function ls (args, silent, cb) { var dir = path.resolve(npm.dir, "..") readInstalled(dir, function (er, data) { - if (er || silent) return cb(er, data) + var lite = getLite(bfsify(data)) + if (er || silent) return cb(er, data, lite) + var long = npm.config.get("long") - var out = makePretty(bfsify(data), long, dir).join("\n") - output.write(out, function (er) { cb(er, data) }) + , json = npm.config.get("json") + , out + if (json) { + var seen = [] + var d = long ? bfsify(data) : lite + // the raw data can be circular + out = JSON.stringify(d, function (k, o) { + if (typeof o === "object") { + if (-1 !== seen.indexOf(o)) return "[Circular]" + seen.push(o) + } + return o + }, 2) + } else { + out = makePretty(bfsify(data), long, dir).join("\n") + } + output.write(out, function (er) { cb(er, data, lite) }) }) } +function getLite (data, noname) { + var lite = {} + , maxDepth = npm.config.get("depth") + + if (!noname && data.name) lite.name = data.name + if (data.version) lite.version = data.version + if (data.extraneous) { + lite.extraneous = true + lite.problems = lite.problems || [] + lite.problems.push( "extraneous: " + + data.name + "@" + data.version + + " " + (data.path || "") ) + } + + if (data.invalid) { + lite.invalid = true + lite.problems = lite.problems || [] + lite.problems.push( "invalid: " + + data.name + "@" + data.version + + " " + (data.path || "") ) + } + + if (data.dependencies) { + var deps = Object.keys(data.dependencies) + if (deps.length) lite.dependencies = deps.map(function (d) { + var dep = data.dependencies[d] + if (typeof dep === "string") { + lite.problems = lite.problems || [] + var p + if (data.depth >= maxDepth) { + p = "max depth reached: " + } else { + p = "missing: " + } + p += d + "@" + dep + + ", required by " + + data.name + "@" + data.version + lite.problems.push(p) + return [d, { required: dep, missing: true }] + } + return [d, getLite(dep, true)] + }).reduce(function (deps, d) { + if (d[1].problems) { + lite.problems = lite.problems || [] + lite.problems.push.apply(lite.problems, d[1].problems) + } + deps[d[0]] = d[1] + return deps + }, {}) + } + return lite +} + function bfsify (root, current, queue, seen) { // walk over the data, and turn it from this: // +-- a diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index de68393d39..53197082cb 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -138,6 +138,7 @@ var commandCache = {} , "unpublish" , "owner" , "deprecate" + , "shrinkwrap" , "help" , "help-search" diff --git a/deps/npm/lib/outdated.js b/deps/npm/lib/outdated.js index 496dfbd426..e883abd359 100644 --- a/deps/npm/lib/outdated.js +++ b/deps/npm/lib/outdated.js @@ -48,6 +48,10 @@ function makePretty (p) { , dir = path.resolve(p[0], "node_modules", dep) , has = p[2] , want = p[3] + + // XXX add --json support + // Should match (more or less) the output of ls --json + if (parseable) { var str = dir if (npm.config.get("long")) { diff --git a/deps/npm/lib/search.js b/deps/npm/lib/search.js index 92f4319f58..213390eb08 100644 --- a/deps/npm/lib/search.js +++ b/deps/npm/lib/search.js @@ -137,7 +137,8 @@ function prettify (data, args) { , stdout = process.stdout , cols = !tty.isatty(stdout.fd) ? Infinity : stdout._handle ? stdout._handle.getWindowSize()[0] - : tty.getWindowSize()[1] + : process.stdout.getWindowSize()[0] + cols = (cols == 0) ? Infinity : cols } catch (ex) { cols = Infinity } // name, desc, author, keywords diff --git a/deps/npm/lib/shrinkwrap.js b/deps/npm/lib/shrinkwrap.js new file mode 100644 index 0000000000..59942d5866 --- /dev/null +++ b/deps/npm/lib/shrinkwrap.js @@ -0,0 +1,49 @@ +// emit JSON describing versions of all packages currently installed (for later +// use with shrinkwrap install) + +module.exports = exports = shrinkwrap + +var npm = require("./npm.js") + , output = require("./utils/output.js") + , log = require("./utils/log.js") + , fs = require("fs") + , path = require("path") + +shrinkwrap.usage = "npm shrinkwrap" + +function shrinkwrap (args, silent, cb) { + if (typeof cb !== "function") cb = silent, silent = false + + if (args.length) { + log.warn("shrinkwrap doesn't take positional args.") + } + + npm.commands.ls([], true, function (er, _, pkginfo) { + if (er) return cb(er) + shrinkwrap_(pkginfo, silent, cb) + }) +} + +function shrinkwrap_ (pkginfo, silent, cb) { + if (pkginfo.problems) { + return cb(new Error("Problems were encountered\n" + +"Please correct and try again.\n" + +pkginfo.problems.join("\n"))) + } + try { + var swdata = JSON.stringify(pkginfo, null, 2) + "\n" + } catch (er) { + log.error("Error converting package info to json") + return cb(er) + } + + var file = path.resolve(npm.prefix, "npm-shrinkwrap.json") + + fs.writeFile(file, swdata, function (er) { + if (er) return cb(er) + if (silent) return cb(null, pkginfo) + output.write("wrote npm-shrinkwrap.json", function (er) { + cb(er, pkginfo) + }) + }) +} diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js index f8b3d6e0f9..771eddf7db 100644 --- a/deps/npm/lib/unbuild.js +++ b/deps/npm/lib/unbuild.js @@ -65,7 +65,12 @@ function rmBins (pkg, folder, parent, top, cb) { } function rmMans (pkg, folder, parent, top, cb) { - if (!pkg.man || !top || process.platform === "win32") return cb() + if (!pkg.man + || !top + || process.platform === "win32" + || !npm.config.get("global")) { + return cb() + } var manRoot = path.resolve(npm.config.get("prefix"), "share", "man") asyncMap(pkg.man, function (man, cb) { var parseMan = man.match(/(.*)\.([0-9]+)(\.gz)?$/) diff --git a/deps/npm/lib/utils/cmd-shim.js b/deps/npm/lib/utils/cmd-shim.js index a7892e8ee3..f53ab3cf83 100644 --- a/deps/npm/lib/utils/cmd-shim.js +++ b/deps/npm/lib/utils/cmd-shim.js @@ -73,16 +73,16 @@ function writeShim_ (from, to, prog, args, cb) { target = "" shTarget = "" } else { - longProg = "\"%~dp0\"\\\"" + prog + ".exe\"" + longProg = "\"%~dp0\\" + prog + ".exe\"" shLongProg = "\"`dirname \"$0\"`/" + prog + "\"" target = "\"%~dp0\\" + target + "\"" shTarget = "\"`dirname \"$0\"`/" + shTarget + "\"" } - // @IF EXIST "%~dp0"\"node.exe" ( + // @IF EXIST "%~dp0\node.exe" ( // "%~dp0\node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %* // ) ELSE ( - // node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %* + // node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %* // ) var cmd if (longProg) { diff --git a/deps/npm/lib/utils/config-defs.js b/deps/npm/lib/utils/config-defs.js index d368c49726..9c50741357 100644 --- a/deps/npm/lib/utils/config-defs.js +++ b/deps/npm/lib/utils/config-defs.js @@ -161,6 +161,7 @@ Object.defineProperty(exports, "defaults", {get: function () { , "init.author.name" : "" , "init.author.email" : "" , "init.author.url" : "" + , json: false , link: false , logfd : 2 , loglevel : "http" @@ -206,6 +207,7 @@ Object.defineProperty(exports, "defaults", {get: function () { , userignorefile : path.resolve(home, ".npmignore") , umask: 022 , version : false + , versions : false , viewer: process.platform === "win32" ? "browser" : "man" , yes: null @@ -238,6 +240,7 @@ exports.types = , "init.author.name" : String , "init.author.email" : String , "init.author.url" : ["", url] + , json: Boolean , link: Boolean , logfd : [Number, Stream] , loglevel : ["silent","win","error","warn","http","info","verbose","silly"] @@ -279,6 +282,7 @@ exports.types = , userignorefile : path , umask: Octal , version : Boolean + , versions : Boolean , viewer: String , yes: [false, null, Boolean] , _exit : Boolean diff --git a/deps/npm/lib/utils/read-installed.js b/deps/npm/lib/utils/read-installed.js index 6c0ece25bc..60cbea15c5 100644 --- a/deps/npm/lib/utils/read-installed.js +++ b/deps/npm/lib/utils/read-installed.js @@ -125,7 +125,8 @@ function readInstalled_ (folder, parent, name, reqver, depth, maxDepth, cb) { }) readJson(path.resolve(folder, "package.json"), function (er, data) { - obj = data + obj = copy(data) + if (!parent) { obj = obj || true er = null @@ -269,6 +270,15 @@ function findUnmet (obj) { return obj } +function copy (obj) { + if (!obj || typeof obj !== 'object') return obj + if (Array.isArray(obj)) return obj.map(copy) + + var o = {} + for (var i in obj) o[i] = copy(obj[i]) + return o +} + if (module === require.main) { var util = require("util") console.error("testing") diff --git a/deps/npm/lib/utils/read-json.js b/deps/npm/lib/utils/read-json.js index 388d6727eb..8fdd60f66d 100644 --- a/deps/npm/lib/utils/read-json.js +++ b/deps/npm/lib/utils/read-json.js @@ -35,7 +35,7 @@ function readJson (jsonFile, opts, cb) { , contributors = null , serverjs = null - if (opts.wscript != null) { + if (opts.wscript !== null && opts.wscript !== undefined) { wscript = opts.wscript next() } else fs.readFile( path.join(path.dirname(jsonFile), "wscript") @@ -47,7 +47,7 @@ function readJson (jsonFile, opts, cb) { next() }) - if (opts.contributors != null) { + if (opts.contributors !== null && opts.contributors !== undefined) { contributors = opts.contributors next() } else fs.readFile( path.join(path.dirname(jsonFile), "AUTHORS") @@ -64,7 +64,7 @@ function readJson (jsonFile, opts, cb) { next() }) - if (opts.serverjs != null) { + if (opts.serverjs !== null && opts.serverjs !== undefined) { serverjs = opts.serverjs next() } else fs.stat( path.join(path.dirname(jsonFile), "server.js") @@ -82,16 +82,48 @@ function readJson (jsonFile, opts, cb) { return } - fs.readFile(jsonFile, processJson(opts, function (er, data) { + // XXX this api here is insane. being internal is no excuse. + // please refactor. + var thenLoad = processJson(opts, function (er, data) { if (er) return cb(er) var doLoad = !(jsonFile.indexOf(npm.cache) === 0 && path.basename(path.dirname(jsonFile)) !== "package") if (!doLoad) return cb(er, data) loadPackageDefaults(data, path.dirname(jsonFile), cb) - })) + }) + + fs.readFile(jsonFile, function (er, data) { + if (er && er.code === "ENOENT") { + // single-file module, maybe? + // check index.js for a /**package { ... } **/ section. + var indexFile = path.resolve(path.dirname(jsonFile), "index.js") + return fs.readFile(indexFile, function (er2, data) { + // if this doesn't work, then die with the original error. + if (er2) return cb(er) + data = parseIndex(data) + if (!data) return cb(er) + thenLoad(null, data) + }) + } + thenLoad(er, data) + }) } } +// sync. no io. +// /**package { "name": "foo", "version": "1.2.3", ... } **/ +function parseIndex (data) { + data = data.toString() + data = data.split(/^\/\*\*package(?:\s|$)/m) + if (data.length < 2) return null + data = data[1] + data = data.split(/\*\*\/$/m) + if (data.length < 2) return null + data = data[0] + data = data.replace(/^\s*\*/mg, "") + return data +} + function processJson (opts, cb) { if (typeof cb !== "function") cb = opts, opts = {} if (typeof cb !== "function") { @@ -113,8 +145,8 @@ function processJson (opts, cb) { } function processJsonString (opts, cb) { return function (er, jsonString) { - jsonString += "" if (er) return cb(er, jsonString) + jsonString += "" var json try { json = JSON.parse(jsonString) diff --git a/deps/npm/lib/view.js b/deps/npm/lib/view.js index 3e39f76de9..33a5d0df80 100644 --- a/deps/npm/lib/view.js +++ b/deps/npm/lib/view.js @@ -70,6 +70,7 @@ function view (args, silent, cb) { data.versions = Object.keys(data.versions).sort(semver.compare) if (!args.length) args = [""] + // remove readme unless we asked for it if (-1 === args.indexOf("readme")) { delete data.readme } @@ -81,6 +82,10 @@ function view (args, silent, cb) { delete versions[v] } if (semver.satisfies(v, version)) args.forEach(function (args) { + // remove readme unless we asked for it + if (-1 === args.indexOf("readme")) { + delete versions[v].readme + } results.push(showFields(data, versions[v], args)) }) }) diff --git a/deps/npm/man/man1/config.1 b/deps/npm/man/man1/config.1 index 57fc35a8af..82f38fea74 100644 --- a/deps/npm/man/man1/config.1 +++ b/deps/npm/man/man1/config.1 @@ -633,6 +633,24 @@ Type: String .P The value \fBnpm init\fR should use by default for the package author\'s homepage\. . +.SS "json" +. +.IP "\(bu" 4 +Default: false +. +.IP "\(bu" 4 +Type: Boolean +. +.IP "" 0 +. +.P +Whether or not to output JSON data, rather than the normal output\. +. +.P +This feature is currently experimental, and the output data structures +for many commands is either not implemented in JSON yet, or subject to +change\. Only the output from \fBnpm ls \-\-json\fR is currently valid\. +. .SS "link" . .IP "\(bu" 4 @@ -1181,6 +1199,23 @@ If true, output the npm version and exit successfully\. .P Only relevant when specified explicitly on the command line\. . +.SS "versions" +. +.IP "\(bu" 4 +Default: false +. +.IP "\(bu" 4 +Type: boolean +. +.IP "" 0 +. +.P +If true, output the npm version as well as node\'s \fBprocess\.versions\fR +hash, and exit successfully\. +. +.P +Only relevant when specified explicitly on the command line\. +. .SS "viewer" . .IP "\(bu" 4 diff --git a/deps/npm/man/man1/index.1 b/deps/npm/man/man1/index.1 index d2ac3829bf..bc1c2c6733 100644 --- a/deps/npm/man/man1/index.1 +++ b/deps/npm/man/man1/index.1 @@ -132,6 +132,9 @@ .SH "npm help semver" The semantic versioner for npm . +.SH "npm help shrinkwrap" + Lock down dependency versions +. .SH "npm help star" Mark your favorite packages . @@ -246,6 +249,9 @@ .SH "npm apihelp search" Search for packages . +.SH "npm apihelp shrinkwrap" + programmatically generate package shrinkwrap file +. .SH "npm apihelp start" Start a package . diff --git a/deps/npm/man/man1/install.1 b/deps/npm/man/man1/install.1 index 28cfc16b04..96676562c0 100644 --- a/deps/npm/man/man1/install.1 +++ b/deps/npm/man/man1/install.1 @@ -21,7 +21,9 @@ npm install <name>@<version range> .fi . .SH "DESCRIPTION" -This command installs a package, and any packages that it depends on\. +This command installs a package, and any packages that it depends on\. If the +package has a shrinkwrap file, the installation of dependencies will be driven +by that\. See npm help shrinkwrap\. . .P A \fBpackage\fR is: @@ -370,5 +372,8 @@ npm help tag .IP "\(bu" 4 npm help rm . +.IP "\(bu" 4 +npm help shrinkwrap +. .IP "" 0 diff --git a/deps/npm/man/man1/list.1 b/deps/npm/man/man1/list.1 index 7e348d343b..d531dceeb1 100644 --- a/deps/npm/man/man1/list.1 +++ b/deps/npm/man/man1/list.1 @@ -32,6 +32,19 @@ When run as \fBll\fR or \fBla\fR, it shows extended information by default\. . .SH "CONFIGURATION" . +.SS "json" +. +.IP "\(bu" 4 +Default: false +. +.IP "\(bu" 4 +Type: Boolean +. +.IP "" 0 +. +.P +Show information in JSON format\. +. .SS "long" . .IP "\(bu" 4 diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 88aec9802b..6ae5610bbf 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -14,7 +14,7 @@ npm <command> [args] .fi . .SH "VERSION" -1.1.1 +1.1.2 . .SH "DESCRIPTION" npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/man/man1/shrinkwrap.1 b/deps/npm/man/man1/shrinkwrap.1 new file mode 100644 index 0000000000..8328b62fda --- /dev/null +++ b/deps/npm/man/man1/shrinkwrap.1 @@ -0,0 +1,261 @@ +.\" Generated with Ronnjs/v0.1 +.\" http://github.com/kapouer/ronnjs/ +. +.TH "NPM\-SHRINKWRAP" "1" "February 2012" "" "" +. +.SH "NAME" +\fBnpm-shrinkwrap\fR \-\- Lock down dependency versions +. +.SH "SYNOPSIS" +. +.nf +npm shrinkwrap +. +.fi +. +.SH "DESCRIPTION" +This command locks down the versions of a package\'s dependencies so that you can +control exactly which versions of each dependency will be used when your package +is installed\. +. +.P +By default, "npm install" recursively installs the target\'s dependencies (as +specified in package\.json), choosing the latest available version that satisfies +the dependency\'s semver pattern\. In some situations, particularly when shipping +software where each change is tightly managed, it\'s desirable to fully specify +each version of each dependency recursively so that subsequent builds and +deploys do not inadvertently pick up newer versions of a dependency that satisfy +the semver pattern\. Specifying specific semver patterns in each dependency\'s +package\.json would facilitate this, but that\'s not always possible or desirable, +as when another author owns the npm package\. It\'s also possible to check +dependencies directly into source control, but that may be undesirable for other +reasons\. +. +.P +As an example, consider package A: +. +.IP "" 4 +. +.nf +{ + "name": "A", + "version": "0\.1\.0", + "dependencies": { + "B": "<0\.1\.0" + } +} +. +.fi +. +.IP "" 0 +. +.P +package B: +. +.IP "" 4 +. +.nf +{ + "name": "B", + "version": "0\.0\.1", + "dependencies": { + "C": "<0\.1\.0" + } +} +. +.fi +. +.IP "" 0 +. +.P +and package C: +. +.IP "" 4 +. +.nf +{ + "name": "C, + "version": "0\.0\.1" +} +. +.fi +. +.IP "" 0 +. +.P +If these are the only versions of A, B, and C available in the registry, then +a normal "npm install A" will install: +. +.IP "" 4 +. +.nf +A@0\.1\.0 +`\-\- B@0\.0\.1 + `\-\- C@0\.0\.1 +. +.fi +. +.IP "" 0 +. +.P +However, if B@0\.0\.2 is published, then a fresh "npm install A" will install: +. +.IP "" 4 +. +.nf +A@0\.1\.0 +`\-\- B@0\.0\.2 + `\-\- C@0\.0\.1 +. +.fi +. +.IP "" 0 +. +.P +assuming the new version did not modify B\'s dependencies\. Of course, the new +version of B could include a new version of C and any number of new +dependencies\. If such changes are undesirable, the author of A could specify a +dependency on B@0\.0\.1\. However, if A\'s author and B\'s author are not the same +person, there\'s no way for A\'s author to say that he or she does not want to +pull in newly published versions of C when B hasn\'t changed at all\. +. +.P +In this case, A\'s author can run +. +.IP "" 4 +. +.nf +npm shrinkwrap +. +.fi +. +.IP "" 0 +. +.P +This generates npm\-shrinkwrap\.json, which will look something like this: +. +.IP "" 4 +. +.nf +{ + "name": "A", + "version": "0\.1\.0", + "dependencies": { + "B": { + "version": "0\.0\.1", + "dependencies": { + "C": { + "version": "0\.1\.0" + } + } + } + } +} +. +.fi +. +.IP "" 0 +. +.P +The shrinkwrap command has locked down the dependencies based on what\'s +currently installed in node_modules\. When "npm install" installs a package with +a npm\-shrinkwrap\.json file in the package root, the shrinkwrap file (rather than +package\.json files) completely drives the installation of that package and all +of its dependencies (recursively)\. So now the author publishes A@0\.1\.0, and +subsequent installs of this package will use B@0\.0\.1 and C@0\.1\.0, regardless the +dependencies and versions listed in A\'s, B\'s, and C\'s package\.json files\. +. +.SS "Using shrinkwrapped packages" +Using a shrinkwrapped package is no different than using any other package: you +can "npm install" it by hand, or add a dependency to your package\.json file and +"npm install" it\. +. +.SS "Building shrinkwrapped packages" +To shrinkwrap an existing package: +. +.IP "1" 4 +Run "npm install" in the package root to install the current versions of all +dependencies\. +. +.IP "2" 4 +Validate that the package works as expected with these versions\. +. +.IP "3" 4 +Run "npm shrinkwrap", add npm\-shrinkwrap\.json to git, and publish your +package\. +. +.IP "" 0 +. +.P +To add or update a dependency in a shrinkwrapped package: +. +.IP "1" 4 +Run "npm install" in the package root to install the current versions of all +dependencies\. +. +.IP "2" 4 +Add or update dependencies\. "npm install" each new or updated package +individually and then update package\.json\. Note that they must be +explicitly named in order to be installed: running \fBnpm install\fR with +no arguments will merely reproduce the existing shrinkwrap\. +. +.IP "3" 4 +Validate that the package works as expected with the new dependencies\. +. +.IP "4" 4 +Run "npm shrinkwrap", commit the new npm\-shrinkwrap\.json, and publish your +package\. +. +.IP "" 0 +. +.P +You can use npm help outdated to view dependencies with newer versions available\. +. +.SS "Other Notes" +Since "npm shrinkwrap" uses the locally installed packages to construct the +shrinkwrap file, devDependencies will be included if and only if you\'ve +installed them already when you make the shrinkwrap\. +. +.P +A shrinkwrap file must be consistent with the package\'s package\.json file\. "npm +shrinkwrap" will fail if required dependencies are not already installed, since +that would result in a shrinkwrap that wouldn\'t actually work\. Similarly, the +command will fail if there are extraneous packages (not referenced by +package\.json), since that would indicate that package\.json is not correct\. +. +.P +If shrinkwrapped package A depends on shrinkwrapped package B, B\'s shrinkwrap +will not be used as part of the installation of A\. However, because A\'s +shrinkwrap is constructed from a valid installation of B and recursively +specifies all dependencies, the contents of B\'s shrinkwrap will implicitly be +included in A\'s shrinkwrap\. +. +.SS "Caveats" +Shrinkwrap files only lock down package versions, not actual package contents\. +While discouraged, a package author can republish an existing version of a +package, causing shrinkwrapped packages using that version to pick up different +code than they were before\. If you want to avoid any risk that a byzantine +author replaces a package you\'re using with code that breaks your application, +you could modify the shrinkwrap file to use git URL references rather than +version numbers so that npm always fetches all packages from git\. +. +.P +If you wish to lock down the specific bytes included in a package, for +example to have 100% confidence in being able to reproduce a deployment +or build, then you ought to check your dependencies into source control, +or pursue some other mechanism that can verify contents rather than +versions\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +npm help install +. +.IP "\(bu" 4 +npm help json +. +.IP "\(bu" 4 +npm help list +. +.IP "" 0 + diff --git a/deps/npm/man/man3/ls.3 b/deps/npm/man/man3/ls.3 index 5796d7c6f3..6b597edb89 100644 --- a/deps/npm/man/man3/ls.3 +++ b/deps/npm/man/man3/ls.3 @@ -31,6 +31,13 @@ It will print out extraneous, missing, and invalid packages\. If the silent parameter is set to true, nothing will be output to the screen, but the data will still be returned\. . +.P +Callback is provided an error if one occurred, the full data about which +packages are installed and which dependencies they will receive, and a +"lite" data object which just shows which versions are installed where\. +Note that the full data object is a circular structure, so care must be +taken if it is serialized to JSON\. +. .SH "CONFIGURATION" . .SS "long" diff --git a/deps/npm/man/man3/npm.3 b/deps/npm/man/man3/npm.3 index eaaed85a11..01e63293f0 100644 --- a/deps/npm/man/man3/npm.3 +++ b/deps/npm/man/man3/npm.3 @@ -21,7 +21,7 @@ npm\.load(configObject, function (er, npm) { .fi . .SH "VERSION" -1.1.1 +1.1.2 . .SH "DESCRIPTION" This is the API documentation for npm\. diff --git a/deps/npm/man/man3/shrinkwrap.3 b/deps/npm/man/man3/shrinkwrap.3 new file mode 100644 index 0000000000..34112f8d5a --- /dev/null +++ b/deps/npm/man/man3/shrinkwrap.3 @@ -0,0 +1,30 @@ +.\" Generated with Ronnjs/v0.1 +.\" http://github.com/kapouer/ronnjs/ +. +.TH "NPM\-SHRINKWRAP" "3" "February 2012" "" "" +. +.SH "NAME" +\fBnpm-shrinkwrap\fR \-\- programmatically generate package shrinkwrap file +. +.SH "SYNOPSIS" +. +.nf +npm\.commands\.shrinkwrap(args, [silent,] callback) +. +.fi +. +.SH "DESCRIPTION" +This acts much the same ways as shrinkwrapping on the command\-line\. +. +.P +This command does not take any arguments, but \'args\' must be defined\. +Beyond that, if any arguments are passed in, npm will politely warn that it +does not take positional arguments\. +. +.P +If the \'silent\' parameter is set to true, nothing will be output to the screen, +but the shrinkwrap file will still be written\. +. +.P +Finally, \'callback\' is a function that will be called when the shrinkwrap has +been saved\. diff --git a/deps/npm/node_modules/block-stream/package.json b/deps/npm/node_modules/block-stream/package.json index 203961a144..1080b6bc9a 100644 --- a/deps/npm/node_modules/block-stream/package.json +++ b/deps/npm/node_modules/block-stream/package.json @@ -2,13 +2,13 @@ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", "name": "block-stream", "description": "a stream of blocks", - "version": "0.0.4", + "version": "0.0.5", "repository": { "type": "git", "url": "git://github.com/isaacs/block-stream.git" }, "engines": { - "node": "0.4 || ~0.5.8 || 0.6" + "node": "0.4 || ~0.5.8 || 0.6 || 0.7" }, "main": "block-stream.js", "dependencies": { diff --git a/deps/npm/node_modules/request/README.md b/deps/npm/node_modules/request/README.md index 4ea89f794a..e5839b50e6 100644 --- a/deps/npm/node_modules/request/README.md +++ b/deps/npm/node_modules/request/README.md @@ -38,7 +38,7 @@ request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. ```javascript -fs.readStream('file.json').pipe(request.put('http://mysite.com/obj.json')) +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) ``` Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. @@ -146,6 +146,7 @@ request.post({url:url, oauth:oauth}, function (e, r, body) { The first argument can be either a url or an options object. The only required option is uri, all others are optional. * `uri` || `url` - fully qualified uri or a parsed url object from url.parse() +* `qs` - object containing querystring values to be appended to the uri * `method` - http method, defaults to GET * `headers` - http headers, defaults to {} * `body` - entity body for POST and PUT requests. Must be buffer or string. @@ -153,6 +154,7 @@ The first argument can be either a url or an options object. The only required o * `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. * `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. * `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. +* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. * `maxRedirects` - the maximum number of redirects to follow, defaults to 10. * `onResponse` - If true the callback will be fired on the "response" event instead of "end". If a function it will be called on "response" and not effect the regular semantics of the main callback on "end". * `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. diff --git a/deps/npm/node_modules/request/main.js b/deps/npm/node_modules/request/main.js index a25393ec3e..5c14264163 100644 --- a/deps/npm/node_modules/request/main.js +++ b/deps/npm/node_modules/request/main.js @@ -1,4 +1,4 @@ -// Copyright 2010-2011 Mikeal Rogers +// Copyright 2010-2012 Mikeal Rogers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -67,7 +67,9 @@ function isReadStream (rs) { function copy (obj) { var o = {} - for (var i in obj) o[i] = obj[i] + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) return o } @@ -83,24 +85,31 @@ function Request (options) { if (typeof options === 'string') { options = {uri:options} } - + + var reserved = Object.keys(Request.prototype) for (var i in options) { - this[i] = options[i] + if (reserved.indexOf(i) === -1) { + this[i] = options[i] + } else { + if (typeof options[i] === 'function') { + delete options[i] + } + } } - if (!this.pool) this.pool = globalPool - this.dests = [] - this.__isRequestRequest = true + options = copy(options) + + this.init(options) } util.inherits(Request, stream.Stream) -Request.prototype.getAgent = function (host, port) { - if (!this.pool[host+':'+port]) { - this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port}) - } - return this.pool[host+':'+port] -} -Request.prototype.request = function () { +Request.prototype.init = function (options) { var self = this - + + if (!options) options = {} + + if (!self.pool) self.pool = globalPool + self.dests = [] + self.__isRequestRequest = true + // Protect against double callback if (!self._callback && self.callback) { self._callback = self.callback @@ -129,12 +138,13 @@ Request.prototype.request = function () { self._redirectsFollowed = self._redirectsFollowed || 0 self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true - if (self.followRedirect) + self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false; + if (self.followRedirect || self.followAllRedirects) self.redirects = self.redirects || [] self.headers = self.headers ? copy(self.headers) : {} - var setHost = false + self.setHost = false if (!self.headers.host) { self.headers.host = self.uri.hostname if (self.uri.port) { @@ -142,27 +152,10 @@ Request.prototype.request = function () { !(self.uri.port === 443 && self.uri.protocol === 'https:') ) self.headers.host += (':'+self.uri.port) } - setHost = true - } - - if (self.jar === false) { - // disable cookies - var cookies = false; - self._disableCookies = true; - } else if (self.jar) { - // fetch cookie from the user defined cookie jar - var cookies = self.jar.get({ url: self.uri.href }) - } else { - // fetch cookie from the global cookie jar - var cookies = cookieJar.get({ url: self.uri.href }) - } - if (cookies) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value; - }).join("; "); - - self.headers.Cookie = cookieString; + self.setHost = true } + + self.jar(options.jar) if (!self.uri.pathname) {self.uri.pathname = '/'} if (!self.uri.port) { @@ -183,65 +176,29 @@ Request.prototype.request = function () { delete self.callback } - var clientErrorHandler = function (error) { - if (setHost) delete self.headers.host + self.clientErrorHandler = function (error) { + if (self.setHost) delete self.headers.host if (self.req._reusedSocket && error.code === 'ECONNRESET') { self.agent = {addRequest: ForeverAgent.prototype.addRequestNoreuse.bind(self.agent)} self.start() self.req.end() return } - if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer); + self.timeoutTimer = null; + } self.emit('error', error) } if (self.onResponse) self.on('error', function (e) {self.onResponse(e)}) if (self.callback) self.on('error', function (e) {self.callback(e)}) - if (self.form) { - self.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - self.body = qs.stringify(self.form).toString('utf8') - } - - if (self.oauth) { - var form - if (self.headers['content-type'] && - self.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(self.body) - } - if (self.uri.query) { - form = qs.parse(self.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in self.oauth) oa['oauth_'+i] = self.oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - - var baseurl = self.uri.protocol + '//' + self.uri.host + self.uri.pathname - var signature = oauth.hmacsign(self.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in self.oauth) { - // skip - } else { - delete oa['oauth_'+i] - } - } - self.headers.authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - self.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + if (options.form) { + self.form(options.form) + } + + if (options.oauth) { + self.oauth(options.oauth) } if (self.uri.auth && !self.headers.authorization) { @@ -251,6 +208,8 @@ Request.prototype.request = function () { self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) } + if (options.qs) self.qs(options.qs) + if (self.uri.path) { self.path = self.uri.path } else { @@ -261,39 +220,10 @@ Request.prototype.request = function () { if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - if (self.json) { - self.headers['content-type'] = 'application/json' - if (typeof self.json === 'boolean') { - if (typeof self.body === 'object') self.body = JSON.stringify(self.body) - } else { - self.body = JSON.stringify(self.json) - } - - } else if (self.multipart) { - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related;boundary="frontier"'; - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + ';boundary="frontier"'; - } - - if (!self.multipart.forEach) throw new Error('Argument error, options.multipart.') - - self.multipart.forEach(function (part) { - var body = part.body - if(!body) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--frontier\r\n' - Object.keys(part).forEach(function(key){ - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--frontier--')) + if (options.json) { + self.json(options.json) + } else if (options.multipart) { + self.multipart(options.multipart) } if (self.body) { @@ -340,162 +270,6 @@ Request.prototype.request = function () { } } - self.start = function () { - self._started = true - self.method = self.method || 'GET' - self.href = self.uri.href - if (log) log('%method %href', self) - self.req = self.httpModule.request(self, function (response) { - self.response = response - response.request = self - - if (self.httpModule === https && - self.strictSSL && - !response.client.authorized) { - var sslErr = response.client.authorizationError - self.emit('error', new Error('SSL Error: '+ sslErr)) - return - } - - if (setHost) delete self.headers.host - if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) - - if (response.headers['set-cookie'] && (!self._disableCookies)) { - response.headers['set-cookie'].forEach(function(cookie) { - if (self.jar) self.jar.add(new Cookie(cookie)) - else cookieJar.add(new Cookie(cookie)) - }) - } - - if (response.statusCode >= 300 && - response.statusCode < 400 && - self.followRedirect && - self.method !== 'PUT' && - self.method !== 'POST' && - response.headers.location) { - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(response.headers.location)) { - response.headers.location = url.resolve(self.uri.href, response.headers.location) - } - self.uri = response.headers.location - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: response.headers.location - } - ) - delete self.req - delete self.agent - delete self._started - if (self.headers) { - delete self.headers.host - } - if (log) log('Redirect to %uri', self) - request(self, self.callback) - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.pipeDest = function (dest) { - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (self.pipefilter) self.pipefilter(response, dest) - } - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - self.emit('response', response) - - if (self.onResponse) { - self.onResponse(null, response) - } - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - if (buffer.length && Buffer.isBuffer(buffer[0])) { - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString() - } - } else if (buffer.length) { - response.body = buffer.join('') - } - - if (self.json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - - self.callback(null, response, response.body) - }) - } - } - }) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function() { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - } - - self.req.on('error', clientErrorHandler) - } - self.once('pipe', function (src) { if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") self.src = src @@ -540,20 +314,346 @@ Request.prototype.request = function () { self.ntick = true }) } -Request.prototype.pipe = function (dest) { +Request.prototype.getAgent = function (host, port) { + if (!this.pool[host+':'+port]) { + this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port}) + } + return this.pool[host+':'+port] +} +Request.prototype.start = function () { + var self = this + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + if (log) log('%method %href', self) + self.req = self.httpModule.request(self, function (response) { + self.response = response + response.request = self + + if (self.httpModule === https && + self.strictSSL && + !response.client.authorized) { + var sslErr = response.client.authorizationError + self.emit('error', new Error('SSL Error: '+ sslErr)) + return + } + + if (self.setHost) delete self.headers.host + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer); + self.timeoutTimer = null; + } + + if (response.headers['set-cookie'] && (!self._disableCookies)) { + response.headers['set-cookie'].forEach(function(cookie) { + if (self._jar) self._jar.add(new Cookie(cookie)) + else cookieJar.add(new Cookie(cookie)) + }) + } + + if (response.statusCode >= 300 && response.statusCode < 400 && + (self.followAllRedirects || + (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST'))) && + response.headers.location) { + if (self._redirectsFollowed >= self.maxRedirects) { + self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) + return + } + self._redirectsFollowed += 1 + + if (!isUrl.test(response.headers.location)) { + response.headers.location = url.resolve(self.uri.href, response.headers.location) + } + self.uri = response.headers.location + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: response.headers.location + } + ) + self.method = 'GET'; // Force all redirects to use GET + delete self.req + delete self.agent + delete self._started + if (self.headers) { + delete self.headers.host + } + if (log) log('Redirect to %uri', self) + self.init() + return // Ignore the rest of the response + } else { + self._redirectsFollowed = self._redirectsFollowed || 0 + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) self.response.emit('end') + }) + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") + } else { + response.setEncoding(self.encoding) + } + } + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + response.on("data", function (chunk) { + self._destdata = true + self.emit("data", chunk) + }) + response.on("end", function (chunk) { + self._ended = true + self.emit("end", chunk) + }) + response.on("close", function () {self.emit("close")}) + + self.emit('response', response) + + if (self.onResponse) { + self.onResponse(null, response) + } + if (self.callback) { + var buffer = [] + var bodyLen = 0 + self.on("data", function (chunk) { + buffer.push(chunk) + bodyLen += chunk.length + }) + self.on("end", function () { + if (buffer.length && Buffer.isBuffer(buffer[0])) { + var body = new Buffer(bodyLen) + var i = 0 + buffer.forEach(function (chunk) { + chunk.copy(body, i, 0, chunk.length) + i += chunk.length + }) + if (self.encoding === null) { + response.body = body + } else { + response.body = body.toString() + } + } else if (buffer.length) { + response.body = buffer.join('') + } + + if (self.json) { + try { + response.body = JSON.parse(response.body) + } catch (e) {} + } + + self.callback(null, response, response.body) + }) + } + } + }) + + if (self.timeout && !self.timeoutTimer) { + self.timeoutTimer = setTimeout(function() { + self.req.abort() + var e = new Error("ETIMEDOUT") + e.code = "ETIMEDOUT" + self.emit("error", e) + }, self.timeout) + + // Set additional timeout on socket - in case if remote + // server freeze after sending headers + self.req.setTimeout(self.timeout, function(){ + if (self.req) { + self.req.abort() + var e = new Error("ESOCKETTIMEDOUT") + e.code = "ESOCKETTIMEDOUT" + self.emit("error", e) + } + }); + } + + self.req.on('error', self.clientErrorHandler) + + self.emit('request', self.req) +} +Request.prototype.pipeDest = function (dest) { + var response = this.response + // Called after the response is received + if (dest.headers) { + dest.headers['content-type'] = response.headers['content-type'] + if (response.headers['content-length']) { + dest.headers['content-length'] = response.headers['content-length'] + } + } + if (dest.setHeader) { + for (var i in response.headers) { + dest.setHeader(i, response.headers[i]) + } + dest.statusCode = response.statusCode + } + if (this.pipefilter) this.pipefilter(response, dest) +} + +// Composable API +Request.prototype.setHeader = function (name, value, clobber) { + if (clobber === undefined) clobber = true + if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value + else this.headers[name] += ',' + value + return this +} +Request.prototype.setHeaders = function (headers) { + for (i in headers) {this.setHeader(i, headers[i])} + return this +} +Request.prototype.qs = function (q, clobber) { + var uri = { + protocol: this.uri.protocol, + host: this.uri.host, + pathname: this.uri.pathname, + query: clobber ? q : qs.parse(this.uri.query), + hash: this.uri.hash + }; + if (!clobber) for (var i in q) uri.query[i] = q[i] + + this.uri= url.parse(url.format(uri)) + + return this +} +Request.prototype.form = function (form) { + this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' + this.body = qs.stringify(form).toString('utf8') + return this +} +Request.prototype.multipart = function (multipart) { + var self = this + self.body = [] + + if (!self.headers['content-type']) { + self.headers['content-type'] = 'multipart/related;boundary="frontier"'; + } else { + self.headers['content-type'] = self.headers['content-type'].split(';')[0] + ';boundary="frontier"'; + } + + if (!multipart.forEach) throw new Error('Argument error, options.multipart.') + + multipart.forEach(function (part) { + var body = part.body + if(!body) throw Error('Body attribute missing in multipart.') + delete part.body + var preamble = '--frontier\r\n' + Object.keys(part).forEach(function(key){ + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + self.body.push(new Buffer(preamble)) + self.body.push(new Buffer(body)) + self.body.push(new Buffer('\r\n')) + }) + self.body.push(new Buffer('--frontier--')) + return self +} +Request.prototype.json = function (val) { + this.setHeader('content-type', 'application/json') + this.setHeader('accept', 'application/json') + if (typeof val === 'boolean') { + if (typeof this.body === 'object') this.body = JSON.stringify(this.body) + } else { + this.body = JSON.stringify(val) + } + return this +} +Request.prototype.oauth = function (_oauth) { + var form + if (this.headers['content-type'] && + this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === + 'application/x-www-form-urlencoded' + ) { + form = qs.parse(this.body) + } + if (this.uri.query) { + form = qs.parse(this.uri.query) + } + if (!form) form = {} + var oa = {} + for (var i in form) oa[i] = form[i] + for (var i in _oauth) oa['oauth_'+i] = _oauth[i] + if (!oa.oauth_version) oa.oauth_version = '1.0' + if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() + if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') + + oa.oauth_signature_method = 'HMAC-SHA1' + + var consumer_secret = oa.oauth_consumer_secret + delete oa.oauth_consumer_secret + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname + var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) + + // oa.oauth_signature = signature + for (var i in form) { + if ( i.slice(0, 'oauth_') in _oauth) { + // skip + } else { + delete oa['oauth_'+i] + } + } + this.headers.authorization = + 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') + this.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + return this +} +Request.prototype.jar = function (jar) { + var cookies + + if (this._redirectsFollowed === 0) { + this.originalCookieHeader = this.headers.cookie + } + + if (jar === false) { + // disable cookies + cookies = false; + this._disableCookies = true; + } else if (jar) { + // fetch cookie from the user defined cookie jar + cookies = jar.get({ url: this.uri.href }) + } else { + // fetch cookie from the global cookie jar + cookies = cookieJar.get({ url: this.uri.href }) + } + + if (cookies && cookies.length) { + var cookieString = cookies.map(function (c) { + return c.name + "=" + c.value + }).join("; ") + + if (this.originalCookieHeader) { + // Don't overwrite existing Cookie header + this.headers.cookie = this.originalCookieHeader + '; ' + cookieString + } else { + this.headers.cookie = cookieString + } + } + this._jar = jar + return this +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { if (this.response) { if (this._destdata) { throw new Error("You cannot pipe after data has been emitted from the response.") } else if (this._ended) { throw new Error("You cannot pipe after the response has been ended.") } else { - stream.Stream.prototype.pipe.call(this, dest) + stream.Stream.prototype.pipe.call(this, dest, opts) this.pipeDest(dest) return dest } } else { this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest) + stream.Stream.prototype.pipe.call(this, dest, opts) return dest } } @@ -562,10 +662,11 @@ Request.prototype.write = function () { if (!this.req) throw new Error("This request has been piped before http.request() was called.") this.req.write.apply(this.req, arguments) } -Request.prototype.end = function () { +Request.prototype.end = function (chunk) { + if (chunk) this.write(chunk) if (!this._started) this.start() if (!this.req) throw new Error("This request has been piped before http.request() was called.") - this.req.end.apply(this.req, arguments) + this.req.end() } Request.prototype.pause = function () { if (!this.response) throw new Error("This request has been piped before http.request() was called.") @@ -575,12 +676,36 @@ Request.prototype.resume = function () { if (!this.response) throw new Error("This request has been piped before http.request() was called.") this.response.resume.apply(this.response, arguments) } +Request.prototype.destroy = function () { + if (!this._ended) this.end() +} + +// organize params for post, put, head, del +function initParams(uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + uri = options.uri; + } + return { uri: uri, options: options, callback: callback }; +} + +function request (uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + } -function request (options, callback) { - if (typeof options === 'string') options = {uri:options} - if (callback) options.callback = callback + if (callback) options.callback = callback; var r = new Request(options) - r.request() return r } @@ -588,12 +713,12 @@ module.exports = request request.defaults = function (options) { var def = function (method) { - var d = function (opts, callback) { - if (typeof opts === 'string') opts = {uri:opts} + var d = function (uri, opts, callback) { + var params = initParams(uri, opts, callback); for (var i in options) { - if (opts[i] === undefined) opts[i] = options[i] + if (params.options[i] === undefined) params.options[i] = options[i] } - return method(opts, callback) + return method(params.uri, params.options, params.callback) } return d } @@ -620,33 +745,34 @@ request.forever = function (agentOptions, optionsArg) { } request.get = request -request.post = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'POST' - return request(options, callback) -} -request.put = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'PUT' - return request(options, callback) -} -request.head = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'HEAD' +request.post = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'POST'; + return request(params.uri, params.options, params.callback) +} +request.put = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'PUT' + return request(params.uri, params.options, params.callback) +} +request.head = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'HEAD' if (options.body || options.requestBodyStream || options.json || options.multipart) { throw new Error("HTTP HEAD requests MUST NOT include a request body.") } - return request(options, callback) + return request(params.uri, params.options, params.callback) } -request.del = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'DELETE' - return request(options, callback) +request.del = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'DELETE' + return request(params.uri, params.options, params.callback) } request.jar = function () { return new CookieJar } request.cookie = function (str) { + if (str && str.uri) str = str.uri if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") return new Cookie(str) } diff --git a/deps/npm/node_modules/request/mimetypes.js b/deps/npm/node_modules/request/mimetypes.js index 86910064c9..59b21b419c 100644 --- a/deps/npm/node_modules/request/mimetypes.js +++ b/deps/npm/node_modules/request/mimetypes.js @@ -1,5 +1,6 @@ // from http://github.com/felixge/node-paperboy exports.types = { + "3gp":"video/3gpp", "aiff":"audio/x-aiff", "arj":"application/x-arj-compressed", "asf":"video/x-ms-asf", @@ -50,17 +51,21 @@ exports.types = { "lzh":"application/octet-stream", "m":"text/plain", "m3u":"audio/x-mpegurl", + "m4v":"video/mp4", "man":"application/x-troff-man", "me":"application/x-troff-me", "midi":"audio/midi", "mif":"application/x-mif", "mime":"www/mime", + "mkv":" video/x-matrosk", "movie":"video/x-sgi-movie", - "mustache":"text/plain", "mp4":"video/mp4", + "mp41":"video/mp4", + "mp42":"video/mp4", "mpg":"video/mpeg", "mpga":"audio/mpeg", "ms":"application/x-troff-ms", + "mustache":"text/plain", "nc":"application/x-netcdf", "oda":"application/oda", "ogm":"application/ogg", @@ -123,6 +128,7 @@ exports.types = { "vrm":"x-world/x-vrml", "wav":"audio/x-wav", "wax":"audio/x-ms-wax", + "webm":"video/webm", "wma":"audio/x-ms-wma", "wmv":"video/x-ms-wmv", "wmx":"video/x-ms-wmx", @@ -134,7 +140,7 @@ exports.types = { "xpm":"image/x-xpixmap", "xwd":"image/x-xwindowdump", "xyz":"chemical/x-pdb", - "zip":"application/zip", + "zip":"application/zip" }; exports.lookup = function(ext, defaultType) { diff --git a/deps/npm/node_modules/request/oauth.js b/deps/npm/node_modules/request/oauth.js index 25db669775..31b9dc65fe 100644 --- a/deps/npm/node_modules/request/oauth.js +++ b/deps/npm/node_modules/request/oauth.js @@ -19,7 +19,7 @@ function rfc3986 (str) { function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret, body) { // adapted from https://dev.twitter.com/docs/auth/oauth var base = - httpMethod + "&" + + (httpMethod || 'GET') + "&" + encodeURIComponent( base_uri ) + "&" + Object.keys(params).sort().map(function (i) { // big WTF here with the escape + encoding but it's what twitter wants diff --git a/deps/npm/node_modules/request/package.json b/deps/npm/node_modules/request/package.json index 7e194d583c..305cf167b1 100644 --- a/deps/npm/node_modules/request/package.json +++ b/deps/npm/node_modules/request/package.json @@ -1,7 +1,7 @@ { "name" : "request" , "description" : "Simplified HTTP request client." , "tags" : ["http", "simple", "util", "utility"] -, "version" : "2.9.100" +, "version" : "2.9.151" , "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>" , "repository" : { "type" : "git" @@ -11,5 +11,5 @@ { "url" : "http://github.com/mikeal/request/issues" } , "engines" : ["node >= 0.3.6"] , "main" : "./main" -, "scripts": { "test": "bash tests/run.sh" } +, "scripts": { "test": "node tests/run.js" } } diff --git a/deps/npm/package.json b/deps/npm/package.json index b94dbeca17..25d30fbe0a 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -10,7 +10,7 @@ "install", "package.json" ], - "version": "1.1.1", + "version": "1.1.2", "preferGlobal": true, "config": { "publishtest": false |