mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
deps: upgrade npm to 7.5.0
PR-URL: https://github.com/nodejs/node/pull/37117 Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
133 files changed
+12634
-3495
No files matched your search
Vendored
+1
@@ -747,3 +747,4 @@ marsonya <16393876+marsonya@users.noreply.github.com>
|
||||
Jeff Griffiths <jeff@eko-recordings.ca>
|
||||
Michael Garvin <gar+gh@danger.computer>
|
||||
Gar <gar+gh@danger.computer>
|
||||
dr-js <dr@dr.run>
|
||||
Vendored
+57
@@ -1,3 +1,60 @@
|
||||
## v7.5.0 (2021-01-28)
|
||||
|
||||
### FEATURES
|
||||
|
||||
* [`d011266b7`](https://github.com/npm/cli/commit/d011266b733367aad283ccbfb9d2b19442c3405f)
|
||||
[#1319](https://github.com/npm/cli/issues/1319)
|
||||
add npm diff command
|
||||
([@ruyadorno](https://github.com/ruyadorno))
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
* [`d2f8af2da`](https://github.com/npm/cli/commit/d2f8af2da64d510d3d363aec10531bebf840d84e)
|
||||
[#2445](https://github.com/npm/cli/issues/2445)
|
||||
publish: don't complain about missing auth until after registry is chosen
|
||||
([@dr-js](https://github.com/dr-js))
|
||||
|
||||
### DOCUMENTATION
|
||||
|
||||
* [`8d3fd63aa`](https://github.com/npm/cli/commit/8d3fd63aaa6a5c9b3d2281dd0bd9e1c270b35941)
|
||||
[#2559](https://github.com/npm/cli/issues/2559)
|
||||
updates to readme, removal, contributing and several other docs
|
||||
([@darcyclarke](https://github.com/darcyclarke))
|
||||
* [`7772d9f9f`](https://github.com/npm/cli/commit/7772d9f9f9f853573a7ff8e7fb60c5e46566f596)
|
||||
[#2542](https://github.com/npm/cli/issues/2542)
|
||||
fix grammar on caching docs for search, exec and init
|
||||
([@wraithgar](https://github.com/wraithgar))
|
||||
* [`52e8a1aef`](https://github.com/npm/cli/commit/52e8a1aef4aab3f378c20276a9109bb3f00eccd5)
|
||||
[#2558](https://github.com/npm/cli/issues/2558)
|
||||
refreshed npm updated docs
|
||||
([@ruyadorno](https://github.com/ruyadorno))
|
||||
* [`abae00ca0`](https://github.com/npm/cli/commit/abae00ca05925e521696dd12480853509aab6c0a)
|
||||
[#2565](https://github.com/npm/cli/issues/2565)
|
||||
update npm command docs
|
||||
([@wraithgar](https://github.com/wraithgar))
|
||||
* [`9351cbf9a`](https://github.com/npm/cli/commit/9351cbf9afd2310c56b9953c005505ea5126a5d4)
|
||||
[#2566](https://github.com/npm/cli/issues/2566)
|
||||
refresh npm run-script docs
|
||||
([@ruyadorno](https://github.com/ruyadorno))
|
||||
|
||||
### DEPENDENCIES
|
||||
|
||||
* [`56c08863e`](https://github.com/npm/cli/commit/56c08863e15cb9cf8662b99ddc627cfcdff0348d)
|
||||
`hosted-git-info@3.0.8`
|
||||
* [`18a93f06b`](https://github.com/npm/cli/commit/18a93f06b632be051b9455e32a85e4e75066f52c)
|
||||
`ssri@8.0.1`
|
||||
* [`cb768f671`](https://github.com/npm/cli/commit/cb768f671c4d8d5a09d9a6c5a74227d300e81104)
|
||||
`@npmcli/move-file@1.1.1`
|
||||
* [`32cc0a4be`](https://github.com/npm/cli/commit/32cc0a4be76465093e3d0f314215a0ec46dc03c6)
|
||||
`minipass-fetch@1.3.3`
|
||||
* fixes ssl settings passthrough
|
||||
* [`530997968`](https://github.com/npm/cli/commit/530997968fbbd9e8bf016689b1d192daa812b4de)
|
||||
`@npmcli/arborist@2.1.0`
|
||||
* added signal handler to rollback when possible
|
||||
* prevent ERESOLVEs caused by loose root dep specs
|
||||
* detect conflicts among nested peerOptional deps
|
||||
* properly buildIdealTree when root is a symlink
|
||||
|
||||
## v7.4.3 (2021-01-21)
|
||||
|
||||
### DOCUMENTATION
|
||||
|
||||
Vendored
+29
-164
@@ -1,191 +1,56 @@
|
||||
# npm CLI Contributor Roles and Responsibilities
|
||||
# Contributing
|
||||
|
||||
## Table of Contents
|
||||
## Code of Conduct
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Code Structure](#code-structure)
|
||||
* [Running Tests](#running-tests)
|
||||
* [Debugging](#debugging)
|
||||
* [Coverage](#coverage)
|
||||
* [Benchmarking](#benchmarking)
|
||||
* [Types of Contributions](#types-of-contributions)
|
||||
* [Contributing an Issue?](#contributing-an-issue)
|
||||
* [Contributing a Question?](#contributing-a-question)
|
||||
* [Contributing a Bug Fix?](#contributing-a-bug-fix)
|
||||
* [Contributing a Feature?](#contributing-a-bug-feature)
|
||||
* [Development Dependencies](#development-dependencies)
|
||||
* [Dependencies](#dependencies)
|
||||
All interactions in the **npm** organization on GitHub are considered to be covered by our standard [Code of Conduct](https://www.npmjs.com/policies/conduct).
|
||||
|
||||
## Introduction
|
||||
## Development
|
||||
|
||||
Welcome to the npm CLI Contributor Guide! This document outlines the npm CLI repository's process for community interaction and contribution. This includes the issue tracker, pull requests, wiki pages, and, to a certain extent, outside communication in the context of the npm CLI. This is an entry point for anyone wishing to contribute their time and effort to making npm a better tool for the JavaScript community!
|
||||
**1. Clone this repository...**
|
||||
|
||||
All interactions in the npm repository are covered by the [npm Code of Conduct](https://www.npmjs.com/policies/conduct)
|
||||
|
||||
|
||||
## Code Structure
|
||||
```
|
||||
/
|
||||
├── bin/
|
||||
│ │ # Directory for executable files. It's very rare that you
|
||||
│ │ # will need to update a file in this directory.
|
||||
│ │
|
||||
│ ├── npm # npm-cli entrypoint for bourne shell
|
||||
│ ├── npm-cli.js # npm-cli entrypoint for node
|
||||
│ ├── npm.cmd # npm-cli entrypoint for windows
|
||||
│ ├── npx # npx entrypoint for bourne shell
|
||||
│ ├── npx-cli.js # npx entrypoint for node
|
||||
│ └── npx.cmd # npx entrypoint for windows
|
||||
│
|
||||
├── docs/ 📖
|
||||
│ │ # Directory that contains the documentation website for
|
||||
│ │ # the npm-cli. You can run this website locally, and have
|
||||
│ │ # offline docs! 🔥📖🤓
|
||||
│ │
|
||||
│ ├── content/ # Markdown files for site content
|
||||
│ ├── src/ # Source files for the website; gatsby related
|
||||
│ └── package.json # Site manifest; scripts and dependencies
|
||||
│
|
||||
├── lib/ 📦
|
||||
│ # All the Good Bits(tm) of the CLI project live here
|
||||
│
|
||||
├── node_modules/ 🔋
|
||||
│ # Vendored dependencies for the CLI project (See the
|
||||
│ # dependencies section below for more details).
|
||||
│
|
||||
├── scripts/ 📜
|
||||
│ # We've created some helper scripts for working with the
|
||||
│ # CLI project, specifically around managing our vendored
|
||||
│ # dependencies, merging in pull-requests, and publishing
|
||||
│ # releases.
|
||||
│
|
||||
├── test/ 🧪
|
||||
│ # All the tests for the CLI live in this folder. We've
|
||||
│ # got a lot of tests 🤓🧪🩺
|
||||
│
|
||||
├── CONTRIBUTING.md # This file! 🎉
|
||||
└── package.json # The projects main manifest file 📃
|
||||
```bash
|
||||
$ git clone git@github.com:npm/cli.git
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
**2. Navigate into project & install development-specific dependencies...**
|
||||
|
||||
```bash
|
||||
$ cd ./npm && npm install
|
||||
```
|
||||
# Make sure you install the dependencies first before running tests.
|
||||
$ npm install
|
||||
|
||||
# Run tests for the CLI (it could take a while).
|
||||
**3. Write some code &/or add some tests...**
|
||||
|
||||
```bash
|
||||
...
|
||||
```
|
||||
|
||||
**4. Run tests & ensure they pass...**
|
||||
```
|
||||
$ npm run test
|
||||
```
|
||||
|
||||
## Debugging
|
||||
**5. Open a [Pull Request](https://github.com/npm/cli/pulls) for your work & become the newest conributor to `npm`! 🎉**
|
||||
|
||||
It can be tricky to track down issues in the CLI. It's a large code base that has been evolving for over a decade. There is a handy `make` command that will connect the **cloned repository** you have on your machine with the global command, so you can add `console.log` statements or debug any other way you feel most comfortable with.
|
||||
## Test Coverage
|
||||
|
||||
```
|
||||
# Clone the repository to start with
|
||||
$ git clone git@github.com:npm/cli.git
|
||||
We expect that every new feature or bug fix comes with corresponding tests that validate the solutions. We strive to have as close to, if not exactly, 100% code coverage.
|
||||
|
||||
# Change working directories into the repository
|
||||
$ cd cli
|
||||
**You can find out what the current test coverage percentage is by running...**
|
||||
|
||||
# Make sure you have the latest code (if that's what you're trying to debug)
|
||||
$ git fetch origin latest
|
||||
|
||||
# Connect repository to the global namespace
|
||||
$ make link
|
||||
|
||||
#################
|
||||
# ALTERNATIVELY
|
||||
#################
|
||||
# If you're working on a feature or bug, you can run the same command on your
|
||||
# working branch and link that code.
|
||||
|
||||
# Create new branch to work from (there are many ways)
|
||||
$ git checkout -b feature/awesome-feature
|
||||
|
||||
# Connect repository to global namespace
|
||||
$ make link
|
||||
```
|
||||
|
||||
## Coverage
|
||||
|
||||
We try and make sure that each new feature or bug fix has tests to go along with them in order to keep code coverages consistent and increasing. We are actively striving for 100% code coverage!
|
||||
|
||||
```
|
||||
# You can run the following command to find out coverage
|
||||
```bash
|
||||
$ npm run test-coverage
|
||||
```
|
||||
|
||||
## Benchmarking
|
||||
## Performance & Benchmarks
|
||||
|
||||
We often want to know if the bug we've fixed for the feature we've added has any sort of performance impact. We've created a [benchmark suite](https://github.com/npm/benchmarks) to run against the CLI project from pull-requests. If you would like to know if there are any performance impacts to the work you're contributing, simply do the following:
|
||||
We've set up an automated [benchmark](https://github.com/npm/benchmarks) integration that will run against all Pull Requests; Posting back a comment with the results of the run.
|
||||
|
||||
1. Make a pull-request against this repository
|
||||
2. Add the following comment to the pull-request: "`test this please ✅`"
|
||||
|
||||
This will trigger the [benchmark suite](https://github.com/npm/benchmarks) to run against your pull-request, and when it's finished running it will post a comment on your pull-request just like below. You'll be able to see the results from the suite inline in your pull-request.
|
||||
|
||||
> You'll notice that the bot-user will also add a 🚀 reaction to your comment to
|
||||
let you know that it's sent the request to start the benchmark suite.
|
||||
**Example:**
|
||||
|
||||

|
||||
|
||||
If you've updated your pull-request and you'd like to run the the benchmark suite again, simple update your original comment, by adding `test this please ✅` again, or simply just adding another emoji to the **end**. _(The trigger is the phrase "test this please ✅" at the beginning of a comment. Updates will trigger as well, so long as the phrase stays at the beginning.)_.
|
||||
You can learn more about this tool, including how to run & configure it manually, [here](https://github.com/npm/benchmarks)
|
||||
|
||||

|
||||
## Reporting Bugs
|
||||
|
||||
## Types of Contributions
|
||||
|
||||
### Contributing an Issue?
|
||||
|
||||
Great!! Is your [new issue](https://github.com/npm/cli/issues/new/choose) a [bug](https://github.com/npm/cli/issues/new?template=bug.md&title=%5BBUG%5D+%3Ctitle%3E), a [feature](https://github.com/npm/cli/issues/new?template=feature.md&title=%5BFEATURE%5D+%3Ctitle%3E), or a [question](https://github.com/npm/cli/issues/new?template=question.md&title=%5BQUESTION%5D+%3Ctitle%3E)?
|
||||
|
||||
### Contributing a Question?
|
||||
|
||||
Huh? 🤔 Got a situation you're not sure about?! Perfect! We've got some resources you can use.
|
||||
|
||||
* Our [documentation site](https://docs.npmjs.com/)
|
||||
* The local docs that come with the CLI project
|
||||
|
||||
> **Example**: `npm help install --viewer browser`
|
||||
|
||||
* The man pages that are built and shipped with the CLI
|
||||
|
||||
> **Example**: `man npm-install` (only on linux/macOS)
|
||||
|
||||
* Search of the [current issues](https://github.com/npm/cli/issues)
|
||||
|
||||
### Contributing a Bug Fix?
|
||||
|
||||
We'd be happy to triage and help! Head over to the issues and [create a new one](https://github.com/npm/cli/issues/new?template=bug.md&title=%5BBUG%5D+%3Ctitle%3E)!
|
||||
|
||||
> We'll need a little bit of information about what happened, rather than "it broke". Such as:
|
||||
* When did/does this bug happen?
|
||||
* Can you reproduce it? _(Can you make it happen more than once.)_
|
||||
* What version of `node`/`npm` are you running on your computer?
|
||||
* What did you expect it to do?
|
||||
* What did it _actually do?
|
||||
* etc...
|
||||
|
||||
### Contributing a Feature?
|
||||
|
||||
Snazzy, we're always up for fancy new things! If the feature is fairly minor, the team can triage it and prioritize it into our backlog. However, if the feature is a little more complex, then it's best to create an [RFC](https://en.wikipedia.org/wiki/Request_for_Comments) in our [RFC repository](https://github.com/npm/rfcs). Exactly how to do that is outlined in that repository. If you're not sure _exactly_ how to implement your idea, or don't want to make a document about your idea, then please create an issue on that repository. We consider these RRFC's, or a "Requesting Request For Comment".
|
||||
|
||||
## Development Dependencies
|
||||
|
||||
You'll need a few things installed in order to update and test the CLI project during development:
|
||||
|
||||
* [node](https://nodejs.org/) v8 or greater
|
||||
|
||||
> We recommend that you have a [node version manager](https://github.com/nvm-sh/nvm) installed if you plan on fixing bugs that might be present in a specific version of node. With a version manager you can easily switch versions of node and test if your changes to the CLI project are working.
|
||||
|
||||
* [git](https://git-scm.com/) v2.11+
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
> Package vendoring is commonly referred to as the case where dependent packages are stored in the same place as your project. That usually means you dependencies are checked into your source management system, such as Git.
|
||||
|
||||
The CLI project vendors its dependencies in the `node_modules/` folder. Meaning all the dependencies that the CLI project uses are contained within the project itself. This is represented by the `bundledDependencies` section in the root level `package.json` file. The main reason for this is because the `npm` CLI project is distributed with the NodeJS runtime and needs to work out of the box, which means all dependencies need to be available after the runtime is installed.
|
||||
|
||||
There are a couple scripts created to help manage this process in the `scripts/` folder.
|
||||
When submitting a new bug report, please first [search](https://github.com/npm/cli/issues) for an existing or similar report & then use one of our existing [issue templates](https://github.com/npm/cli/issues/new/choose) if you believe you've come across a unique problem. Duplicate issues, or issues that don't use one of our templates may get closed without a response.
|
||||
Vendored
+35
-145
@@ -1,163 +1,53 @@
|
||||
npm(1) -- a JavaScript package manager
|
||||
==============================
|
||||
[](https://github.com/npm/cli/actions?query=workflow%3A%22Node+CI%22+branch%3Alatest) [](https://coveralls.io/github/npm/cli?branch=latest)
|
||||
|
||||
[](https://travis-ci.org/npm/cli)
|
||||
# npm - a JavaScript package manager
|
||||
|
||||
## SYNOPSIS
|
||||
### Requirements
|
||||
|
||||
This is just enough info to get you up and running.
|
||||
* [**Node.js** `v10`](https://nodejs.org/en/download/) or higher must be installed to run this program
|
||||
|
||||
Much more info will be available via `npm help` once it's installed.
|
||||
### Installation
|
||||
|
||||
## IMPORTANT
|
||||
**`npm`** comes bundled with [**`node`**](https://nodejs.org/), & most third-party distributions, by default. Officially supported downloads/distributions can be found at: [nodejs.org/en/download](https://nodejs.org/en/download)
|
||||
|
||||
**You need node v6 or higher to run this program.**
|
||||
#### Direct Download
|
||||
|
||||
To install an old **and unsupported** version of npm that works on node v5
|
||||
and prior, clone the git repo and dig through the old tags and branches.
|
||||
You can download & install **`npm`** directly from [**npmjs**.com](https://npmjs.com/) using our custom `install.sh` script:
|
||||
|
||||
**npm is configured to use npm, Inc.'s public registry at
|
||||
<https://registry.npmjs.org> by default.** Use of the npm public registry
|
||||
is subject to terms of use available at <https://www.npmjs.com/policies/terms>.
|
||||
|
||||
You can configure npm to use any compatible registry you
|
||||
like, and even run your own registry. Check out the [doc on
|
||||
registries](https://docs.npmjs.com/misc/registry).
|
||||
|
||||
## Super Easy Install
|
||||
|
||||
npm is bundled with [node](https://nodejs.org/en/download/).
|
||||
|
||||
### Windows Computers
|
||||
|
||||
[Get the MSI](https://nodejs.org/en/download/). npm is in it.
|
||||
|
||||
### Apple Macintosh Computers
|
||||
|
||||
[Get the pkg](https://nodejs.org/en/download/). npm is in it.
|
||||
|
||||
### Other Sorts of Unices
|
||||
|
||||
Run `make install`. npm will be installed with node.
|
||||
|
||||
If you want a more fancy pants install (a different version, customized
|
||||
paths, etc.) then read on.
|
||||
|
||||
## Fancy Install (Unix)
|
||||
|
||||
There's a pretty robust install script at
|
||||
<https://www.npmjs.com/install.sh>. You can download that and run it.
|
||||
|
||||
Here's an example using curl:
|
||||
|
||||
```sh
|
||||
```bash
|
||||
curl -L https://www.npmjs.com/install.sh | sh
|
||||
```
|
||||
|
||||
### Slightly Fancier
|
||||
#### Node Version Managers
|
||||
|
||||
You can set any npm configuration params with that script:
|
||||
If you're looking to manage multiple versions of **`node`** &/or **`npm`**, consider using a "Node Version Manager" such as:
|
||||
|
||||
```sh
|
||||
npm_config_prefix=/some/path sh install.sh
|
||||
* [**`nvm`**](https://github.com/nvm-sh/nvm)
|
||||
* [**`nvs`**](https://github.com/jasongin/nvs)
|
||||
* [**`nave`**](https://github.com/isaacs/nave)
|
||||
* [**`n`**](https://github.com/tj/n)
|
||||
* [**`volta`**](https://github.com/volta-cli/volta)
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
npm <command>
|
||||
```
|
||||
|
||||
Or, you can run it in uber-debuggery mode:
|
||||
### Links & Resources
|
||||
|
||||
```sh
|
||||
npm_debug=1 sh install.sh
|
||||
```
|
||||
* [**Documentation**](https://docs.npmjs.com/) - Official docs & how-tos for all things **npm**
|
||||
* Note: you can also search docs locally with `npm help-search <query>`
|
||||
* [**Bug Tracker**](https://github.com/npm/cli/issues) - Search or submit bugs against the CLI
|
||||
* [**Roadmap**](https://github.com/npm/roadmap) - Track & follow along with our public roadmap
|
||||
* [**Feedback**](https://github.com/npm/feedback) - Contribute ideas & discussion around the npm registry, website & CLI
|
||||
* [**RFCs**](https://github.com/npm/rfcs) - Contribute ideas & specifications for the API/design of the npm CLI
|
||||
* [**Service Status**](https://status.npmjs.org/) - Monitor the current status & see incident reports for the website & registry
|
||||
* [**Project Status**](https://npm.github.io/statusboard/) - See the health of all our maintained OSS projects in one view
|
||||
* [**Events Calendar**](https://calendar.google.com/calendar/u/0/embed?src=npmjs.com_oonluqt8oftrt0vmgrfbg6q6go@group.calendar.google.com) - Keep track of our Open RFC calls, releases, meetups, conferences & more
|
||||
* [**Support**](https://www.npmjs.com/support) - Experiencing problems with the **npm** [website](https://npmjs.com) or [registry](https://registry.npmjs.org)? File a ticket [here](https://www.npmjs.com/support)
|
||||
|
||||
### Even Fancier
|
||||
### Acknowledgments
|
||||
|
||||
Get the code with git. Use `make` to build the docs and do other stuff.
|
||||
If you plan on hacking on npm, `make link` is your friend.
|
||||
|
||||
If you've got the npm source code, you can also semi-permanently set
|
||||
arbitrary config keys using the `./configure --key=val ...`, and then
|
||||
run npm commands by doing `node bin/npm-cli.js <command> <args>`. (This is helpful
|
||||
for testing, or running stuff without actually installing npm itself.)
|
||||
|
||||
## Windows Install or Upgrade
|
||||
|
||||
Many improvements for Windows users have been made in npm 3 - you will have a better
|
||||
experience if you run a recent version of npm. To upgrade, either use [Microsoft's
|
||||
upgrade tool](https://github.com/felixrieseberg/npm-windows-upgrade),
|
||||
[download a new version of Node](https://nodejs.org/en/download/),
|
||||
or follow the Windows upgrade instructions in the
|
||||
[Installing/upgrading npm](https://npm.community/t/installing-upgrading-npm/251/2) post.
|
||||
|
||||
If that's not fancy enough for you, then you can fetch the code with
|
||||
git, and mess with it directly.
|
||||
|
||||
## Installing on Cygwin
|
||||
|
||||
No.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
So sad to see you go.
|
||||
|
||||
```sh
|
||||
sudo npm uninstall npm -g
|
||||
```
|
||||
Or, if that fails,
|
||||
|
||||
```sh
|
||||
sudo make uninstall
|
||||
```
|
||||
|
||||
## More Severe Uninstalling
|
||||
|
||||
Usually, the above instructions are sufficient. That will remove
|
||||
npm, but leave behind anything you've installed.
|
||||
|
||||
If you would like to remove all the packages that you have installed,
|
||||
then you can use the `npm ls` command to find them, and then `npm rm` to
|
||||
remove them.
|
||||
|
||||
To remove cruft left behind by npm 0.x, you can use the included
|
||||
`clean-old.sh` script file. You can run it conveniently like this:
|
||||
|
||||
```sh
|
||||
npm explore npm -g -- sh scripts/clean-old.sh
|
||||
```
|
||||
|
||||
npm uses two configuration files, one for per-user configs, and another
|
||||
for global (every-user) configs. You can view them by doing:
|
||||
|
||||
```sh
|
||||
npm config get userconfig # defaults to ~/.npmrc
|
||||
npm config get globalconfig # defaults to /usr/local/etc/npmrc
|
||||
```
|
||||
|
||||
Uninstalling npm does not remove configuration files by default. You
|
||||
must remove them yourself manually if you want them gone. Note that
|
||||
this means that future npm installs will not remember the settings that
|
||||
you have chosen.
|
||||
|
||||
## More Docs
|
||||
|
||||
Check out the [docs](https://docs.npmjs.com/).
|
||||
|
||||
You can use the `npm help` command to read any of them.
|
||||
|
||||
If you're a developer, and you want to use npm to publish your program,
|
||||
you should [read this](https://docs.npmjs.com/misc/developers).
|
||||
|
||||
## BUGS
|
||||
|
||||
When you find issues, please report them:
|
||||
|
||||
* web:
|
||||
<https://github.com/npm/cli/issues>
|
||||
* archived web:
|
||||
<https://npm.community/c/bugs>
|
||||
|
||||
Be sure to include *all* of the output from the npm command that didn't work
|
||||
as expected. The `npm-debug.log` file is also helpful to provide.
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
* npm(1)
|
||||
* npm-help(1)
|
||||
* `npm` is configured to use the **npm Public Registry** at [https://registry.npmjs.org](https://registry.npmjs.org) by default; Usage of this registry is subject to **Terms of Use** available at [https://npmjs.com/policies/terms](https://npmjs.com/policies/terms)
|
||||
* You can configure `npm` to use any other compatible registry you prefer. You can read more about configuring third-party registries [here](https://docs.npmjs.com/cli/v7/using-npm/registry)
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
---
|
||||
title: npm-diff
|
||||
section: 1
|
||||
description: The registry diff command
|
||||
---
|
||||
|
||||
### Synopsis
|
||||
|
||||
```bash
|
||||
npm diff [...<paths>]
|
||||
npm diff --diff=<pkg-name> [...<paths>]
|
||||
npm diff --diff=<version-a> [--diff=<version-b>] [...<paths>]
|
||||
npm diff --diff=<spec-a> [--diff=<spec-b>] [...<paths>]
|
||||
npm diff [--diff-ignore-all-space] [--diff-name-only] [...<paths>]
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Similar to its `git diff` counterpart, this command will print diff patches
|
||||
of files for packages published to the npm registry.
|
||||
|
||||
* `npm diff --diff=<spec-a> --diff=<spec-b>`
|
||||
|
||||
Compares two package versions using their registry specifiers, e.g:
|
||||
`npm diff --diff=pkg@1.0.0 --diff=pkg@^2.0.0`. It's also possible to
|
||||
compare across forks of any package,
|
||||
e.g: `npm diff --diff=pkg@1.0.0 --diff=pkg-fork@1.0.0`.
|
||||
|
||||
Any valid spec can be used, so that it's also possible to compare
|
||||
directories or git repositories,
|
||||
e.g: `npm diff --diff=pkg@latest --diff=./packages/pkg`
|
||||
|
||||
Here's an example comparing two different versions of a package named
|
||||
`abbrev` from the registry:
|
||||
|
||||
```bash
|
||||
npm diff --diff=abbrev@1.1.0 --diff=abbrev@1.1.1
|
||||
```
|
||||
|
||||
On success, output looks like:
|
||||
|
||||
```bash
|
||||
diff --git a/package.json b/package.json
|
||||
index v1.1.0..v1.1.1 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
- "version": "1.1.0",
|
||||
+ "version": "1.1.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"main": "abbrev.js",
|
||||
```
|
||||
|
||||
Given the flexible nature of npm specs, you can also target local
|
||||
directories or git repos just like when using `npm install`:
|
||||
|
||||
```bash
|
||||
npm diff --diff=https://github.com/npm/libnpmdiff --diff=./local-path
|
||||
```
|
||||
|
||||
In the example above we can compare the contents from the package installed
|
||||
from the git repo at `github.com/npm/libnpmdiff` with the contents of the
|
||||
`./local-path` that contains a valid package, such as a modified copy of
|
||||
the original.
|
||||
|
||||
* `npm diff` (in a package directory, no arguments):
|
||||
|
||||
If the package is published to the registry, `npm diff` will fetch the
|
||||
tarball version tagged as `latest` (this value can be configured using the
|
||||
`tag` option) and proceed to compare the contents of files present in that
|
||||
tarball, with the current files in your local file system.
|
||||
|
||||
This workflow provides a handy way for package authors to see what
|
||||
package-tracked files have been changed in comparison with the latest
|
||||
published version of that package.
|
||||
|
||||
* `npm diff --diff=<pkg-name>` (in a package directory):
|
||||
|
||||
When using a single package name (with no version or tag specifier) as an
|
||||
argument, `npm diff` will work in a similar way to
|
||||
[`npm-outdated`](npm-outdated) and reach for the registry to figure out
|
||||
what current published version of the package named <pkg-name> will satisfy
|
||||
its dependent declared semver-range. Once that specific version is known
|
||||
`npm diff` will print diff patches comparing the current version of
|
||||
<pkg-name> found in the local file system with that specific version
|
||||
returned by the registry.
|
||||
|
||||
Given a package named `abbrev` that is currently installed:
|
||||
|
||||
```bash
|
||||
npm diff --diff=abbrev
|
||||
```
|
||||
|
||||
That will request from the registry its most up to date version and
|
||||
will print a diff output comparing the currently installed version to this
|
||||
newer one if the version numbers are not the same.
|
||||
|
||||
* `npm diff --diff=<spec-a>` (in a package directory):
|
||||
|
||||
Similar to using only a single package name, it's also possible to declare
|
||||
a full registry specifier version if you wish to compare the local version
|
||||
of an installed package with the specific version/tag/semver-range provided
|
||||
in `<spec-a>`.
|
||||
|
||||
An example: assuming `pkg@1.0.0` is installed in the current `node_modules`
|
||||
folder, running:
|
||||
|
||||
```bash
|
||||
npm diff --diff=pkg@2.0.0
|
||||
```
|
||||
|
||||
It will effectively be an alias to
|
||||
`npm diff --diff=pkg@1.0.0 --diff=pkg@2.0.0`.
|
||||
|
||||
* `npm diff --diff=<semver-a> [--diff=<semver-b>]` (in a package directory):
|
||||
|
||||
Using `npm diff` along with semver-valid version numbers is a shorthand
|
||||
to compare different versions of the current package.
|
||||
|
||||
It needs to be run from a package directory, such that for a package named
|
||||
`pkg` running `npm diff --diff=1.0.0 --diff=1.0.1` is the same as running
|
||||
`npm diff --diff=pkg@1.0.0 --diff=pkg@1.0.1`.
|
||||
|
||||
If only a single argument `<version-a>` is provided, then the current local
|
||||
file system is going to be compared against that version.
|
||||
|
||||
Here's an example comparing two specific versions (published to the
|
||||
configured registry) of the current project directory:
|
||||
|
||||
```bash
|
||||
npm diff --diff=1.0.0 --diff=1.1.0
|
||||
```
|
||||
|
||||
Note that tag names are not valid `--diff` argument values, if you wish to
|
||||
compare to a published tag, you must use the `pkg@tagname` syntax.
|
||||
|
||||
#### Filtering files
|
||||
|
||||
It's possible to also specify positional arguments using file names or globs
|
||||
pattern matching in order to limit the result of diff patches to only a subset
|
||||
of files for a given package, e.g:
|
||||
|
||||
```bash
|
||||
npm diff --diff=pkg@2 ./lib/ CHANGELOG.md
|
||||
```
|
||||
|
||||
In the example above the diff output is only going to print contents of files
|
||||
located within the folder `./lib/` and changed lines of code within the
|
||||
`CHANGELOG.md` file.
|
||||
|
||||
### Configuration
|
||||
|
||||
#### diff
|
||||
|
||||
* Type: Array<String>
|
||||
* Default: null
|
||||
|
||||
Defines npm package specifiers to compare using the `npm diff` command.
|
||||
|
||||
This can be specified up to 2 times.
|
||||
|
||||
#### diff-name-only
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
When set to `true` running `npm diff` only returns the names of the files that
|
||||
have any difference.
|
||||
|
||||
#### diff-unified
|
||||
|
||||
* Type: Number
|
||||
* Default: `3`
|
||||
|
||||
The number of lines of context to print in the unified diff format output.
|
||||
|
||||
#### diff-ignore-all-space
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Ignore whitespace when comparing lines. This ignores differences even if one
|
||||
line has whitespace where the other line has none.
|
||||
|
||||
#### diff-no-prefix
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Do not show any source or destination prefix.
|
||||
|
||||
#### diff-src-prefix
|
||||
|
||||
* Type: String
|
||||
* Default: `"a/"`
|
||||
|
||||
Show the given source prefix in diff patches headers instead of using "a/".
|
||||
|
||||
#### diff-dst-prefix
|
||||
|
||||
* Type: String
|
||||
* Default: `"b/"`
|
||||
|
||||
Show the given source prefix in diff patches headers instead of using "b/".
|
||||
|
||||
#### diff-text
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Treat all files as text.
|
||||
|
||||
#### global
|
||||
|
||||
* Default: false
|
||||
* Type: Boolean
|
||||
|
||||
Uses packages from the global space as a source for comparison.
|
||||
|
||||
#### tag
|
||||
|
||||
* Type: String
|
||||
* Default: `"latest"`
|
||||
|
||||
The tag used to fetch the tarball that will be compared with the local file
|
||||
system files when running npm diff with no arguments.
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
* [npm outdated](/commands/npm-outdated)
|
||||
* [npm install](/commands/npm-install)
|
||||
* [npm config](/commands/npm-config)
|
||||
* [npm registry](/using-npm/registry)
|
||||
+22
@@ -173,6 +173,28 @@ This resulted in some shifts in its functionality:
|
||||
- The `--shell` option is replaced with `--script-shell`, but maintained
|
||||
in the `npx` executable for backwards compatibility.
|
||||
|
||||
### A note on caching
|
||||
|
||||
The npm cli utilizes its internal package cache when using the package
|
||||
name specified. You can use the following to change how and when the
|
||||
cli uses this cache. See [`npm cache`](/commands/npm-cache) for more on
|
||||
how the cache works.
|
||||
|
||||
#### prefer-online
|
||||
|
||||
Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache.
|
||||
|
||||
#### prefer-offline
|
||||
|
||||
Bypasses staleness checks for packages. Missing data will still be
|
||||
requested from the server. To force full offline mode, use `offline`.
|
||||
|
||||
#### offline
|
||||
|
||||
Forces full offline mode. Any packages not locally cached will result in
|
||||
an error.
|
||||
|
||||
### See Also
|
||||
|
||||
* [npm run-script](/commands/npm-run-script)
|
||||
|
||||
+23
@@ -71,9 +71,32 @@ Generate it without having it ask any questions:
|
||||
$ npm init -y
|
||||
```
|
||||
|
||||
### A note on caching
|
||||
|
||||
The npm cli utilizes its internal package cache when using the package
|
||||
name specified. You can use the following to change how and when the
|
||||
cli uses this cache. See [`npm cache`](/commands/npm-cache) for more on
|
||||
how the cache works.
|
||||
|
||||
#### prefer-online
|
||||
|
||||
Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache.
|
||||
|
||||
#### prefer-offline
|
||||
|
||||
Bypasses staleness checks for packages. Missing data will still be
|
||||
requested from the server. To force full offline mode, use `offline`.
|
||||
|
||||
#### offline
|
||||
|
||||
Forces full offline mode. Any packages not locally cached will result in
|
||||
an error.
|
||||
|
||||
### See Also
|
||||
|
||||
* [init-package-json module](http://npm.im/init-package-json)
|
||||
* [package.json](/configuring-npm/package-json)
|
||||
* [npm version](/commands/npm-version)
|
||||
* [npm scope](/using-npm/scope)
|
||||
* [npm exec](/commands/npm-exec)
|
||||
-1
@@ -39,4 +39,3 @@ on the command line when changing ownership with `--otp`.
|
||||
* [npm publish](/commands/npm-publish)
|
||||
* [npm registry](/using-npm/registry)
|
||||
* [npm adduser](/commands/npm-adduser)
|
||||
* [npm disputes](/using-npm/disputes)
|
||||
+34
-5
@@ -32,7 +32,7 @@ npm run test -- --grep="pattern"
|
||||
```
|
||||
|
||||
The arguments will only be passed to the script specified after ```npm run```
|
||||
and not to any pre or post script.
|
||||
and not to any `pre` or `post` script.
|
||||
|
||||
The `env` script is a special built-in command that can be used to list
|
||||
environment variables that will be available to the script at runtime. If an
|
||||
@@ -56,7 +56,8 @@ instead of
|
||||
```
|
||||
|
||||
The actual shell your script is run within is platform dependent. By default,
|
||||
on Unix-like systems it is the `/bin/sh` command, on Windows it is the `cmd.exe`.
|
||||
on Unix-like systems it is the `/bin/sh` command, on Windows it is
|
||||
`cmd.exe`.
|
||||
The actual shell referred to by `/bin/sh` also depends on the system.
|
||||
You can customize the shell with the `script-shell` configuration.
|
||||
|
||||
@@ -73,15 +74,43 @@ If `--scripts-prepend-node-path=auto` is passed (which has been the default
|
||||
in `npm` v3), this is only performed when that `node` executable is not
|
||||
found in the `PATH`.
|
||||
|
||||
If you try to run a script without having a `node_modules` directory and it fails,
|
||||
you will be given a warning to run `npm install`, just in case you've forgotten.
|
||||
If you try to run a script without having a `node_modules` directory and it
|
||||
fails, you will be given a warning to run `npm install`, just in case you've
|
||||
forgotten.
|
||||
|
||||
You can use the `--silent` flag to prevent showing `npm ERR!` output on error.
|
||||
### Configuration
|
||||
|
||||
#### if-present
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
You can use the `--if-present` flag to avoid exiting with a non-zero exit code
|
||||
when the script is undefined. This lets you run potentially undefined scripts
|
||||
without breaking the execution chain.
|
||||
|
||||
#### ignore-scripts
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Skips running `pre` and `post` scripts.
|
||||
|
||||
#### script-shell
|
||||
|
||||
* Type: String
|
||||
* Default: `null`
|
||||
|
||||
Optional custom script to use to execute the command. If not defined defaults
|
||||
to `/bin/sh` on Unix, defaults to `env.comspec` or `cmd.exe` on Windows.
|
||||
|
||||
#### silent
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
You can use the `--silent` flag to prevent showing `npm ERR!` output on error.
|
||||
|
||||
### See Also
|
||||
|
||||
* [npm scripts](/using-npm/scripts)
|
||||
|
||||
+3
-3
@@ -110,13 +110,13 @@ on how the cache works.
|
||||
|
||||
#### prefer-online
|
||||
|
||||
Forced staleness checks for cached searches, making the cli look for
|
||||
Forces staleness checks for cached searches, making the cli look for
|
||||
updates immediately even for fresh search results.
|
||||
|
||||
#### prefer-offline
|
||||
|
||||
Bypasses staleness checks for cached. Missing data will still be
|
||||
requested from the server. To force full offline mode, use `offline`.
|
||||
Bypasses staleness checks for cached searches. Missing data will still
|
||||
be requested from the server. To force full offline mode, use `offline`.
|
||||
|
||||
#### offline
|
||||
|
||||
|
||||
+10
-19
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: npm-update
|
||||
section: 1
|
||||
description: Update a package
|
||||
description: Update packages
|
||||
---
|
||||
|
||||
### Synopsis
|
||||
@@ -27,22 +27,11 @@ packages.
|
||||
If no package name is specified, all packages in the specified location (global
|
||||
or local) will be updated.
|
||||
|
||||
As of `npm@2.6.1`, the `npm update` will only inspect top-level packages.
|
||||
Prior versions of `npm` would also recursively inspect all dependencies.
|
||||
To get the old behavior, use `npm --depth 9999 update`.
|
||||
|
||||
As of `npm@5.0.0`, the `npm update` will change `package.json` to save the
|
||||
new version as the minimum required dependency. To get the old behavior,
|
||||
use `npm update --no-save`.
|
||||
|
||||
### Example
|
||||
|
||||
IMPORTANT VERSION NOTE: these examples assume `npm@2.6.1` or later. For
|
||||
older versions of `npm`, you must specify `--depth 0` to get the behavior
|
||||
described below.
|
||||
|
||||
For the examples below, assume that the current package is `app` and it depends
|
||||
on dependencies, `dep1` (`dep2`, .. etc.). The published versions of `dep1` are:
|
||||
on dependencies, `dep1` (`dep2`, .. etc.). The published versions of `dep1`
|
||||
are:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -84,10 +73,10 @@ However, if `app`'s `package.json` contains:
|
||||
}
|
||||
```
|
||||
|
||||
In this case, running `npm update` will install `dep1@1.1.2`. Even though the `latest`
|
||||
tag points to `1.2.2`, this version does not satisfy `~1.1.1`, which is equivalent
|
||||
to `>=1.1.1 <1.2.0`. So the highest-sorting version that satisfies `~1.1.1` is used,
|
||||
which is `1.1.2`.
|
||||
In this case, running `npm update` will install `dep1@1.1.2`. Even though the
|
||||
`latest` tag points to `1.2.2`, this version do not satisfy `~1.1.1`, which is
|
||||
equivalent to `>=1.1.1 <1.2.0`. So the highest-sorting version that satisfies
|
||||
`~1.1.1` is used, which is `1.1.2`.
|
||||
|
||||
#### Caret Dependencies below 1.0.0
|
||||
|
||||
@@ -120,7 +109,9 @@ version that satisfies `^0.4.0` (`>= 0.4.0 <0.5.0`)
|
||||
package that is `outdated` -- that is, has a version that is different from
|
||||
`wanted`.
|
||||
|
||||
Note: Globally installed packages are treated as if they are installed with a caret semver range specified. So if you require to update to `latest` you may need to run `npm install -g [<pkg>...]`
|
||||
Note: Globally installed packages are treated as if they are installed with a
|
||||
caret semver range specified. So if you require to update to `latest` you may
|
||||
need to run `npm install -g [<pkg>...]`
|
||||
|
||||
NOTE: If a package has been upgraded to a version newer than `latest`, it will
|
||||
be _downgraded_.
|
||||
|
||||
+10
-11
@@ -83,37 +83,37 @@ Take the following example:
|
||||
}
|
||||
```
|
||||
|
||||
This runs all your tests, and proceeds only if they pass. Then runs your `build` script, and
|
||||
This runs all your tests and proceeds only if they pass. Then runs your `build` script, and
|
||||
adds everything in the `dist` directory to the commit. After the commit, it pushes the new commit
|
||||
and tag up to the server, and deletes the `build/temp` directory.
|
||||
|
||||
### Configuration
|
||||
|
||||
#### allow-same-version
|
||||
#### `allow-same-version`
|
||||
|
||||
* Default: false
|
||||
* Default: `false`
|
||||
* Type: Boolean
|
||||
|
||||
Prevents throwing an error when `npm version` is used to set the new version
|
||||
Prevents throwing an error when `npm version` is used to set the new version
|
||||
to the same value as the current version.
|
||||
|
||||
#### git-tag-version
|
||||
#### `git-tag-version`
|
||||
|
||||
* Default: true
|
||||
* Default: `true`
|
||||
* Type: Boolean
|
||||
|
||||
Commit and tag the version change.
|
||||
|
||||
#### commit-hooks
|
||||
#### `commit-hooks`
|
||||
|
||||
* Default: true
|
||||
* Default: `true`
|
||||
* Type: Boolean
|
||||
|
||||
Run git commit hooks when committing the version change.
|
||||
|
||||
#### sign-git-tag
|
||||
#### `sign-git-tag`
|
||||
|
||||
* Default: false
|
||||
* Default: `false`
|
||||
* Type: Boolean
|
||||
|
||||
Pass the `-s` flag to git to sign the tag.
|
||||
@@ -126,5 +126,4 @@ Note that you must have a default GPG key set up in your git config for this to
|
||||
* [npm run-script](/commands/npm-run-script)
|
||||
* [npm scripts](/using-npm/scripts)
|
||||
* [package.json](/configuring-npm/package-json)
|
||||
* [semver](/using-npm/semver)
|
||||
* [config](/using-npm/config)
|
||||
+18
-20
@@ -17,50 +17,48 @@ aliases: info, show, v
|
||||
This command shows data about a package and prints it to the stream
|
||||
referenced by the `outfd` config, which defaults to stdout.
|
||||
|
||||
To show the package registry entry for the `connect` package, you can do
|
||||
this:
|
||||
As an example, to view information about the `connect` package from the registry, you would run:
|
||||
|
||||
```bash
|
||||
npm view connect
|
||||
```
|
||||
|
||||
The default version is "latest" if unspecified.
|
||||
The default version is `"latest"` if unspecified.
|
||||
|
||||
Field names can be specified after the package descriptor.
|
||||
For example, to show the dependencies of the `ronn` package at version
|
||||
0.3.5, you could do the following:
|
||||
`0.3.5`, you could do the following:
|
||||
|
||||
```bash
|
||||
npm view ronn@0.3.5 dependencies
|
||||
```
|
||||
|
||||
You can view child fields by separating them with a period.
|
||||
To view the git repository URL for the latest version of npm, you could
|
||||
do this:
|
||||
To view the git repository URL for the latest version of `npm`, you would run the following command:
|
||||
|
||||
```bash
|
||||
npm view npm repository.url
|
||||
```
|
||||
|
||||
This makes it easy to view information about a dependency with a bit of
|
||||
shell scripting. For example, to view all the data about the version of
|
||||
opts that ronn depends on, you can do this:
|
||||
shell scripting. For example, to view all the data about the version of
|
||||
`opts` that `ronn` depends on, you could write the following:
|
||||
|
||||
```bash
|
||||
npm view opts@$(npm view ronn dependencies.opts)
|
||||
```
|
||||
|
||||
For fields that are arrays, requesting a non-numeric field will return
|
||||
all of the values from the objects in the list. For example, to get all
|
||||
the contributor names for the "express" project, you can do this:
|
||||
all of the values from the objects in the list. For example, to get all
|
||||
the contributor names for the `express` package, you would run:
|
||||
|
||||
```bash
|
||||
npm view express contributors.email
|
||||
```
|
||||
|
||||
You may also use numeric indices in square braces to specifically select
|
||||
an item in an array field. To just get the email address of the first
|
||||
contributor in the list, you can do this:
|
||||
an item in an array field. To just get the email address of the first
|
||||
contributor in the list, you can run:
|
||||
|
||||
```bash
|
||||
npm view express contributors[0].email
|
||||
@@ -75,7 +73,7 @@ npm view express contributors.name contributors.email
|
||||
```
|
||||
|
||||
"Person" fields are shown as a string if they would be shown as an
|
||||
object. So, for example, this will show the list of npm contributors in
|
||||
object. So, for example, this will show the list of `npm` contributors in
|
||||
the shortened string format. (See [`package.json`](/configuring-npm/package.json) for more on this.)
|
||||
|
||||
```bash
|
||||
@@ -83,12 +81,12 @@ npm view npm contributors
|
||||
```
|
||||
|
||||
If a version range is provided, then data will be printed for every
|
||||
matching version of the package. This will show which version of jsdom
|
||||
was required by each matching version of yui3:
|
||||
matching version of the package. This will show which version of `jsdom`
|
||||
was required by each matching version of `yui3`:
|
||||
|
||||
```bash
|
||||
npm view yui3@'>0.5.4' dependencies.jsdom
|
||||
```
|
||||
```
|
||||
|
||||
To show the `connect` package version history, you can do
|
||||
this:
|
||||
@@ -100,15 +98,15 @@ npm view connect versions
|
||||
### Output
|
||||
|
||||
If only a single string field for a single version is output, then it
|
||||
will not be colorized or quoted, so as to enable piping the output to
|
||||
will not be colorized or quoted, to enable piping the output to
|
||||
another command. If the field is an object, it will be output as a JavaScript object literal.
|
||||
|
||||
If the --json flag is given, the outputted fields will be JSON.
|
||||
If the `--json` flag is given, the outputted fields will be JSON.
|
||||
|
||||
If the version range matches multiple versions, than each printed value
|
||||
If the version range matches multiple versions then each printed value
|
||||
will be prefixed with the version it applies to.
|
||||
|
||||
If multiple fields are requested, than each of them are prefixed with
|
||||
If multiple fields are requested, then each of them is prefixed with
|
||||
the field name.
|
||||
|
||||
### See Also
|
||||
|
||||
+60
-45
@@ -20,36 +20,42 @@ npm is the package manager for the Node JavaScript platform. It puts
|
||||
modules in place so that node can find them, and manages dependency
|
||||
conflicts intelligently.
|
||||
|
||||
It is extremely configurable to support a wide variety of use cases.
|
||||
Most commonly, it is used to publish, discover, install, and develop node
|
||||
It is extremely configurable to support a variety of use cases. Most
|
||||
commonly, you use it to publish, discover, install, and develop node
|
||||
programs.
|
||||
|
||||
Run `npm help` to get a list of available commands.
|
||||
|
||||
### Important
|
||||
|
||||
npm is configured to use npm, Inc.'s public registry at
|
||||
npm comes preconfigured to use npm's public registry at
|
||||
https://registry.npmjs.org by default. Use of the npm public registry is
|
||||
subject to terms of use available at https://www.npmjs.com/policies/terms.
|
||||
subject to terms of use available at
|
||||
https://www.npmjs.com/policies/terms.
|
||||
|
||||
You can configure npm to use any compatible registry you like, and even run
|
||||
your own registry. Use of someone else's registry may be governed by their
|
||||
terms of use.
|
||||
You can configure npm to use any compatible registry you like, and even
|
||||
run your own registry. Use of someone else's registry is governed by
|
||||
their terms of use.
|
||||
|
||||
### Introduction
|
||||
|
||||
You probably got npm because you want to install stuff.
|
||||
|
||||
Use `npm install blerg` to install the latest version of "blerg". Check out
|
||||
[`npm install`](/commands/npm-install) for more info. It can do a lot of stuff.
|
||||
The very first thing you will most likely want to run in any node
|
||||
program is `npm install` to install its dependencies.
|
||||
|
||||
Use the `npm search` command to show everything that's available.
|
||||
Use `npm ls` to show everything you've installed.
|
||||
You can also run `npm install blerg` to install the latest version of
|
||||
"blerg". Check out [`npm install`](/commands/npm-install) for more
|
||||
info. It can do a lot of stuff.
|
||||
|
||||
Use the `npm search` command to show everything that's available in the
|
||||
public registry. Use `npm ls` to show everything you've installed.
|
||||
|
||||
### Dependencies
|
||||
|
||||
If a package references to another package with a git URL, npm depends
|
||||
on a preinstalled git.
|
||||
If a package lists a dependency using a git URL, npm will install that
|
||||
dependency using the [`git`](https://github.com/git-guides/install-git)
|
||||
command and will generate an error if it is not installed.
|
||||
|
||||
If one of the packages npm tries to install is a native node module and
|
||||
requires compiling of C++ Code, npm will use
|
||||
@@ -64,20 +70,22 @@ the [node-gyp Wiki](https://github.com/nodejs/node-gyp/wiki).
|
||||
|
||||
### Directories
|
||||
|
||||
See [`folders`](/configuring-npm/folders) to learn about where npm puts stuff.
|
||||
See [`folders`](/configuring-npm/folders) to learn about where npm puts
|
||||
stuff.
|
||||
|
||||
In particular, npm has two modes of operation:
|
||||
|
||||
* global mode:
|
||||
npm installs packages into the install prefix at
|
||||
`prefix/lib/node_modules` and bins are installed in `prefix/bin`.
|
||||
* local mode:
|
||||
npm installs packages into the current project directory, which
|
||||
defaults to the current working directory. Packages are installed to
|
||||
`./node_modules`, and bins are installed to `./node_modules/.bin`.
|
||||
defaults to the current working directory. Packages install to
|
||||
`./node_modules`, and bins to `./node_modules/.bin`.
|
||||
* global mode:
|
||||
npm installs packages into the install prefix at
|
||||
`$npm_config_prefix/lib/node_modules` and bins to
|
||||
`$npm_config_prefix/bin`.
|
||||
|
||||
Local mode is the default. Use `-g` or `--global` on any command to
|
||||
operate in global mode instead.
|
||||
run in global mode instead.
|
||||
|
||||
### Developer Usage
|
||||
|
||||
@@ -85,20 +93,22 @@ If you're using npm to develop and publish your code, check out the
|
||||
following help topics:
|
||||
|
||||
* json:
|
||||
Make a package.json file. See [`package.json`](/configuring-npm/package-json).
|
||||
Make a package.json file. See
|
||||
[`package.json`](/configuring-npm/package-json).
|
||||
* link:
|
||||
For linking your current working code into Node's path, so that you
|
||||
don't have to reinstall every time you make a change. Use
|
||||
`npm link` to do this.
|
||||
Links your current working code into Node's path, so that you don't
|
||||
have to reinstall every time you make a change. Use [`npm
|
||||
link`](/commands/npm-link) to do this.
|
||||
* install:
|
||||
It's a good idea to install things if you don't need the symbolic link.
|
||||
Especially, installing other peoples code from the registry is done via
|
||||
`npm install`
|
||||
It's a good idea to install things if you don't need the symbolic
|
||||
link. Especially, installing other peoples code from the registry is
|
||||
done via [`npm install`](/commands/npm-install)
|
||||
* adduser:
|
||||
Create an account or log in. Credentials are stored in the
|
||||
user config file.
|
||||
Create an account or log in. When you do this, npm will store
|
||||
credentials in the user config file config file.
|
||||
* publish:
|
||||
Use the `npm publish` command to upload your code to the registry.
|
||||
Use the [`npm publish`](/commands/npm-publish`) command to upload your
|
||||
code to the registry.
|
||||
|
||||
#### Configuration
|
||||
|
||||
@@ -108,20 +118,20 @@ npm is extremely configurable. It reads its configuration options from
|
||||
* Command line switches:
|
||||
Set a config with `--key val`. All keys take a value, even if they
|
||||
are booleans (the config parser doesn't know what the options are at
|
||||
the time of parsing). If no value is provided, then the option is set
|
||||
to boolean `true`.
|
||||
the time of parsing). If you do not provide a value (`--key`) then
|
||||
the option is set to boolean `true`.
|
||||
* Environment Variables:
|
||||
Set any config by prefixing the name in an environment variable with
|
||||
`npm_config_`. For example, `export npm_config_key=val`.
|
||||
* User Configs:
|
||||
The file at $HOME/.npmrc is an ini-formatted list of configs. If
|
||||
The file at `$HOME/.npmrc` is an ini-formatted list of configs. If
|
||||
present, it is parsed. If the `userconfig` option is set in the cli
|
||||
or env, then that will be used instead.
|
||||
or env, that file will be used instead.
|
||||
* Global Configs:
|
||||
The file found at ../etc/npmrc (from the node executable, by default
|
||||
this resolves to /usr/local/etc/npmrc) will be parsed if it is found.
|
||||
If the `globalconfig` option is set in the cli, env, or user config,
|
||||
then that file is parsed instead.
|
||||
The file found at `./etc/npmrc` (relative to the global prefix will be
|
||||
parsed if it is found. See [`npm prefix`](/commands/npm-prefix) for
|
||||
more info on the global prefix. If the `globalconfig` option is set
|
||||
in the cli, env, or user config, then that file is parsed instead.
|
||||
* Defaults:
|
||||
npm's default configuration options are defined in
|
||||
lib/utils/config-defs.js. These must not be changed.
|
||||
@@ -132,15 +142,17 @@ See [`config`](/using-npm/config) for much much more information.
|
||||
|
||||
Patches welcome!
|
||||
|
||||
If you would like to contribute, but don't know what to work on, read
|
||||
the [contributing guidelines](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md)
|
||||
and check the issues list.
|
||||
If you would like to help, but don't know what to work on, read the
|
||||
[contributing
|
||||
guidelines](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md) and
|
||||
check the issues list.
|
||||
|
||||
### Bugs
|
||||
|
||||
When you find issues, please report them: <https://github.com/npm/cli/issues>
|
||||
When you find issues, please report them:
|
||||
<https://github.com/npm/cli/issues>
|
||||
|
||||
Be sure to follow the template and bug reporting guidelines.
|
||||
Please be sure to follow the template and bug reporting guidelines.
|
||||
|
||||
### Feature Requests
|
||||
|
||||
@@ -153,8 +165,11 @@ Or suggest formal RFC proposals:
|
||||
* <https://github.com/npm/rfcs>
|
||||
|
||||
### See Also
|
||||
|
||||
* [npm help](/commands/npm-help)
|
||||
* [package.json](/configuring-npm/package-json)
|
||||
* [npm install](/commands/npm-install)
|
||||
* [npm config](/commands/npm-config)
|
||||
* [npmrc](/configuring-npm/npmrc)
|
||||
* [npm config](/commands/npm-config)
|
||||
* [npm install](/commands/npm-install)
|
||||
* [npm prefix](/commands/npm-prefix)
|
||||
* [npm publish](/commands/npm-publish)
|
||||
+5
-7
@@ -63,8 +63,6 @@ Version must be parseable by
|
||||
[node-semver](https://github.com/npm/node-semver), which is bundled with
|
||||
npm as a dependency. (`npm install semver` to use it yourself.)
|
||||
|
||||
More on version numbers and ranges at [semver](/using-npm/semver).
|
||||
|
||||
### description
|
||||
|
||||
Put a description in it. It's a string. This helps people discover your
|
||||
@@ -564,8 +562,8 @@ tarball or git URL.
|
||||
**Please do not put test harnesses or transpilers or other "development"
|
||||
time tools in your `dependencies` object.** See `devDependencies`, below.
|
||||
|
||||
See [semver](/using-npm/semver) for more details about specifying version
|
||||
ranges.
|
||||
See [semver]([/using-npm/semver](https://github.com/npm/node-semver#versions))
|
||||
for more details about specifying version ranges.
|
||||
|
||||
* `version` Must match `version` exactly
|
||||
* `>version` Must be greater than `version`
|
||||
@@ -573,8 +571,8 @@ ranges.
|
||||
* `<version`
|
||||
* `<=version`
|
||||
* `~version` "Approximately equivalent to version" See
|
||||
[semver](/using-npm/semver)
|
||||
* `^version` "Compatible with version" See [semver](/using-npm/semver)
|
||||
[semver](https://github.com/npm/node-semver#versions)
|
||||
* `^version` "Compatible with version" See [semver](https://github.com/npm/node-semver#versions)
|
||||
* `1.2.x` 1.2.0, 1.2.1, etc., but not 1.3.0
|
||||
* `http://...` See 'URLs as Dependencies' below
|
||||
* `*` Matches any version
|
||||
@@ -1027,7 +1025,7 @@ npm will default some values based on package contents.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [semver](/using-npm/semver)
|
||||
* [semver](https://github.com/npm/node-semver#versions)
|
||||
* [workspaces](/using-npm/workspaces)
|
||||
* [npm init](/commands/npm-init)
|
||||
* [npm version](/commands/npm-version)
|
||||
|
||||
+57
@@ -379,6 +379,63 @@ commands that modify your local installation, eg, `install`, `update`,
|
||||
`dedupe`, `uninstall`. This is NOT currently honored by some network related
|
||||
commands, eg `dist-tags`, `owner`, etc.
|
||||
|
||||
#### diff
|
||||
|
||||
* Default: null
|
||||
* Type: String, Array, null
|
||||
|
||||
Define arguments to compare in `npm diff`.
|
||||
|
||||
#### diff-name-only
|
||||
|
||||
* Default: false
|
||||
* Type: Boolean
|
||||
|
||||
Prints only filenames when using `npm diff`.
|
||||
|
||||
#### diff-unified
|
||||
|
||||
* Type: number
|
||||
* Default: `3`
|
||||
|
||||
The number of lines of context to print in `npm diff`.
|
||||
|
||||
#### diff-ignore-all-space
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Ignore whitespace when comparing lines in `npm diff.
|
||||
|
||||
#### diff-no-prefix
|
||||
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Do not show any source or destination prefix in `npm diff` output.
|
||||
|
||||
#### diff-src-prefix
|
||||
|
||||
* Type: String
|
||||
* Default: `"a/"`
|
||||
|
||||
Source prefix to be used in `npm diff` output.
|
||||
|
||||
#### diff-dst-prefix
|
||||
|
||||
* Type: String
|
||||
* Default: `"b/"`
|
||||
|
||||
Destination prefix to be used in `npm diff` output.
|
||||
|
||||
#### diff-text
|
||||
|
||||
* Alias: `-a`
|
||||
* Type: Boolean
|
||||
* Default: false
|
||||
|
||||
Treat all files as text in `npm diff`.
|
||||
|
||||
#### editor
|
||||
|
||||
* Default: `EDITOR` environment variable if set, or `"vi"` on Posix,
|
||||
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
---
|
||||
title: disputes
|
||||
section: 7
|
||||
description: Handling Module Name Disputes
|
||||
---
|
||||
|
||||
This document describes the steps that you should take to resolve module name
|
||||
disputes with other npm publishers. It also describes special steps you should
|
||||
take about names you think infringe your trademarks.
|
||||
|
||||
This document is a clarification of the acceptable behavior outlined in the
|
||||
[npm Code of Conduct](https://www.npmjs.com/policies/conduct), and nothing in
|
||||
this document should be interpreted to contradict any aspect of the npm Code of
|
||||
Conduct.
|
||||
|
||||
### TL;DR
|
||||
|
||||
1. Get the author email with `npm owner ls <pkgname>`
|
||||
2. Email the author, CC <support@npmjs.com>
|
||||
3. After a few weeks, if there's no resolution, we'll sort it out.
|
||||
|
||||
Don't squat on package names. Publish code or move out of the way.
|
||||
|
||||
### Description
|
||||
|
||||
There sometimes arise cases where a user publishes a module, and then later,
|
||||
some other user wants to use that name. Here are some common ways that happens
|
||||
(each of these is based on actual events.)
|
||||
|
||||
1. Alice writes a JavaScript module `foo`, which is not node-specific. Alice
|
||||
doesn't use node at all. Yusuf wants to use `foo` in node, so he wraps it in
|
||||
an npm module. Some time later, Alice starts using node, and wants to take
|
||||
over management of her program.
|
||||
2. Yusuf writes an npm module `foo`, and publishes it. Perhaps much later, Alice
|
||||
finds a bug in `foo`, and fixes it. She sends a pull request to Yusuf, but
|
||||
Yusuf doesn't have the time to deal with it, because he has a new job and a
|
||||
new baby and is focused on his new Erlang project, and kind of not involved
|
||||
with node any more. Alice would like to publish a new `foo`, but can't,
|
||||
because the name is taken.
|
||||
3. Yusuf writes a 10-line flow-control library, and calls it `foo`, and
|
||||
publishes it to the npm registry. Being a simple little thing, it never
|
||||
really has to be updated. Alice works for Foo Inc, the makers of the
|
||||
critically acclaimed and widely-marketed `foo` JavaScript toolkit framework.
|
||||
They publish it to npm as `foojs`, but people are routinely confused when
|
||||
`npm install foo` is some different thing.
|
||||
4. Yusuf writes a parser for the widely-known `foo` file format, because he
|
||||
needs it for work. Then, he gets a new job, and never updates the prototype.
|
||||
Later on, Alice writes a much more complete `foo` parser, but can't publish,
|
||||
because Yusuf's `foo` is in the way.
|
||||
|
||||
1. `npm owner ls foo`. This will tell Alice the email address of the owner
|
||||
(Yusuf).
|
||||
2. Alice emails Yusuf, explaining the situation **as respectfully as possible**,
|
||||
and what she would like to do with the module name. She adds the npm support
|
||||
staff <support@npmjs.com> to the CC list of the email. Mention in the email
|
||||
that Yusuf can run npm owner `add alice foo` to add Alice as an owner of the
|
||||
foo package.
|
||||
3. After a reasonable amount of time, if Yusuf has not responded, or if Yusuf
|
||||
and Alice can't come to any sort of resolution, email support
|
||||
<support@npmjs.com> and we'll sort it out. ("Reasonable" is usually at least
|
||||
4 weeks.)
|
||||
|
||||
### Reasoning
|
||||
|
||||
In almost every case so far, the parties involved have been able to reach an
|
||||
amicable resolution without any major intervention. Most people really do want
|
||||
to be reasonable, and are probably not even aware that they're in your way.
|
||||
|
||||
Module ecosystems are most vibrant and powerful when they are as self-directed
|
||||
as possible. If an admin one day deletes something you had worked on, then that
|
||||
is going to make most people quite upset, regardless of the justification. When
|
||||
humans solve their problems by talking to other humans with respect, everyone
|
||||
has the chance to end up feeling good about the interaction.
|
||||
|
||||
### Exceptions
|
||||
|
||||
Some things are not allowed, and will be removed without discussion if they are
|
||||
brought to the attention of the npm registry admins, including but not limited
|
||||
to:
|
||||
|
||||
1. Malware (that is, a package designed to exploit or harm the machine on which
|
||||
it is installed).
|
||||
2. Violations of copyright or licenses (for example, cloning an MIT-licensed
|
||||
program, and then removing or changing the copyright and license statement).
|
||||
3. Illegal content.
|
||||
4. "Squatting" on a package name that you plan to use, but aren't actually
|
||||
using. Sorry, I don't care how great the name is, or how perfect a fit it is
|
||||
for the thing that someday might happen. If someone wants to use it today,
|
||||
and you're just taking up space with an empty tarball, you're going to be
|
||||
evicted.
|
||||
5. Putting empty packages in the registry. Packages must have SOME
|
||||
functionality. It can be silly, but it can't be nothing. (See also:
|
||||
squatting.)
|
||||
6. Doing weird things with the registry, like using it as your own personal
|
||||
application database or otherwise putting non-packagey things into it.
|
||||
7. Other things forbidden by the npm
|
||||
[Code of Conduct](https://www.npmjs.com/policies/conduct) such as hateful
|
||||
language, pornographic content, or harassment.
|
||||
|
||||
If you see bad behavior like this, please report it to <abuse@npmjs.com> right
|
||||
away. **You are never expected to resolve abusive behavior on your own. We are
|
||||
here to help.**
|
||||
|
||||
### Trademarks
|
||||
|
||||
If you think another npm publisher is infringing your trademark, such as by
|
||||
using a confusingly similar package name, email <abuse@npmjs.com> with a link to
|
||||
the package or user account on [https://www.npmjs.com/](https://www.npmjs.com/).
|
||||
Attach a copy of your trademark registration certificate.
|
||||
|
||||
If we see that the package's publisher is intentionally misleading others by
|
||||
misusing your registered mark without permission, we will transfer the package
|
||||
name to you. Otherwise, we will contact the package publisher and ask them to
|
||||
clear up any confusion with changes to their package's `README` file or
|
||||
metadata.
|
||||
|
||||
### Changes
|
||||
|
||||
This is a living document and may be updated from time to time. Please refer to
|
||||
the [git history for this document](https://github.com/npm/cli/commits/latest/doc/misc/npm-disputes.md)
|
||||
to view the changes.
|
||||
|
||||
### License
|
||||
|
||||
Copyright (C) npm, Inc., All rights reserved
|
||||
|
||||
This document may be reused under a Creative Commons Attribution-ShareAlike
|
||||
License.
|
||||
|
||||
### See also
|
||||
|
||||
* [npm registry](/using-npm/registry)
|
||||
* [npm owner](/commands/npm-owner)
|
||||
+7
-36
@@ -10,7 +10,7 @@ To resolve packages by name and version, npm talks to a registry website
|
||||
that implements the CommonJS Package Registry specification for reading
|
||||
package info.
|
||||
|
||||
npm is configured to use npm, Inc.'s public registry at
|
||||
npm is configured to use the **npm public registry** at
|
||||
<https://registry.npmjs.org> by default. Use of the npm public registry is
|
||||
subject to terms of use available at <https://www.npmjs.com/policies/terms>.
|
||||
|
||||
@@ -23,9 +23,7 @@ write APIs as well, to allow for publishing packages and managing user
|
||||
account information.
|
||||
|
||||
The npm public registry is powered by a CouchDB database,
|
||||
of which there is a public mirror at
|
||||
<https://skimdb.npmjs.com/registry>. The code for the couchapp is
|
||||
available at <https://github.com/npm/npm-registry-couchapp>.
|
||||
of which there is a public mirror at <https://skimdb.npmjs.com/registry>.
|
||||
|
||||
The registry URL used is determined by the scope of the package (see
|
||||
[`scope`](/using-npm/scope). If no scope is specified, the default registry is used, which is
|
||||
@@ -55,44 +53,18 @@ about your environment:
|
||||
The npm registry does not try to correlate the information in these headers
|
||||
with any authenticated accounts that may be used in the same requests.
|
||||
|
||||
### Can I run my own private registry?
|
||||
### How can I prevent my package from being published in the official registry?
|
||||
|
||||
Yes!
|
||||
|
||||
The easiest way is to replicate the couch database, and use the same (or
|
||||
similar) design doc to implement the APIs.
|
||||
|
||||
If you set up continuous replication from the official CouchDB, and then
|
||||
set your internal CouchDB as the registry config, then you'll be able
|
||||
to read any published packages, in addition to your private ones, and by
|
||||
default will only publish internally.
|
||||
|
||||
If you then want to publish a package for the whole world to see, you can
|
||||
simply override the `--registry` option for that `publish` command.
|
||||
|
||||
### I don't want my package published in the official registry. It's private.
|
||||
|
||||
Set `"private": true` in your package.json to prevent it from being
|
||||
Set `"private": true` in your `package.json` to prevent it from being
|
||||
published at all, or
|
||||
`"publishConfig":{"registry":"http://my-internal-registry.local"}`
|
||||
to force it to be published only to your internal registry.
|
||||
to force it to be published only to your internal/private registry.
|
||||
|
||||
See [`package.json`](/configuring-npm/package-json) for more info on what goes in the package.json file.
|
||||
|
||||
### Will you replicate from my registry into the public one?
|
||||
### Where can I find my own, & other's, published packages?
|
||||
|
||||
No. If you want things to be public, then publish them into the public
|
||||
registry using npm. What little security there is would be for nought
|
||||
otherwise.
|
||||
|
||||
### Do I have to use couchdb to build a registry that npm can talk to?
|
||||
|
||||
No, but it's way easier. Basically, yes, you do, or you have to
|
||||
effectively implement the entire CouchDB API anyway.
|
||||
|
||||
### Is there a website or something to see package docs and such?
|
||||
|
||||
Yes, head over to <https://www.npmjs.com/>
|
||||
<https://www.npmjs.com/>
|
||||
|
||||
### See also
|
||||
|
||||
@@ -100,4 +72,3 @@ Yes, head over to <https://www.npmjs.com/>
|
||||
* [config](/using-npm/config)
|
||||
* [npmrc](/configuring-npm/npmrc)
|
||||
* [npm developers](/using-npm/developers)
|
||||
* [npm disputes](/using-npm/disputes)
|
||||
-2
@@ -58,8 +58,6 @@ modules. To track those down, you can do the following:
|
||||
find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ;
|
||||
```
|
||||
|
||||
(This is also in the README file.)
|
||||
|
||||
### See also
|
||||
|
||||
* [npm uninstall](/commands/npm-uninstall)
|
||||
|
||||
-415
@@ -1,415 +0,0 @@
|
||||
---
|
||||
title: semver
|
||||
section: 7
|
||||
description: The semantic versioner for npm
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install --save semver
|
||||
````
|
||||
|
||||
## Usage
|
||||
|
||||
As a node module:
|
||||
|
||||
```js
|
||||
const semver = require('semver')
|
||||
|
||||
semver.valid('1.2.3') // '1.2.3'
|
||||
semver.valid('a.b.c') // null
|
||||
semver.clean(' =v1.2.3 ') // '1.2.3'
|
||||
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
|
||||
semver.gt('1.2.3', '9.8.7') // false
|
||||
semver.lt('1.2.3', '9.8.7') // true
|
||||
semver.minVersion('>=1.0.0') // '1.0.0'
|
||||
semver.valid(semver.coerce('v2')) // '2.0.0'
|
||||
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
|
||||
```
|
||||
|
||||
As a command-line utility:
|
||||
|
||||
```
|
||||
$ semver -h
|
||||
|
||||
A JavaScript implementation of the https://semver.org/ specification
|
||||
Copyright Isaac Z. Schlueter
|
||||
|
||||
Usage: semver [options] <version> [<version> [...]]
|
||||
Prints valid versions sorted by SemVer precedence
|
||||
|
||||
Options:
|
||||
-r --range <range>
|
||||
Print versions that match the specified range.
|
||||
|
||||
-i --increment [<level>]
|
||||
Increment a version by the specified level. Level can
|
||||
be one of: major, minor, patch, premajor, preminor,
|
||||
prepatch, or prerelease. Default level is 'patch'.
|
||||
Only one version may be specified.
|
||||
|
||||
--preid <identifier>
|
||||
Identifier to be used to prefix premajor, preminor,
|
||||
prepatch or prerelease version increments.
|
||||
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
-c --coerce
|
||||
Coerce a string into SemVer if possible
|
||||
(does not imply --loose)
|
||||
|
||||
Program exits successfully if any valid version satisfies
|
||||
all supplied ranges, and prints all satisfying versions.
|
||||
|
||||
If no satisfying versions are found, then exits failure.
|
||||
|
||||
Versions are printed in ascending order, so supplying
|
||||
multiple versions to the utility will just sort them.
|
||||
```
|
||||
|
||||
## Versions
|
||||
|
||||
A "version" is described by the `v2.0.0` specification found at
|
||||
<https://semver.org/>.
|
||||
|
||||
A leading `"="` or `"v"` character is stripped off and ignored.
|
||||
|
||||
## Ranges
|
||||
|
||||
A `version range` is a set of `comparators` which specify versions
|
||||
that satisfy the range.
|
||||
|
||||
A `comparator` is composed of an `operator` and a `version`. The set
|
||||
of primitive `operators` is:
|
||||
|
||||
* `<` Less than
|
||||
* `<=` Less than or equal to
|
||||
* `>` Greater than
|
||||
* `>=` Greater than or equal to
|
||||
* `=` Equal. If no operator is specified, then equality is assumed,
|
||||
so this operator is optional, but MAY be included.
|
||||
|
||||
For example, the comparator `>=1.2.7` would match the versions
|
||||
`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6`
|
||||
or `1.1.0`.
|
||||
|
||||
Comparators can be joined by whitespace to form a `comparator set`,
|
||||
which is satisfied by the **intersection** of all of the comparators
|
||||
it includes.
|
||||
|
||||
A range is composed of one or more comparator sets, joined by `||`. A
|
||||
version matches a range if and only if every comparator in at least
|
||||
one of the `||`-separated comparator sets is satisfied by the version.
|
||||
|
||||
For example, the range `>=1.2.7 <1.3.0` would match the versions
|
||||
`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`,
|
||||
or `1.1.0`.
|
||||
|
||||
The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`,
|
||||
`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`.
|
||||
|
||||
### Prerelease Tags
|
||||
|
||||
If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then
|
||||
it will only be allowed to satisfy comparator sets if at least one
|
||||
comparator with the same `[major, minor, patch]` tuple also has a
|
||||
prerelease tag.
|
||||
|
||||
For example, the range `>1.2.3-alpha.3` would be allowed to match the
|
||||
version `1.2.3-alpha.7`, but it would *not* be satisfied by
|
||||
`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater
|
||||
than" `1.2.3-alpha.3` according to the SemVer sort rules. The version
|
||||
range only accepts prerelease tags on the `1.2.3` version. The
|
||||
version `3.4.5` *would* satisfy the range, because it does not have a
|
||||
prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`.
|
||||
|
||||
The purpose for this behavior is twofold. First, prerelease versions
|
||||
frequently are updated very quickly, and contain many breaking changes
|
||||
that are (by the author's design) not yet fit for public consumption.
|
||||
Therefore, by default, they are excluded from range matching
|
||||
semantics.
|
||||
|
||||
Second, a user who has opted into using a prerelease version has
|
||||
clearly indicated the intent to use *that specific* set of
|
||||
alpha/beta/rc versions. By including a prerelease tag in the range,
|
||||
the user is indicating that they are aware of the risk. However, it
|
||||
is still not appropriate to assume that they have opted into taking a
|
||||
similar risk on the *next* set of prerelease versions.
|
||||
|
||||
Note that this behavior can be suppressed (treating all prerelease
|
||||
versions as if they were normal versions, for the purpose of range
|
||||
matching) by setting the `includePrerelease` flag on the options
|
||||
object to any
|
||||
[functions](https://github.com/npm/node-semver#functions) that do
|
||||
range matching.
|
||||
|
||||
#### Prerelease Identifiers
|
||||
|
||||
The method `.inc` takes an additional `identifier` string argument that
|
||||
will append the value of the string as a prerelease identifier:
|
||||
|
||||
```javascript
|
||||
semver.inc('1.2.3', 'prerelease', 'beta')
|
||||
// '1.2.4-beta.0'
|
||||
```
|
||||
|
||||
command-line example:
|
||||
|
||||
```bash
|
||||
$ semver 1.2.3 -i prerelease --preid beta
|
||||
1.2.4-beta.0
|
||||
```
|
||||
|
||||
Which then can be used to increment further:
|
||||
|
||||
```bash
|
||||
$ semver 1.2.4-beta.0 -i prerelease
|
||||
1.2.4-beta.1
|
||||
```
|
||||
|
||||
### Advanced Range Syntax
|
||||
|
||||
Advanced range syntax desugars to primitive comparators in
|
||||
deterministic ways.
|
||||
|
||||
Advanced ranges may be combined in the same way as primitive
|
||||
comparators using white space or `||`.
|
||||
|
||||
#### Hyphen Ranges `X.Y.Z - A.B.C`
|
||||
|
||||
Specifies an inclusive set.
|
||||
|
||||
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
|
||||
|
||||
If a partial version is provided as the first version in the inclusive
|
||||
range, then the missing pieces are replaced with zeroes.
|
||||
|
||||
* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4`
|
||||
|
||||
If a partial version is provided as the second version in the
|
||||
inclusive range, then all versions that start with the supplied parts
|
||||
of the tuple are accepted, but nothing that would be greater than the
|
||||
provided tuple parts.
|
||||
|
||||
* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0`
|
||||
* `1.2.3 - 2` := `>=1.2.3 <3.0.0`
|
||||
|
||||
#### X-Ranges `1.2.x` `1.X` `1.2.*` `*`
|
||||
|
||||
Any of `X`, `x`, or `*` may be used to "stand in" for one of the
|
||||
numeric values in the `[major, minor, patch]` tuple.
|
||||
|
||||
* `*` := `>=0.0.0` (Any version satisfies)
|
||||
* `1.x` := `>=1.0.0 <2.0.0` (Matching major version)
|
||||
* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions)
|
||||
|
||||
A partial version range is treated as an X-Range, so the special
|
||||
character is in fact optional.
|
||||
|
||||
* `""` (empty string) := `*` := `>=0.0.0`
|
||||
* `1` := `1.x.x` := `>=1.0.0 <2.0.0`
|
||||
* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0`
|
||||
|
||||
#### Tilde Ranges `~1.2.3` `~1.2` `~1`
|
||||
|
||||
Allows patch-level changes if a minor version is specified on the
|
||||
comparator. Allows minor-level changes if not.
|
||||
|
||||
* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0`
|
||||
* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`)
|
||||
* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`)
|
||||
* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0`
|
||||
* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`)
|
||||
* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`)
|
||||
* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in
|
||||
the `1.2.3` version will be allowed, if they are greater than or
|
||||
equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
|
||||
`1.2.4-beta.2` would not, because it is a prerelease of a
|
||||
different `[major, minor, patch]` tuple.
|
||||
|
||||
#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4`
|
||||
|
||||
Allows changes that do not modify the left-most non-zero digit in the
|
||||
`[major, minor, patch]` tuple. In other words, this allows patch and
|
||||
minor updates for versions `1.0.0` and above, patch updates for
|
||||
versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`.
|
||||
|
||||
Many authors treat a `0.x` version as if the `x` were the major
|
||||
"breaking-change" indicator.
|
||||
|
||||
Caret ranges are ideal when an author may make breaking changes
|
||||
between `0.2.4` and `0.3.0` releases, which is a common practice.
|
||||
However, it presumes that there will *not* be breaking changes between
|
||||
`0.2.4` and `0.2.5`. It allows for changes that are presumed to be
|
||||
additive (but non-breaking), according to commonly observed practices.
|
||||
|
||||
* `^1.2.3` := `>=1.2.3 <2.0.0`
|
||||
* `^0.2.3` := `>=0.2.3 <0.3.0`
|
||||
* `^0.0.3` := `>=0.0.3 <0.0.4`
|
||||
* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in
|
||||
the `1.2.3` version will be allowed, if they are greater than or
|
||||
equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
|
||||
`1.2.4-beta.2` would not, because it is a prerelease of a
|
||||
different `[major, minor, patch]` tuple.
|
||||
* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the
|
||||
`0.0.3` version *only* will be allowed, if they are greater than or
|
||||
equal to `beta`. So, `0.0.3-pr.2` would be allowed.
|
||||
|
||||
When parsing caret ranges, a missing `patch` value desugars to the
|
||||
number `0`, but will allow flexibility within that value, even if the
|
||||
major and minor versions are both `0`.
|
||||
|
||||
* `^1.2.x` := `>=1.2.0 <2.0.0`
|
||||
* `^0.0.x` := `>=0.0.0 <0.1.0`
|
||||
* `^0.0` := `>=0.0.0 <0.1.0`
|
||||
|
||||
A missing `minor` and `patch` values will desugar to zero, but also
|
||||
allow flexibility within those values, even if the major version is
|
||||
zero.
|
||||
|
||||
* `^1.x` := `>=1.0.0 <2.0.0`
|
||||
* `^0.x` := `>=0.0.0 <1.0.0`
|
||||
|
||||
### Range Grammar
|
||||
|
||||
Putting all this together, here is a Backus-Naur grammar for ranges,
|
||||
for the benefit of parser authors:
|
||||
|
||||
```bnf
|
||||
range-set ::= range ( logical-or range ) *
|
||||
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
|
||||
range ::= hyphen | simple ( ' ' simple ) * | ''
|
||||
hyphen ::= partial ' - ' partial
|
||||
simple ::= primitive | partial | tilde | caret
|
||||
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
|
||||
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
|
||||
xr ::= 'x' | 'X' | '*' | nr
|
||||
nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
|
||||
tilde ::= '~' partial
|
||||
caret ::= '^' partial
|
||||
qualifier ::= ( '-' pre )? ( '+' build )?
|
||||
pre ::= parts
|
||||
build ::= parts
|
||||
parts ::= part ( '.' part ) *
|
||||
part ::= nr | [-0-9A-Za-z]+
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
All methods and classes take a final `options` object argument. All
|
||||
options in this object are `false` by default. The options supported
|
||||
are:
|
||||
|
||||
- `loose` Be more forgiving about not-quite-valid semver strings.
|
||||
(Any resulting output will always be 100% strict compliant, of
|
||||
course.) For backwards compatibility reasons, if the `options`
|
||||
argument is a boolean value instead of an object, it is interpreted
|
||||
to be the `loose` param.
|
||||
- `includePrerelease` Set to suppress the [default
|
||||
behavior](https://github.com/npm/node-semver#prerelease-tags) of
|
||||
excluding prerelease tagged versions from ranges unless they are
|
||||
explicitly opted into.
|
||||
|
||||
Strict-mode Comparators and Ranges will be strict about the SemVer
|
||||
strings that they parse.
|
||||
|
||||
* `valid(v)`: Return the parsed version, or null if it's not valid.
|
||||
* `inc(v, release)`: Return the version incremented by the release
|
||||
type (`major`, `premajor`, `minor`, `preminor`, `patch`,
|
||||
`prepatch`, or `prerelease`), or null if it's not valid
|
||||
* `premajor` in one call will bump the version up to the next major
|
||||
version and down to a prerelease of that major version.
|
||||
`preminor`, and `prepatch` work the same way.
|
||||
* If called from a non-prerelease version, the `prerelease` will work the
|
||||
same as `prepatch`. It increments the patch version, then makes a
|
||||
prerelease. If the input version is already a prerelease it simply
|
||||
increments it.
|
||||
* `prerelease(v)`: Returns an array of prerelease components, or null
|
||||
if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]`
|
||||
* `major(v)`: Return the major version number.
|
||||
* `minor(v)`: Return the minor version number.
|
||||
* `patch(v)`: Return the patch version number.
|
||||
* `intersects(r1, r2, loose)`: Return true if the two supplied ranges
|
||||
or comparators intersect.
|
||||
* `parse(v)`: Attempt to parse a string as a semantic version, returning either
|
||||
a `SemVer` object or `null`.
|
||||
|
||||
### Comparison
|
||||
|
||||
* `gt(v1, v2)`: `v1 > v2`
|
||||
* `gte(v1, v2)`: `v1 >= v2`
|
||||
* `lt(v1, v2)`: `v1 < v2`
|
||||
* `lte(v1, v2)`: `v1 <= v2`
|
||||
* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent,
|
||||
even if they're not the exact same string. You already know how to
|
||||
compare strings.
|
||||
* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`.
|
||||
* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call
|
||||
the corresponding function above. `"==="` and `"!=="` do simple
|
||||
string comparison, but are included for completeness. Throws if an
|
||||
invalid comparison string is provided.
|
||||
* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if
|
||||
`v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
|
||||
* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions
|
||||
in descending order when passed to `Array.sort()`.
|
||||
* `diff(v1, v2)`: Returns difference between two versions by the release type
|
||||
(`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`),
|
||||
or null if the versions are the same.
|
||||
|
||||
### Comparators
|
||||
|
||||
* `intersects(comparator)`: Return true if the comparators intersect
|
||||
|
||||
### Ranges
|
||||
|
||||
* `validRange(range)`: Return the valid range or null if it's not valid
|
||||
* `satisfies(version, range)`: Return true if the version satisfies the
|
||||
range.
|
||||
* `maxSatisfying(versions, range)`: Return the highest version in the list
|
||||
that satisfies the range, or `null` if none of them do.
|
||||
* `minSatisfying(versions, range)`: Return the lowest version in the list
|
||||
that satisfies the range, or `null` if none of them do.
|
||||
* `minVersion(range)`: Return the lowest version that can possibly match
|
||||
the given range.
|
||||
* `gtr(version, range)`: Return `true` if version is greater than all the
|
||||
versions possible in the range.
|
||||
* `ltr(version, range)`: Return `true` if version is less than all the
|
||||
versions possible in the range.
|
||||
* `outside(version, range, hilo)`: Return true if the version is outside
|
||||
the bounds of the range in either the high or low direction. The
|
||||
`hilo` argument must be either the string `'>'` or `'<'`. (This is
|
||||
the function called by `gtr` and `ltr`.)
|
||||
* `intersects(range)`: Return true if any of the ranges comparators intersect
|
||||
|
||||
Note that, since ranges may be non-contiguous, a version might not be
|
||||
greater than a range, less than a range, *or* satisfy a range! For
|
||||
example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9`
|
||||
until `2.0.0`, so the version `1.2.10` would not be greater than the
|
||||
range (because `2.0.1` satisfies, which is higher), nor less than the
|
||||
range (since `1.2.8` satisfies, which is lower), and it also does not
|
||||
satisfy the range.
|
||||
|
||||
If you want to know if a version satisfies or does not satisfy a
|
||||
range, use the `satisfies(version, range)` function.
|
||||
|
||||
### Coercion
|
||||
|
||||
* `coerce(version)`: Coerces a string to semver if possible
|
||||
|
||||
This aims to provide a very forgiving translation of a non-semver string to
|
||||
semver. It looks for the first digit in a string, and consumes all
|
||||
remaining characters which satisfy at least a partial semver (e.g., `1`,
|
||||
`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer
|
||||
versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All
|
||||
surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes
|
||||
`3.4.0`). Only text which lacks digits will fail coercion (`version one`
|
||||
is not valid). The maximum length for any semver component considered for
|
||||
coercion is 16 characters; longer components will be ignored
|
||||
(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any
|
||||
semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value
|
||||
components are invalid (`9999999999999999.4.7.4` is likely invalid).
|
||||
+346
@@ -0,0 +1,346 @@
|
||||
<html><head>
|
||||
<title>npm-diff</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
color: #24292e;
|
||||
|
||||
margin: 0;
|
||||
|
||||
line-height: 1.5;
|
||||
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
}
|
||||
#rainbar {
|
||||
height: 10px;
|
||||
background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0366d6;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 1em 0px;
|
||||
padding: 1em;
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
|
||||
display: block;
|
||||
overflow: auto;
|
||||
|
||||
white-space: pre;
|
||||
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
code {
|
||||
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 85%;
|
||||
padding: 0.2em 0.4em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
pre > code {
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#logobar {
|
||||
background-color: #333333;
|
||||
margin: 0 auto;
|
||||
padding: 1em 4em;
|
||||
}
|
||||
#logobar .logo {
|
||||
float: left;
|
||||
}
|
||||
#logobar .title {
|
||||
font-weight: 600;
|
||||
color: #dddddd;
|
||||
float: left;
|
||||
margin: 5px 0 0 1em;
|
||||
}
|
||||
#logobar:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 0 auto;
|
||||
padding: 0 4em;
|
||||
}
|
||||
|
||||
#table_of_contents > h2 {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
#table_of_contents ul:first-child {
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
padding: 1em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
#table_of_contents ul {
|
||||
list-style-type: none;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
#table_of_contents li {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#table_of_contents li a {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
header.title {
|
||||
border-bottom: solid 1px #e1e4e8;
|
||||
}
|
||||
header.title > h1 {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
header.title > .description {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
footer#edit {
|
||||
border-top: solid 1px #e1e4e8;
|
||||
margin: 3em 0 4em 0;
|
||||
padding-top: 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<div id="rainbar"></div>
|
||||
<div id="logobar">
|
||||
<svg class="logo" role="img" height="32" width="32" viewBox="0 0 700 700">
|
||||
<polygon fill="#cb0000" points="0,700 700,700 700,0 0,0"></polygon>
|
||||
<polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150"></polygon>
|
||||
</svg>
|
||||
<div class="title">
|
||||
npm command-line interface
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="content">
|
||||
<header class="title">
|
||||
<h1 id="npm-diff">npm-diff</h1>
|
||||
<span class="description">The registry diff command</span>
|
||||
</header>
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="synopsis">Synopsis</h3>
|
||||
<pre lang="bash"><code>npm diff [...<paths>]
|
||||
npm diff --diff=<pkg-name> [...<paths>]
|
||||
npm diff --diff=<version-a> [--diff=<version-b>] [...<paths>]
|
||||
npm diff --diff=<spec-a> [--diff=<spec-b>] [...<paths>]
|
||||
npm diff [--diff-ignore-all-space] [--diff-name-only] [...<paths>]
|
||||
</code></pre>
|
||||
<h3 id="description">Description</h3>
|
||||
<p>Similar to its <code>git diff</code> counterpart, this command will print diff patches
|
||||
of files for packages published to the npm registry.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>npm diff --diff=<spec-a> --diff=<spec-b></code></p>
|
||||
<p>Compares two package versions using their registry specifiers, e.g:
|
||||
<code>npm diff --diff=pkg@1.0.0 --diff=pkg@^2.0.0</code>. It’s also possible to
|
||||
compare across forks of any package,
|
||||
e.g: <code>npm diff --diff=pkg@1.0.0 --diff=pkg-fork@1.0.0</code>.</p>
|
||||
<p>Any valid spec can be used, so that it’s also possible to compare
|
||||
directories or git repositories,
|
||||
e.g: <code>npm diff --diff=pkg@latest --diff=./packages/pkg</code></p>
|
||||
<p>Here’s an example comparing two different versions of a package named
|
||||
<code>abbrev</code> from the registry:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=abbrev@1.1.0 --diff=abbrev@1.1.1
|
||||
</code></pre>
|
||||
<p>On success, output looks like:</p>
|
||||
<pre lang="bash"><code>diff --git a/package.json b/package.json
|
||||
index v1.1.0..v1.1.1 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
- "version": "1.1.0",
|
||||
+ "version": "1.1.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"main": "abbrev.js",
|
||||
</code></pre>
|
||||
<p>Given the flexible nature of npm specs, you can also target local
|
||||
directories or git repos just like when using <code>npm install</code>:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=https://github.com/npm/libnpmdiff --diff=./local-path
|
||||
</code></pre>
|
||||
<p>In the example above we can compare the contents from the package installed
|
||||
from the git repo at <code>github.com/npm/libnpmdiff</code> with the contents of the
|
||||
<code>./local-path</code> that contains a valid package, such as a modified copy of
|
||||
the original.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>npm diff</code> (in a package directory, no arguments):</p>
|
||||
<p>If the package is published to the registry, <code>npm diff</code> will fetch the
|
||||
tarball version tagged as <code>latest</code> (this value can be configured using the
|
||||
<code>tag</code> option) and proceed to compare the contents of files present in that
|
||||
tarball, with the current files in your local file system.</p>
|
||||
<p>This workflow provides a handy way for package authors to see what
|
||||
package-tracked files have been changed in comparison with the latest
|
||||
published version of that package.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>npm diff --diff=<pkg-name></code> (in a package directory):</p>
|
||||
<p>When using a single package name (with no version or tag specifier) as an
|
||||
argument, <code>npm diff</code> will work in a similar way to
|
||||
<a href="npm-outdated"><code>npm-outdated</code></a> and reach for the registry to figure out
|
||||
what current published version of the package named <!-- raw HTML omitted --> will satisfy
|
||||
its dependent declared semver-range. Once that specific version is known
|
||||
<code>npm diff</code> will print diff patches comparing the current version of
|
||||
<!-- raw HTML omitted --> found in the local file system with that specific version
|
||||
returned by the registry.</p>
|
||||
<p>Given a package named <code>abbrev</code> that is currently installed:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=abbrev
|
||||
</code></pre>
|
||||
<p>That will request from the registry its most up to date version and
|
||||
will print a diff output comparing the currently installed version to this
|
||||
newer one if the version numbers are not the same.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>npm diff --diff=<spec-a></code> (in a package directory):</p>
|
||||
<p>Similar to using only a single package name, it’s also possible to declare
|
||||
a full registry specifier version if you wish to compare the local version
|
||||
of an installed package with the specific version/tag/semver-range provided
|
||||
in <code><spec-a></code>.</p>
|
||||
<p>An example: assuming <code>pkg@1.0.0</code> is installed in the current <code>node_modules</code>
|
||||
folder, running:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=pkg@2.0.0
|
||||
</code></pre>
|
||||
<p>It will effectively be an alias to
|
||||
<code>npm diff --diff=pkg@1.0.0 --diff=pkg@2.0.0</code>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>npm diff --diff=<semver-a> [--diff=<semver-b>]</code> (in a package directory):</p>
|
||||
<p>Using <code>npm diff</code> along with semver-valid version numbers is a shorthand
|
||||
to compare different versions of the current package.</p>
|
||||
<p>It needs to be run from a package directory, such that for a package named
|
||||
<code>pkg</code> running <code>npm diff --diff=1.0.0 --diff=1.0.1</code> is the same as running
|
||||
<code>npm diff --diff=pkg@1.0.0 --diff=pkg@1.0.1</code>.</p>
|
||||
<p>If only a single argument <code><version-a></code> is provided, then the current local
|
||||
file system is going to be compared against that version.</p>
|
||||
<p>Here’s an example comparing two specific versions (published to the
|
||||
configured registry) of the current project directory:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=1.0.0 --diff=1.1.0
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Note that tag names are not valid <code>--diff</code> argument values, if you wish to
|
||||
compare to a published tag, you must use the <code>pkg@tagname</code> syntax.</p>
|
||||
<h4 id="filtering-files">Filtering files</h4>
|
||||
<p>It’s possible to also specify positional arguments using file names or globs
|
||||
pattern matching in order to limit the result of diff patches to only a subset
|
||||
of files for a given package, e.g:</p>
|
||||
<pre lang="bash"><code>npm diff --diff=pkg@2 ./lib/ CHANGELOG.md
|
||||
</code></pre>
|
||||
<p>In the example above the diff output is only going to print contents of files
|
||||
located within the folder <code>./lib/</code> and changed lines of code within the
|
||||
<code>CHANGELOG.md</code> file.</p>
|
||||
<h3 id="configuration">Configuration</h3>
|
||||
<h4 id="diff">diff</h4>
|
||||
<ul>
|
||||
<li>Type: Array<!-- raw HTML omitted --></li>
|
||||
<li>Default: null</li>
|
||||
</ul>
|
||||
<p>Defines npm package specifiers to compare using the <code>npm diff</code> command.</p>
|
||||
<p>This can be specified up to 2 times.</p>
|
||||
<h4 id="diff-name-only">diff-name-only</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>When set to <code>true</code> running <code>npm diff</code> only returns the names of the files that
|
||||
have any difference.</p>
|
||||
<h4 id="diff-unified">diff-unified</h4>
|
||||
<ul>
|
||||
<li>Type: Number</li>
|
||||
<li>Default: <code>3</code></li>
|
||||
</ul>
|
||||
<p>The number of lines of context to print in the unified diff format output.</p>
|
||||
<h4 id="diff-ignore-all-space">diff-ignore-all-space</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Ignore whitespace when comparing lines. This ignores differences even if one
|
||||
line has whitespace where the other line has none.</p>
|
||||
<h4 id="diff-no-prefix">diff-no-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Do not show any source or destination prefix.</p>
|
||||
<h4 id="diff-src-prefix">diff-src-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>"a/"</code></li>
|
||||
</ul>
|
||||
<p>Show the given source prefix in diff patches headers instead of using “a/”.</p>
|
||||
<h4 id="diff-dst-prefix">diff-dst-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>"b/"</code></li>
|
||||
</ul>
|
||||
<p>Show the given source prefix in diff patches headers instead of using “b/”.</p>
|
||||
<h4 id="diff-text">diff-text</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Treat all files as text.</p>
|
||||
<h4 id="global">global</h4>
|
||||
<ul>
|
||||
<li>Default: false</li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Uses packages from the global space as a source for comparison.</p>
|
||||
<h4 id="tag">tag</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>"latest"</code></li>
|
||||
</ul>
|
||||
<p>The tag used to fetch the tarball that will be compared with the local file
|
||||
system files when running npm diff with no arguments.</p>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a href="../commands/npm-outdated.html">npm outdated</a></li>
|
||||
<li><a href="../commands/npm-install.html">npm install</a></li>
|
||||
<li><a href="../commands/npm-config.html">npm config</a></li>
|
||||
<li><a href="../using-npm/registry.html">npm registry</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer id="edit">
|
||||
<a href="https://github.com/npm/cli/edit/latest/docs/content/commands/npm-diff.md">
|
||||
<svg role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentcolor" style="vertical-align: text-bottom; margin-right: 0.3em;">
|
||||
<path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path>
|
||||
</svg>
|
||||
Edit this page on GitHub
|
||||
</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
+15
-1
@@ -141,7 +141,7 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#npx-vs-npm-exec"><code>npx</code> vs <code>npm exec</code></a></li><li><a href="#examples">Examples</a></li><li><a href="#compatibility-with-older-npx-versions">Compatibility with Older npx Versions</a></li><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#npx-vs-npm-exec"><code>npx</code> vs <code>npm exec</code></a></li><li><a href="#examples">Examples</a></li><li><a href="#compatibility-with-older-npx-versions">Compatibility with Older npx Versions</a></li><li><a href="#a-note-on-caching">A note on caching</a></li><ul><li><a href="#prefer-online">prefer-online</a></li><li><a href="#prefer-offline">prefer-offline</a></li><li><a href="#offline">offline</a></li></ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="synopsis">Synopsis</h3>
|
||||
@@ -273,6 +273,20 @@ with.</li>
|
||||
<li>The <code>--shell</code> option is replaced with <code>--script-shell</code>, but maintained
|
||||
in the <code>npx</code> executable for backwards compatibility.</li>
|
||||
</ul>
|
||||
<h3 id="a-note-on-caching">A note on caching</h3>
|
||||
<p>The npm cli utilizes its internal package cache when using the package
|
||||
name specified. You can use the following to change how and when the
|
||||
cli uses this cache. See <a href="../commands/npm-cache.html"><code>npm cache</code></a> for more on
|
||||
how the cache works.</p>
|
||||
<h4 id="prefer-online">prefer-online</h4>
|
||||
<p>Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache.</p>
|
||||
<h4 id="prefer-offline">prefer-offline</h4>
|
||||
<p>Bypasses staleness checks for packages. Missing data will still be
|
||||
requested from the server. To force full offline mode, use <code>offline</code>.</p>
|
||||
<h4 id="offline">offline</h4>
|
||||
<p>Forces full offline mode. Any packages not locally cached will result in
|
||||
an error.</p>
|
||||
<h3 id="see-also">See Also</h3>
|
||||
<ul>
|
||||
<li><a href="../commands/npm-run-script.html">npm run-script</a></li>
|
||||
|
||||
+16
-1
@@ -141,7 +141,7 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#examples">Examples</a></li><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#examples">Examples</a></li><li><a href="#a-note-on-caching">A note on caching</a></li><ul><li><a href="#prefer-online">prefer-online</a></li><li><a href="#prefer-offline">prefer-offline</a></li><li><a href="#offline">offline</a></li></ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="synopsis">Synopsis</h3>
|
||||
@@ -189,12 +189,27 @@ $ npm init
|
||||
<p>Generate it without having it ask any questions:</p>
|
||||
<pre lang="bash"><code>$ npm init -y
|
||||
</code></pre>
|
||||
<h3 id="a-note-on-caching">A note on caching</h3>
|
||||
<p>The npm cli utilizes its internal package cache when using the package
|
||||
name specified. You can use the following to change how and when the
|
||||
cli uses this cache. See <a href="../commands/npm-cache.html"><code>npm cache</code></a> for more on
|
||||
how the cache works.</p>
|
||||
<h4 id="prefer-online">prefer-online</h4>
|
||||
<p>Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache.</p>
|
||||
<h4 id="prefer-offline">prefer-offline</h4>
|
||||
<p>Bypasses staleness checks for packages. Missing data will still be
|
||||
requested from the server. To force full offline mode, use <code>offline</code>.</p>
|
||||
<h4 id="offline">offline</h4>
|
||||
<p>Forces full offline mode. Any packages not locally cached will result in
|
||||
an error.</p>
|
||||
<h3 id="see-also">See Also</h3>
|
||||
<ul>
|
||||
<li><a href="http://npm.im/init-package-json">init-package-json module</a></li>
|
||||
<li><a href="../configuring-npm/package-json.html">package.json</a></li>
|
||||
<li><a href="../commands/npm-version.html">npm version</a></li>
|
||||
<li><a href="../using-npm/scope.html">npm scope</a></li>
|
||||
<li><a href="../commands/npm-exec.html">npm exec</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
+1
-1
@@ -159,7 +159,7 @@ tree at all, use <a href="../commands/npm-explain.html"><code>npm explain</code>
|
||||
the results to only the paths to the packages named. Note that nested
|
||||
packages will <em>also</em> show the paths to the specified packages. For
|
||||
example, running <code>npm ls promzard</code> in npm’s source tree will show:</p>
|
||||
<pre lang="bash"><code>npm@7.4.3 /path/to/npm
|
||||
<pre lang="bash"><code>npm@7.5.0 /path/to/npm
|
||||
└─┬ init-package-json@0.0.4
|
||||
└── promzard@0.1.5
|
||||
</code></pre>
|
||||
|
||||
@@ -173,7 +173,6 @@ on the command line when changing ownership with <code>--otp</code>.</p>
|
||||
<li><a href="../commands/npm-publish.html">npm publish</a></li>
|
||||
<li><a href="../using-npm/registry.html">npm registry</a></li>
|
||||
<li><a href="../commands/npm-adduser.html">npm adduser</a></li>
|
||||
<li><a href="../using-npm/disputes.html">npm disputes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
+32
-6
@@ -141,7 +141,7 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#configuration">Configuration</a></li><ul><li><a href="#if-present">if-present</a></li><li><a href="#ignore-scripts">ignore-scripts</a></li><li><a href="#script-shell">script-shell</a></li><li><a href="#silent">silent</a></li></ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="synopsis">Synopsis</h3>
|
||||
@@ -162,7 +162,7 @@ pass <code>-</code>-prefixed flags and options which would otherwise be parsed b
|
||||
<pre lang="bash"><code>npm run test -- --grep="pattern"
|
||||
</code></pre>
|
||||
<p>The arguments will only be passed to the script specified after <code>npm run</code>
|
||||
and not to any pre or post script.</p>
|
||||
and not to any <code>pre</code> or <code>post</code> script.</p>
|
||||
<p>The <code>env</code> script is a special built-in command that can be used to list
|
||||
environment variables that will be available to the script at runtime. If an
|
||||
“env” command is defined in your package, it will take precedence over the
|
||||
@@ -178,7 +178,8 @@ provided by locally-installed dependencies can be used without the
|
||||
<pre lang="bash"><code>"scripts": {"test": "node_modules/.bin/tap test/*.js"}
|
||||
</code></pre>
|
||||
<p>The actual shell your script is run within is platform dependent. By default,
|
||||
on Unix-like systems it is the <code>/bin/sh</code> command, on Windows it is the <code>cmd.exe</code>.
|
||||
on Unix-like systems it is the <code>/bin/sh</code> command, on Windows it is
|
||||
<code>cmd.exe</code>.
|
||||
The actual shell referred to by <code>/bin/sh</code> also depends on the system.
|
||||
You can customize the shell with the <code>script-shell</code> configuration.</p>
|
||||
<p>Scripts are run from the root of the package folder, regardless of what the
|
||||
@@ -192,12 +193,37 @@ passed, the directory within which <code>node</code> resides is added to the <co
|
||||
If <code>--scripts-prepend-node-path=auto</code> is passed (which has been the default
|
||||
in <code>npm</code> v3), this is only performed when that <code>node</code> executable is not
|
||||
found in the <code>PATH</code>.</p>
|
||||
<p>If you try to run a script without having a <code>node_modules</code> directory and it fails,
|
||||
you will be given a warning to run <code>npm install</code>, just in case you’ve forgotten.</p>
|
||||
<p>You can use the <code>--silent</code> flag to prevent showing <code>npm ERR!</code> output on error.</p>
|
||||
<p>If you try to run a script without having a <code>node_modules</code> directory and it
|
||||
fails, you will be given a warning to run <code>npm install</code>, just in case you’ve
|
||||
forgotten.</p>
|
||||
<h3 id="configuration">Configuration</h3>
|
||||
<h4 id="if-present">if-present</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>You can use the <code>--if-present</code> flag to avoid exiting with a non-zero exit code
|
||||
when the script is undefined. This lets you run potentially undefined scripts
|
||||
without breaking the execution chain.</p>
|
||||
<h4 id="ignore-scripts">ignore-scripts</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Skips running <code>pre</code> and <code>post</code> scripts.</p>
|
||||
<h4 id="script-shell">script-shell</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>null</code></li>
|
||||
</ul>
|
||||
<p>Optional custom script to use to execute the command. If not defined defaults
|
||||
to <code>/bin/sh</code> on Unix, defaults to <code>env.comspec</code> or <code>cmd.exe</code> on Windows.</p>
|
||||
<h4 id="silent">silent</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>You can use the <code>--silent</code> flag to prevent showing <code>npm ERR!</code> output on error.</p>
|
||||
<h3 id="see-also">See Also</h3>
|
||||
<ul>
|
||||
<li><a href="../using-npm/scripts.html">npm scripts</a></li>
|
||||
|
||||
+3
-3
@@ -230,11 +230,11 @@ locally in its cache. You can use the following to change how and when
|
||||
the cli uses this cache. See <a href="../commands/npm-cache.html"><code>npm cache</code></a> for more
|
||||
on how the cache works.</p>
|
||||
<h4 id="prefer-online">prefer-online</h4>
|
||||
<p>Forced staleness checks for cached searches, making the cli look for
|
||||
<p>Forces staleness checks for cached searches, making the cli look for
|
||||
updates immediately even for fresh search results.</p>
|
||||
<h4 id="prefer-offline">prefer-offline</h4>
|
||||
<p>Bypasses staleness checks for cached. Missing data will still be
|
||||
requested from the server. To force full offline mode, use <code>offline</code>.</p>
|
||||
<p>Bypasses staleness checks for cached searches. Missing data will still
|
||||
be requested from the server. To force full offline mode, use <code>offline</code>.</p>
|
||||
<h4 id="offline">offline</h4>
|
||||
<p>Forces full offline mode. Any searches not locally cached will result in
|
||||
an error.</p>
|
||||
|
||||
+10
-16
@@ -136,7 +136,7 @@ npm command-line interface
|
||||
<section id="content">
|
||||
<header class="title">
|
||||
<h1 id="npm-update">npm-update</h1>
|
||||
<span class="description">Update a package</span>
|
||||
<span class="description">Update packages</span>
|
||||
</header>
|
||||
|
||||
<section id="table_of_contents">
|
||||
@@ -159,18 +159,10 @@ as well.</p>
|
||||
packages.</p>
|
||||
<p>If no package name is specified, all packages in the specified location (global
|
||||
or local) will be updated.</p>
|
||||
<p>As of <code>npm@2.6.1</code>, the <code>npm update</code> will only inspect top-level packages.
|
||||
Prior versions of <code>npm</code> would also recursively inspect all dependencies.
|
||||
To get the old behavior, use <code>npm --depth 9999 update</code>.</p>
|
||||
<p>As of <code>npm@5.0.0</code>, the <code>npm update</code> will change <code>package.json</code> to save the
|
||||
new version as the minimum required dependency. To get the old behavior,
|
||||
use <code>npm update --no-save</code>.</p>
|
||||
<h3 id="example">Example</h3>
|
||||
<p>IMPORTANT VERSION NOTE: these examples assume <code>npm@2.6.1</code> or later. For
|
||||
older versions of <code>npm</code>, you must specify <code>--depth 0</code> to get the behavior
|
||||
described below.</p>
|
||||
<p>For the examples below, assume that the current package is <code>app</code> and it depends
|
||||
on dependencies, <code>dep1</code> (<code>dep2</code>, .. etc.). The published versions of <code>dep1</code> are:</p>
|
||||
on dependencies, <code>dep1</code> (<code>dep2</code>, .. etc.). The published versions of <code>dep1</code>
|
||||
are:</p>
|
||||
<pre lang="json"><code>{
|
||||
"dist-tags": { "latest": "1.2.2" },
|
||||
"versions": [
|
||||
@@ -200,10 +192,10 @@ on dependencies, <code>dep1</code> (<code>dep2</code>, .. etc.). The published
|
||||
"dep1": "~1.1.1"
|
||||
}
|
||||
</code></pre>
|
||||
<p>In this case, running <code>npm update</code> will install <code>dep1@1.1.2</code>. Even though the <code>latest</code>
|
||||
tag points to <code>1.2.2</code>, this version does not satisfy <code>~1.1.1</code>, which is equivalent
|
||||
to <code>>=1.1.1 <1.2.0</code>. So the highest-sorting version that satisfies <code>~1.1.1</code> is used,
|
||||
which is <code>1.1.2</code>.</p>
|
||||
<p>In this case, running <code>npm update</code> will install <code>dep1@1.1.2</code>. Even though the
|
||||
<code>latest</code> tag points to <code>1.2.2</code>, this version do not satisfy <code>~1.1.1</code>, which is
|
||||
equivalent to <code>>=1.1.1 <1.2.0</code>. So the highest-sorting version that satisfies
|
||||
<code>~1.1.1</code> is used, which is <code>1.1.2</code>.</p>
|
||||
<h4 id="caret-dependencies-below-100">Caret Dependencies below 1.0.0</h4>
|
||||
<p>Suppose <code>app</code> has a caret dependency on a version below <code>1.0.0</code>, for example:</p>
|
||||
<pre lang="json"><code>"dependencies": {
|
||||
@@ -223,7 +215,9 @@ version that satisfies <code>^0.4.0</code> (<code>>= 0.4.0 <0.5.0</code>)<
|
||||
<p><code>npm update -g</code> will apply the <code>update</code> action to each globally installed
|
||||
package that is <code>outdated</code> – that is, has a version that is different from
|
||||
<code>wanted</code>.</p>
|
||||
<p>Note: Globally installed packages are treated as if they are installed with a caret semver range specified. So if you require to update to <code>latest</code> you may need to run <code>npm install -g [<pkg>...]</code></p>
|
||||
<p>Note: Globally installed packages are treated as if they are installed with a
|
||||
caret semver range specified. So if you require to update to <code>latest</code> you may
|
||||
need to run <code>npm install -g [<pkg>...]</code></p>
|
||||
<p>NOTE: If a package has been upgraded to a version newer than <code>latest</code>, it will
|
||||
be <em>downgraded</em>.</p>
|
||||
<h3 id="see-also">See Also</h3>
|
||||
|
||||
+10
-11
@@ -141,7 +141,7 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#configuration">Configuration</a></li><ul><li><a href="#allow-same-version">allow-same-version</a></li><li><a href="#git-tag-version">git-tag-version</a></li><li><a href="#commit-hooks">commit-hooks</a></li><li><a href="#sign-git-tag">sign-git-tag</a></li></ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
<div id="_table_of_contents"><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#description">Description</a></li><li><a href="#configuration">Configuration</a></li><ul><li><a href="#allow-same-version"><code>allow-same-version</code></a></li><li><a href="#git-tag-version"><code>git-tag-version</code></a></li><li><a href="#commit-hooks"><code>commit-hooks</code></a></li><li><a href="#sign-git-tag"><code>sign-git-tag</code></a></li></ul><li><a href="#see-also">See Also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="synopsis">Synopsis</h3>
|
||||
@@ -207,32 +207,32 @@ the commit and/or tag.</li>
|
||||
"postversion": "git push && git push --tags && rm -rf build/temp"
|
||||
}
|
||||
</code></pre>
|
||||
<p>This runs all your tests, and proceeds only if they pass. Then runs your <code>build</code> script, and
|
||||
<p>This runs all your tests and proceeds only if they pass. Then runs your <code>build</code> script, and
|
||||
adds everything in the <code>dist</code> directory to the commit. After the commit, it pushes the new commit
|
||||
and tag up to the server, and deletes the <code>build/temp</code> directory.</p>
|
||||
<h3 id="configuration">Configuration</h3>
|
||||
<h4 id="allow-same-version">allow-same-version</h4>
|
||||
<h4 id="allow-same-version"><code>allow-same-version</code></h4>
|
||||
<ul>
|
||||
<li>Default: false</li>
|
||||
<li>Default: <code>false</code></li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Prevents throwing an error when <code>npm version</code> is used to set the new version
|
||||
to the same value as the current version.</p>
|
||||
<h4 id="git-tag-version">git-tag-version</h4>
|
||||
<h4 id="git-tag-version"><code>git-tag-version</code></h4>
|
||||
<ul>
|
||||
<li>Default: true</li>
|
||||
<li>Default: <code>true</code></li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Commit and tag the version change.</p>
|
||||
<h4 id="commit-hooks">commit-hooks</h4>
|
||||
<h4 id="commit-hooks"><code>commit-hooks</code></h4>
|
||||
<ul>
|
||||
<li>Default: true</li>
|
||||
<li>Default: <code>true</code></li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Run git commit hooks when committing the version change.</p>
|
||||
<h4 id="sign-git-tag">sign-git-tag</h4>
|
||||
<h4 id="sign-git-tag"><code>sign-git-tag</code></h4>
|
||||
<ul>
|
||||
<li>Default: false</li>
|
||||
<li>Default: <code>false</code></li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Pass the <code>-s</code> flag to git to sign the tag.</p>
|
||||
@@ -243,7 +243,6 @@ to the same value as the current version.</p>
|
||||
<li><a href="../commands/npm-run-script.html">npm run-script</a></li>
|
||||
<li><a href="../using-npm/scripts.html">npm scripts</a></li>
|
||||
<li><a href="../configuring-npm/package-json.html">package.json</a></li>
|
||||
<li><a href="../using-npm/semver.html">semver</a></li>
|
||||
<li><a href="../using-npm/config.html">config</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
+17
-19
@@ -152,34 +152,32 @@ aliases: info, show, v
|
||||
<h3 id="description">Description</h3>
|
||||
<p>This command shows data about a package and prints it to the stream
|
||||
referenced by the <code>outfd</code> config, which defaults to stdout.</p>
|
||||
<p>To show the package registry entry for the <code>connect</code> package, you can do
|
||||
this:</p>
|
||||
<p>As an example, to view information about the <code>connect</code> package from the registry, you would run:</p>
|
||||
<pre lang="bash"><code>npm view connect
|
||||
</code></pre>
|
||||
<p>The default version is “latest” if unspecified.</p>
|
||||
<p>The default version is <code>"latest"</code> if unspecified.</p>
|
||||
<p>Field names can be specified after the package descriptor.
|
||||
For example, to show the dependencies of the <code>ronn</code> package at version
|
||||
0.3.5, you could do the following:</p>
|
||||
<code>0.3.5</code>, you could do the following:</p>
|
||||
<pre lang="bash"><code>npm view ronn@0.3.5 dependencies
|
||||
</code></pre>
|
||||
<p>You can view child fields by separating them with a period.
|
||||
To view the git repository URL for the latest version of npm, you could
|
||||
do this:</p>
|
||||
To view the git repository URL for the latest version of <code>npm</code>, you would run the following command:</p>
|
||||
<pre lang="bash"><code>npm view npm repository.url
|
||||
</code></pre>
|
||||
<p>This makes it easy to view information about a dependency with a bit of
|
||||
shell scripting. For example, to view all the data about the version of
|
||||
opts that ronn depends on, you can do this:</p>
|
||||
shell scripting. For example, to view all the data about the version of
|
||||
<code>opts</code> that <code>ronn</code> depends on, you could write the following:</p>
|
||||
<pre lang="bash"><code>npm view opts@$(npm view ronn dependencies.opts)
|
||||
</code></pre>
|
||||
<p>For fields that are arrays, requesting a non-numeric field will return
|
||||
all of the values from the objects in the list. For example, to get all
|
||||
the contributor names for the “express” project, you can do this:</p>
|
||||
all of the values from the objects in the list. For example, to get all
|
||||
the contributor names for the <code>express</code> package, you would run:</p>
|
||||
<pre lang="bash"><code>npm view express contributors.email
|
||||
</code></pre>
|
||||
<p>You may also use numeric indices in square braces to specifically select
|
||||
an item in an array field. To just get the email address of the first
|
||||
contributor in the list, you can do this:</p>
|
||||
an item in an array field. To just get the email address of the first
|
||||
contributor in the list, you can run:</p>
|
||||
<pre lang="bash"><code>npm view express contributors[0].email
|
||||
</code></pre>
|
||||
<p>Multiple fields may be specified, and will be printed one after another.
|
||||
@@ -188,13 +186,13 @@ can do this:</p>
|
||||
<pre lang="bash"><code>npm view express contributors.name contributors.email
|
||||
</code></pre>
|
||||
<p>“Person” fields are shown as a string if they would be shown as an
|
||||
object. So, for example, this will show the list of npm contributors in
|
||||
object. So, for example, this will show the list of <code>npm</code> contributors in
|
||||
the shortened string format. (See <a href="../configuring-npm/package.json.html"><code>package.json</code></a> for more on this.)</p>
|
||||
<pre lang="bash"><code>npm view npm contributors
|
||||
</code></pre>
|
||||
<p>If a version range is provided, then data will be printed for every
|
||||
matching version of the package. This will show which version of jsdom
|
||||
was required by each matching version of yui3:</p>
|
||||
matching version of the package. This will show which version of <code>jsdom</code>
|
||||
was required by each matching version of <code>yui3</code>:</p>
|
||||
<pre lang="bash"><code>npm view yui3@'>0.5.4' dependencies.jsdom
|
||||
</code></pre>
|
||||
<p>To show the <code>connect</code> package version history, you can do
|
||||
@@ -203,12 +201,12 @@ this:</p>
|
||||
</code></pre>
|
||||
<h3 id="output">Output</h3>
|
||||
<p>If only a single string field for a single version is output, then it
|
||||
will not be colorized or quoted, so as to enable piping the output to
|
||||
will not be colorized or quoted, to enable piping the output to
|
||||
another command. If the field is an object, it will be output as a JavaScript object literal.</p>
|
||||
<p>If the –json flag is given, the outputted fields will be JSON.</p>
|
||||
<p>If the version range matches multiple versions, than each printed value
|
||||
<p>If the <code>--json</code> flag is given, the outputted fields will be JSON.</p>
|
||||
<p>If the version range matches multiple versions then each printed value
|
||||
will be prefixed with the version it applies to.</p>
|
||||
<p>If multiple fields are requested, than each of them are prefixed with
|
||||
<p>If multiple fields are requested, then each of them is prefixed with
|
||||
the field name.</p>
|
||||
<h3 id="see-also">See Also</h3>
|
||||
<ul>
|
||||
|
||||
+58
-46
@@ -148,31 +148,36 @@ npm command-line interface
|
||||
<pre lang="bash"><code>npm <command> [args]
|
||||
</code></pre>
|
||||
<h3 id="version">Version</h3>
|
||||
<p>7.4.3</p>
|
||||
<p>7.5.0</p>
|
||||
<h3 id="description">Description</h3>
|
||||
<p>npm is the package manager for the Node JavaScript platform. It puts
|
||||
modules in place so that node can find them, and manages dependency
|
||||
conflicts intelligently.</p>
|
||||
<p>It is extremely configurable to support a wide variety of use cases.
|
||||
Most commonly, it is used to publish, discover, install, and develop node
|
||||
<p>It is extremely configurable to support a variety of use cases. Most
|
||||
commonly, you use it to publish, discover, install, and develop node
|
||||
programs.</p>
|
||||
<p>Run <code>npm help</code> to get a list of available commands.</p>
|
||||
<h3 id="important">Important</h3>
|
||||
<p>npm is configured to use npm, Inc.’s public registry at
|
||||
<p>npm comes preconfigured to use npm’s public registry at
|
||||
<a href="https://registry.npmjs.org">https://registry.npmjs.org</a> by default. Use of the npm public registry is
|
||||
subject to terms of use available at <a href="https://www.npmjs.com/policies/terms">https://www.npmjs.com/policies/terms</a>.</p>
|
||||
<p>You can configure npm to use any compatible registry you like, and even run
|
||||
your own registry. Use of someone else’s registry may be governed by their
|
||||
terms of use.</p>
|
||||
subject to terms of use available at
|
||||
<a href="https://www.npmjs.com/policies/terms">https://www.npmjs.com/policies/terms</a>.</p>
|
||||
<p>You can configure npm to use any compatible registry you like, and even
|
||||
run your own registry. Use of someone else’s registry is governed by
|
||||
their terms of use.</p>
|
||||
<h3 id="introduction">Introduction</h3>
|
||||
<p>You probably got npm because you want to install stuff.</p>
|
||||
<p>Use <code>npm install blerg</code> to install the latest version of “blerg”. Check out
|
||||
<a href="../commands/npm-install.html"><code>npm install</code></a> for more info. It can do a lot of stuff.</p>
|
||||
<p>Use the <code>npm search</code> command to show everything that’s available.
|
||||
Use <code>npm ls</code> to show everything you’ve installed.</p>
|
||||
<p>The very first thing you will most likely want to run in any node
|
||||
program is <code>npm install</code> to install its dependencies.</p>
|
||||
<p>You can also run <code>npm install blerg</code> to install the latest version of
|
||||
“blerg”. Check out <a href="../commands/npm-install.html"><code>npm install</code></a> for more
|
||||
info. It can do a lot of stuff.</p>
|
||||
<p>Use the <code>npm search</code> command to show everything that’s available in the
|
||||
public registry. Use <code>npm ls</code> to show everything you’ve installed.</p>
|
||||
<h3 id="dependencies">Dependencies</h3>
|
||||
<p>If a package references to another package with a git URL, npm depends
|
||||
on a preinstalled git.</p>
|
||||
<p>If a package lists a dependency using a git URL, npm will install that
|
||||
dependency using the <a href="https://github.com/git-guides/install-git"><code>git</code></a>
|
||||
command and will generate an error if it is not installed.</p>
|
||||
<p>If one of the packages npm tries to install is a native node module and
|
||||
requires compiling of C++ Code, npm will use
|
||||
<a href="https://github.com/nodejs/node-gyp">node-gyp</a> for that task.
|
||||
@@ -184,38 +189,41 @@ For more information visit
|
||||
<a href="https://github.com/nodejs/node-gyp">the node-gyp repository</a> and
|
||||
the <a href="https://github.com/nodejs/node-gyp/wiki">node-gyp Wiki</a>.</p>
|
||||
<h3 id="directories">Directories</h3>
|
||||
<p>See <a href="../configuring-npm/folders.html"><code>folders</code></a> to learn about where npm puts stuff.</p>
|
||||
<p>See <a href="../configuring-npm/folders.html"><code>folders</code></a> to learn about where npm puts
|
||||
stuff.</p>
|
||||
<p>In particular, npm has two modes of operation:</p>
|
||||
<ul>
|
||||
<li>global mode:
|
||||
npm installs packages into the install prefix at
|
||||
<code>prefix/lib/node_modules</code> and bins are installed in <code>prefix/bin</code>.</li>
|
||||
<li>local mode:
|
||||
npm installs packages into the current project directory, which
|
||||
defaults to the current working directory. Packages are installed to
|
||||
<code>./node_modules</code>, and bins are installed to <code>./node_modules/.bin</code>.</li>
|
||||
defaults to the current working directory. Packages install to
|
||||
<code>./node_modules</code>, and bins to <code>./node_modules/.bin</code>.</li>
|
||||
<li>global mode:
|
||||
npm installs packages into the install prefix at
|
||||
<code>$npm_config_prefix/lib/node_modules</code> and bins to
|
||||
<code>$npm_config_prefix/bin</code>.</li>
|
||||
</ul>
|
||||
<p>Local mode is the default. Use <code>-g</code> or <code>--global</code> on any command to
|
||||
operate in global mode instead.</p>
|
||||
run in global mode instead.</p>
|
||||
<h3 id="developer-usage">Developer Usage</h3>
|
||||
<p>If you’re using npm to develop and publish your code, check out the
|
||||
following help topics:</p>
|
||||
<ul>
|
||||
<li>json:
|
||||
Make a package.json file. See <a href="../configuring-npm/package-json.html"><code>package.json</code></a>.</li>
|
||||
Make a package.json file. See
|
||||
<a href="../configuring-npm/package-json.html"><code>package.json</code></a>.</li>
|
||||
<li>link:
|
||||
For linking your current working code into Node’s path, so that you
|
||||
don’t have to reinstall every time you make a change. Use
|
||||
<code>npm link</code> to do this.</li>
|
||||
Links your current working code into Node’s path, so that you don’t
|
||||
have to reinstall every time you make a change. Use <a href="../commands/npm-link.html"><code>npm link</code></a> to do this.</li>
|
||||
<li>install:
|
||||
It’s a good idea to install things if you don’t need the symbolic link.
|
||||
Especially, installing other peoples code from the registry is done via
|
||||
<code>npm install</code></li>
|
||||
It’s a good idea to install things if you don’t need the symbolic
|
||||
link. Especially, installing other peoples code from the registry is
|
||||
done via <a href="../commands/npm-install.html"><code>npm install</code></a></li>
|
||||
<li>adduser:
|
||||
Create an account or log in. Credentials are stored in the
|
||||
user config file.</li>
|
||||
Create an account or log in. When you do this, npm will store
|
||||
credentials in the user config file config file.</li>
|
||||
<li>publish:
|
||||
Use the <code>npm publish</code> command to upload your code to the registry.</li>
|
||||
Use the <a href="../commands/npm-publish%60.html"><code>npm publish</code></a> command to upload your
|
||||
code to the registry.</li>
|
||||
</ul>
|
||||
<h4 id="configuration">Configuration</h4>
|
||||
<p>npm is extremely configurable. It reads its configuration options from
|
||||
@@ -224,20 +232,20 @@ Use the <code>npm publish</code> command to upload your code to the registry.</l
|
||||
<li>Command line switches:
|
||||
Set a config with <code>--key val</code>. All keys take a value, even if they
|
||||
are booleans (the config parser doesn’t know what the options are at
|
||||
the time of parsing). If no value is provided, then the option is set
|
||||
to boolean <code>true</code>.</li>
|
||||
the time of parsing). If you do not provide a value (<code>--key</code>) then
|
||||
the option is set to boolean <code>true</code>.</li>
|
||||
<li>Environment Variables:
|
||||
Set any config by prefixing the name in an environment variable with
|
||||
<code>npm_config_</code>. For example, <code>export npm_config_key=val</code>.</li>
|
||||
<li>User Configs:
|
||||
The file at $HOME/.npmrc is an ini-formatted list of configs. If
|
||||
The file at <code>$HOME/.npmrc</code> is an ini-formatted list of configs. If
|
||||
present, it is parsed. If the <code>userconfig</code> option is set in the cli
|
||||
or env, then that will be used instead.</li>
|
||||
or env, that file will be used instead.</li>
|
||||
<li>Global Configs:
|
||||
The file found at ../etc/npmrc (from the node executable, by default
|
||||
this resolves to /usr/local/etc/npmrc) will be parsed if it is found.
|
||||
If the <code>globalconfig</code> option is set in the cli, env, or user config,
|
||||
then that file is parsed instead.</li>
|
||||
The file found at <code>./etc/npmrc</code> (relative to the global prefix will be
|
||||
parsed if it is found. See <a href="../commands/npm-prefix.html"><code>npm prefix</code></a> for
|
||||
more info on the global prefix. If the <code>globalconfig</code> option is set
|
||||
in the cli, env, or user config, then that file is parsed instead.</li>
|
||||
<li>Defaults:
|
||||
npm’s default configuration options are defined in
|
||||
lib/utils/config-defs.js. These must not be changed.</li>
|
||||
@@ -245,12 +253,14 @@ lib/utils/config-defs.js. These must not be changed.</li>
|
||||
<p>See <a href="../using-npm/config.html"><code>config</code></a> for much much more information.</p>
|
||||
<h3 id="contributions">Contributions</h3>
|
||||
<p>Patches welcome!</p>
|
||||
<p>If you would like to contribute, but don’t know what to work on, read
|
||||
the <a href="https://github.com/npm/cli/blob/latest/CONTRIBUTING.md">contributing guidelines</a>
|
||||
and check the issues list.</p>
|
||||
<p>If you would like to help, but don’t know what to work on, read the
|
||||
<a href="https://github.com/npm/cli/blob/latest/CONTRIBUTING.md">contributing
|
||||
guidelines</a> and
|
||||
check the issues list.</p>
|
||||
<h3 id="bugs">Bugs</h3>
|
||||
<p>When you find issues, please report them: <a href="https://github.com/npm/cli/issues">https://github.com/npm/cli/issues</a></p>
|
||||
<p>Be sure to follow the template and bug reporting guidelines.</p>
|
||||
<p>When you find issues, please report them:
|
||||
<a href="https://github.com/npm/cli/issues">https://github.com/npm/cli/issues</a></p>
|
||||
<p>Please be sure to follow the template and bug reporting guidelines.</p>
|
||||
<h3 id="feature-requests">Feature Requests</h3>
|
||||
<p>Discuss new feature ideas on our discussion forum:</p>
|
||||
<ul>
|
||||
@@ -264,9 +274,11 @@ and check the issues list.</p>
|
||||
<ul>
|
||||
<li><a href="../commands/npm-help.html">npm help</a></li>
|
||||
<li><a href="../configuring-npm/package-json.html">package.json</a></li>
|
||||
<li><a href="../commands/npm-install.html">npm install</a></li>
|
||||
<li><a href="../commands/npm-config.html">npm config</a></li>
|
||||
<li><a href="../configuring-npm/npmrc.html">npmrc</a></li>
|
||||
<li><a href="../commands/npm-config.html">npm config</a></li>
|
||||
<li><a href="../commands/npm-install.html">npm install</a></li>
|
||||
<li><a href="../commands/npm-prefix.html">npm prefix</a></li>
|
||||
<li><a href="../commands/npm-publish.html">npm publish</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
+5
-6
@@ -193,7 +193,6 @@ version fields are optional.</p>
|
||||
<p>Version must be parseable by
|
||||
<a href="https://github.com/npm/node-semver">node-semver</a>, which is bundled with
|
||||
npm as a dependency. (<code>npm install semver</code> to use it yourself.)</p>
|
||||
<p>More on version numbers and ranges at <a href="../using-npm/semver.html">semver</a>.</p>
|
||||
<h3 id="description2">description</h3>
|
||||
<p>Put a description in it. It’s a string. This helps people discover your
|
||||
package, as it’s listed in <code>npm search</code>.</p>
|
||||
@@ -566,8 +565,8 @@ space-separated descriptors. Dependencies can also be identified with a
|
||||
tarball or git URL.</p>
|
||||
<p><strong>Please do not put test harnesses or transpilers or other “development”
|
||||
time tools in your <code>dependencies</code> object.</strong> See <code>devDependencies</code>, below.</p>
|
||||
<p>See <a href="../using-npm/semver.html">semver</a> for more details about specifying version
|
||||
ranges.</p>
|
||||
<p>See <a href="%5B/using-npm/semver%5D(https://github.com/npm/node-semver#versions)">semver</a>
|
||||
for more details about specifying version ranges.</p>
|
||||
<ul>
|
||||
<li><code>version</code> Must match <code>version</code> exactly</li>
|
||||
<li><code>>version</code> Must be greater than <code>version</code></li>
|
||||
@@ -575,8 +574,8 @@ ranges.</p>
|
||||
<li><code><version</code></li>
|
||||
<li><code><=version</code></li>
|
||||
<li><code>~version</code> “Approximately equivalent to version” See
|
||||
<a href="../using-npm/semver.html">semver</a></li>
|
||||
<li><code>^version</code> “Compatible with version” See <a href="../using-npm/semver.html">semver</a></li>
|
||||
<a href="https://github.com/npm/node-semver#versions">semver</a></li>
|
||||
<li><code>^version</code> “Compatible with version” See <a href="https://github.com/npm/node-semver#versions">semver</a></li>
|
||||
<li><code>1.2.x</code> 1.2.0, 1.2.1, etc., but not 1.3.0</li>
|
||||
<li><code>http://...</code> See ‘URLs as Dependencies’ below</li>
|
||||
<li><code>*</code> Matches any version</li>
|
||||
@@ -917,7 +916,7 @@ optional. Lines which start with a <code>#</code> or are blank, will be ignored
|
||||
</ul>
|
||||
<h3 id="see-also">SEE ALSO</h3>
|
||||
<ul>
|
||||
<li><a href="../using-npm/semver.html">semver</a></li>
|
||||
<li><a href="https://github.com/npm/node-semver#versions">semver</a></li>
|
||||
<li><a href="../using-npm/workspaces.html">workspaces</a></li>
|
||||
<li><a href="../commands/npm-init.html">npm init</a></li>
|
||||
<li><a href="../commands/npm-version.html">npm version</a></li>
|
||||
|
||||
+50
-1
@@ -141,7 +141,7 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><ul><li><a href="#command-line-flags">Command Line Flags</a></li><li><a href="#environment-variables">Environment Variables</a></li><li><a href="#npmrc-files">npmrc Files</a></li><li><a href="#default-configs">Default Configs</a></li></ul><li><a href="#shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</a></li><li><a href="#config-settings">Config Settings</a></li><ul><li><a href="#access">access</a></li><li><a href="#all">all</a></li><li><a href="#allow-same-version">allow-same-version</a></li><li><a href="#always-auth">always-auth</a></li><li><a href="#also">also</a></li><li><a href="#audit">audit</a></li><li><a href="#audit-level">audit-level</a></li><li><a href="#auth-type">auth-type</a></li><li><a href="#before">before</a></li><li><a href="#bin-links">bin-links</a></li><li><a href="#browser">browser</a></li><li><a href="#ca">ca</a></li><li><a href="#cafile">cafile</a></li><li><a href="#cache">cache</a></li><li><a href="#cache-lock-stale">cache-lock-stale</a></li><li><a href="#cache-lock-retries">cache-lock-retries</a></li><li><a href="#cache-lock-wait">cache-lock-wait</a></li><li><a href="#cache-max">cache-max</a></li><li><a href="#cache-min">cache-min</a></li><li><a href="#call">call</a></li><li><a href="#cert">cert</a></li><li><a href="#cidr">cidr</a></li><li><a href="#commit-hooks">commit-hooks</a></li><li><a href="#color">color</a></li><li><a href="#depth">depth</a></li><li><a href="#description2">description</a></li><li><a href="#dev">dev</a></li><li><a href="#dry-run">dry-run</a></li><li><a href="#editor">editor</a></li><li><a href="#engine-strict">engine-strict</a></li><li><a href="#force">force</a></li><li><a href="#foreground-scripts">foreground-scripts</a></li><li><a href="#format-package-lock">format-package-lock</a></li><li><a href="#fund">fund</a></li><li><a href="#fetch-retries">fetch-retries</a></li><li><a href="#fetch-retry-factor">fetch-retry-factor</a></li><li><a href="#fetch-retry-mintimeout">fetch-retry-mintimeout</a></li><li><a href="#fetch-retry-maxtimeout">fetch-retry-maxtimeout</a></li><li><a href="#fetch-timeout">fetch-timeout</a></li><li><a href="#git">git</a></li><li><a href="#git-tag-version">git-tag-version</a></li><li><a href="#global">global</a></li><li><a href="#globalconfig">globalconfig</a></li><li><a href="#global-style">global-style</a></li><li><a href="#heading">heading</a></li><li><a href="#https-proxy">https-proxy</a></li><li><a href="#if-present">if-present</a></li><li><a href="#ignore-prepublish">ignore-prepublish</a></li><li><a href="#ignore-scripts">ignore-scripts</a></li><li><a href="#include">include</a></li><li><a href="#init-module">init-module</a></li><li><a href="#init-author-name">init-author-name</a></li><li><a href="#init-author-email">init-author-email</a></li><li><a href="#init-author-url">init-author-url</a></li><li><a href="#init-license">init-license</a></li><li><a href="#init-version">init-version</a></li><li><a href="#json">json</a></li><li><a href="#key">key</a></li><li><a href="#legacy-bundling">legacy-bundling</a></li><li><a href="#legacy-peer-deps">legacy-peer-deps</a></li><li><a href="#link">link</a></li><li><a href="#local-address">local-address</a></li><li><a href="#loglevel">loglevel</a></li><li><a href="#logs-max">logs-max</a></li><li><a href="#long">long</a></li><li><a href="#maxsockets">maxsockets</a></li><li><a href="#message">message</a></li><li><a href="#node-options">node-options</a></li><li><a href="#node-version">node-version</a></li><li><a href="#noproxy">noproxy</a></li><li><a href="#offline">offline</a></li><li><a href="#only">only</a></li><li><a href="#optional">optional</a></li><li><a href="#otp">otp</a></li><li><a href="#package-lock">package-lock</a></li><li><a href="#package-lock-only">package-lock-only</a></li><li><a href="#parseable">parseable</a></li><li><a href="#prefer-offline">prefer-offline</a></li><li><a href="#prefer-online">prefer-online</a></li><li><a href="#prefix">prefix</a></li><li><a href="#preid">preid</a></li><li><a href="#production">production</a></li><li><a href="#progress">progress</a></li><li><a href="#proxy">proxy</a></li><li><a href="#read-only">read-only</a></li><li><a href="#rebuild-bundle">rebuild-bundle</a></li><li><a href="#registry">registry</a></li><li><a href="#rollback">rollback</a></li><li><a href="#save">save</a></li><li><a href="#save-bundle">save-bundle</a></li><li><a href="#save-prod">save-prod</a></li><li><a href="#save-dev">save-dev</a></li><li><a href="#save-exact">save-exact</a></li><li><a href="#save-optional">save-optional</a></li><li><a href="#save-prefix">save-prefix</a></li><li><a href="#scope">scope</a></li><li><a href="#script-shell">script-shell</a></li><li><a href="#scripts-prepend-node-path">scripts-prepend-node-path</a></li><li><a href="#searchexclude">searchexclude</a></li><li><a href="#searchopts">searchopts</a></li><li><a href="#searchlimit">searchlimit</a></li><li><aLine truncated
|
||||
<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><ul><li><a href="#command-line-flags">Command Line Flags</a></li><li><a href="#environment-variables">Environment Variables</a></li><li><a href="#npmrc-files">npmrc Files</a></li><li><a href="#default-configs">Default Configs</a></li></ul><li><a href="#shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</a></li><li><a href="#config-settings">Config Settings</a></li><ul><li><a href="#access">access</a></li><li><a href="#all">all</a></li><li><a href="#allow-same-version">allow-same-version</a></li><li><a href="#always-auth">always-auth</a></li><li><a href="#also">also</a></li><li><a href="#audit">audit</a></li><li><a href="#audit-level">audit-level</a></li><li><a href="#auth-type">auth-type</a></li><li><a href="#before">before</a></li><li><a href="#bin-links">bin-links</a></li><li><a href="#browser">browser</a></li><li><a href="#ca">ca</a></li><li><a href="#cafile">cafile</a></li><li><a href="#cache">cache</a></li><li><a href="#cache-lock-stale">cache-lock-stale</a></li><li><a href="#cache-lock-retries">cache-lock-retries</a></li><li><a href="#cache-lock-wait">cache-lock-wait</a></li><li><a href="#cache-max">cache-max</a></li><li><a href="#cache-min">cache-min</a></li><li><a href="#call">call</a></li><li><a href="#cert">cert</a></li><li><a href="#cidr">cidr</a></li><li><a href="#commit-hooks">commit-hooks</a></li><li><a href="#color">color</a></li><li><a href="#depth">depth</a></li><li><a href="#description2">description</a></li><li><a href="#dev">dev</a></li><li><a href="#dry-run">dry-run</a></li><li><a href="#diff">diff</a></li><li><a href="#diff-name-only">diff-name-only</a></li><li><a href="#diff-unified">diff-unified</a></li><li><a href="#diff-ignore-all-space">diff-ignore-all-space</a></li><li><a href="#diff-no-prefix">diff-no-prefix</a></li><li><a href="#diff-src-prefix">diff-src-prefix</a></li><li><a href="#diff-dst-prefix">diff-dst-prefix</a></li><li><a href="#diff-text">diff-text</a></li><li><a href="#editor">editor</a></li><li><a href="#engine-strict">engine-strict</a></li><li><a href="#force">force</a></li><li><a href="#foreground-scripts">foreground-scripts</a></li><li><a href="#format-package-lock">format-package-lock</a></li><li><a href="#fund">fund</a></li><li><a href="#fetch-retries">fetch-retries</a></li><li><a href="#fetch-retry-factor">fetch-retry-factor</a></li><li><a href="#fetch-retry-mintimeout">fetch-retry-mintimeout</a></li><li><a href="#fetch-retry-maxtimeout">fetch-retry-maxtimeout</a></li><li><a href="#fetch-timeout">fetch-timeout</a></li><li><a href="#git">git</a></li><li><a href="#git-tag-version">git-tag-version</a></li><li><a href="#global">global</a></li><li><a href="#globalconfig">globalconfig</a></li><li><a href="#global-style">global-style</a></li><li><a href="#heading">heading</a></li><li><a href="#https-proxy">https-proxy</a></li><li><a href="#if-present">if-present</a></li><li><a href="#ignore-prepublish">ignore-prepublish</a></li><li><a href="#ignore-scripts">ignore-scripts</a></li><li><a href="#include">include</a></li><li><a href="#init-module">init-module</a></li><li><a href="#init-author-name">init-author-name</a></li><li><a href="#init-author-email">init-author-email</a></li><li><a href="#init-author-url">init-author-url</a></li><li><a href="#init-license">init-license</a></li><li><a href="#init-version">init-version</a></li><li><a href="#json">json</a></li><li><a href="#key">key</a></li><li><a href="#legacy-bundling">legacy-bundling</a></li><li><a href="#legacy-peer-deps">legacy-peer-deps</a></li><li><a href="#link">link</a></li><li><a href="#local-address">local-address</a></li><li><a href="#loglevel">loglevel</a></li><li><a href="#logs-max">logs-max</a></li><li><a href="#long">long</a></li><li><a href="#maxsockets">maxsockets</a></li><li><a href="#message">message</a></li><li><a href="#node-options">node-options</a></li><li><a href="#node-version">node-version</a></li><li><a href="#noproxy">noproxy</a></li><li><a href="#offline">offline</a></li><li><a href="#only">only</a></li><li><a href="#optional">optional</a></li><li><a href="#otp">otp</a></li><li><a href="#package-lock">package-lock</a></li><li><a href="#package-lock-only">package-lock-only</a></li><li><a href="#parseable">parseable</a></li><li><a href="#prefer-offline">prefer-offline</a></li><li><a href="#prefer-online">prefer-online</a></li><li><a href="#prefix">prefix</a></li><li><a href="#preid">preid</a></li><li><a href="#production">production</a></li><li><a href="#progress">progress</a></li><li><a href="#proxy">proxy</a></li><li><a href="#read-only">read-only</a></li><li><a href="#rebuild-bundle">rebuild-bundle</a></li><li><a href="#registry">registry</a></li><li><a href="#rollback">rollback</a></li><li><a href="#save">save</a></li><li><a href="#save-bundle">save-bundle</a></li><li><a href="#save-prod">save-prod</a></li><li><a href="#save-dev">save-dev</a></li><li><a href="#save-exact">save-exact</a></lLine truncated
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="description">Description</h3>
|
||||
@@ -451,6 +451,55 @@ only report what it would have done. This can be passed into any of the
|
||||
commands that modify your local installation, eg, <code>install</code>, <code>update</code>,
|
||||
<code>dedupe</code>, <code>uninstall</code>. This is NOT currently honored by some network related
|
||||
commands, eg <code>dist-tags</code>, <code>owner</code>, etc.</p>
|
||||
<h4 id="diff">diff</h4>
|
||||
<ul>
|
||||
<li>Default: null</li>
|
||||
<li>Type: String, Array, null</li>
|
||||
</ul>
|
||||
<p>Define arguments to compare in <code>npm diff</code>.</p>
|
||||
<h4 id="diff-name-only">diff-name-only</h4>
|
||||
<ul>
|
||||
<li>Default: false</li>
|
||||
<li>Type: Boolean</li>
|
||||
</ul>
|
||||
<p>Prints only filenames when using <code>npm diff</code>.</p>
|
||||
<h4 id="diff-unified">diff-unified</h4>
|
||||
<ul>
|
||||
<li>Type: number</li>
|
||||
<li>Default: <code>3</code></li>
|
||||
</ul>
|
||||
<p>The number of lines of context to print in <code>npm diff</code>.</p>
|
||||
<h4 id="diff-ignore-all-space">diff-ignore-all-space</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Ignore whitespace when comparing lines in `npm diff.</p>
|
||||
<h4 id="diff-no-prefix">diff-no-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Do not show any source or destination prefix in <code>npm diff</code> output.</p>
|
||||
<h4 id="diff-src-prefix">diff-src-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>"a/"</code></li>
|
||||
</ul>
|
||||
<p>Source prefix to be used in <code>npm diff</code> output.</p>
|
||||
<h4 id="diff-dst-prefix">diff-dst-prefix</h4>
|
||||
<ul>
|
||||
<li>Type: String</li>
|
||||
<li>Default: <code>"b/"</code></li>
|
||||
</ul>
|
||||
<p>Destination prefix to be used in <code>npm diff</code> output.</p>
|
||||
<h4 id="diff-text">diff-text</h4>
|
||||
<ul>
|
||||
<li>Alias: <code>-a</code></li>
|
||||
<li>Type: Boolean</li>
|
||||
<li>Default: false</li>
|
||||
</ul>
|
||||
<p>Treat all files as text in <code>npm diff</code>.</p>
|
||||
<h4 id="editor">editor</h4>
|
||||
<ul>
|
||||
<li>Default: <code>EDITOR</code> environment variable if set, or <code>"vi"</code> on Posix,
|
||||
|
||||
-285
@@ -1,285 +0,0 @@
|
||||
<html><head>
|
||||
<title>disputes</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
color: #24292e;
|
||||
|
||||
margin: 0;
|
||||
|
||||
line-height: 1.5;
|
||||
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
}
|
||||
#rainbar {
|
||||
height: 10px;
|
||||
background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0366d6;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 1em 0px;
|
||||
padding: 1em;
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
|
||||
display: block;
|
||||
overflow: auto;
|
||||
|
||||
white-space: pre;
|
||||
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
code {
|
||||
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 85%;
|
||||
padding: 0.2em 0.4em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
pre > code {
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#logobar {
|
||||
background-color: #333333;
|
||||
margin: 0 auto;
|
||||
padding: 1em 4em;
|
||||
}
|
||||
#logobar .logo {
|
||||
float: left;
|
||||
}
|
||||
#logobar .title {
|
||||
font-weight: 600;
|
||||
color: #dddddd;
|
||||
float: left;
|
||||
margin: 5px 0 0 1em;
|
||||
}
|
||||
#logobar:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 0 auto;
|
||||
padding: 0 4em;
|
||||
}
|
||||
|
||||
#table_of_contents > h2 {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
#table_of_contents ul:first-child {
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
padding: 1em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
#table_of_contents ul {
|
||||
list-style-type: none;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
#table_of_contents li {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#table_of_contents li a {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
header.title {
|
||||
border-bottom: solid 1px #e1e4e8;
|
||||
}
|
||||
header.title > h1 {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
header.title > .description {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
footer#edit {
|
||||
border-top: solid 1px #e1e4e8;
|
||||
margin: 3em 0 4em 0;
|
||||
padding-top: 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<div id="rainbar"></div>
|
||||
<div id="logobar">
|
||||
<svg class="logo" role="img" height="32" width="32" viewBox="0 0 700 700">
|
||||
<polygon fill="#cb0000" points="0,700 700,700 700,0 0,0"></polygon>
|
||||
<polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150"></polygon>
|
||||
</svg>
|
||||
<div class="title">
|
||||
npm command-line interface
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="content">
|
||||
<header class="title">
|
||||
<h1 id="disputes">disputes</h1>
|
||||
<span class="description">Handling Module Name Disputes</span>
|
||||
</header>
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#tldr">TL;DR</a></li><li><a href="#description">Description</a></li><li><a href="#reasoning">Reasoning</a></li><li><a href="#exceptions">Exceptions</a></li><li><a href="#trademarks">Trademarks</a></li><li><a href="#changes">Changes</a></li><li><a href="#license">License</a></li><li><a href="#see-also">See also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><p>This document describes the steps that you should take to resolve module name
|
||||
disputes with other npm publishers. It also describes special steps you should
|
||||
take about names you think infringe your trademarks.</p>
|
||||
<p>This document is a clarification of the acceptable behavior outlined in the
|
||||
<a href="https://www.npmjs.com/policies/conduct">npm Code of Conduct</a>, and nothing in
|
||||
this document should be interpreted to contradict any aspect of the npm Code of
|
||||
Conduct.</p>
|
||||
<h3 id="tldr">TL;DR</h3>
|
||||
<ol>
|
||||
<li>Get the author email with <code>npm owner ls <pkgname></code></li>
|
||||
<li>Email the author, CC <a href="mailto:support@npmjs.com">support@npmjs.com</a></li>
|
||||
<li>After a few weeks, if there’s no resolution, we’ll sort it out.</li>
|
||||
</ol>
|
||||
<p>Don’t squat on package names. Publish code or move out of the way.</p>
|
||||
<h3 id="description">Description</h3>
|
||||
<p>There sometimes arise cases where a user publishes a module, and then later,
|
||||
some other user wants to use that name. Here are some common ways that happens
|
||||
(each of these is based on actual events.)</p>
|
||||
<ol>
|
||||
<li>
|
||||
<p>Alice writes a JavaScript module <code>foo</code>, which is not node-specific. Alice
|
||||
doesn’t use node at all. Yusuf wants to use <code>foo</code> in node, so he wraps it in
|
||||
an npm module. Some time later, Alice starts using node, and wants to take
|
||||
over management of her program.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Yusuf writes an npm module <code>foo</code>, and publishes it. Perhaps much later, Alice
|
||||
finds a bug in <code>foo</code>, and fixes it. She sends a pull request to Yusuf, but
|
||||
Yusuf doesn’t have the time to deal with it, because he has a new job and a
|
||||
new baby and is focused on his new Erlang project, and kind of not involved
|
||||
with node any more. Alice would like to publish a new <code>foo</code>, but can’t,
|
||||
because the name is taken.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Yusuf writes a 10-line flow-control library, and calls it <code>foo</code>, and
|
||||
publishes it to the npm registry. Being a simple little thing, it never
|
||||
really has to be updated. Alice works for Foo Inc, the makers of the
|
||||
critically acclaimed and widely-marketed <code>foo</code> JavaScript toolkit framework.
|
||||
They publish it to npm as <code>foojs</code>, but people are routinely confused when
|
||||
<code>npm install foo</code> is some different thing.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Yusuf writes a parser for the widely-known <code>foo</code> file format, because he
|
||||
needs it for work. Then, he gets a new job, and never updates the prototype.
|
||||
Later on, Alice writes a much more complete <code>foo</code> parser, but can’t publish,
|
||||
because Yusuf’s <code>foo</code> is in the way.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>npm owner ls foo</code>. This will tell Alice the email address of the owner
|
||||
(Yusuf).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Alice emails Yusuf, explaining the situation <strong>as respectfully as possible</strong>,
|
||||
and what she would like to do with the module name. She adds the npm support
|
||||
staff <a href="mailto:support@npmjs.com">support@npmjs.com</a> to the CC list of the email. Mention in the email
|
||||
that Yusuf can run npm owner <code>add alice foo</code> to add Alice as an owner of the
|
||||
foo package.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After a reasonable amount of time, if Yusuf has not responded, or if Yusuf
|
||||
and Alice can’t come to any sort of resolution, email support
|
||||
<a href="mailto:support@npmjs.com">support@npmjs.com</a> and we’ll sort it out. (“Reasonable” is usually at least
|
||||
4 weeks.)</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h3 id="reasoning">Reasoning</h3>
|
||||
<p>In almost every case so far, the parties involved have been able to reach an
|
||||
amicable resolution without any major intervention. Most people really do want
|
||||
to be reasonable, and are probably not even aware that they’re in your way.</p>
|
||||
<p>Module ecosystems are most vibrant and powerful when they are as self-directed
|
||||
as possible. If an admin one day deletes something you had worked on, then that
|
||||
is going to make most people quite upset, regardless of the justification. When
|
||||
humans solve their problems by talking to other humans with respect, everyone
|
||||
has the chance to end up feeling good about the interaction.</p>
|
||||
<h3 id="exceptions">Exceptions</h3>
|
||||
<p>Some things are not allowed, and will be removed without discussion if they are
|
||||
brought to the attention of the npm registry admins, including but not limited
|
||||
to:</p>
|
||||
<ol>
|
||||
<li>Malware (that is, a package designed to exploit or harm the machine on which
|
||||
it is installed).</li>
|
||||
<li>Violations of copyright or licenses (for example, cloning an MIT-licensed
|
||||
program, and then removing or changing the copyright and license statement).</li>
|
||||
<li>Illegal content.</li>
|
||||
<li>“Squatting” on a package name that you plan to use, but aren’t actually
|
||||
using. Sorry, I don’t care how great the name is, or how perfect a fit it is
|
||||
for the thing that someday might happen. If someone wants to use it today,
|
||||
and you’re just taking up space with an empty tarball, you’re going to be
|
||||
evicted.</li>
|
||||
<li>Putting empty packages in the registry. Packages must have SOME
|
||||
functionality. It can be silly, but it can’t be nothing. (See also:
|
||||
squatting.)</li>
|
||||
<li>Doing weird things with the registry, like using it as your own personal
|
||||
application database or otherwise putting non-packagey things into it.</li>
|
||||
<li>Other things forbidden by the npm
|
||||
<a href="https://www.npmjs.com/policies/conduct">Code of Conduct</a> such as hateful
|
||||
language, pornographic content, or harassment.</li>
|
||||
</ol>
|
||||
<p>If you see bad behavior like this, please report it to <a href="mailto:abuse@npmjs.com">abuse@npmjs.com</a> right
|
||||
away. <strong>You are never expected to resolve abusive behavior on your own. We are
|
||||
here to help.</strong></p>
|
||||
<h3 id="trademarks">Trademarks</h3>
|
||||
<p>If you think another npm publisher is infringing your trademark, such as by
|
||||
using a confusingly similar package name, email <a href="mailto:abuse@npmjs.com">abuse@npmjs.com</a> with a link to
|
||||
the package or user account on <a href="https://www.npmjs.com/">https://www.npmjs.com/</a>.
|
||||
Attach a copy of your trademark registration certificate.</p>
|
||||
<p>If we see that the package’s publisher is intentionally misleading others by
|
||||
misusing your registered mark without permission, we will transfer the package
|
||||
name to you. Otherwise, we will contact the package publisher and ask them to
|
||||
clear up any confusion with changes to their package’s <code>README</code> file or
|
||||
metadata.</p>
|
||||
<h3 id="changes">Changes</h3>
|
||||
<p>This is a living document and may be updated from time to time. Please refer to
|
||||
the <a href="https://github.com/npm/cli/commits/latest/doc/misc/npm-disputes.md">git history for this document</a>
|
||||
to view the changes.</p>
|
||||
<h3 id="license">License</h3>
|
||||
<p>Copyright (C) npm, Inc., All rights reserved</p>
|
||||
<p>This document may be reused under a Creative Commons Attribution-ShareAlike
|
||||
License.</p>
|
||||
<h3 id="see-also">See also</h3>
|
||||
<ul>
|
||||
<li><a href="../using-npm/registry.html">npm registry</a></li>
|
||||
<li><a href="../commands/npm-owner.html">npm owner</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer id="edit">
|
||||
<a href="https://github.com/npm/cli/edit/latest/docs/content/using-npm/disputes.md">
|
||||
<svg role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentcolor" style="vertical-align: text-bottom; margin-right: 0.3em;">
|
||||
<path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path>
|
||||
</svg>
|
||||
Edit this page on GitHub
|
||||
</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
+8
-28
@@ -141,14 +141,14 @@ npm command-line interface
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><li><a href="#does-npm-send-any-information-about-me-back-to-the-registry">Does npm send any information about me back to the registry?</a></li><li><a href="#can-i-run-my-own-private-registry">Can I run my own private registry?</a></li><li><a href="#i-dont-want-my-package-published-in-the-official-registry-its-private">I don’t want my package published in the official registry. It’s private.</a></li><li><a href="#will-you-replicate-from-my-registry-into-the-public-one">Will you replicate from my registry into the public one?</a></li><li><a href="#do-i-have-to-use-couchdb-to-build-a-registry-that-npm-can-talk-to">Do I have to use couchdb to build a registry that npm can talk to?</a></li><li><a href="#is-there-a-website-or-something-to-see-package-docs-and-such">Is there a website or something to see package docs and such?</a></li><li><a href="#see-also">See also</a></li></ul></div>
|
||||
<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><li><a href="#does-npm-send-any-information-about-me-back-to-the-registry">Does npm send any information about me back to the registry?</a></li><li><a href="#how-can-i-prevent-my-package-from-being-published-in-the-official-registry">How can I prevent my package from being published in the official registry?</a></li><li><a href="#where-can-i-find-my-own--others-published-packages">Where can I find my own, & other’s, published packages?</a></li><li><a href="#see-also">See also</a></li></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h3 id="description">Description</h3>
|
||||
<p>To resolve packages by name and version, npm talks to a registry website
|
||||
that implements the CommonJS Package Registry specification for reading
|
||||
package info.</p>
|
||||
<p>npm is configured to use npm, Inc.’s public registry at
|
||||
<p>npm is configured to use the <strong>npm public registry</strong> at
|
||||
<a href="https://registry.npmjs.org">https://registry.npmjs.org</a> by default. Use of the npm public registry is
|
||||
subject to terms of use available at <a href="https://www.npmjs.com/policies/terms">https://www.npmjs.com/policies/terms</a>.</p>
|
||||
<p>You can configure npm to use any compatible registry you like, and even run
|
||||
@@ -158,9 +158,7 @@ terms of use.</p>
|
||||
write APIs as well, to allow for publishing packages and managing user
|
||||
account information.</p>
|
||||
<p>The npm public registry is powered by a CouchDB database,
|
||||
of which there is a public mirror at
|
||||
<a href="https://skimdb.npmjs.com/registry">https://skimdb.npmjs.com/registry</a>. The code for the couchapp is
|
||||
available at <a href="https://github.com/npm/npm-registry-couchapp">https://github.com/npm/npm-registry-couchapp</a>.</p>
|
||||
of which there is a public mirror at <a href="https://skimdb.npmjs.com/registry">https://skimdb.npmjs.com/registry</a>.</p>
|
||||
<p>The registry URL used is determined by the scope of the package (see
|
||||
<a href="../using-npm/scope.html"><code>scope</code></a>. If no scope is specified, the default registry is used, which is
|
||||
supplied by the <code>registry</code> config parameter. See <a href="../commands/npm-config.html"><code>npm config</code></a>,
|
||||
@@ -185,38 +183,20 @@ build farms.</li>
|
||||
</ul>
|
||||
<p>The npm registry does not try to correlate the information in these headers
|
||||
with any authenticated accounts that may be used in the same requests.</p>
|
||||
<h3 id="can-i-run-my-own-private-registry">Can I run my own private registry?</h3>
|
||||
<p>Yes!</p>
|
||||
<p>The easiest way is to replicate the couch database, and use the same (or
|
||||
similar) design doc to implement the APIs.</p>
|
||||
<p>If you set up continuous replication from the official CouchDB, and then
|
||||
set your internal CouchDB as the registry config, then you’ll be able
|
||||
to read any published packages, in addition to your private ones, and by
|
||||
default will only publish internally.</p>
|
||||
<p>If you then want to publish a package for the whole world to see, you can
|
||||
simply override the <code>--registry</code> option for that <code>publish</code> command.</p>
|
||||
<h3 id="i-dont-want-my-package-published-in-the-official-registry-its-private">I don’t want my package published in the official registry. It’s private.</h3>
|
||||
<p>Set <code>"private": true</code> in your package.json to prevent it from being
|
||||
<h3 id="how-can-i-prevent-my-package-from-being-published-in-the-official-registry">How can I prevent my package from being published in the official registry?</h3>
|
||||
<p>Set <code>"private": true</code> in your <code>package.json</code> to prevent it from being
|
||||
published at all, or
|
||||
<code>"publishConfig":{"registry":"http://my-internal-registry.local"}</code>
|
||||
to force it to be published only to your internal registry.</p>
|
||||
to force it to be published only to your internal/private registry.</p>
|
||||
<p>See <a href="../configuring-npm/package-json.html"><code>package.json</code></a> for more info on what goes in the package.json file.</p>
|
||||
<h3 id="will-you-replicate-from-my-registry-into-the-public-one">Will you replicate from my registry into the public one?</h3>
|
||||
<p>No. If you want things to be public, then publish them into the public
|
||||
registry using npm. What little security there is would be for nought
|
||||
otherwise.</p>
|
||||
<h3 id="do-i-have-to-use-couchdb-to-build-a-registry-that-npm-can-talk-to">Do I have to use couchdb to build a registry that npm can talk to?</h3>
|
||||
<p>No, but it’s way easier. Basically, yes, you do, or you have to
|
||||
effectively implement the entire CouchDB API anyway.</p>
|
||||
<h3 id="is-there-a-website-or-something-to-see-package-docs-and-such">Is there a website or something to see package docs and such?</h3>
|
||||
<p>Yes, head over to <a href="https://www.npmjs.com/">https://www.npmjs.com/</a></p>
|
||||
<h3 id="where-can-i-find-my-own--others-published-packages">Where can I find my own, & other’s, published packages?</h3>
|
||||
<p><a href="https://www.npmjs.com/">https://www.npmjs.com/</a></p>
|
||||
<h3 id="see-also">See also</h3>
|
||||
<ul>
|
||||
<li><a href="../commands/npm-config.html">npm config</a></li>
|
||||
<li><a href="../using-npm/config.html">config</a></li>
|
||||
<li><a href="../configuring-npm/npmrc.html">npmrc</a></li>
|
||||
<li><a href="../using-npm/developers.html">npm developers</a></li>
|
||||
<li><a href="../using-npm/disputes.html">npm disputes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
-1
@@ -177,7 +177,6 @@ around:</p>
|
||||
modules. To track those down, you can do the following:</p>
|
||||
<pre lang="bash"><code>find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ;
|
||||
</code></pre>
|
||||
<p>(This is also in the README file.)</p>
|
||||
<h3 id="see-also">See also</h3>
|
||||
<ul>
|
||||
<li><a href="../commands/npm-uninstall.html">npm uninstall</a></li>
|
||||
|
||||
-521
@@ -1,521 +0,0 @@
|
||||
<html><head>
|
||||
<title>semver</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
color: #24292e;
|
||||
|
||||
margin: 0;
|
||||
|
||||
line-height: 1.5;
|
||||
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
}
|
||||
#rainbar {
|
||||
height: 10px;
|
||||
background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0366d6;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 1em 0px;
|
||||
padding: 1em;
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
|
||||
display: block;
|
||||
overflow: auto;
|
||||
|
||||
white-space: pre;
|
||||
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
code {
|
||||
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 85%;
|
||||
padding: 0.2em 0.4em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
pre > code {
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#logobar {
|
||||
background-color: #333333;
|
||||
margin: 0 auto;
|
||||
padding: 1em 4em;
|
||||
}
|
||||
#logobar .logo {
|
||||
float: left;
|
||||
}
|
||||
#logobar .title {
|
||||
font-weight: 600;
|
||||
color: #dddddd;
|
||||
float: left;
|
||||
margin: 5px 0 0 1em;
|
||||
}
|
||||
#logobar:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 0 auto;
|
||||
padding: 0 4em;
|
||||
}
|
||||
|
||||
#table_of_contents > h2 {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
#table_of_contents ul:first-child {
|
||||
border: solid 1px #e1e4e8;
|
||||
border-radius: 6px;
|
||||
padding: 1em;
|
||||
background-color: #f6f8fa;
|
||||
color: #393a34;
|
||||
}
|
||||
#table_of_contents ul {
|
||||
list-style-type: none;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
#table_of_contents li {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#table_of_contents li a {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
header.title {
|
||||
border-bottom: solid 1px #e1e4e8;
|
||||
}
|
||||
header.title > h1 {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
header.title > .description {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
footer#edit {
|
||||
border-top: solid 1px #e1e4e8;
|
||||
margin: 3em 0 4em 0;
|
||||
padding-top: 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<div id="rainbar"></div>
|
||||
<div id="logobar">
|
||||
<svg class="logo" role="img" height="32" width="32" viewBox="0 0 700 700">
|
||||
<polygon fill="#cb0000" points="0,700 700,700 700,0 0,0"></polygon>
|
||||
<polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150"></polygon>
|
||||
</svg>
|
||||
<div class="title">
|
||||
npm command-line interface
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="content">
|
||||
<header class="title">
|
||||
<h1 id="semver">semver</h1>
|
||||
<span class="description">The semantic versioner for npm</span>
|
||||
</header>
|
||||
|
||||
<section id="table_of_contents">
|
||||
<h2 id="table-of-contents">Table of contents</h2>
|
||||
<div id="_table_of_contents"><ul><li><a href="#install">Install</a></li><li><a href="#usage">Usage</a></li><li><a href="#versions">Versions</a></li><li><a href="#ranges">Ranges</a></li><ul><li><a href="#prerelease-tags">Prerelease Tags</a></li><ul><li><a href="#prerelease-identifiers">Prerelease Identifiers</a></li></ul><li><a href="#advanced-range-syntax">Advanced Range Syntax</a></li><ul><li><a href="#hyphen-ranges-xyz---abc">Hyphen Ranges <code>X.Y.Z - A.B.C</code></a></li><li><a href="#x-ranges-12x-1x-12-">X-Ranges <code>1.2.x</code> <code>1.X</code> <code>1.2.*</code> <code>*</code></a></li><li><a href="#tilde-ranges-123-12-1">Tilde Ranges <code>~1.2.3</code> <code>~1.2</code> <code>~1</code></a></li><li><a href="#caret-ranges-123-025-004">Caret Ranges <code>^1.2.3</code> <code>^0.2.5</code> <code>^0.0.4</code></a></li></ul><li><a href="#range-grammar">Range Grammar</a></li></ul><li><a href="#functions">Functions</a></li><ul><li><a href="#comparison">Comparison</a></li><li><a href="#comparators">Comparators</a></li><li><a href="#ranges2">Ranges</a></li><li><a href="#coercion">Coercion</a></li></ul></ul></div>
|
||||
</section>
|
||||
|
||||
<div id="_content"><h2 id="install">Install</h2>
|
||||
<pre lang="bash"><code>npm install --save semver
|
||||
</code></pre>
|
||||
<h2 id="usage">Usage</h2>
|
||||
<p>As a node module:</p>
|
||||
<pre lang="js"><code>const semver = require('semver')
|
||||
|
||||
semver.valid('1.2.3') // '1.2.3'
|
||||
semver.valid('a.b.c') // null
|
||||
semver.clean(' =v1.2.3 ') // '1.2.3'
|
||||
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
|
||||
semver.gt('1.2.3', '9.8.7') // false
|
||||
semver.lt('1.2.3', '9.8.7') // true
|
||||
semver.minVersion('>=1.0.0') // '1.0.0'
|
||||
semver.valid(semver.coerce('v2')) // '2.0.0'
|
||||
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
|
||||
</code></pre>
|
||||
<p>As a command-line utility:</p>
|
||||
<pre><code>$ semver -h
|
||||
|
||||
A JavaScript implementation of the https://semver.org/ specification
|
||||
Copyright Isaac Z. Schlueter
|
||||
|
||||
Usage: semver [options] <version> [<version> [...]]
|
||||
Prints valid versions sorted by SemVer precedence
|
||||
|
||||
Options:
|
||||
-r --range <range>
|
||||
Print versions that match the specified range.
|
||||
|
||||
-i --increment [<level>]
|
||||
Increment a version by the specified level. Level can
|
||||
be one of: major, minor, patch, premajor, preminor,
|
||||
prepatch, or prerelease. Default level is 'patch'.
|
||||
Only one version may be specified.
|
||||
|
||||
--preid <identifier>
|
||||
Identifier to be used to prefix premajor, preminor,
|
||||
prepatch or prerelease version increments.
|
||||
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
-c --coerce
|
||||
Coerce a string into SemVer if possible
|
||||
(does not imply --loose)
|
||||
|
||||
Program exits successfully if any valid version satisfies
|
||||
all supplied ranges, and prints all satisfying versions.
|
||||
|
||||
If no satisfying versions are found, then exits failure.
|
||||
|
||||
Versions are printed in ascending order, so supplying
|
||||
multiple versions to the utility will just sort them.
|
||||
</code></pre>
|
||||
<h2 id="versions">Versions</h2>
|
||||
<p>A “version” is described by the <code>v2.0.0</code> specification found at
|
||||
<a href="https://semver.org/">https://semver.org/</a>.</p>
|
||||
<p>A leading <code>"="</code> or <code>"v"</code> character is stripped off and ignored.</p>
|
||||
<h2 id="ranges">Ranges</h2>
|
||||
<p>A <code>version range</code> is a set of <code>comparators</code> which specify versions
|
||||
that satisfy the range.</p>
|
||||
<p>A <code>comparator</code> is composed of an <code>operator</code> and a <code>version</code>. The set
|
||||
of primitive <code>operators</code> is:</p>
|
||||
<ul>
|
||||
<li><code><</code> Less than</li>
|
||||
<li><code><=</code> Less than or equal to</li>
|
||||
<li><code>></code> Greater than</li>
|
||||
<li><code>>=</code> Greater than or equal to</li>
|
||||
<li><code>=</code> Equal. If no operator is specified, then equality is assumed,
|
||||
so this operator is optional, but MAY be included.</li>
|
||||
</ul>
|
||||
<p>For example, the comparator <code>>=1.2.7</code> would match the versions
|
||||
<code>1.2.7</code>, <code>1.2.8</code>, <code>2.5.3</code>, and <code>1.3.9</code>, but not the versions <code>1.2.6</code>
|
||||
or <code>1.1.0</code>.</p>
|
||||
<p>Comparators can be joined by whitespace to form a <code>comparator set</code>,
|
||||
which is satisfied by the <strong>intersection</strong> of all of the comparators
|
||||
it includes.</p>
|
||||
<p>A range is composed of one or more comparator sets, joined by <code>||</code>. A
|
||||
version matches a range if and only if every comparator in at least
|
||||
one of the <code>||</code>-separated comparator sets is satisfied by the version.</p>
|
||||
<p>For example, the range <code>>=1.2.7 <1.3.0</code> would match the versions
|
||||
<code>1.2.7</code>, <code>1.2.8</code>, and <code>1.2.99</code>, but not the versions <code>1.2.6</code>, <code>1.3.0</code>,
|
||||
or <code>1.1.0</code>.</p>
|
||||
<p>The range <code>1.2.7 || >=1.2.9 <2.0.0</code> would match the versions <code>1.2.7</code>,
|
||||
<code>1.2.9</code>, and <code>1.4.6</code>, but not the versions <code>1.2.8</code> or <code>2.0.0</code>.</p>
|
||||
<h3 id="prerelease-tags">Prerelease Tags</h3>
|
||||
<p>If a version has a prerelease tag (for example, <code>1.2.3-alpha.3</code>) then
|
||||
it will only be allowed to satisfy comparator sets if at least one
|
||||
comparator with the same <code>[major, minor, patch]</code> tuple also has a
|
||||
prerelease tag.</p>
|
||||
<p>For example, the range <code>>1.2.3-alpha.3</code> would be allowed to match the
|
||||
version <code>1.2.3-alpha.7</code>, but it would <em>not</em> be satisfied by
|
||||
<code>3.4.5-alpha.9</code>, even though <code>3.4.5-alpha.9</code> is technically “greater
|
||||
than” <code>1.2.3-alpha.3</code> according to the SemVer sort rules. The version
|
||||
range only accepts prerelease tags on the <code>1.2.3</code> version. The
|
||||
version <code>3.4.5</code> <em>would</em> satisfy the range, because it does not have a
|
||||
prerelease flag, and <code>3.4.5</code> is greater than <code>1.2.3-alpha.7</code>.</p>
|
||||
<p>The purpose for this behavior is twofold. First, prerelease versions
|
||||
frequently are updated very quickly, and contain many breaking changes
|
||||
that are (by the author’s design) not yet fit for public consumption.
|
||||
Therefore, by default, they are excluded from range matching
|
||||
semantics.</p>
|
||||
<p>Second, a user who has opted into using a prerelease version has
|
||||
clearly indicated the intent to use <em>that specific</em> set of
|
||||
alpha/beta/rc versions. By including a prerelease tag in the range,
|
||||
the user is indicating that they are aware of the risk. However, it
|
||||
is still not appropriate to assume that they have opted into taking a
|
||||
similar risk on the <em>next</em> set of prerelease versions.</p>
|
||||
<p>Note that this behavior can be suppressed (treating all prerelease
|
||||
versions as if they were normal versions, for the purpose of range
|
||||
matching) by setting the <code>includePrerelease</code> flag on the options
|
||||
object to any
|
||||
<a href="https://github.com/npm/node-semver#functions">functions</a> that do
|
||||
range matching.</p>
|
||||
<h4 id="prerelease-identifiers">Prerelease Identifiers</h4>
|
||||
<p>The method <code>.inc</code> takes an additional <code>identifier</code> string argument that
|
||||
will append the value of the string as a prerelease identifier:</p>
|
||||
<pre lang="javascript"><code>semver.inc('1.2.3', 'prerelease', 'beta')
|
||||
// '1.2.4-beta.0'
|
||||
</code></pre>
|
||||
<p>command-line example:</p>
|
||||
<pre lang="bash"><code>$ semver 1.2.3 -i prerelease --preid beta
|
||||
1.2.4-beta.0
|
||||
</code></pre>
|
||||
<p>Which then can be used to increment further:</p>
|
||||
<pre lang="bash"><code>$ semver 1.2.4-beta.0 -i prerelease
|
||||
1.2.4-beta.1
|
||||
</code></pre>
|
||||
<h3 id="advanced-range-syntax">Advanced Range Syntax</h3>
|
||||
<p>Advanced range syntax desugars to primitive comparators in
|
||||
deterministic ways.</p>
|
||||
<p>Advanced ranges may be combined in the same way as primitive
|
||||
comparators using white space or <code>||</code>.</p>
|
||||
<h4 id="hyphen-ranges-xyz---abc">Hyphen Ranges <code>X.Y.Z - A.B.C</code></h4>
|
||||
<p>Specifies an inclusive set.</p>
|
||||
<ul>
|
||||
<li><code>1.2.3 - 2.3.4</code> := <code>>=1.2.3 <=2.3.4</code></li>
|
||||
</ul>
|
||||
<p>If a partial version is provided as the first version in the inclusive
|
||||
range, then the missing pieces are replaced with zeroes.</p>
|
||||
<ul>
|
||||
<li><code>1.2 - 2.3.4</code> := <code>>=1.2.0 <=2.3.4</code></li>
|
||||
</ul>
|
||||
<p>If a partial version is provided as the second version in the
|
||||
inclusive range, then all versions that start with the supplied parts
|
||||
of the tuple are accepted, but nothing that would be greater than the
|
||||
provided tuple parts.</p>
|
||||
<ul>
|
||||
<li><code>1.2.3 - 2.3</code> := <code>>=1.2.3 <2.4.0</code></li>
|
||||
<li><code>1.2.3 - 2</code> := <code>>=1.2.3 <3.0.0</code></li>
|
||||
</ul>
|
||||
<h4 id="x-ranges-12x-1x-12-">X-Ranges <code>1.2.x</code> <code>1.X</code> <code>1.2.*</code> <code>*</code></h4>
|
||||
<p>Any of <code>X</code>, <code>x</code>, or <code>*</code> may be used to “stand in” for one of the
|
||||
numeric values in the <code>[major, minor, patch]</code> tuple.</p>
|
||||
<ul>
|
||||
<li><code>*</code> := <code>>=0.0.0</code> (Any version satisfies)</li>
|
||||
<li><code>1.x</code> := <code>>=1.0.0 <2.0.0</code> (Matching major version)</li>
|
||||
<li><code>1.2.x</code> := <code>>=1.2.0 <1.3.0</code> (Matching major and minor versions)</li>
|
||||
</ul>
|
||||
<p>A partial version range is treated as an X-Range, so the special
|
||||
character is in fact optional.</p>
|
||||
<ul>
|
||||
<li><code>""</code> (empty string) := <code>*</code> := <code>>=0.0.0</code></li>
|
||||
<li><code>1</code> := <code>1.x.x</code> := <code>>=1.0.0 <2.0.0</code></li>
|
||||
<li><code>1.2</code> := <code>1.2.x</code> := <code>>=1.2.0 <1.3.0</code></li>
|
||||
</ul>
|
||||
<h4 id="tilde-ranges-123-12-1">Tilde Ranges <code>~1.2.3</code> <code>~1.2</code> <code>~1</code></h4>
|
||||
<p>Allows patch-level changes if a minor version is specified on the
|
||||
comparator. Allows minor-level changes if not.</p>
|
||||
<ul>
|
||||
<li><code>~1.2.3</code> := <code>>=1.2.3 <1.(2+1).0</code> := <code>>=1.2.3 <1.3.0</code></li>
|
||||
<li><code>~1.2</code> := <code>>=1.2.0 <1.(2+1).0</code> := <code>>=1.2.0 <1.3.0</code> (Same as <code>1.2.x</code>)</li>
|
||||
<li><code>~1</code> := <code>>=1.0.0 <(1+1).0.0</code> := <code>>=1.0.0 <2.0.0</code> (Same as <code>1.x</code>)</li>
|
||||
<li><code>~0.2.3</code> := <code>>=0.2.3 <0.(2+1).0</code> := <code>>=0.2.3 <0.3.0</code></li>
|
||||
<li><code>~0.2</code> := <code>>=0.2.0 <0.(2+1).0</code> := <code>>=0.2.0 <0.3.0</code> (Same as <code>0.2.x</code>)</li>
|
||||
<li><code>~0</code> := <code>>=0.0.0 <(0+1).0.0</code> := <code>>=0.0.0 <1.0.0</code> (Same as <code>0.x</code>)</li>
|
||||
<li><code>~1.2.3-beta.2</code> := <code>>=1.2.3-beta.2 <1.3.0</code> Note that prereleases in
|
||||
the <code>1.2.3</code> version will be allowed, if they are greater than or
|
||||
equal to <code>beta.2</code>. So, <code>1.2.3-beta.4</code> would be allowed, but
|
||||
<code>1.2.4-beta.2</code> would not, because it is a prerelease of a
|
||||
different <code>[major, minor, patch]</code> tuple.</li>
|
||||
</ul>
|
||||
<h4 id="caret-ranges-123-025-004">Caret Ranges <code>^1.2.3</code> <code>^0.2.5</code> <code>^0.0.4</code></h4>
|
||||
<p>Allows changes that do not modify the left-most non-zero digit in the
|
||||
<code>[major, minor, patch]</code> tuple. In other words, this allows patch and
|
||||
minor updates for versions <code>1.0.0</code> and above, patch updates for
|
||||
versions <code>0.X >=0.1.0</code>, and <em>no</em> updates for versions <code>0.0.X</code>.</p>
|
||||
<p>Many authors treat a <code>0.x</code> version as if the <code>x</code> were the major
|
||||
“breaking-change” indicator.</p>
|
||||
<p>Caret ranges are ideal when an author may make breaking changes
|
||||
between <code>0.2.4</code> and <code>0.3.0</code> releases, which is a common practice.
|
||||
However, it presumes that there will <em>not</em> be breaking changes between
|
||||
<code>0.2.4</code> and <code>0.2.5</code>. It allows for changes that are presumed to be
|
||||
additive (but non-breaking), according to commonly observed practices.</p>
|
||||
<ul>
|
||||
<li><code>^1.2.3</code> := <code>>=1.2.3 <2.0.0</code></li>
|
||||
<li><code>^0.2.3</code> := <code>>=0.2.3 <0.3.0</code></li>
|
||||
<li><code>^0.0.3</code> := <code>>=0.0.3 <0.0.4</code></li>
|
||||
<li><code>^1.2.3-beta.2</code> := <code>>=1.2.3-beta.2 <2.0.0</code> Note that prereleases in
|
||||
the <code>1.2.3</code> version will be allowed, if they are greater than or
|
||||
equal to <code>beta.2</code>. So, <code>1.2.3-beta.4</code> would be allowed, but
|
||||
<code>1.2.4-beta.2</code> would not, because it is a prerelease of a
|
||||
different <code>[major, minor, patch]</code> tuple.</li>
|
||||
<li><code>^0.0.3-beta</code> := <code>>=0.0.3-beta <0.0.4</code> Note that prereleases in the
|
||||
<code>0.0.3</code> version <em>only</em> will be allowed, if they are greater than or
|
||||
equal to <code>beta</code>. So, <code>0.0.3-pr.2</code> would be allowed.</li>
|
||||
</ul>
|
||||
<p>When parsing caret ranges, a missing <code>patch</code> value desugars to the
|
||||
number <code>0</code>, but will allow flexibility within that value, even if the
|
||||
major and minor versions are both <code>0</code>.</p>
|
||||
<ul>
|
||||
<li><code>^1.2.x</code> := <code>>=1.2.0 <2.0.0</code></li>
|
||||
<li><code>^0.0.x</code> := <code>>=0.0.0 <0.1.0</code></li>
|
||||
<li><code>^0.0</code> := <code>>=0.0.0 <0.1.0</code></li>
|
||||
</ul>
|
||||
<p>A missing <code>minor</code> and <code>patch</code> values will desugar to zero, but also
|
||||
allow flexibility within those values, even if the major version is
|
||||
zero.</p>
|
||||
<ul>
|
||||
<li><code>^1.x</code> := <code>>=1.0.0 <2.0.0</code></li>
|
||||
<li><code>^0.x</code> := <code>>=0.0.0 <1.0.0</code></li>
|
||||
</ul>
|
||||
<h3 id="range-grammar">Range Grammar</h3>
|
||||
<p>Putting all this together, here is a Backus-Naur grammar for ranges,
|
||||
for the benefit of parser authors:</p>
|
||||
<pre lang="bnf"><code>range-set ::= range ( logical-or range ) *
|
||||
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
|
||||
range ::= hyphen | simple ( ' ' simple ) * | ''
|
||||
hyphen ::= partial ' - ' partial
|
||||
simple ::= primitive | partial | tilde | caret
|
||||
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
|
||||
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
|
||||
xr ::= 'x' | 'X' | '*' | nr
|
||||
nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
|
||||
tilde ::= '~' partial
|
||||
caret ::= '^' partial
|
||||
qualifier ::= ( '-' pre )? ( '+' build )?
|
||||
pre ::= parts
|
||||
build ::= parts
|
||||
parts ::= part ( '.' part ) *
|
||||
part ::= nr | [-0-9A-Za-z]+
|
||||
</code></pre>
|
||||
<h2 id="functions">Functions</h2>
|
||||
<p>All methods and classes take a final <code>options</code> object argument. All
|
||||
options in this object are <code>false</code> by default. The options supported
|
||||
are:</p>
|
||||
<ul>
|
||||
<li><code>loose</code> Be more forgiving about not-quite-valid semver strings.
|
||||
(Any resulting output will always be 100% strict compliant, of
|
||||
course.) For backwards compatibility reasons, if the <code>options</code>
|
||||
argument is a boolean value instead of an object, it is interpreted
|
||||
to be the <code>loose</code> param.</li>
|
||||
<li><code>includePrerelease</code> Set to suppress the <a href="https://github.com/npm/node-semver#prerelease-tags">default
|
||||
behavior</a> of
|
||||
excluding prerelease tagged versions from ranges unless they are
|
||||
explicitly opted into.</li>
|
||||
</ul>
|
||||
<p>Strict-mode Comparators and Ranges will be strict about the SemVer
|
||||
strings that they parse.</p>
|
||||
<ul>
|
||||
<li><code>valid(v)</code>: Return the parsed version, or null if it’s not valid.</li>
|
||||
<li><code>inc(v, release)</code>: Return the version incremented by the release
|
||||
type (<code>major</code>, <code>premajor</code>, <code>minor</code>, <code>preminor</code>, <code>patch</code>,
|
||||
<code>prepatch</code>, or <code>prerelease</code>), or null if it’s not valid
|
||||
<ul>
|
||||
<li><code>premajor</code> in one call will bump the version up to the next major
|
||||
version and down to a prerelease of that major version.
|
||||
<code>preminor</code>, and <code>prepatch</code> work the same way.</li>
|
||||
<li>If called from a non-prerelease version, the <code>prerelease</code> will work the
|
||||
same as <code>prepatch</code>. It increments the patch version, then makes a
|
||||
prerelease. If the input version is already a prerelease it simply
|
||||
increments it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>prerelease(v)</code>: Returns an array of prerelease components, or null
|
||||
if none exist. Example: <code>prerelease('1.2.3-alpha.1') -> ['alpha', 1]</code></li>
|
||||
<li><code>major(v)</code>: Return the major version number.</li>
|
||||
<li><code>minor(v)</code>: Return the minor version number.</li>
|
||||
<li><code>patch(v)</code>: Return the patch version number.</li>
|
||||
<li><code>intersects(r1, r2, loose)</code>: Return true if the two supplied ranges
|
||||
or comparators intersect.</li>
|
||||
<li><code>parse(v)</code>: Attempt to parse a string as a semantic version, returning either
|
||||
a <code>SemVer</code> object or <code>null</code>.</li>
|
||||
</ul>
|
||||
<h3 id="comparison">Comparison</h3>
|
||||
<ul>
|
||||
<li><code>gt(v1, v2)</code>: <code>v1 > v2</code></li>
|
||||
<li><code>gte(v1, v2)</code>: <code>v1 >= v2</code></li>
|
||||
<li><code>lt(v1, v2)</code>: <code>v1 < v2</code></li>
|
||||
<li><code>lte(v1, v2)</code>: <code>v1 <= v2</code></li>
|
||||
<li><code>eq(v1, v2)</code>: <code>v1 == v2</code> This is true if they’re logically equivalent,
|
||||
even if they’re not the exact same string. You already know how to
|
||||
compare strings.</li>
|
||||
<li><code>neq(v1, v2)</code>: <code>v1 != v2</code> The opposite of <code>eq</code>.</li>
|
||||
<li><code>cmp(v1, comparator, v2)</code>: Pass in a comparison string, and it’ll call
|
||||
the corresponding function above. <code>"==="</code> and <code>"!=="</code> do simple
|
||||
string comparison, but are included for completeness. Throws if an
|
||||
invalid comparison string is provided.</li>
|
||||
<li><code>compare(v1, v2)</code>: Return <code>0</code> if <code>v1 == v2</code>, or <code>1</code> if <code>v1</code> is greater, or <code>-1</code> if
|
||||
<code>v2</code> is greater. Sorts in ascending order if passed to <code>Array.sort()</code>.</li>
|
||||
<li><code>rcompare(v1, v2)</code>: The reverse of compare. Sorts an array of versions
|
||||
in descending order when passed to <code>Array.sort()</code>.</li>
|
||||
<li><code>diff(v1, v2)</code>: Returns difference between two versions by the release type
|
||||
(<code>major</code>, <code>premajor</code>, <code>minor</code>, <code>preminor</code>, <code>patch</code>, <code>prepatch</code>, or <code>prerelease</code>),
|
||||
or null if the versions are the same.</li>
|
||||
</ul>
|
||||
<h3 id="comparators">Comparators</h3>
|
||||
<ul>
|
||||
<li><code>intersects(comparator)</code>: Return true if the comparators intersect</li>
|
||||
</ul>
|
||||
<h3 id="ranges2">Ranges</h3>
|
||||
<ul>
|
||||
<li><code>validRange(range)</code>: Return the valid range or null if it’s not valid</li>
|
||||
<li><code>satisfies(version, range)</code>: Return true if the version satisfies the
|
||||
range.</li>
|
||||
<li><code>maxSatisfying(versions, range)</code>: Return the highest version in the list
|
||||
that satisfies the range, or <code>null</code> if none of them do.</li>
|
||||
<li><code>minSatisfying(versions, range)</code>: Return the lowest version in the list
|
||||
that satisfies the range, or <code>null</code> if none of them do.</li>
|
||||
<li><code>minVersion(range)</code>: Return the lowest version that can possibly match
|
||||
the given range.</li>
|
||||
<li><code>gtr(version, range)</code>: Return <code>true</code> if version is greater than all the
|
||||
versions possible in the range.</li>
|
||||
<li><code>ltr(version, range)</code>: Return <code>true</code> if version is less than all the
|
||||
versions possible in the range.</li>
|
||||
<li><code>outside(version, range, hilo)</code>: Return true if the version is outside
|
||||
the bounds of the range in either the high or low direction. The
|
||||
<code>hilo</code> argument must be either the string <code>'>'</code> or <code>'<'</code>. (This is
|
||||
the function called by <code>gtr</code> and <code>ltr</code>.)</li>
|
||||
<li><code>intersects(range)</code>: Return true if any of the ranges comparators intersect</li>
|
||||
</ul>
|
||||
<p>Note that, since ranges may be non-contiguous, a version might not be
|
||||
greater than a range, less than a range, <em>or</em> satisfy a range! For
|
||||
example, the range <code>1.2 <1.2.9 || >2.0.0</code> would have a hole from <code>1.2.9</code>
|
||||
until <code>2.0.0</code>, so the version <code>1.2.10</code> would not be greater than the
|
||||
range (because <code>2.0.1</code> satisfies, which is higher), nor less than the
|
||||
range (since <code>1.2.8</code> satisfies, which is lower), and it also does not
|
||||
satisfy the range.</p>
|
||||
<p>If you want to know if a version satisfies or does not satisfy a
|
||||
range, use the <code>satisfies(version, range)</code> function.</p>
|
||||
<h3 id="coercion">Coercion</h3>
|
||||
<ul>
|
||||
<li><code>coerce(version)</code>: Coerces a string to semver if possible</li>
|
||||
</ul>
|
||||
<p>This aims to provide a very forgiving translation of a non-semver string to
|
||||
semver. It looks for the first digit in a string, and consumes all
|
||||
remaining characters which satisfy at least a partial semver (e.g., <code>1</code>,
|
||||
<code>1.2</code>, <code>1.2.3</code>) up to the max permitted length (256 characters). Longer
|
||||
versions are simply truncated (<code>4.6.3.9.2-alpha2</code> becomes <code>4.6.3</code>). All
|
||||
surrounding text is simply ignored (<code>v3.4 replaces v3.3.1</code> becomes
|
||||
<code>3.4.0</code>). Only text which lacks digits will fail coercion (<code>version one</code>
|
||||
is not valid). The maximum length for any semver component considered for
|
||||
coercion is 16 characters; longer components will be ignored
|
||||
(<code>10000000000000000.4.7.4</code> becomes <code>4.7.4</code>). The maximum value for any
|
||||
semver component is <code>Number.MAX_SAFE_INTEGER || (2**53 - 1)</code>; higher value
|
||||
components are invalid (<code>9999999999999999.4.7.4</code> is likely invalid).</p>
|
||||
</div>
|
||||
|
||||
<footer id="edit">
|
||||
<a href="https://github.com/npm/cli/edit/latest/docs/content/using-npm/semver.md">
|
||||
<svg role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentcolor" style="vertical-align: text-bottom; margin-right: 0.3em;">
|
||||
<path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path>
|
||||
</svg>
|
||||
Edit this page on GitHub
|
||||
</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
Vendored
+266
@@ -0,0 +1,266 @@
|
||||
const { resolve } = require('path')
|
||||
|
||||
const semver = require('semver')
|
||||
const libdiff = require('libnpmdiff')
|
||||
const npa = require('npm-package-arg')
|
||||
const Arborist = require('@npmcli/arborist')
|
||||
const npmlog = require('npmlog')
|
||||
const pacote = require('pacote')
|
||||
const pickManifest = require('npm-pick-manifest')
|
||||
|
||||
const npm = require('./npm.js')
|
||||
const usageUtil = require('./utils/usage.js')
|
||||
const output = require('./utils/output.js')
|
||||
const completion = require('./utils/completion/none.js')
|
||||
const readLocalPkg = require('./utils/read-local-package.js')
|
||||
|
||||
const usage = usageUtil(
|
||||
'diff',
|
||||
'npm diff [...<paths>]' +
|
||||
'\nnpm diff --diff=<pkg-name> [...<paths>]' +
|
||||
'\nnpm diff --diff=<version-a> [--diff=<version-b>] [...<paths>]' +
|
||||
'\nnpm diff --diff=<spec-a> [--diff=<spec-b>] [...<paths>]' +
|
||||
'\nnpm diff [--diff-ignore-all-space] [--diff-name-only] [...<paths>] [...<paths>]'
|
||||
)
|
||||
|
||||
const cmd = (args, cb) => diff(args).then(() => cb()).catch(cb)
|
||||
|
||||
const where = () => {
|
||||
const globalTop = resolve(npm.globalDir, '..')
|
||||
const { global } = npm.flatOptions
|
||||
return global ? globalTop : npm.prefix
|
||||
}
|
||||
|
||||
const diff = async (args) => {
|
||||
const specs = npm.flatOptions.diff.filter(d => d)
|
||||
if (specs.length > 2) {
|
||||
throw new TypeError(
|
||||
'Can\'t use more than two --diff arguments.\n\n' +
|
||||
`Usage:\n${usage}`
|
||||
)
|
||||
}
|
||||
|
||||
const [a, b] = await retrieveSpecs(specs)
|
||||
npmlog.info('diff', { src: a, dst: b })
|
||||
|
||||
const res = await libdiff([a, b], { ...npm.flatOptions, diffFiles: args })
|
||||
return output(res)
|
||||
}
|
||||
|
||||
const retrieveSpecs = ([a, b]) => {
|
||||
// no arguments, defaults to comparing cwd
|
||||
// to its latest published registry version
|
||||
if (!a)
|
||||
return defaultSpec()
|
||||
|
||||
// single argument, used to compare wanted versions of an
|
||||
// installed dependency or to compare the cwd to a published version
|
||||
if (!b)
|
||||
return transformSingleSpec(a)
|
||||
|
||||
return convertVersionsToSpecs([a, b])
|
||||
.then(findVersionsByPackageName)
|
||||
}
|
||||
|
||||
const defaultSpec = async () => {
|
||||
let noPackageJson
|
||||
let pkgName
|
||||
try {
|
||||
pkgName = await readLocalPkg()
|
||||
} catch (e) {
|
||||
npmlog.verbose('diff', 'could not read project dir package.json')
|
||||
noPackageJson = true
|
||||
}
|
||||
|
||||
if (!pkgName || noPackageJson) {
|
||||
throw new Error(
|
||||
'Needs multiple arguments to compare or run from a project dir.\n\n' +
|
||||
`Usage:\n${usage}`
|
||||
)
|
||||
}
|
||||
|
||||
return [
|
||||
`${pkgName}@${npm.flatOptions.defaultTag}`,
|
||||
`file:${npm.prefix}`,
|
||||
]
|
||||
}
|
||||
|
||||
const transformSingleSpec = async (a) => {
|
||||
let noPackageJson
|
||||
let pkgName
|
||||
try {
|
||||
pkgName = await readLocalPkg()
|
||||
} catch (e) {
|
||||
npmlog.verbose('diff', 'could not read project dir package.json')
|
||||
noPackageJson = true
|
||||
}
|
||||
const missingPackageJson = new Error(
|
||||
'Needs multiple arguments to compare or run from a project dir.\n\n' +
|
||||
`Usage:\n${usage}`
|
||||
)
|
||||
|
||||
const specSelf = () => {
|
||||
if (noPackageJson)
|
||||
throw missingPackageJson
|
||||
|
||||
return `file:${npm.prefix}`
|
||||
}
|
||||
|
||||
// using a valid semver range, that means it should just diff
|
||||
// the cwd against a published version to the registry using the
|
||||
// same project name and the provided semver range
|
||||
if (semver.validRange(a)) {
|
||||
if (!pkgName)
|
||||
throw missingPackageJson
|
||||
|
||||
return [
|
||||
`${pkgName}@${a}`,
|
||||
specSelf(),
|
||||
]
|
||||
}
|
||||
|
||||
// when using a single package name as arg and it's part of the current
|
||||
// install tree, then retrieve the current installed version and compare
|
||||
// it against the same value `npm outdated` would suggest you to update to
|
||||
const spec = npa(a)
|
||||
if (spec.registry) {
|
||||
let actualTree
|
||||
let node
|
||||
try {
|
||||
const opts = {
|
||||
...npm.flatOptions,
|
||||
path: where(),
|
||||
}
|
||||
const arb = new Arborist(opts)
|
||||
actualTree = await arb.loadActual(opts)
|
||||
node = actualTree &&
|
||||
actualTree.inventory.query('name', spec.name)
|
||||
.values().next().value
|
||||
} catch (e) {
|
||||
npmlog.verbose('diff', 'failed to load actual install tree')
|
||||
}
|
||||
|
||||
if (!node || !node.name || !node.package || !node.package.version) {
|
||||
return [
|
||||
`${spec.name}@${spec.fetchSpec}`,
|
||||
specSelf(),
|
||||
]
|
||||
}
|
||||
|
||||
const tryRootNodeSpec = () =>
|
||||
(actualTree && actualTree.edgesOut.get(spec.name) || {}).spec
|
||||
|
||||
const tryAnySpec = () => {
|
||||
for (const edge of node.edgesIn)
|
||||
return edge.spec
|
||||
}
|
||||
|
||||
const aSpec = `file:${node.realpath}`
|
||||
|
||||
// finds what version of the package to compare against, if a exact
|
||||
// version or tag was passed than it should use that, otherwise
|
||||
// work from the top of the arborist tree to find the original semver
|
||||
// range declared in the package that depends on the package.
|
||||
let bSpec
|
||||
if (spec.rawSpec)
|
||||
bSpec = spec.rawSpec
|
||||
else {
|
||||
const bTargetVersion =
|
||||
tryRootNodeSpec()
|
||||
|| tryAnySpec()
|
||||
|
||||
// figure out what to compare against,
|
||||
// follows same logic to npm outdated "Wanted" results
|
||||
const packument = await pacote.packument(spec, {
|
||||
...npm.flatOptions,
|
||||
preferOnline: true,
|
||||
})
|
||||
bSpec = pickManifest(
|
||||
packument,
|
||||
bTargetVersion,
|
||||
{ ...npm.flatOptions }
|
||||
).version
|
||||
}
|
||||
|
||||
return [
|
||||
`${spec.name}@${aSpec}`,
|
||||
`${spec.name}@${bSpec}`,
|
||||
]
|
||||
} else if (spec.type === 'directory') {
|
||||
return [
|
||||
`file:${spec.fetchSpec}`,
|
||||
specSelf(),
|
||||
]
|
||||
} else {
|
||||
throw new Error(
|
||||
'Spec type not supported.\n\n' +
|
||||
`Usage:\n${usage}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const convertVersionsToSpecs = async ([a, b]) => {
|
||||
const semverA = semver.validRange(a)
|
||||
const semverB = semver.validRange(b)
|
||||
|
||||
// both specs are semver versions, assume current project dir name
|
||||
if (semverA && semverB) {
|
||||
let pkgName
|
||||
try {
|
||||
pkgName = await readLocalPkg()
|
||||
} catch (e) {
|
||||
npmlog.verbose('diff', 'could not read project dir package.json')
|
||||
}
|
||||
|
||||
if (!pkgName) {
|
||||
throw new Error(
|
||||
'Needs to be run from a project dir in order to diff two versions.\n\n' +
|
||||
`Usage:\n${usage}`
|
||||
)
|
||||
}
|
||||
return [`${pkgName}@${a}`, `${pkgName}@${b}`]
|
||||
}
|
||||
|
||||
// otherwise uses the name from the other arg to
|
||||
// figure out the spec.name of what to compare
|
||||
if (!semverA && semverB)
|
||||
return [a, `${npa(a).name}@${b}`]
|
||||
|
||||
if (semverA && !semverB)
|
||||
return [`${npa(b).name}@${a}`, b]
|
||||
|
||||
// no valid semver ranges used
|
||||
return [a, b]
|
||||
}
|
||||
|
||||
const findVersionsByPackageName = async (specs) => {
|
||||
let actualTree
|
||||
try {
|
||||
const opts = {
|
||||
...npm.flatOptions,
|
||||
path: where(),
|
||||
}
|
||||
const arb = new Arborist(opts)
|
||||
actualTree = await arb.loadActual(opts)
|
||||
} catch (e) {
|
||||
npmlog.verbose('diff', 'failed to load actual install tree')
|
||||
}
|
||||
|
||||
return specs.map(i => {
|
||||
const spec = npa(i)
|
||||
if (spec.rawSpec)
|
||||
return i
|
||||
|
||||
const node = actualTree
|
||||
&& actualTree.inventory.query('name', spec.name)
|
||||
.values().next().value
|
||||
|
||||
const res = !node || !node.package || !node.package.version
|
||||
? spec.fetchSpec
|
||||
: `file:${node.realpath}`
|
||||
|
||||
return `${spec.name}@${res}`
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = Object.assign(cmd, { completion, usage })
|
||||
Vendored
+4
@@ -132,11 +132,15 @@ const searchFiles = async (args, data, files) => {
|
||||
|
||||
// sort results by number of results found, then by number of hits
|
||||
// then by number of matching lines
|
||||
|
||||
// coverage is ignored here because the contents of results are
|
||||
// nondeterministic due to either glob or readFiles or Object.entries
|
||||
return results.sort((a, b) =>
|
||||
a.found.length > b.found.length ? -1
|
||||
: a.found.length < b.found.length ? 1
|
||||
: a.totalHits > b.totalHits ? -1
|
||||
: a.totalHits < b.totalHits ? 1
|
||||
/* istanbul ignore next */
|
||||
: a.lines.length > b.lines.length ? -1
|
||||
: a.lines.length < b.lines.length ? 1
|
||||
: 0).slice(0, 10)
|
||||
|
||||
Vendored
+17
-16
@@ -35,22 +35,7 @@ const publish = async args => {
|
||||
log.verbose('publish', args)
|
||||
|
||||
const opts = { ...npm.flatOptions }
|
||||
const { json, defaultTag, registry } = opts
|
||||
|
||||
if (!registry) {
|
||||
throw Object.assign(new Error('No registry specified.'), {
|
||||
code: 'ENOREGISTRY',
|
||||
})
|
||||
}
|
||||
|
||||
if (!opts.dryRun) {
|
||||
const creds = npm.config.getCredentialsByURI(registry)
|
||||
if (!creds.token && !creds.username) {
|
||||
throw Object.assign(new Error('This command requires you to be logged in.'), {
|
||||
code: 'ENEEDAUTH',
|
||||
})
|
||||
}
|
||||
}
|
||||
const { json, defaultTag } = opts
|
||||
|
||||
if (semver.validRange(defaultTag))
|
||||
throw new Error('Tag name must not be a valid SemVer range: ' + defaultTag.trim())
|
||||
@@ -91,6 +76,22 @@ const publish_ = async (arg, opts) => {
|
||||
if (manifest.publishConfig)
|
||||
Object.assign(opts, publishConfigToOpts(manifest.publishConfig))
|
||||
|
||||
const { registry } = opts
|
||||
if (!registry) {
|
||||
throw Object.assign(new Error('No registry specified.'), {
|
||||
code: 'ENOREGISTRY',
|
||||
})
|
||||
}
|
||||
|
||||
if (!dryRun) {
|
||||
const creds = npm.config.getCredentialsByURI(registry)
|
||||
if (!creds.token && !creds.username) {
|
||||
throw Object.assign(new Error('This command requires you to be logged in.'), {
|
||||
code: 'ENEEDAUTH',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// only run scripts for directory type publishes
|
||||
if (spec.type === 'directory') {
|
||||
await runScript({
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ const cmdList = [
|
||||
'prefix',
|
||||
'bin',
|
||||
'whoami',
|
||||
'diff',
|
||||
'dist-tag',
|
||||
'ping',
|
||||
|
||||
|
||||
Vendored
+16
@@ -74,6 +74,14 @@ const defaults = {
|
||||
depth: null,
|
||||
description: true,
|
||||
dev: false,
|
||||
diff: [],
|
||||
'diff-unified': null,
|
||||
'diff-ignore-all-space': false,
|
||||
'diff-name-only': false,
|
||||
'diff-no-prefix': false,
|
||||
'diff-src-prefix': '',
|
||||
'diff-dst-prefix': '',
|
||||
'diff-text': false,
|
||||
'dry-run': false,
|
||||
editor,
|
||||
'engine-strict': false,
|
||||
@@ -216,6 +224,14 @@ const types = {
|
||||
depth: [null, Number],
|
||||
description: Boolean,
|
||||
dev: Boolean,
|
||||
diff: [String, Array],
|
||||
'diff-unified': [null, Number],
|
||||
'diff-ignore-all-space': Boolean,
|
||||
'diff-name-only': Boolean,
|
||||
'diff-no-prefix': Boolean,
|
||||
'diff-src-prefix': String,
|
||||
'diff-dst-prefix': String,
|
||||
'diff-text': Boolean,
|
||||
'dry-run': Boolean,
|
||||
editor: String,
|
||||
'engine-strict': Boolean,
|
||||
|
||||
Vendored
+9
@@ -102,6 +102,15 @@ const flatten = obj => ({
|
||||
staleness: obj.searchstaleness,
|
||||
},
|
||||
|
||||
diff: obj.diff,
|
||||
diffUnified: obj['diff-unified'],
|
||||
diffIgnoreAllSpace: obj['diff-ignore-all-space'],
|
||||
diffNameOnly: obj['diff-name-only'],
|
||||
diffNoPrefix: obj['diff-no-prefix'],
|
||||
diffSrcPrefix: obj['diff-src-prefix'],
|
||||
diffDstPrefix: obj['diff-dst-prefix'],
|
||||
diffText: obj['diff-text'],
|
||||
|
||||
dryRun: obj['dry-run'],
|
||||
engineStrict: obj['engine-strict'],
|
||||
|
||||
|
||||
Vendored
+266
@@ -0,0 +1,266 @@
|
||||
.TH "NPM\-DIFF" "1" "January 2021" "" ""
|
||||
.SH "NAME"
|
||||
\fBnpm-diff\fR \- The registry diff command
|
||||
.SS Synopsis
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff [\.\.\.<paths>]
|
||||
npm diff \-\-diff=<pkg\-name> [\.\.\.<paths>]
|
||||
npm diff \-\-diff=<version\-a> [\-\-diff=<version\-b>] [\.\.\.<paths>]
|
||||
npm diff \-\-diff=<spec\-a> [\-\-diff=<spec\-b>] [\.\.\.<paths>]
|
||||
npm diff [\-\-diff\-ignore\-all\-space] [\-\-diff\-name\-only] [\.\.\.<paths>]
|
||||
.fi
|
||||
.RE
|
||||
.SS Description
|
||||
.P
|
||||
Similar to its \fBgit diff\fP counterpart, this command will print diff patches
|
||||
of files for packages published to the npm registry\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBnpm diff \-\-diff=<spec\-a> \-\-diff=<spec\-b>\fP
|
||||
Compares two package versions using their registry specifiers, e\.g:
|
||||
\fBnpm diff \-\-diff=pkg@1\.0\.0 \-\-diff=pkg@^2\.0\.0\fP\|\. It's also possible to
|
||||
compare across forks of any package,
|
||||
e\.g: \fBnpm diff \-\-diff=pkg@1\.0\.0 \-\-diff=pkg\-fork@1\.0\.0\fP\|\.
|
||||
Any valid spec can be used, so that it's also possible to compare
|
||||
directories or git repositories,
|
||||
e\.g: \fBnpm diff \-\-diff=pkg@latest \-\-diff=\./packages/pkg\fP
|
||||
Here's an example comparing two different versions of a package named
|
||||
\fBabbrev\fP from the registry:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=abbrev@1\.1\.0 \-\-diff=abbrev@1\.1\.1
|
||||
.fi
|
||||
.RE
|
||||
On success, output looks like:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
diff \-\-git a/package\.json b/package\.json
|
||||
index v1\.1\.0\.\.v1\.1\.1 100644
|
||||
\-\-\- a/package\.json
|
||||
+++ b/package\.json
|
||||
@@ \-1,6 +1,6 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
\- "version": "1\.1\.0",
|
||||
+ "version": "1\.1\.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z\. Schlueter <i@izs\.me>",
|
||||
"main": "abbrev\.js",
|
||||
.fi
|
||||
.RE
|
||||
Given the flexible nature of npm specs, you can also target local
|
||||
directories or git repos just like when using \fBnpm install\fP:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=https://github\.com/npm/libnpmdiff \-\-diff=\./local\-path
|
||||
.fi
|
||||
.RE
|
||||
In the example above we can compare the contents from the package installed
|
||||
from the git repo at \fBgithub\.com/npm/libnpmdiff\fP with the contents of the
|
||||
\fB\|\./local\-path\fP that contains a valid package, such as a modified copy of
|
||||
the original\.
|
||||
.IP \(bu 2
|
||||
\fBnpm diff\fP (in a package directory, no arguments):
|
||||
If the package is published to the registry, \fBnpm diff\fP will fetch the
|
||||
tarball version tagged as \fBlatest\fP (this value can be configured using the
|
||||
\fBtag\fP option) and proceed to compare the contents of files present in that
|
||||
tarball, with the current files in your local file system\.
|
||||
This workflow provides a handy way for package authors to see what
|
||||
package\-tracked files have been changed in comparison with the latest
|
||||
published version of that package\.
|
||||
.IP \(bu 2
|
||||
\fBnpm diff \-\-diff=<pkg\-name>\fP (in a package directory):
|
||||
When using a single package name (with no version or tag specifier) as an
|
||||
argument, \fBnpm diff\fP will work in a similar way to
|
||||
\fBnpm\-outdated\fP \fInpm\-outdated\fR and reach for the registry to figure out
|
||||
what current published version of the package named <pkg\-name> will satisfy
|
||||
its dependent declared semver\-range\. Once that specific version is known
|
||||
\fBnpm diff\fP will print diff patches comparing the current version of
|
||||
<pkg\-name> found in the local file system with that specific version
|
||||
returned by the registry\.
|
||||
Given a package named \fBabbrev\fP that is currently installed:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=abbrev
|
||||
.fi
|
||||
.RE
|
||||
That will request from the registry its most up to date version and
|
||||
will print a diff output comparing the currently installed version to this
|
||||
newer one if the version numbers are not the same\.
|
||||
.IP \(bu 2
|
||||
\fBnpm diff \-\-diff=<spec\-a>\fP (in a package directory):
|
||||
Similar to using only a single package name, it's also possible to declare
|
||||
a full registry specifier version if you wish to compare the local version
|
||||
of an installed package with the specific version/tag/semver\-range provided
|
||||
in \fB<spec\-a>\fP\|\.
|
||||
An example: assuming \fBpkg@1\.0\.0\fP is installed in the current \fBnode_modules\fP
|
||||
folder, running:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=pkg@2\.0\.0
|
||||
.fi
|
||||
.RE
|
||||
It will effectively be an alias to
|
||||
\fBnpm diff \-\-diff=pkg@1\.0\.0 \-\-diff=pkg@2\.0\.0\fP\|\.
|
||||
.IP \(bu 2
|
||||
\fBnpm diff \-\-diff=<semver\-a> [\-\-diff=<semver\-b>]\fP (in a package directory):
|
||||
Using \fBnpm diff\fP along with semver\-valid version numbers is a shorthand
|
||||
to compare different versions of the current package\.
|
||||
It needs to be run from a package directory, such that for a package named
|
||||
\fBpkg\fP running \fBnpm diff \-\-diff=1\.0\.0 \-\-diff=1\.0\.1\fP is the same as running
|
||||
\fBnpm diff \-\-diff=pkg@1\.0\.0 \-\-diff=pkg@1\.0\.1\fP\|\.
|
||||
If only a single argument \fB<version\-a>\fP is provided, then the current local
|
||||
file system is going to be compared against that version\.
|
||||
Here's an example comparing two specific versions (published to the
|
||||
configured registry) of the current project directory:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=1\.0\.0 \-\-diff=1\.1\.0
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.RE
|
||||
.P
|
||||
Note that tag names are not valid \fB\-\-diff\fP argument values, if you wish to
|
||||
compare to a published tag, you must use the \fBpkg@tagname\fP syntax\.
|
||||
.SS Filtering files
|
||||
.P
|
||||
It's possible to also specify positional arguments using file names or globs
|
||||
pattern matching in order to limit the result of diff patches to only a subset
|
||||
of files for a given package, e\.g:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm diff \-\-diff=pkg@2 \./lib/ CHANGELOG\.md
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
In the example above the diff output is only going to print contents of files
|
||||
located within the folder \fB\|\./lib/\fP and changed lines of code within the
|
||||
\fBCHANGELOG\.md\fP file\.
|
||||
.SS Configuration
|
||||
.SS diff
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Array<String>
|
||||
.IP \(bu 2
|
||||
Default: null
|
||||
|
||||
.RE
|
||||
.P
|
||||
Defines npm package specifiers to compare using the \fBnpm diff\fP command\.
|
||||
.P
|
||||
This can be specified up to 2 times\.
|
||||
.SS diff\-name\-only
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
When set to \fBtrue\fP running \fBnpm diff\fP only returns the names of the files that
|
||||
have any difference\.
|
||||
.SS diff\-unified
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Number
|
||||
.IP \(bu 2
|
||||
Default: \fB3\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
The number of lines of context to print in the unified diff format output\.
|
||||
.SS diff\-ignore\-all\-space
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Ignore whitespace when comparing lines\. This ignores differences even if one
|
||||
line has whitespace where the other line has none\.
|
||||
.SS diff\-no\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Do not show any source or destination prefix\.
|
||||
.SS diff\-src\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fB"a/"\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
Show the given source prefix in diff patches headers instead of using "a/"\.
|
||||
.SS diff\-dst\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fB"b/"\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
Show the given source prefix in diff patches headers instead of using "b/"\.
|
||||
.SS diff\-text
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Treat all files as text\.
|
||||
.SS global
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
.RE
|
||||
.P
|
||||
Uses packages from the global space as a source for comparison\.
|
||||
.SS tag
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fB"latest"\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
The tag used to fetch the tarball that will be compared with the local file
|
||||
system files when running npm diff with no arguments\.
|
||||
.SH See Also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
npm help outdated
|
||||
.IP \(bu 2
|
||||
npm help install
|
||||
.IP \(bu 2
|
||||
npm help config
|
||||
.IP \(bu 2
|
||||
npm help registry
|
||||
|
||||
.RE
|
||||
Vendored
+18
@@ -200,6 +200,24 @@ The \fB\-\-shell\fP option is replaced with \fB\-\-script\-shell\fP, but maintai
|
||||
in the \fBnpx\fP executable for backwards compatibility\.
|
||||
|
||||
.RE
|
||||
.SS A note on caching
|
||||
.P
|
||||
The npm cli utilizes its internal package cache when using the package
|
||||
name specified\. You can use the following to change how and when the
|
||||
cli uses this cache\. See npm help \fBcache\fP for more on
|
||||
how the cache works\.
|
||||
.SS prefer\-online
|
||||
.P
|
||||
Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache\.
|
||||
.SS prefer\-offline
|
||||
.P
|
||||
Bypasses staleness checks for packages\. Missing data will still be
|
||||
requested from the server\. To force full offline mode, use \fBoffline\fP\|\.
|
||||
.SS offline
|
||||
.P
|
||||
Forces full offline mode\. Any packages not locally cached will result in
|
||||
an error\.
|
||||
.SS See Also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
|
||||
Vendored
+20
@@ -80,6 +80,24 @@ Generate it without having it ask any questions:
|
||||
$ npm init \-y
|
||||
.fi
|
||||
.RE
|
||||
.SS A note on caching
|
||||
.P
|
||||
The npm cli utilizes its internal package cache when using the package
|
||||
name specified\. You can use the following to change how and when the
|
||||
cli uses this cache\. See npm help \fBcache\fP for more on
|
||||
how the cache works\.
|
||||
.SS prefer\-online
|
||||
.P
|
||||
Forces staleness checks for packages, making the cli look for updates
|
||||
immediately even if the package is already in the cache\.
|
||||
.SS prefer\-offline
|
||||
.P
|
||||
Bypasses staleness checks for packages\. Missing data will still be
|
||||
requested from the server\. To force full offline mode, use \fBoffline\fP\|\.
|
||||
.SS offline
|
||||
.P
|
||||
Forces full offline mode\. Any packages not locally cached will result in
|
||||
an error\.
|
||||
.SS See Also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
@@ -90,5 +108,7 @@ npm help package\.json
|
||||
npm help version
|
||||
.IP \(bu 2
|
||||
npm help scope
|
||||
.IP \(bu 2
|
||||
npm help exec
|
||||
|
||||
.RE
|
||||
Vendored
+1
-1
@@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm@7\.4\.3 /path/to/npm
|
||||
npm@7\.5\.0 /path/to/npm
|
||||
└─┬ init\-package\-json@0\.0\.4
|
||||
└── promzard@0\.1\.5
|
||||
.fi
|
||||
|
||||
Vendored
-2
@@ -45,7 +45,5 @@ npm help publish
|
||||
npm help registry
|
||||
.IP \(bu 2
|
||||
npm help adduser
|
||||
.IP \(bu 2
|
||||
npm help disputes
|
||||
|
||||
.RE
|
||||
Vendored
+46
-6
@@ -32,7 +32,7 @@ npm run test \-\- \-\-grep="pattern"
|
||||
.RE
|
||||
.P
|
||||
The arguments will only be passed to the script specified after \fBnpm run\fP
|
||||
and not to any pre or post script\.
|
||||
and not to any \fBpre\fP or \fBpost\fP script\.
|
||||
.P
|
||||
The \fBenv\fP script is a special built\-in command that can be used to list
|
||||
environment variables that will be available to the script at runtime\. If an
|
||||
@@ -60,7 +60,8 @@ instead of
|
||||
.RE
|
||||
.P
|
||||
The actual shell your script is run within is platform dependent\. By default,
|
||||
on Unix\-like systems it is the \fB/bin/sh\fP command, on Windows it is the \fBcmd\.exe\fP\|\.
|
||||
on Unix\-like systems it is the \fB/bin/sh\fP command, on Windows it is
|
||||
\fBcmd\.exe\fP\|\.
|
||||
The actual shell referred to by \fB/bin/sh\fP also depends on the system\.
|
||||
You can customize the shell with the \fBscript\-shell\fP configuration\.
|
||||
.P
|
||||
@@ -77,14 +78,53 @@ If \fB\-\-scripts\-prepend\-node\-path=auto\fP is passed (which has been the def
|
||||
in \fBnpm\fP v3), this is only performed when that \fBnode\fP executable is not
|
||||
found in the \fBPATH\fP\|\.
|
||||
.P
|
||||
If you try to run a script without having a \fBnode_modules\fP directory and it fails,
|
||||
you will be given a warning to run \fBnpm install\fP, just in case you've forgotten\.
|
||||
.P
|
||||
You can use the \fB\-\-silent\fP flag to prevent showing \fBnpm ERR!\fP output on error\.
|
||||
If you try to run a script without having a \fBnode_modules\fP directory and it
|
||||
fails, you will be given a warning to run \fBnpm install\fP, just in case you've
|
||||
forgotten\.
|
||||
.SS Configuration
|
||||
.SS if\-present
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
You can use the \fB\-\-if\-present\fP flag to avoid exiting with a non\-zero exit code
|
||||
when the script is undefined\. This lets you run potentially undefined scripts
|
||||
without breaking the execution chain\.
|
||||
.SS ignore\-scripts
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Skips running \fBpre\fP and \fBpost\fP scripts\.
|
||||
.SS script\-shell
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fBnull\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
Optional custom script to use to execute the command\. If not defined defaults
|
||||
to \fB/bin/sh\fP on Unix, defaults to \fBenv\.comspec\fP or \fBcmd\.exe\fP on Windows\.
|
||||
.SS silent
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
You can use the \fB\-\-silent\fP flag to prevent showing \fBnpm ERR!\fP output on error\.
|
||||
.SS See Also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
|
||||
Vendored
+3
-3
@@ -129,12 +129,12 @@ the cli uses this cache\. See npm help \fBcache\fP for more
|
||||
on how the cache works\.
|
||||
.SS prefer\-online
|
||||
.P
|
||||
Forced staleness checks for cached searches, making the cli look for
|
||||
Forces staleness checks for cached searches, making the cli look for
|
||||
updates immediately even for fresh search results\.
|
||||
.SS prefer\-offline
|
||||
.P
|
||||
Bypasses staleness checks for cached\. Missing data will still be
|
||||
requested from the server\. To force full offline mode, use \fBoffline\fP\|\.
|
||||
Bypasses staleness checks for cached searches\. Missing data will still
|
||||
be requested from the server\. To force full offline mode, use \fBoffline\fP\|\.
|
||||
.SS offline
|
||||
.P
|
||||
Forces full offline mode\. Any searches not locally cached will result in
|
||||
|
||||
Vendored
+10
-19
@@ -1,6 +1,6 @@
|
||||
.TH "NPM\-UPDATE" "1" "January 2021" "" ""
|
||||
.SH "NAME"
|
||||
\fBnpm-update\fR \- Update a package
|
||||
\fBnpm-update\fR \- Update packages
|
||||
.SS Synopsis
|
||||
.P
|
||||
.RS 2
|
||||
@@ -24,22 +24,11 @@ packages\.
|
||||
.P
|
||||
If no package name is specified, all packages in the specified location (global
|
||||
or local) will be updated\.
|
||||
.P
|
||||
As of \fBnpm@2\.6\.1\fP, the \fBnpm update\fP will only inspect top\-level packages\.
|
||||
Prior versions of \fBnpm\fP would also recursively inspect all dependencies\.
|
||||
To get the old behavior, use \fBnpm \-\-depth 9999 update\fP\|\.
|
||||
.P
|
||||
As of \fBnpm@5\.0\.0\fP, the \fBnpm update\fP will change \fBpackage\.json\fP to save the
|
||||
new version as the minimum required dependency\. To get the old behavior,
|
||||
use \fBnpm update \-\-no\-save\fP\|\.
|
||||
.SS Example
|
||||
.P
|
||||
IMPORTANT VERSION NOTE: these examples assume \fBnpm@2\.6\.1\fP or later\. For
|
||||
older versions of \fBnpm\fP, you must specify \fB\-\-depth 0\fP to get the behavior
|
||||
described below\.
|
||||
.P
|
||||
For the examples below, assume that the current package is \fBapp\fP and it depends
|
||||
on dependencies, \fBdep1\fP (\fBdep2\fP, \.\. etc\.)\. The published versions of \fBdep1\fP are:
|
||||
on dependencies, \fBdep1\fP (\fBdep2\fP, \.\. etc\.)\. The published versions of \fBdep1\fP
|
||||
are:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -85,10 +74,10 @@ However, if \fBapp\fP\|'s \fBpackage\.json\fP contains:
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
In this case, running \fBnpm update\fP will install \fBdep1@1\.1\.2\fP\|\. Even though the \fBlatest\fP
|
||||
tag points to \fB1\.2\.2\fP, this version does not satisfy \fB~1\.1\.1\fP, which is equivalent
|
||||
to \fB>=1\.1\.1 <1\.2\.0\fP\|\. So the highest\-sorting version that satisfies \fB~1\.1\.1\fP is used,
|
||||
which is \fB1\.1\.2\fP\|\.
|
||||
In this case, running \fBnpm update\fP will install \fBdep1@1\.1\.2\fP\|\. Even though the
|
||||
\fBlatest\fP tag points to \fB1\.2\.2\fP, this version do not satisfy \fB~1\.1\.1\fP, which is
|
||||
equivalent to \fB>=1\.1\.1 <1\.2\.0\fP\|\. So the highest\-sorting version that satisfies
|
||||
\fB~1\.1\.1\fP is used, which is \fB1\.1\.2\fP\|\.
|
||||
.SS Caret Dependencies below 1\.0\.0
|
||||
.P
|
||||
Suppose \fBapp\fP has a caret dependency on a version below \fB1\.0\.0\fP, for example:
|
||||
@@ -122,7 +111,9 @@ version that satisfies \fB^0\.4\.0\fP (\fB>= 0\.4\.0 <0\.5\.0\fP)
|
||||
package that is \fBoutdated\fP \-\- that is, has a version that is different from
|
||||
\fBwanted\fP\|\.
|
||||
.P
|
||||
Note: Globally installed packages are treated as if they are installed with a caret semver range specified\. So if you require to update to \fBlatest\fP you may need to run \fBnpm install \-g [<pkg>\.\.\.]\fP
|
||||
Note: Globally installed packages are treated as if they are installed with a
|
||||
caret semver range specified\. So if you require to update to \fBlatest\fP you may
|
||||
need to run \fBnpm install \-g [<pkg>\.\.\.]\fP
|
||||
.P
|
||||
NOTE: If a package has been upgraded to a version newer than \fBlatest\fP, it will
|
||||
be \fIdowngraded\fR\|\.
|
||||
|
||||
Vendored
+10
-12
@@ -96,45 +96,45 @@ Take the following example:
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
This runs all your tests, and proceeds only if they pass\. Then runs your \fBbuild\fP script, and
|
||||
This runs all your tests and proceeds only if they pass\. Then runs your \fBbuild\fP script, and
|
||||
adds everything in the \fBdist\fP directory to the commit\. After the commit, it pushes the new commit
|
||||
and tag up to the server, and deletes the \fBbuild/temp\fP directory\.
|
||||
.SS Configuration
|
||||
.SS allow\-same\-version
|
||||
.SS \fBallow\-same\-version\fP
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
Default: \fBfalse\fP
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
.RE
|
||||
.P
|
||||
Prevents throwing an error when \fBnpm version\fP is used to set the new version
|
||||
Prevents throwing an error when \fBnpm version\fP is used to set the new version
|
||||
to the same value as the current version\.
|
||||
.SS git\-tag\-version
|
||||
.SS \fBgit\-tag\-version\fP
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: true
|
||||
Default: \fBtrue\fP
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
.RE
|
||||
.P
|
||||
Commit and tag the version change\.
|
||||
.SS commit\-hooks
|
||||
.SS \fBcommit\-hooks\fP
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: true
|
||||
Default: \fBtrue\fP
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
.RE
|
||||
.P
|
||||
Run git commit hooks when committing the version change\.
|
||||
.SS sign\-git\-tag
|
||||
.SS \fBsign\-git\-tag\fP
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
Default: \fBfalse\fP
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
@@ -154,8 +154,6 @@ npm help scripts
|
||||
.IP \(bu 2
|
||||
npm help package\.json
|
||||
.IP \(bu 2
|
||||
npm help semver
|
||||
.IP \(bu 2
|
||||
npm help config
|
||||
|
||||
.RE
|
||||
Vendored
+17
-19
@@ -15,8 +15,7 @@ aliases: info, show, v
|
||||
This command shows data about a package and prints it to the stream
|
||||
referenced by the \fBoutfd\fP config, which defaults to stdout\.
|
||||
.P
|
||||
To show the package registry entry for the \fBconnect\fP package, you can do
|
||||
this:
|
||||
As an example, to view information about the \fBconnect\fP package from the registry, you would run:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -24,11 +23,11 @@ npm view connect
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
The default version is "latest" if unspecified\.
|
||||
The default version is \fB"latest"\fP if unspecified\.
|
||||
.P
|
||||
Field names can be specified after the package descriptor\.
|
||||
For example, to show the dependencies of the \fBronn\fP package at version
|
||||
0\.3\.5, you could do the following:
|
||||
\fB0\.3\.5\fP, you could do the following:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -37,8 +36,7 @@ npm view ronn@0\.3\.5 dependencies
|
||||
.RE
|
||||
.P
|
||||
You can view child fields by separating them with a period\.
|
||||
To view the git repository URL for the latest version of npm, you could
|
||||
do this:
|
||||
To view the git repository URL for the latest version of \fBnpm\fP, you would run the following command:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -47,8 +45,8 @@ npm view npm repository\.url
|
||||
.RE
|
||||
.P
|
||||
This makes it easy to view information about a dependency with a bit of
|
||||
shell scripting\. For example, to view all the data about the version of
|
||||
opts that ronn depends on, you can do this:
|
||||
shell scripting\. For example, to view all the data about the version of
|
||||
\fBopts\fP that \fBronn\fP depends on, you could write the following:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -57,8 +55,8 @@ npm view opts@$(npm view ronn dependencies\.opts)
|
||||
.RE
|
||||
.P
|
||||
For fields that are arrays, requesting a non\-numeric field will return
|
||||
all of the values from the objects in the list\. For example, to get all
|
||||
the contributor names for the "express" project, you can do this:
|
||||
all of the values from the objects in the list\. For example, to get all
|
||||
the contributor names for the \fBexpress\fP package, you would run:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -67,8 +65,8 @@ npm view express contributors\.email
|
||||
.RE
|
||||
.P
|
||||
You may also use numeric indices in square braces to specifically select
|
||||
an item in an array field\. To just get the email address of the first
|
||||
contributor in the list, you can do this:
|
||||
an item in an array field\. To just get the email address of the first
|
||||
contributor in the list, you can run:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -87,7 +85,7 @@ npm view express contributors\.name contributors\.email
|
||||
.RE
|
||||
.P
|
||||
"Person" fields are shown as a string if they would be shown as an
|
||||
object\. So, for example, this will show the list of npm contributors in
|
||||
object\. So, for example, this will show the list of \fBnpm\fP contributors in
|
||||
the shortened string format\. (See npm help \fBpackage\.json\fP for more on this\.)
|
||||
.P
|
||||
.RS 2
|
||||
@@ -97,8 +95,8 @@ npm view npm contributors
|
||||
.RE
|
||||
.P
|
||||
If a version range is provided, then data will be printed for every
|
||||
matching version of the package\. This will show which version of jsdom
|
||||
was required by each matching version of yui3:
|
||||
matching version of the package\. This will show which version of \fBjsdom\fP
|
||||
was required by each matching version of \fByui3\fP:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
@@ -117,15 +115,15 @@ npm view connect versions
|
||||
.SS Output
|
||||
.P
|
||||
If only a single string field for a single version is output, then it
|
||||
will not be colorized or quoted, so as to enable piping the output to
|
||||
will not be colorized or quoted, to enable piping the output to
|
||||
another command\. If the field is an object, it will be output as a JavaScript object literal\.
|
||||
.P
|
||||
If the \-\-json flag is given, the outputted fields will be JSON\.
|
||||
If the \fB\-\-json\fP flag is given, the outputted fields will be JSON\.
|
||||
.P
|
||||
If the version range matches multiple versions, than each printed value
|
||||
If the version range matches multiple versions then each printed value
|
||||
will be prefixed with the version it applies to\.
|
||||
.P
|
||||
If multiple fields are requested, than each of them are prefixed with
|
||||
If multiple fields are requested, then each of them is prefixed with
|
||||
the field name\.
|
||||
.SS See Also
|
||||
.RS 0
|
||||
|
||||
Vendored
+63
-47
@@ -10,40 +10,46 @@ npm <command> [args]
|
||||
.RE
|
||||
.SS Version
|
||||
.P
|
||||
7\.4\.3
|
||||
7\.5\.0
|
||||
.SS Description
|
||||
.P
|
||||
npm is the package manager for the Node JavaScript platform\. It puts
|
||||
modules in place so that node can find them, and manages dependency
|
||||
conflicts intelligently\.
|
||||
.P
|
||||
It is extremely configurable to support a wide variety of use cases\.
|
||||
Most commonly, it is used to publish, discover, install, and develop node
|
||||
It is extremely configurable to support a variety of use cases\. Most
|
||||
commonly, you use it to publish, discover, install, and develop node
|
||||
programs\.
|
||||
.P
|
||||
Run \fBnpm help\fP to get a list of available commands\.
|
||||
.SS Important
|
||||
.P
|
||||
npm is configured to use npm, Inc\.'s public registry at
|
||||
npm comes preconfigured to use npm's public registry at
|
||||
https://registry\.npmjs\.org by default\. Use of the npm public registry is
|
||||
subject to terms of use available at https://www\.npmjs\.com/policies/terms\.
|
||||
subject to terms of use available at
|
||||
https://www\.npmjs\.com/policies/terms\.
|
||||
.P
|
||||
You can configure npm to use any compatible registry you like, and even run
|
||||
your own registry\. Use of someone else's registry may be governed by their
|
||||
terms of use\.
|
||||
You can configure npm to use any compatible registry you like, and even
|
||||
run your own registry\. Use of someone else's registry is governed by
|
||||
their terms of use\.
|
||||
.SS Introduction
|
||||
.P
|
||||
You probably got npm because you want to install stuff\.
|
||||
.P
|
||||
Use \fBnpm install blerg\fP to install the latest version of "blerg"\. Check out
|
||||
npm help \fBinstall\fP for more info\. It can do a lot of stuff\.
|
||||
The very first thing you will most likely want to run in any node
|
||||
program is \fBnpm install\fP to install its dependencies\.
|
||||
.P
|
||||
Use the \fBnpm search\fP command to show everything that's available\.
|
||||
Use \fBnpm ls\fP to show everything you've installed\.
|
||||
You can also run \fBnpm install blerg\fP to install the latest version of
|
||||
"blerg"\. Check out npm help \fBinstall\fP for more
|
||||
info\. It can do a lot of stuff\.
|
||||
.P
|
||||
Use the \fBnpm search\fP command to show everything that's available in the
|
||||
public registry\. Use \fBnpm ls\fP to show everything you've installed\.
|
||||
.SS Dependencies
|
||||
.P
|
||||
If a package references to another package with a git URL, npm depends
|
||||
on a preinstalled git\.
|
||||
If a package lists a dependency using a git URL, npm will install that
|
||||
dependency using the \fBgit\fP \fIhttps://github\.com/git\-guides/install\-git\fR
|
||||
command and will generate an error if it is not installed\.
|
||||
.P
|
||||
If one of the packages npm tries to install is a native node module and
|
||||
requires compiling of C++ Code, npm will use
|
||||
@@ -57,24 +63,26 @@ the node\-gyp repository \fIhttps://github\.com/nodejs/node\-gyp\fR and
|
||||
the node\-gyp Wiki \fIhttps://github\.com/nodejs/node\-gyp/wiki\fR\|\.
|
||||
.SS Directories
|
||||
.P
|
||||
See npm help \fBfolders\fP to learn about where npm puts stuff\.
|
||||
See npm help \fBfolders\fP to learn about where npm puts
|
||||
stuff\.
|
||||
.P
|
||||
In particular, npm has two modes of operation:
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
global mode:
|
||||
npm installs packages into the install prefix at
|
||||
\fBprefix/lib/node_modules\fP and bins are installed in \fBprefix/bin\fP\|\.
|
||||
.IP \(bu 2
|
||||
local mode:
|
||||
npm installs packages into the current project directory, which
|
||||
defaults to the current working directory\. Packages are installed to
|
||||
\fB\|\./node_modules\fP, and bins are installed to \fB\|\./node_modules/\.bin\fP\|\.
|
||||
defaults to the current working directory\. Packages install to
|
||||
\fB\|\./node_modules\fP, and bins to \fB\|\./node_modules/\.bin\fP\|\.
|
||||
.IP \(bu 2
|
||||
global mode:
|
||||
npm installs packages into the install prefix at
|
||||
\fB$npm_config_prefix/lib/node_modules\fP and bins to
|
||||
\fB$npm_config_prefix/bin\fP\|\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
Local mode is the default\. Use \fB\-g\fP or \fB\-\-global\fP on any command to
|
||||
operate in global mode instead\.
|
||||
run in global mode instead\.
|
||||
.SS Developer Usage
|
||||
.P
|
||||
If you're using npm to develop and publish your code, check out the
|
||||
@@ -82,24 +90,26 @@ following help topics:
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
json:
|
||||
Make a package\.json file\. See npm help \fBpackage\.json\fP\|\.
|
||||
Make a package\.json file\. See
|
||||
npm help \fBpackage\.json\fP\|\.
|
||||
.IP \(bu 2
|
||||
link:
|
||||
For linking your current working code into Node's path, so that you
|
||||
don't have to reinstall every time you make a change\. Use
|
||||
\fBnpm link\fP to do this\.
|
||||
Links your current working code into Node's path, so that you don't
|
||||
have to reinstall every time you make a change\. Use npm help \fBnpm
|
||||
link\fP to do this\.
|
||||
.IP \(bu 2
|
||||
install:
|
||||
It's a good idea to install things if you don't need the symbolic link\.
|
||||
Especially, installing other peoples code from the registry is done via
|
||||
\fBnpm install\fP
|
||||
It's a good idea to install things if you don't need the symbolic
|
||||
link\. Especially, installing other peoples code from the registry is
|
||||
done via npm help \fBinstall\fP
|
||||
.IP \(bu 2
|
||||
adduser:
|
||||
Create an account or log in\. Credentials are stored in the
|
||||
user config file\.
|
||||
Create an account or log in\. When you do this, npm will store
|
||||
credentials in the user config file config file\.
|
||||
.IP \(bu 2
|
||||
publish:
|
||||
Use the \fBnpm publish\fP command to upload your code to the registry\.
|
||||
Use the npm help \fBpublish\fP command to upload your
|
||||
code to the registry\.
|
||||
|
||||
.RE
|
||||
.SS Configuration
|
||||
@@ -111,23 +121,23 @@ npm is extremely configurable\. It reads its configuration options from
|
||||
Command line switches:
|
||||
Set a config with \fB\-\-key val\fP\|\. All keys take a value, even if they
|
||||
are booleans (the config parser doesn't know what the options are at
|
||||
the time of parsing)\. If no value is provided, then the option is set
|
||||
to boolean \fBtrue\fP\|\.
|
||||
the time of parsing)\. If you do not provide a value (\fB\-\-key\fP) then
|
||||
the option is set to boolean \fBtrue\fP\|\.
|
||||
.IP \(bu 2
|
||||
Environment Variables:
|
||||
Set any config by prefixing the name in an environment variable with
|
||||
\fBnpm_config_\fP\|\. For example, \fBexport npm_config_key=val\fP\|\.
|
||||
.IP \(bu 2
|
||||
User Configs:
|
||||
The file at $HOME/\.npmrc is an ini\-formatted list of configs\. If
|
||||
The file at \fB$HOME/\.npmrc\fP is an ini\-formatted list of configs\. If
|
||||
present, it is parsed\. If the \fBuserconfig\fP option is set in the cli
|
||||
or env, then that will be used instead\.
|
||||
or env, that file will be used instead\.
|
||||
.IP \(bu 2
|
||||
Global Configs:
|
||||
The file found at \.\./etc/npmrc (from the node executable, by default
|
||||
this resolves to /usr/local/etc/npmrc) will be parsed if it is found\.
|
||||
If the \fBglobalconfig\fP option is set in the cli, env, or user config,
|
||||
then that file is parsed instead\.
|
||||
The file found at \fB\|\./etc/npmrc\fP (relative to the global prefix will be
|
||||
parsed if it is found\. See npm help \fBprefix\fP for
|
||||
more info on the global prefix\. If the \fBglobalconfig\fP option is set
|
||||
in the cli, env, or user config, then that file is parsed instead\.
|
||||
.IP \(bu 2
|
||||
Defaults:
|
||||
npm's default configuration options are defined in
|
||||
@@ -140,14 +150,16 @@ See npm help \fBconfig\fP for much much more information\.
|
||||
.P
|
||||
Patches welcome!
|
||||
.P
|
||||
If you would like to contribute, but don't know what to work on, read
|
||||
the contributing guidelines \fIhttps://github\.com/npm/cli/blob/latest/CONTRIBUTING\.md\fR
|
||||
and check the issues list\.
|
||||
If you would like to help, but don't know what to work on, read the
|
||||
contributing
|
||||
guidelines \fIhttps://github\.com/npm/cli/blob/latest/CONTRIBUTING\.md\fR and
|
||||
check the issues list\.
|
||||
.SS Bugs
|
||||
.P
|
||||
When you find issues, please report them: https://github\.com/npm/cli/issues
|
||||
When you find issues, please report them:
|
||||
https://github\.com/npm/cli/issues
|
||||
.P
|
||||
Be sure to follow the template and bug reporting guidelines\.
|
||||
Please be sure to follow the template and bug reporting guidelines\.
|
||||
.SS Feature Requests
|
||||
.P
|
||||
Discuss new feature ideas on our discussion forum:
|
||||
@@ -170,10 +182,14 @@ npm help help
|
||||
.IP \(bu 2
|
||||
npm help package\.json
|
||||
.IP \(bu 2
|
||||
npm help install
|
||||
npm help npmrc
|
||||
.IP \(bu 2
|
||||
npm help config
|
||||
.IP \(bu 2
|
||||
npm help npmrc
|
||||
npm help install
|
||||
.IP \(bu 2
|
||||
npm help prefix
|
||||
.IP \(bu 2
|
||||
npm help publish
|
||||
|
||||
.RE
|
||||
Vendored
+5
-7
@@ -69,8 +69,6 @@ version fields are optional\.
|
||||
Version must be parseable by
|
||||
node\-semver \fIhttps://github\.com/npm/node\-semver\fR, which is bundled with
|
||||
npm as a dependency\. (\fBnpm install semver\fP to use it yourself\.)
|
||||
.P
|
||||
More on version numbers and ranges at npm help semver\.
|
||||
.SS description
|
||||
.P
|
||||
Put a description in it\. It's a string\. This helps people discover your
|
||||
@@ -622,8 +620,8 @@ tarball or git URL\.
|
||||
\fBPlease do not put test harnesses or transpilers or other "development"
|
||||
time tools in your \fBdependencies\fP object\.\fR See \fBdevDependencies\fP, below\.
|
||||
.P
|
||||
See npm help semver for more details about specifying version
|
||||
ranges\.
|
||||
See semver \fI[/using\-npm/semver](https://github\.com/npm/node\-semver#versions)\fR
|
||||
for more details about specifying version ranges\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBversion\fP Must match \fBversion\fP exactly
|
||||
@@ -637,9 +635,9 @@ ranges\.
|
||||
\fB<=version\fP
|
||||
.IP \(bu 2
|
||||
\fB~version\fP "Approximately equivalent to version" See
|
||||
npm help semver
|
||||
semver \fIhttps://github\.com/npm/node\-semver#versions\fR
|
||||
.IP \(bu 2
|
||||
\fB^version\fP "Compatible with version" See npm help semver
|
||||
\fB^version\fP "Compatible with version" See semver \fIhttps://github\.com/npm/node\-semver#versions\fR
|
||||
.IP \(bu 2
|
||||
\fB1\.2\.x\fP 1\.2\.0, 1\.2\.1, etc\., but not 1\.3\.0
|
||||
.IP \(bu 2
|
||||
@@ -1126,7 +1124,7 @@ optional\. Lines which start with a \fB#\fP or are blank, will be ignored\.
|
||||
.SS SEE ALSO
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
npm help semver
|
||||
semver \fIhttps://github\.com/npm/node\-semver#versions\fR
|
||||
.IP \(bu 2
|
||||
npm help workspaces
|
||||
.IP \(bu 2
|
||||
|
||||
Vendored
+82
@@ -498,6 +498,88 @@ only report what it would have done\. This can be passed into any of the
|
||||
commands that modify your local installation, eg, \fBinstall\fP, \fBupdate\fP,
|
||||
\fBdedupe\fP, \fBuninstall\fP\|\. This is NOT currently honored by some network related
|
||||
commands, eg \fBdist\-tags\fP, \fBowner\fP, etc\.
|
||||
.SS diff
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: null
|
||||
.IP \(bu 2
|
||||
Type: String, Array, null
|
||||
|
||||
.RE
|
||||
.P
|
||||
Define arguments to compare in \fBnpm diff\fP\|\.
|
||||
.SS diff\-name\-only
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
|
||||
.RE
|
||||
.P
|
||||
Prints only filenames when using \fBnpm diff\fP\|\.
|
||||
.SS diff\-unified
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: number
|
||||
.IP \(bu 2
|
||||
Default: \fB3\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
The number of lines of context to print in \fBnpm diff\fP\|\.
|
||||
.SS diff\-ignore\-all\-space
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Ignore whitespace when comparing lines in `npm diff\.
|
||||
.SS diff\-no\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Do not show any source or destination prefix in \fBnpm diff\fP output\.
|
||||
.SS diff\-src\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fB"a/"\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
Source prefix to be used in \fBnpm diff\fP output\.
|
||||
.SS diff\-dst\-prefix
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Type: String
|
||||
.IP \(bu 2
|
||||
Default: \fB"b/"\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
Destination prefix to be used in \fBnpm diff\fP output\.
|
||||
.SS diff\-text
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
Alias: \fB\-a\fP
|
||||
.IP \(bu 2
|
||||
Type: Boolean
|
||||
.IP \(bu 2
|
||||
Default: false
|
||||
|
||||
.RE
|
||||
.P
|
||||
Treat all files as text in \fBnpm diff\fP\|\.
|
||||
.SS editor
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
|
||||
Vendored
-149
@@ -1,149 +0,0 @@
|
||||
.TH "DISPUTES" "7" "January 2021" "" ""
|
||||
.SH "NAME"
|
||||
\fBdisputes\fR \- Handling Module Name Disputes
|
||||
.P
|
||||
This document describes the steps that you should take to resolve module name
|
||||
disputes with other npm publishers\. It also describes special steps you should
|
||||
take about names you think infringe your trademarks\.
|
||||
.P
|
||||
This document is a clarification of the acceptable behavior outlined in the
|
||||
npm Code of Conduct \fIhttps://www\.npmjs\.com/policies/conduct\fR, and nothing in
|
||||
this document should be interpreted to contradict any aspect of the npm Code of
|
||||
Conduct\.
|
||||
.SS TL;DR
|
||||
.RS 0
|
||||
.IP 1. 3
|
||||
Get the author email with \fBnpm owner ls <pkgname>\fP
|
||||
.IP 2. 3
|
||||
Email the author, CC support@npmjs\.com
|
||||
.IP 3. 3
|
||||
After a few weeks, if there's no resolution, we'll sort it out\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
Don't squat on package names\. Publish code or move out of the way\.
|
||||
.SS Description
|
||||
.P
|
||||
There sometimes arise cases where a user publishes a module, and then later,
|
||||
some other user wants to use that name\. Here are some common ways that happens
|
||||
(each of these is based on actual events\.)
|
||||
.RS 0
|
||||
.IP 1. 3
|
||||
Alice writes a JavaScript module \fBfoo\fP, which is not node\-specific\. Alice
|
||||
doesn't use node at all\. Yusuf wants to use \fBfoo\fP in node, so he wraps it in
|
||||
an npm module\. Some time later, Alice starts using node, and wants to take
|
||||
over management of her program\.
|
||||
.IP 2. 3
|
||||
Yusuf writes an npm module \fBfoo\fP, and publishes it\. Perhaps much later, Alice
|
||||
finds a bug in \fBfoo\fP, and fixes it\. She sends a pull request to Yusuf, but
|
||||
Yusuf doesn't have the time to deal with it, because he has a new job and a
|
||||
new baby and is focused on his new Erlang project, and kind of not involved
|
||||
with node any more\. Alice would like to publish a new \fBfoo\fP, but can't,
|
||||
because the name is taken\.
|
||||
.IP 3. 3
|
||||
Yusuf writes a 10\-line flow\-control library, and calls it \fBfoo\fP, and
|
||||
publishes it to the npm registry\. Being a simple little thing, it never
|
||||
really has to be updated\. Alice works for Foo Inc, the makers of the
|
||||
critically acclaimed and widely\-marketed \fBfoo\fP JavaScript toolkit framework\.
|
||||
They publish it to npm as \fBfoojs\fP, but people are routinely confused when
|
||||
\fBnpm install foo\fP is some different thing\.
|
||||
.IP 4. 3
|
||||
Yusuf writes a parser for the widely\-known \fBfoo\fP file format, because he
|
||||
needs it for work\. Then, he gets a new job, and never updates the prototype\.
|
||||
Later on, Alice writes a much more complete \fBfoo\fP parser, but can't publish,
|
||||
because Yusuf's \fBfoo\fP is in the way\.
|
||||
.IP 5. 3
|
||||
\fBnpm owner ls foo\fP\|\. This will tell Alice the email address of the owner
|
||||
(Yusuf)\.
|
||||
.IP 6. 3
|
||||
Alice emails Yusuf, explaining the situation \fBas respectfully as possible\fR,
|
||||
and what she would like to do with the module name\. She adds the npm support
|
||||
staff support@npmjs\.com to the CC list of the email\. Mention in the email
|
||||
that Yusuf can run npm owner \fBadd alice foo\fP to add Alice as an owner of the
|
||||
foo package\.
|
||||
.IP 7. 3
|
||||
After a reasonable amount of time, if Yusuf has not responded, or if Yusuf
|
||||
and Alice can't come to any sort of resolution, email support
|
||||
support@npmjs\.com and we'll sort it out\. ("Reasonable" is usually at least
|
||||
4 weeks\.)
|
||||
|
||||
.RE
|
||||
.SS Reasoning
|
||||
.P
|
||||
In almost every case so far, the parties involved have been able to reach an
|
||||
amicable resolution without any major intervention\. Most people really do want
|
||||
to be reasonable, and are probably not even aware that they're in your way\.
|
||||
.P
|
||||
Module ecosystems are most vibrant and powerful when they are as self\-directed
|
||||
as possible\. If an admin one day deletes something you had worked on, then that
|
||||
is going to make most people quite upset, regardless of the justification\. When
|
||||
humans solve their problems by talking to other humans with respect, everyone
|
||||
has the chance to end up feeling good about the interaction\.
|
||||
.SS Exceptions
|
||||
.P
|
||||
Some things are not allowed, and will be removed without discussion if they are
|
||||
brought to the attention of the npm registry admins, including but not limited
|
||||
to:
|
||||
.RS 0
|
||||
.IP 1. 3
|
||||
Malware (that is, a package designed to exploit or harm the machine on which
|
||||
it is installed)\.
|
||||
.IP 2. 3
|
||||
Violations of copyright or licenses (for example, cloning an MIT\-licensed
|
||||
program, and then removing or changing the copyright and license statement)\.
|
||||
.IP 3. 3
|
||||
Illegal content\.
|
||||
.IP 4. 3
|
||||
"Squatting" on a package name that you plan to use, but aren't actually
|
||||
using\. Sorry, I don't care how great the name is, or how perfect a fit it is
|
||||
for the thing that someday might happen\. If someone wants to use it today,
|
||||
and you're just taking up space with an empty tarball, you're going to be
|
||||
evicted\.
|
||||
.IP 5. 3
|
||||
Putting empty packages in the registry\. Packages must have SOME
|
||||
functionality\. It can be silly, but it can't be nothing\. (See also:
|
||||
squatting\.)
|
||||
.IP 6. 3
|
||||
Doing weird things with the registry, like using it as your own personal
|
||||
application database or otherwise putting non\-packagey things into it\.
|
||||
.IP 7. 3
|
||||
Other things forbidden by the npm
|
||||
Code of Conduct \fIhttps://www\.npmjs\.com/policies/conduct\fR such as hateful
|
||||
language, pornographic content, or harassment\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
If you see bad behavior like this, please report it to abuse@npmjs\.com right
|
||||
away\. \fBYou are never expected to resolve abusive behavior on your own\. We are
|
||||
here to help\.\fR
|
||||
.SS Trademarks
|
||||
.P
|
||||
If you think another npm publisher is infringing your trademark, such as by
|
||||
using a confusingly similar package name, email abuse@npmjs\.com with a link to
|
||||
the package or user account on https://www\.npmjs\.com/ \fIhttps://www\.npmjs\.com/\fR\|\.
|
||||
Attach a copy of your trademark registration certificate\.
|
||||
.P
|
||||
If we see that the package's publisher is intentionally misleading others by
|
||||
misusing your registered mark without permission, we will transfer the package
|
||||
name to you\. Otherwise, we will contact the package publisher and ask them to
|
||||
clear up any confusion with changes to their package's \fBREADME\fP file or
|
||||
metadata\.
|
||||
.SS Changes
|
||||
.P
|
||||
This is a living document and may be updated from time to time\. Please refer to
|
||||
the git history for this document \fIhttps://github\.com/npm/cli/commits/latest/doc/misc/npm\-disputes\.md\fR
|
||||
to view the changes\.
|
||||
.SS License
|
||||
.P
|
||||
Copyright (C) npm, Inc\., All rights reserved
|
||||
.P
|
||||
This document may be reused under a Creative Commons Attribution\-ShareAlike
|
||||
License\.
|
||||
.SS See also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
npm help registry
|
||||
.IP \(bu 2
|
||||
npm help owner
|
||||
|
||||
.RE
|
||||
Vendored
+7
-34
@@ -7,7 +7,7 @@ To resolve packages by name and version, npm talks to a registry website
|
||||
that implements the CommonJS Package Registry specification for reading
|
||||
package info\.
|
||||
.P
|
||||
npm is configured to use npm, Inc\.'s public registry at
|
||||
npm is configured to use the \fBnpm public registry\fR at
|
||||
https://registry\.npmjs\.org by default\. Use of the npm public registry is
|
||||
subject to terms of use available at https://www\.npmjs\.com/policies/terms\|\.
|
||||
.P
|
||||
@@ -20,9 +20,7 @@ write APIs as well, to allow for publishing packages and managing user
|
||||
account information\.
|
||||
.P
|
||||
The npm public registry is powered by a CouchDB database,
|
||||
of which there is a public mirror at
|
||||
https://skimdb\.npmjs\.com/registry\|\. The code for the couchapp is
|
||||
available at https://github\.com/npm/npm\-registry\-couchapp\|\.
|
||||
of which there is a public mirror at https://skimdb\.npmjs\.com/registry\|\.
|
||||
.P
|
||||
The registry URL used is determined by the scope of the package (see
|
||||
npm help \fBscope\fP\|\. If no scope is specified, the default registry is used, which is
|
||||
@@ -54,40 +52,17 @@ build farms\.
|
||||
.P
|
||||
The npm registry does not try to correlate the information in these headers
|
||||
with any authenticated accounts that may be used in the same requests\.
|
||||
.SS Can I run my own private registry?
|
||||
.SS How can I prevent my package from being published in the official registry?
|
||||
.P
|
||||
Yes!
|
||||
.P
|
||||
The easiest way is to replicate the couch database, and use the same (or
|
||||
similar) design doc to implement the APIs\.
|
||||
.P
|
||||
If you set up continuous replication from the official CouchDB, and then
|
||||
set your internal CouchDB as the registry config, then you'll be able
|
||||
to read any published packages, in addition to your private ones, and by
|
||||
default will only publish internally\.
|
||||
.P
|
||||
If you then want to publish a package for the whole world to see, you can
|
||||
simply override the \fB\-\-registry\fP option for that \fBpublish\fP command\.
|
||||
.SS I don't want my package published in the official registry\. It's private\.
|
||||
.P
|
||||
Set \fB"private": true\fP in your package\.json to prevent it from being
|
||||
Set \fB"private": true\fP in your \fBpackage\.json\fP to prevent it from being
|
||||
published at all, or
|
||||
\fB"publishConfig":{"registry":"http://my\-internal\-registry\.local"}\fP
|
||||
to force it to be published only to your internal registry\.
|
||||
to force it to be published only to your internal/private registry\.
|
||||
.P
|
||||
See npm help \fBpackage\.json\fP for more info on what goes in the package\.json file\.
|
||||
.SS Will you replicate from my registry into the public one?
|
||||
.SS Where can I find my own, & other's, published packages?
|
||||
.P
|
||||
No\. If you want things to be public, then publish them into the public
|
||||
registry using npm\. What little security there is would be for nought
|
||||
otherwise\.
|
||||
.SS Do I have to use couchdb to build a registry that npm can talk to?
|
||||
.P
|
||||
No, but it's way easier\. Basically, yes, you do, or you have to
|
||||
effectively implement the entire CouchDB API anyway\.
|
||||
.SS Is there a website or something to see package docs and such?
|
||||
.P
|
||||
Yes, head over to https://www\.npmjs\.com/
|
||||
https://www\.npmjs\.com/
|
||||
.SS See also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
@@ -98,7 +73,5 @@ npm help config
|
||||
npm help npmrc
|
||||
.IP \(bu 2
|
||||
npm help developers
|
||||
.IP \(bu 2
|
||||
npm help disputes
|
||||
|
||||
.RE
|
||||
Vendored
-2
@@ -63,8 +63,6 @@ modules\. To track those down, you can do the following:
|
||||
find /usr/local/{lib/node,bin} \-exec grep \-l npm \\{\\} \\; ;
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
(This is also in the README file\.)
|
||||
.SS See also
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
|
||||
Vendored
-510
@@ -1,510 +0,0 @@
|
||||
.TH "SEMVER" "7" "January 2021" "" ""
|
||||
.SH "NAME"
|
||||
\fBsemver\fR \- The semantic versioner for npm
|
||||
.SH Install
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm install \-\-save semver
|
||||
.fi
|
||||
.RE
|
||||
.SH Usage
|
||||
.P
|
||||
As a node module:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
const semver = require('semver')
|
||||
|
||||
semver\.valid('1\.2\.3') // '1\.2\.3'
|
||||
semver\.valid('a\.b\.c') // null
|
||||
semver\.clean(' =v1\.2\.3 ') // '1\.2\.3'
|
||||
semver\.satisfies('1\.2\.3', '1\.x || >=2\.5\.0 || 5\.0\.0 \- 7\.2\.3') // true
|
||||
semver\.gt('1\.2\.3', '9\.8\.7') // false
|
||||
semver\.lt('1\.2\.3', '9\.8\.7') // true
|
||||
semver\.minVersion('>=1\.0\.0') // '1\.0\.0'
|
||||
semver\.valid(semver\.coerce('v2')) // '2\.0\.0'
|
||||
semver\.valid(semver\.coerce('42\.6\.7\.9\.3\-alpha')) // '42\.6\.7'
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
As a command\-line utility:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
$ semver \-h
|
||||
|
||||
A JavaScript implementation of the https://semver\.org/ specification
|
||||
Copyright Isaac Z\. Schlueter
|
||||
|
||||
Usage: semver [options] <version> [<version> [\.\.\.]]
|
||||
Prints valid versions sorted by SemVer precedence
|
||||
|
||||
Options:
|
||||
\-r \-\-range <range>
|
||||
Print versions that match the specified range\.
|
||||
|
||||
\-i \-\-increment [<level>]
|
||||
Increment a version by the specified level\. Level can
|
||||
be one of: major, minor, patch, premajor, preminor,
|
||||
prepatch, or prerelease\. Default level is 'patch'\.
|
||||
Only one version may be specified\.
|
||||
|
||||
\-\-preid <identifier>
|
||||
Identifier to be used to prefix premajor, preminor,
|
||||
prepatch or prerelease version increments\.
|
||||
|
||||
\-l \-\-loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
\-p \-\-include\-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
\-c \-\-coerce
|
||||
Coerce a string into SemVer if possible
|
||||
(does not imply \-\-loose)
|
||||
|
||||
Program exits successfully if any valid version satisfies
|
||||
all supplied ranges, and prints all satisfying versions\.
|
||||
|
||||
If no satisfying versions are found, then exits failure\.
|
||||
|
||||
Versions are printed in ascending order, so supplying
|
||||
multiple versions to the utility will just sort them\.
|
||||
.fi
|
||||
.RE
|
||||
.SH Versions
|
||||
.P
|
||||
A "version" is described by the \fBv2\.0\.0\fP specification found at
|
||||
https://semver\.org/\|\.
|
||||
.P
|
||||
A leading \fB"="\fP or \fB"v"\fP character is stripped off and ignored\.
|
||||
.SH Ranges
|
||||
.P
|
||||
A \fBversion range\fP is a set of \fBcomparators\fP which specify versions
|
||||
that satisfy the range\.
|
||||
.P
|
||||
A \fBcomparator\fP is composed of an \fBoperator\fP and a \fBversion\fP\|\. The set
|
||||
of primitive \fBoperators\fP is:
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB<\fP Less than
|
||||
.IP \(bu 2
|
||||
\fB<=\fP Less than or equal to
|
||||
.IP \(bu 2
|
||||
\fB>\fP Greater than
|
||||
.IP \(bu 2
|
||||
\fB>=\fP Greater than or equal to
|
||||
.IP \(bu 2
|
||||
\fB=\fP Equal\. If no operator is specified, then equality is assumed,
|
||||
so this operator is optional, but MAY be included\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
For example, the comparator \fB>=1\.2\.7\fP would match the versions
|
||||
\fB1\.2\.7\fP, \fB1\.2\.8\fP, \fB2\.5\.3\fP, and \fB1\.3\.9\fP, but not the versions \fB1\.2\.6\fP
|
||||
or \fB1\.1\.0\fP\|\.
|
||||
.P
|
||||
Comparators can be joined by whitespace to form a \fBcomparator set\fP,
|
||||
which is satisfied by the \fBintersection\fR of all of the comparators
|
||||
it includes\.
|
||||
.P
|
||||
A range is composed of one or more comparator sets, joined by \fB||\fP\|\. A
|
||||
version matches a range if and only if every comparator in at least
|
||||
one of the \fB||\fP\-separated comparator sets is satisfied by the version\.
|
||||
.P
|
||||
For example, the range \fB>=1\.2\.7 <1\.3\.0\fP would match the versions
|
||||
\fB1\.2\.7\fP, \fB1\.2\.8\fP, and \fB1\.2\.99\fP, but not the versions \fB1\.2\.6\fP, \fB1\.3\.0\fP,
|
||||
or \fB1\.1\.0\fP\|\.
|
||||
.P
|
||||
The range \fB1\.2\.7 || >=1\.2\.9 <2\.0\.0\fP would match the versions \fB1\.2\.7\fP,
|
||||
\fB1\.2\.9\fP, and \fB1\.4\.6\fP, but not the versions \fB1\.2\.8\fP or \fB2\.0\.0\fP\|\.
|
||||
.SS Prerelease Tags
|
||||
.P
|
||||
If a version has a prerelease tag (for example, \fB1\.2\.3\-alpha\.3\fP) then
|
||||
it will only be allowed to satisfy comparator sets if at least one
|
||||
comparator with the same \fB[major, minor, patch]\fP tuple also has a
|
||||
prerelease tag\.
|
||||
.P
|
||||
For example, the range \fB>1\.2\.3\-alpha\.3\fP would be allowed to match the
|
||||
version \fB1\.2\.3\-alpha\.7\fP, but it would \fInot\fR be satisfied by
|
||||
\fB3\.4\.5\-alpha\.9\fP, even though \fB3\.4\.5\-alpha\.9\fP is technically "greater
|
||||
than" \fB1\.2\.3\-alpha\.3\fP according to the SemVer sort rules\. The version
|
||||
range only accepts prerelease tags on the \fB1\.2\.3\fP version\. The
|
||||
version \fB3\.4\.5\fP \fIwould\fR satisfy the range, because it does not have a
|
||||
prerelease flag, and \fB3\.4\.5\fP is greater than \fB1\.2\.3\-alpha\.7\fP\|\.
|
||||
.P
|
||||
The purpose for this behavior is twofold\. First, prerelease versions
|
||||
frequently are updated very quickly, and contain many breaking changes
|
||||
that are (by the author's design) not yet fit for public consumption\.
|
||||
Therefore, by default, they are excluded from range matching
|
||||
semantics\.
|
||||
.P
|
||||
Second, a user who has opted into using a prerelease version has
|
||||
clearly indicated the intent to use \fIthat specific\fR set of
|
||||
alpha/beta/rc versions\. By including a prerelease tag in the range,
|
||||
the user is indicating that they are aware of the risk\. However, it
|
||||
is still not appropriate to assume that they have opted into taking a
|
||||
similar risk on the \fInext\fR set of prerelease versions\.
|
||||
.P
|
||||
Note that this behavior can be suppressed (treating all prerelease
|
||||
versions as if they were normal versions, for the purpose of range
|
||||
matching) by setting the \fBincludePrerelease\fP flag on the options
|
||||
object to any
|
||||
functions \fIhttps://github\.com/npm/node\-semver#functions\fR that do
|
||||
range matching\.
|
||||
.SS Prerelease Identifiers
|
||||
.P
|
||||
The method \fB\|\.inc\fP takes an additional \fBidentifier\fP string argument that
|
||||
will append the value of the string as a prerelease identifier:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
semver\.inc('1\.2\.3', 'prerelease', 'beta')
|
||||
// '1\.2\.4\-beta\.0'
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
command\-line example:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
$ semver 1\.2\.3 \-i prerelease \-\-preid beta
|
||||
1\.2\.4\-beta\.0
|
||||
.fi
|
||||
.RE
|
||||
.P
|
||||
Which then can be used to increment further:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
$ semver 1\.2\.4\-beta\.0 \-i prerelease
|
||||
1\.2\.4\-beta\.1
|
||||
.fi
|
||||
.RE
|
||||
.SS Advanced Range Syntax
|
||||
.P
|
||||
Advanced range syntax desugars to primitive comparators in
|
||||
deterministic ways\.
|
||||
.P
|
||||
Advanced ranges may be combined in the same way as primitive
|
||||
comparators using white space or \fB||\fP\|\.
|
||||
.SS Hyphen Ranges \fBX\.Y\.Z \- A\.B\.C\fP
|
||||
.P
|
||||
Specifies an inclusive set\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB1\.2\.3 \- 2\.3\.4\fP := \fB>=1\.2\.3 <=2\.3\.4\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
If a partial version is provided as the first version in the inclusive
|
||||
range, then the missing pieces are replaced with zeroes\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB1\.2 \- 2\.3\.4\fP := \fB>=1\.2\.0 <=2\.3\.4\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
If a partial version is provided as the second version in the
|
||||
inclusive range, then all versions that start with the supplied parts
|
||||
of the tuple are accepted, but nothing that would be greater than the
|
||||
provided tuple parts\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB1\.2\.3 \- 2\.3\fP := \fB>=1\.2\.3 <2\.4\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB1\.2\.3 \- 2\fP := \fB>=1\.2\.3 <3\.0\.0\fP
|
||||
|
||||
.RE
|
||||
.SS X\-Ranges \fB1\.2\.x\fP \fB1\.X\fP \fB1\.2\.*\fP \fB*\fP
|
||||
.P
|
||||
Any of \fBX\fP, \fBx\fP, or \fB*\fP may be used to "stand in" for one of the
|
||||
numeric values in the \fB[major, minor, patch]\fP tuple\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB*\fP := \fB>=0\.0\.0\fP (Any version satisfies)
|
||||
.IP \(bu 2
|
||||
\fB1\.x\fP := \fB>=1\.0\.0 <2\.0\.0\fP (Matching major version)
|
||||
.IP \(bu 2
|
||||
\fB1\.2\.x\fP := \fB>=1\.2\.0 <1\.3\.0\fP (Matching major and minor versions)
|
||||
|
||||
.RE
|
||||
.P
|
||||
A partial version range is treated as an X\-Range, so the special
|
||||
character is in fact optional\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB""\fP (empty string) := \fB*\fP := \fB>=0\.0\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB1\fP := \fB1\.x\.x\fP := \fB>=1\.0\.0 <2\.0\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB1\.2\fP := \fB1\.2\.x\fP := \fB>=1\.2\.0 <1\.3\.0\fP
|
||||
|
||||
.RE
|
||||
.SS Tilde Ranges \fB~1\.2\.3\fP \fB~1\.2\fP \fB~1\fP
|
||||
.P
|
||||
Allows patch\-level changes if a minor version is specified on the
|
||||
comparator\. Allows minor\-level changes if not\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB~1\.2\.3\fP := \fB>=1\.2\.3 <1\.(2+1)\.0\fP := \fB>=1\.2\.3 <1\.3\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB~1\.2\fP := \fB>=1\.2\.0 <1\.(2+1)\.0\fP := \fB>=1\.2\.0 <1\.3\.0\fP (Same as \fB1\.2\.x\fP)
|
||||
.IP \(bu 2
|
||||
\fB~1\fP := \fB>=1\.0\.0 <(1+1)\.0\.0\fP := \fB>=1\.0\.0 <2\.0\.0\fP (Same as \fB1\.x\fP)
|
||||
.IP \(bu 2
|
||||
\fB~0\.2\.3\fP := \fB>=0\.2\.3 <0\.(2+1)\.0\fP := \fB>=0\.2\.3 <0\.3\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB~0\.2\fP := \fB>=0\.2\.0 <0\.(2+1)\.0\fP := \fB>=0\.2\.0 <0\.3\.0\fP (Same as \fB0\.2\.x\fP)
|
||||
.IP \(bu 2
|
||||
\fB~0\fP := \fB>=0\.0\.0 <(0+1)\.0\.0\fP := \fB>=0\.0\.0 <1\.0\.0\fP (Same as \fB0\.x\fP)
|
||||
.IP \(bu 2
|
||||
\fB~1\.2\.3\-beta\.2\fP := \fB>=1\.2\.3\-beta\.2 <1\.3\.0\fP Note that prereleases in
|
||||
the \fB1\.2\.3\fP version will be allowed, if they are greater than or
|
||||
equal to \fBbeta\.2\fP\|\. So, \fB1\.2\.3\-beta\.4\fP would be allowed, but
|
||||
\fB1\.2\.4\-beta\.2\fP would not, because it is a prerelease of a
|
||||
different \fB[major, minor, patch]\fP tuple\.
|
||||
|
||||
.RE
|
||||
.SS Caret Ranges \fB^1\.2\.3\fP \fB^0\.2\.5\fP \fB^0\.0\.4\fP
|
||||
.P
|
||||
Allows changes that do not modify the left\-most non\-zero digit in the
|
||||
\fB[major, minor, patch]\fP tuple\. In other words, this allows patch and
|
||||
minor updates for versions \fB1\.0\.0\fP and above, patch updates for
|
||||
versions \fB0\.X >=0\.1\.0\fP, and \fIno\fR updates for versions \fB0\.0\.X\fP\|\.
|
||||
.P
|
||||
Many authors treat a \fB0\.x\fP version as if the \fBx\fP were the major
|
||||
"breaking\-change" indicator\.
|
||||
.P
|
||||
Caret ranges are ideal when an author may make breaking changes
|
||||
between \fB0\.2\.4\fP and \fB0\.3\.0\fP releases, which is a common practice\.
|
||||
However, it presumes that there will \fInot\fR be breaking changes between
|
||||
\fB0\.2\.4\fP and \fB0\.2\.5\fP\|\. It allows for changes that are presumed to be
|
||||
additive (but non\-breaking), according to commonly observed practices\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB^1\.2\.3\fP := \fB>=1\.2\.3 <2\.0\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB^0\.2\.3\fP := \fB>=0\.2\.3 <0\.3\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB^0\.0\.3\fP := \fB>=0\.0\.3 <0\.0\.4\fP
|
||||
.IP \(bu 2
|
||||
\fB^1\.2\.3\-beta\.2\fP := \fB>=1\.2\.3\-beta\.2 <2\.0\.0\fP Note that prereleases in
|
||||
the \fB1\.2\.3\fP version will be allowed, if they are greater than or
|
||||
equal to \fBbeta\.2\fP\|\. So, \fB1\.2\.3\-beta\.4\fP would be allowed, but
|
||||
\fB1\.2\.4\-beta\.2\fP would not, because it is a prerelease of a
|
||||
different \fB[major, minor, patch]\fP tuple\.
|
||||
.IP \(bu 2
|
||||
\fB^0\.0\.3\-beta\fP := \fB>=0\.0\.3\-beta <0\.0\.4\fP Note that prereleases in the
|
||||
\fB0\.0\.3\fP version \fIonly\fR will be allowed, if they are greater than or
|
||||
equal to \fBbeta\fP\|\. So, \fB0\.0\.3\-pr\.2\fP would be allowed\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
When parsing caret ranges, a missing \fBpatch\fP value desugars to the
|
||||
number \fB0\fP, but will allow flexibility within that value, even if the
|
||||
major and minor versions are both \fB0\fP\|\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB^1\.2\.x\fP := \fB>=1\.2\.0 <2\.0\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB^0\.0\.x\fP := \fB>=0\.0\.0 <0\.1\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB^0\.0\fP := \fB>=0\.0\.0 <0\.1\.0\fP
|
||||
|
||||
.RE
|
||||
.P
|
||||
A missing \fBminor\fP and \fBpatch\fP values will desugar to zero, but also
|
||||
allow flexibility within those values, even if the major version is
|
||||
zero\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fB^1\.x\fP := \fB>=1\.0\.0 <2\.0\.0\fP
|
||||
.IP \(bu 2
|
||||
\fB^0\.x\fP := \fB>=0\.0\.0 <1\.0\.0\fP
|
||||
|
||||
.RE
|
||||
.SS Range Grammar
|
||||
.P
|
||||
Putting all this together, here is a Backus\-Naur grammar for ranges,
|
||||
for the benefit of parser authors:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
range\-set ::= range ( logical\-or range ) *
|
||||
logical\-or ::= ( ' ' ) * '||' ( ' ' ) *
|
||||
range ::= hyphen | simple ( ' ' simple ) * | ''
|
||||
hyphen ::= partial ' \- ' partial
|
||||
simple ::= primitive | partial | tilde | caret
|
||||
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
|
||||
partial ::= xr ( '\.' xr ( '\.' xr qualifier ? )? )?
|
||||
xr ::= 'x' | 'X' | '*' | nr
|
||||
nr ::= '0' | ['1'\-'9'] ( ['0'\-'9'] ) *
|
||||
tilde ::= '~' partial
|
||||
caret ::= '^' partial
|
||||
qualifier ::= ( '\-' pre )? ( '+' build )?
|
||||
pre ::= parts
|
||||
build ::= parts
|
||||
parts ::= part ( '\.' part ) *
|
||||
part ::= nr | [\-0\-9A\-Za\-z]+
|
||||
.fi
|
||||
.RE
|
||||
.SH Functions
|
||||
.P
|
||||
All methods and classes take a final \fBoptions\fP object argument\. All
|
||||
options in this object are \fBfalse\fP by default\. The options supported
|
||||
are:
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBloose\fP Be more forgiving about not\-quite\-valid semver strings\.
|
||||
(Any resulting output will always be 100% strict compliant, of
|
||||
course\.) For backwards compatibility reasons, if the \fBoptions\fP
|
||||
argument is a boolean value instead of an object, it is interpreted
|
||||
to be the \fBloose\fP param\.
|
||||
.IP \(bu 2
|
||||
\fBincludePrerelease\fP Set to suppress the default
|
||||
behavior \fIhttps://github\.com/npm/node\-semver#prerelease\-tags\fR of
|
||||
excluding prerelease tagged versions from ranges unless they are
|
||||
explicitly opted into\.
|
||||
|
||||
.RE
|
||||
.P
|
||||
Strict\-mode Comparators and Ranges will be strict about the SemVer
|
||||
strings that they parse\.
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBvalid(v)\fP: Return the parsed version, or null if it's not valid\.
|
||||
.IP \(bu 2
|
||||
\fBinc(v, release)\fP: Return the version incremented by the release
|
||||
type (\fBmajor\fP, \fBpremajor\fP, \fBminor\fP, \fBpreminor\fP, \fBpatch\fP,
|
||||
\fBprepatch\fP, or \fBprerelease\fP), or null if it's not valid
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fBpremajor\fP in one call will bump the version up to the next major
|
||||
version and down to a prerelease of that major version\.
|
||||
\fBpreminor\fP, and \fBprepatch\fP work the same way\.
|
||||
.IP \(bu 2
|
||||
If called from a non\-prerelease version, the \fBprerelease\fP will work the
|
||||
same as \fBprepatch\fP\|\. It increments the patch version, then makes a
|
||||
prerelease\. If the input version is already a prerelease it simply
|
||||
increments it\.
|
||||
|
||||
.RE
|
||||
.IP \(bu 2
|
||||
\fBprerelease(v)\fP: Returns an array of prerelease components, or null
|
||||
if none exist\. Example: \fBprerelease('1\.2\.3\-alpha\.1') \-> ['alpha', 1]\fP
|
||||
.IP \(bu 2
|
||||
\fBmajor(v)\fP: Return the major version number\.
|
||||
.IP \(bu 2
|
||||
\fBminor(v)\fP: Return the minor version number\.
|
||||
.IP \(bu 2
|
||||
\fBpatch(v)\fP: Return the patch version number\.
|
||||
.IP \(bu 2
|
||||
\fBintersects(r1, r2, loose)\fP: Return true if the two supplied ranges
|
||||
or comparators intersect\.
|
||||
.IP \(bu 2
|
||||
\fBparse(v)\fP: Attempt to parse a string as a semantic version, returning either
|
||||
a \fBSemVer\fP object or \fBnull\fP\|\.
|
||||
|
||||
.RE
|
||||
.SS Comparison
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBgt(v1, v2)\fP: \fBv1 > v2\fP
|
||||
.IP \(bu 2
|
||||
\fBgte(v1, v2)\fP: \fBv1 >= v2\fP
|
||||
.IP \(bu 2
|
||||
\fBlt(v1, v2)\fP: \fBv1 < v2\fP
|
||||
.IP \(bu 2
|
||||
\fBlte(v1, v2)\fP: \fBv1 <= v2\fP
|
||||
.IP \(bu 2
|
||||
\fBeq(v1, v2)\fP: \fBv1 == v2\fP This is true if they're logically equivalent,
|
||||
even if they're not the exact same string\. You already know how to
|
||||
compare strings\.
|
||||
.IP \(bu 2
|
||||
\fBneq(v1, v2)\fP: \fBv1 != v2\fP The opposite of \fBeq\fP\|\.
|
||||
.IP \(bu 2
|
||||
\fBcmp(v1, comparator, v2)\fP: Pass in a comparison string, and it'll call
|
||||
the corresponding function above\. \fB"==="\fP and \fB"!=="\fP do simple
|
||||
string comparison, but are included for completeness\. Throws if an
|
||||
invalid comparison string is provided\.
|
||||
.IP \(bu 2
|
||||
\fBcompare(v1, v2)\fP: Return \fB0\fP if \fBv1 == v2\fP, or \fB1\fP if \fBv1\fP is greater, or \fB\-1\fP if
|
||||
\fBv2\fP is greater\. Sorts in ascending order if passed to \fBArray\.sort()\fP\|\.
|
||||
.IP \(bu 2
|
||||
\fBrcompare(v1, v2)\fP: The reverse of compare\. Sorts an array of versions
|
||||
in descending order when passed to \fBArray\.sort()\fP\|\.
|
||||
.IP \(bu 2
|
||||
\fBdiff(v1, v2)\fP: Returns difference between two versions by the release type
|
||||
(\fBmajor\fP, \fBpremajor\fP, \fBminor\fP, \fBpreminor\fP, \fBpatch\fP, \fBprepatch\fP, or \fBprerelease\fP),
|
||||
or null if the versions are the same\.
|
||||
|
||||
.RE
|
||||
.SS Comparators
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBintersects(comparator)\fP: Return true if the comparators intersect
|
||||
|
||||
.RE
|
||||
.SS Ranges
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBvalidRange(range)\fP: Return the valid range or null if it's not valid
|
||||
.IP \(bu 2
|
||||
\fBsatisfies(version, range)\fP: Return true if the version satisfies the
|
||||
range\.
|
||||
.IP \(bu 2
|
||||
\fBmaxSatisfying(versions, range)\fP: Return the highest version in the list
|
||||
that satisfies the range, or \fBnull\fP if none of them do\.
|
||||
.IP \(bu 2
|
||||
\fBminSatisfying(versions, range)\fP: Return the lowest version in the list
|
||||
that satisfies the range, or \fBnull\fP if none of them do\.
|
||||
.IP \(bu 2
|
||||
\fBminVersion(range)\fP: Return the lowest version that can possibly match
|
||||
the given range\.
|
||||
.IP \(bu 2
|
||||
\fBgtr(version, range)\fP: Return \fBtrue\fP if version is greater than all the
|
||||
versions possible in the range\.
|
||||
.IP \(bu 2
|
||||
\fBltr(version, range)\fP: Return \fBtrue\fP if version is less than all the
|
||||
versions possible in the range\.
|
||||
.IP \(bu 2
|
||||
\fBoutside(version, range, hilo)\fP: Return true if the version is outside
|
||||
the bounds of the range in either the high or low direction\. The
|
||||
\fBhilo\fP argument must be either the string \fB\|'>'\fP or \fB\|'<'\fP\|\. (This is
|
||||
the function called by \fBgtr\fP and \fBltr\fP\|\.)
|
||||
.IP \(bu 2
|
||||
\fBintersects(range)\fP: Return true if any of the ranges comparators intersect
|
||||
|
||||
.RE
|
||||
.P
|
||||
Note that, since ranges may be non\-contiguous, a version might not be
|
||||
greater than a range, less than a range, \fIor\fR satisfy a range! For
|
||||
example, the range \fB1\.2 <1\.2\.9 || >2\.0\.0\fP would have a hole from \fB1\.2\.9\fP
|
||||
until \fB2\.0\.0\fP, so the version \fB1\.2\.10\fP would not be greater than the
|
||||
range (because \fB2\.0\.1\fP satisfies, which is higher), nor less than the
|
||||
range (since \fB1\.2\.8\fP satisfies, which is lower), and it also does not
|
||||
satisfy the range\.
|
||||
.P
|
||||
If you want to know if a version satisfies or does not satisfy a
|
||||
range, use the \fBsatisfies(version, range)\fP function\.
|
||||
.SS Coercion
|
||||
.RS 0
|
||||
.IP \(bu 2
|
||||
\fBcoerce(version)\fP: Coerces a string to semver if possible
|
||||
|
||||
.RE
|
||||
.P
|
||||
This aims to provide a very forgiving translation of a non\-semver string to
|
||||
semver\. It looks for the first digit in a string, and consumes all
|
||||
remaining characters which satisfy at least a partial semver (e\.g\., \fB1\fP,
|
||||
\fB1\.2\fP, \fB1\.2\.3\fP) up to the max permitted length (256 characters)\. Longer
|
||||
versions are simply truncated (\fB4\.6\.3\.9\.2\-alpha2\fP becomes \fB4\.6\.3\fP)\. All
|
||||
surrounding text is simply ignored (\fBv3\.4 replaces v3\.3\.1\fP becomes
|
||||
\fB3\.4\.0\fP)\. Only text which lacks digits will fail coercion (\fBversion one\fP
|
||||
is not valid)\. The maximum length for any semver component considered for
|
||||
coercion is 16 characters; longer components will be ignored
|
||||
(\fB10000000000000000\.4\.7\.4\fP becomes \fB4\.7\.4\fP)\. The maximum value for any
|
||||
semver component is \fBNumber\.MAX_SAFE_INTEGER || (2**53 \- 1)\fP; higher value
|
||||
components are invalid (\fB9999999999999999\.4\.7\.4\fP is likely invalid)\.
|
||||
+106
-51
@@ -314,10 +314,11 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
.then(async root => {
|
||||
if (!this[_updateAll] && !this[_global] && !root.meta.loadedFromDisk) {
|
||||
await new this.constructor(this.options).loadActual({ root })
|
||||
const tree = root.target || root
|
||||
// even though we didn't load it from a package-lock.json FILE,
|
||||
// we still loaded it "from disk", meaning we have to reset
|
||||
// dep flags before assuming that any mutations were reflected.
|
||||
if (root.children.size)
|
||||
if (tree.children.size)
|
||||
root.meta.loadedFromDisk = true
|
||||
}
|
||||
return root
|
||||
@@ -332,20 +333,28 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
})
|
||||
}
|
||||
|
||||
[_globalRootNode] () {
|
||||
const root = this[_rootNodeFromPackage]({ dependencies: {} })
|
||||
async [_globalRootNode] () {
|
||||
const root = await this[_rootNodeFromPackage]({ dependencies: {} })
|
||||
// this is a gross kludge to handle the fact that we don't save
|
||||
// metadata on the root node in global installs, because the "root"
|
||||
// node is something like /usr/local/lib.
|
||||
const meta = new Shrinkwrap({ path: this.path })
|
||||
meta.reset()
|
||||
root.meta = meta
|
||||
return Promise.resolve(root)
|
||||
return root
|
||||
}
|
||||
|
||||
[_rootNodeFromPackage] (pkg) {
|
||||
return new Node({
|
||||
async [_rootNodeFromPackage] (pkg) {
|
||||
// if the path doesn't exist, then we explode at this point. Note that
|
||||
// this is not a problem for reify(), since it creates the root path
|
||||
// before ever loading trees.
|
||||
// TODO: make buildIdealTree() and loadActual handle a missing root path,
|
||||
// or a symlink to a missing target, and let reify() create it as needed.
|
||||
const real = await realpath(this.path, this[_rpcache], this[_stcache])
|
||||
const Cls = real === this.path ? Node : Link
|
||||
const root = new Cls({
|
||||
path: this.path,
|
||||
realpath: real,
|
||||
pkg,
|
||||
extraneous: false,
|
||||
dev: false,
|
||||
@@ -355,12 +364,29 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
global: this[_global],
|
||||
legacyPeerDeps: this.legacyPeerDeps,
|
||||
})
|
||||
if (root.isLink) {
|
||||
root.target = new Node({
|
||||
path: real,
|
||||
realpath: real,
|
||||
pkg,
|
||||
extraneous: false,
|
||||
dev: false,
|
||||
devOptional: false,
|
||||
peer: false,
|
||||
optional: false,
|
||||
global: this[_global],
|
||||
legacyPeerDeps: this.legacyPeerDeps,
|
||||
root,
|
||||
})
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
// process the add/rm requests by modifying the root node, and the
|
||||
// update.names request by queueing nodes dependent on those named.
|
||||
async [_applyUserRequests] (options) {
|
||||
process.emit('time', 'idealTree:userRequests')
|
||||
const tree = this.idealTree.target || this.idealTree
|
||||
// If we have a list of package names to update, and we know it's
|
||||
// going to update them wherever they are, add any paths into those
|
||||
// named nodes to the buildIdealTree queue.
|
||||
@@ -373,7 +399,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
const nm = resolve(this.path, 'node_modules')
|
||||
for (const name of await readdir(nm)) {
|
||||
if (this[_updateAll] || this[_updateNames].includes(name))
|
||||
this.idealTree.package.dependencies[name] = '*'
|
||||
tree.package.dependencies[name] = '*'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +407,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
this[_queueVulnDependents](options)
|
||||
|
||||
if (options.rm && options.rm.length) {
|
||||
addRmPkgDeps.rm(this.idealTree.package, options.rm)
|
||||
addRmPkgDeps.rm(tree.package, options.rm)
|
||||
for (const name of options.rm)
|
||||
this[_explicitRequests].add(name)
|
||||
}
|
||||
@@ -391,7 +417,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
|
||||
// triggers a refresh of all edgesOut
|
||||
if (options.add && options.add.length || options.rm && options.rm.length)
|
||||
this.idealTree.package = this.idealTree.package
|
||||
tree.package = tree.package
|
||||
process.emit('timeEnd', 'idealTree:userRequests')
|
||||
}
|
||||
|
||||
@@ -410,8 +436,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
this[_resolvedAdd] = add
|
||||
// now add is a list of spec objects with names.
|
||||
// find a home for each of them!
|
||||
const tree = this.idealTree.target || this.idealTree
|
||||
addRmPkgDeps.add({
|
||||
pkg: this.idealTree.package,
|
||||
pkg: tree.package,
|
||||
add,
|
||||
saveBundle,
|
||||
saveType,
|
||||
@@ -514,7 +541,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
fixAvailable,
|
||||
} = topVuln
|
||||
for (const node of topNodes) {
|
||||
if (node !== this.idealTree) {
|
||||
if (node !== this.idealTree && node !== this.idealTree.target) {
|
||||
// not something we're going to fix, sorry. have to cd into
|
||||
// that directory and fix it yourself.
|
||||
this.log.warn('audit', 'Manual fix required in linked project ' +
|
||||
@@ -606,7 +633,7 @@ This is a one-time fix-up, please be patient...
|
||||
this.addTracker('idealTree:inflate')
|
||||
const queue = []
|
||||
for (const node of inventory.values()) {
|
||||
if (node.isRoot)
|
||||
if (node.isProjectRoot)
|
||||
continue
|
||||
|
||||
queue.push(async () => {
|
||||
@@ -646,11 +673,12 @@ This is a one-time fix-up, please be patient...
|
||||
// at this point we have a virtual tree with the actual root node's
|
||||
// package deps, which may be partly or entirely incomplete, invalid
|
||||
// or extraneous.
|
||||
[_buildDeps] (node) {
|
||||
[_buildDeps] () {
|
||||
process.emit('time', 'idealTree:buildDeps')
|
||||
this[_depsQueue].push(this.idealTree)
|
||||
const tree = this.idealTree.target || this.idealTree
|
||||
this[_depsQueue].push(tree)
|
||||
this.log.silly('idealTree', 'buildDeps')
|
||||
this.addTracker('idealTree', this.idealTree.name, '')
|
||||
this.addTracker('idealTree', tree.name, '')
|
||||
return this[_buildDepStep]()
|
||||
.then(() => process.emit('timeEnd', 'idealTree:buildDeps'))
|
||||
}
|
||||
@@ -835,7 +863,7 @@ This is a one-time fix-up, please be patient...
|
||||
|
||||
// loads a node from an edge, and then loads its peer deps (and their
|
||||
// peer deps, on down the line) into a virtual root parent.
|
||||
[_nodeFromEdge] (edge, parent_) {
|
||||
async [_nodeFromEdge] (edge, parent_, secondEdge = null) {
|
||||
// create a virtual root node with the same deps as the node that
|
||||
// is requesting this one, so that we can get all the peer deps in
|
||||
// a context where they're likely to be resolvable.
|
||||
@@ -843,22 +871,43 @@ This is a one-time fix-up, please be patient...
|
||||
const realParent = edge.peer ? edge.from.resolveParent : edge.from
|
||||
|
||||
const spec = npa.resolve(edge.name, edge.spec, edge.from.path)
|
||||
return this[_nodeFromSpec](edge.name, spec, parent, edge)
|
||||
.then(node => {
|
||||
// handle otherwise unresolvable dependency nesting loops by
|
||||
// creating a symbolic link
|
||||
// a1 -> b1 -> a2 -> b2 -> a1 -> ...
|
||||
// instead of nesting forever, when the loop occurs, create
|
||||
// a symbolic link to the earlier instance
|
||||
for (let p = edge.from.resolveParent; p; p = p.resolveParent) {
|
||||
if (p.matches(node) && !p.isRoot)
|
||||
return new Link({ parent: realParent, target: p })
|
||||
}
|
||||
// keep track of the thing that caused this node to be included.
|
||||
const src = parent.sourceReference
|
||||
this[_peerSetSource].set(node, src)
|
||||
return this[_loadPeerSet](node)
|
||||
})
|
||||
const first = await this[_nodeFromSpec](edge.name, spec, parent, edge)
|
||||
|
||||
// we might have a case where the parent has a peer dependency on
|
||||
// `foo@*` which resolves to v2, but another dep in the set has a
|
||||
// peerDependency on `foo@1`. In that case, if we force it to be v2,
|
||||
// we're unnecessarily triggering an ERESOLVE.
|
||||
// If we have a second edge to worry about, and it's not satisfied
|
||||
// by the first node, try a second and see if that satisfies the
|
||||
// original edge here.
|
||||
const spec2 = secondEdge && npa.resolve(
|
||||
edge.name,
|
||||
secondEdge.spec,
|
||||
secondEdge.from.path
|
||||
)
|
||||
const second = secondEdge && !secondEdge.valid
|
||||
? await this[_nodeFromSpec](edge.name, spec2, parent, secondEdge)
|
||||
: null
|
||||
|
||||
// pick the second one if they're both happy with that, otherwise first
|
||||
const node = second && edge.valid ? second : first
|
||||
// ensure the one we want is the one that's placed
|
||||
node.parent = parent
|
||||
|
||||
// handle otherwise unresolvable dependency nesting loops by
|
||||
// creating a symbolic link
|
||||
// a1 -> b1 -> a2 -> b2 -> a1 -> ...
|
||||
// instead of nesting forever, when the loop occurs, create
|
||||
// a symbolic link to the earlier instance
|
||||
for (let p = edge.from.resolveParent; p; p = p.resolveParent) {
|
||||
if (p.matches(node) && !p.isTop)
|
||||
return new Link({ parent: realParent, target: p })
|
||||
}
|
||||
|
||||
// keep track of the thing that caused this node to be included.
|
||||
const src = parent.sourceReference
|
||||
this[_peerSetSource].set(node, src)
|
||||
return this[_loadPeerSet](node)
|
||||
}
|
||||
|
||||
[_virtualRoot] (node, reuse = false) {
|
||||
@@ -886,7 +935,7 @@ This is a one-time fix-up, please be patient...
|
||||
|
||||
// also skip over any nodes in the tree that failed to load, since those
|
||||
// will crash the install later on anyway.
|
||||
const bd = node.isRoot ? null : node.package.bundleDependencies
|
||||
const bd = node.isProjectRoot ? null : node.package.bundleDependencies
|
||||
const bundled = new Set(bd || [])
|
||||
|
||||
return [...node.edgesOut.values()]
|
||||
@@ -923,7 +972,7 @@ This is a one-time fix-up, please be patient...
|
||||
return true
|
||||
|
||||
// If the user has explicitly asked to install this package, it's a problem.
|
||||
if (node.isRoot && this[_explicitRequests].has(edge.name))
|
||||
if (node.isProjectRoot && this[_explicitRequests].has(edge.name))
|
||||
return true
|
||||
|
||||
// No problems!
|
||||
@@ -1005,30 +1054,34 @@ This is a one-time fix-up, please be patient...
|
||||
// deps to override, but throw if no preference can be determined.
|
||||
async [_loadPeerSet] (node) {
|
||||
const peerEdges = [...node.edgesOut.values()]
|
||||
// we only care about peers here, and don't install peerOptionals
|
||||
.filter(e => e.peer && !e.valid && !e.optional)
|
||||
// we typically only install non-optional peers, but we have to
|
||||
// factor them into the peerSet so that we can avoid conflicts
|
||||
.filter(e => e.peer && !(e.valid && e.to))
|
||||
.sort(({name: a}, {name: b}) => a.localeCompare(b))
|
||||
|
||||
for (const edge of peerEdges) {
|
||||
// already placed this one, and we're happy with it.
|
||||
if (edge.valid)
|
||||
if (edge.valid && edge.to)
|
||||
continue
|
||||
|
||||
const parentEdge = node.parent.edgesOut.get(edge.name)
|
||||
const {isRoot, isWorkspace} = node.parent.sourceReference
|
||||
const isMine = isRoot || isWorkspace
|
||||
if (edge.missing) {
|
||||
const {isProjectRoot, isWorkspace} = node.parent.sourceReference
|
||||
const isMine = isProjectRoot || isWorkspace
|
||||
if (!edge.to) {
|
||||
if (!parentEdge) {
|
||||
// easy, just put the thing there
|
||||
await this[_nodeFromEdge](edge, node.parent)
|
||||
continue
|
||||
} else {
|
||||
// try to put the parent's preference, and make sure that satisfies.
|
||||
// if so, we're good.
|
||||
// if it does not, then we have a problem in strict mode, no problem
|
||||
// if the parent's edge is very broad like >=1, and the edge in
|
||||
// question is something like 1.x, then we want to get a 1.x, not
|
||||
// a 2.x. pass along the child edge as an advisory guideline.
|
||||
// if the parent edge doesn't satisfy the child edge, and the
|
||||
// child edge doesn't satisfy the parent edge, then we have
|
||||
// a conflict. this is always a problem in strict mode, never
|
||||
// in force mode, and a problem in non-strict mode if this isn't
|
||||
// on behalf of the root node. In all such cases, we warn at least.
|
||||
await this[_nodeFromEdge](parentEdge, node.parent)
|
||||
// on behalf of our project. in all such cases, we warn at least.
|
||||
await this[_nodeFromEdge](parentEdge, node.parent, edge)
|
||||
|
||||
// hooray! that worked!
|
||||
if (edge.valid)
|
||||
@@ -1037,8 +1090,9 @@ This is a one-time fix-up, please be patient...
|
||||
// allow it
|
||||
if (this[_force] || !isMine && !this[_strictPeerDeps])
|
||||
continue
|
||||
else
|
||||
this[_failPeerConflict](edge)
|
||||
|
||||
// problem
|
||||
this[_failPeerConflict](edge)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,7 +1155,7 @@ This is a one-time fix-up, please be patient...
|
||||
// top nodes should still get peer deps from their fsParent if possible,
|
||||
// and only install locally if there's no other option, eg for a link
|
||||
// outside of the project root, or for a conflicted dep.
|
||||
const start = edge.peer && !node.isRoot ? node.resolveParent || node
|
||||
const start = edge.peer && !node.isProjectRoot ? node.resolveParent || node
|
||||
: node
|
||||
|
||||
let target
|
||||
@@ -1137,7 +1191,8 @@ This is a one-time fix-up, please be patient...
|
||||
|
||||
// when installing globally, or just in global style, we never place
|
||||
// deps above the first level.
|
||||
if (this[_globalStyle] && check.resolveParent === this.idealTree)
|
||||
const tree = this.idealTree && this.idealTree.target || this.idealTree
|
||||
if (this[_globalStyle] && check.resolveParent === tree)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -1350,8 +1405,8 @@ This is a one-time fix-up, please be patient...
|
||||
// depends on a, and it has a conflict, it's our problem. So, the root
|
||||
// (or whatever is bringing in a) becomes the "effective source" for
|
||||
// the purposes of this calculation.
|
||||
const { isRoot, isWorkspace } = isSource ? target : source || {}
|
||||
const isMine = isRoot || isWorkspace
|
||||
const { isProjectRoot, isWorkspace } = isSource ? target : source || {}
|
||||
const isMine = isProjectRoot || isWorkspace
|
||||
|
||||
// Useful testing thingie right here.
|
||||
// peerEntryEdge should *always* be a non-peer dependency, or a peer
|
||||
|
||||
+74
-25
@@ -1,5 +1,6 @@
|
||||
// mixin implementing the reify method
|
||||
|
||||
const onExit = require('../signal-handling.js')
|
||||
const pacote = require('pacote')
|
||||
const rpj = require('read-package-json-fast')
|
||||
const { updateDepSpec } = require('../dep-spec.js')
|
||||
@@ -27,8 +28,9 @@ const updateRootPackageJson = require('../update-root-package-json.js')
|
||||
const _retiredPaths = Symbol('retiredPaths')
|
||||
const _retiredUnchanged = Symbol('retiredUnchanged')
|
||||
const _sparseTreeDirs = Symbol('sparseTreeDirs')
|
||||
const _sparseTreeRoots = Symbol('sparseTreeRoots')
|
||||
const _savePrefix = Symbol('savePrefix')
|
||||
const _retireShallowNodes = Symbol('retireShallowNodes')
|
||||
const _retireShallowNodes = Symbol.for('retireShallowNodes')
|
||||
const _getBundlesByDepth = Symbol('getBundlesByDepth')
|
||||
const _registryResolved = Symbol('registryResolved')
|
||||
const _addNodeToTrashList = Symbol('addNodeToTrashList')
|
||||
@@ -54,7 +56,7 @@ const _awaitQuickAudit = Symbol('awaitQuickAudit')
|
||||
const _unpackNewModules = Symbol.for('unpackNewModules')
|
||||
const _moveContents = Symbol.for('moveContents')
|
||||
const _moveBackRetiredUnchanged = Symbol.for('moveBackRetiredUnchanged')
|
||||
const _build = Symbol('build')
|
||||
const _build = Symbol.for('build')
|
||||
const _removeTrash = Symbol.for('removeTrash')
|
||||
const _renamePath = Symbol.for('renamePath')
|
||||
const _rollbackRetireShallowNodes = Symbol.for('rollbackRetireShallowNodes')
|
||||
@@ -102,6 +104,7 @@ module.exports = cls => class Reifier extends cls {
|
||||
this[_retiredPaths] = {}
|
||||
this[_retiredUnchanged] = {}
|
||||
this[_sparseTreeDirs] = new Set()
|
||||
this[_sparseTreeRoots] = new Set()
|
||||
this[_trashList] = new Set()
|
||||
}
|
||||
|
||||
@@ -153,16 +156,63 @@ module.exports = cls => class Reifier extends cls {
|
||||
return this[_submitQuickAudit]()
|
||||
}
|
||||
|
||||
await this[_retireShallowNodes]()
|
||||
await this[_createSparseTree]()
|
||||
await this[_addOmitsToTrashList]()
|
||||
await this[_loadShrinkwrapsAndUpdateTrees]()
|
||||
await this[_loadBundlesAndUpdateTrees]()
|
||||
await this[_submitQuickAudit]()
|
||||
await this[_unpackNewModules]()
|
||||
await this[_moveBackRetiredUnchanged]()
|
||||
await this[_build]()
|
||||
// ok, we're about to start touching the fs. need to roll back
|
||||
// if we get an early termination.
|
||||
let reifyTerminated = null
|
||||
const removeHandler = onExit(({signal}) => {
|
||||
// only call once. if signal hits twice, we just terminate
|
||||
removeHandler()
|
||||
reifyTerminated = Object.assign(new Error('process terminated'), {
|
||||
signal,
|
||||
})
|
||||
return false
|
||||
})
|
||||
|
||||
// [rollbackfn, [...actions]]
|
||||
// after each step, if the process was terminated, execute the rollback
|
||||
// note that each rollback *also* calls the previous one when it's
|
||||
// finished, and then the first one throws the error, so we only need
|
||||
// a new rollback step when we have a new thing that must be done to
|
||||
// revert the install.
|
||||
const steps = [
|
||||
[_rollbackRetireShallowNodes, [
|
||||
_retireShallowNodes,
|
||||
]],
|
||||
[_rollbackCreateSparseTree, [
|
||||
_createSparseTree,
|
||||
_addOmitsToTrashList,
|
||||
_loadShrinkwrapsAndUpdateTrees,
|
||||
_loadBundlesAndUpdateTrees,
|
||||
_submitQuickAudit,
|
||||
_unpackNewModules,
|
||||
]],
|
||||
[_rollbackMoveBackRetiredUnchanged, [
|
||||
_moveBackRetiredUnchanged,
|
||||
_build,
|
||||
]],
|
||||
]
|
||||
for (const [rollback, actions] of steps) {
|
||||
for (const action of actions) {
|
||||
try {
|
||||
await this[action]()
|
||||
if (reifyTerminated)
|
||||
throw reifyTerminated
|
||||
} catch (er) {
|
||||
await this[rollback](er)
|
||||
/* istanbul ignore next - rollback throws, should never hit this */
|
||||
throw er
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no rollback for this one, just exit with the error, since the
|
||||
// install completed and can't be safely recovered at this point.
|
||||
await this[_removeTrash]()
|
||||
if (reifyTerminated)
|
||||
throw reifyTerminated
|
||||
|
||||
// done modifying the file system, no need to keep listening for sigs
|
||||
removeHandler()
|
||||
}
|
||||
|
||||
// when doing a local install, we load everything and figure it all out.
|
||||
@@ -183,8 +233,9 @@ module.exports = cls => class Reifier extends cls {
|
||||
const actualOpt = this[_global] ? {
|
||||
ignoreMissing: true,
|
||||
global: true,
|
||||
filter: (node, kid) => !node.isRoot ? true
|
||||
: (node.edgesOut.has(kid) || this[_explicitRequests].has(kid)),
|
||||
filter: (node, kid) => !node.isRoot && node !== node.root.target
|
||||
? true
|
||||
: (node.edgesOut.has(kid) || this[_explicitRequests].has(kid)),
|
||||
} : { ignoreMissing: true }
|
||||
|
||||
if (!this[_global]) {
|
||||
@@ -260,7 +311,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
const movePromises = Object.entries(moves)
|
||||
.map(([from, to]) => this[_renamePath](from, to))
|
||||
return promiseAllRejectLate(movePromises)
|
||||
.catch(er => this[_rollbackRetireShallowNodes](er))
|
||||
.then(() => process.emit('timeEnd', 'reify:retireShallow'))
|
||||
}
|
||||
|
||||
@@ -326,18 +376,22 @@ module.exports = cls => class Reifier extends cls {
|
||||
.map(diff => diff.ideal.path)
|
||||
|
||||
return promiseAllRejectLate(dirs.map(d => mkdirp(d)))
|
||||
.then(() => dirs.forEach(dir => this[_sparseTreeDirs].add(dir)))
|
||||
.then(made => {
|
||||
made.forEach(made => this[_sparseTreeRoots].add(made))
|
||||
dirs.forEach(dir => this[_sparseTreeDirs].add(dir))
|
||||
})
|
||||
.then(() => process.emit('timeEnd', 'reify:createSparse'))
|
||||
.catch(er => this[_rollbackCreateSparseTree](er))
|
||||
}
|
||||
|
||||
[_rollbackCreateSparseTree] (er) {
|
||||
process.emit('time', 'reify:rollback:createSparse')
|
||||
// cut the roots of the sparse tree, not the leaves
|
||||
const moves = this[_retiredPaths]
|
||||
// cut the roots of the sparse tree that were created, not the leaves
|
||||
const roots = this[_sparseTreeRoots]
|
||||
// also delete the moves that we retired, so that we can move them back
|
||||
const failures = []
|
||||
const unlinks = Object.entries(moves)
|
||||
.map(([from, to]) => rimraf(from).catch(er => failures.push([from, er])))
|
||||
const targets = [...roots, ...Object.keys(this[_retiredPaths])]
|
||||
const unlinks = targets
|
||||
.map(path => rimraf(path).catch(er => failures.push([path, er])))
|
||||
return promiseAllRejectLate(unlinks)
|
||||
.then(() => {
|
||||
if (failures.length)
|
||||
@@ -375,7 +429,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
.then(() => this[_diffTrees]())
|
||||
.then(() => this[_createSparseTree]())
|
||||
.then(() => process.emit('timeEnd', 'reify:loadShrinkwraps'))
|
||||
.catch(er => this[_rollbackCreateSparseTree](er))
|
||||
}
|
||||
|
||||
// create a symlink for Links, extract for Nodes
|
||||
@@ -543,7 +596,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
}))))
|
||||
// move onto the next level of bundled items
|
||||
.then(() => this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth))
|
||||
.catch(er => this[_rollbackCreateSparseTree](er))
|
||||
}
|
||||
|
||||
[_getBundlesByDepth] () {
|
||||
@@ -677,7 +729,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
})
|
||||
return promiseAllRejectLate(unpacks)
|
||||
.then(() => process.emit('timeEnd', 'reify:unpack'))
|
||||
.catch(er => this[_rollbackCreateSparseTree](er))
|
||||
}
|
||||
|
||||
// This is the part where we move back the unchanging nodes that were
|
||||
@@ -720,7 +771,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
}))
|
||||
}))
|
||||
.then(() => process.emit('timeEnd', 'reify:unretire'))
|
||||
.catch(er => this[_rollbackMoveBackRetiredUnchanged](er))
|
||||
}
|
||||
|
||||
// move the contents from the fromPath to the node.path
|
||||
@@ -771,7 +821,6 @@ module.exports = cls => class Reifier extends cls {
|
||||
|
||||
return this.rebuild({ nodes, handleOptionalFailure: true })
|
||||
.then(() => process.emit('timeEnd', 'reify:build'))
|
||||
.catch(er => this[_rollbackMoveBackRetiredUnchanged](er))
|
||||
}
|
||||
|
||||
// the tree is pretty much built now, so it's cleanup time.
|
||||
|
||||
+5
-64
@@ -64,70 +64,7 @@ const _meta = Symbol('_meta')
|
||||
const relpath = require('./relpath.js')
|
||||
const consistentResolve = require('./consistent-resolve.js')
|
||||
|
||||
// helper function to output a clearer visualization
|
||||
// of the current node and its descendents
|
||||
class ArboristNode {}
|
||||
|
||||
const printableTree = (tree, path = []) =>
|
||||
(path.includes(tree) ? { location: tree.location } : (path.push(tree), Object.assign(new ArboristNode(), {
|
||||
name: tree.name,
|
||||
...(tree.package && tree.package.version
|
||||
? { version: tree.package.version }
|
||||
: {}),
|
||||
location: tree.location,
|
||||
path: tree.path,
|
||||
realpath: tree.realpath,
|
||||
...(tree.isLink ? { target: printableTree(tree.target, path) } : {}),
|
||||
...(tree.resolved != null ? { resolved: tree.resolved } : {}),
|
||||
...(tree.extraneous ? { extraneous: true } : {
|
||||
...(tree.dev ? { dev: true } : {}),
|
||||
...(tree.optional ? { optional: true } : {}),
|
||||
...(tree.devOptional && !tree.dev && !tree.optional
|
||||
? { devOptional: true } : {}),
|
||||
...(tree.peer ? { peer: true } : {}),
|
||||
}),
|
||||
...(tree.inBundle ? { bundled: true } : {}),
|
||||
// handle top-level tree error
|
||||
...(tree.error
|
||||
? {
|
||||
error: {
|
||||
code: tree.error.code,
|
||||
...(tree.error.path
|
||||
? { path: tree.error.path }
|
||||
: {}),
|
||||
},
|
||||
} : {}),
|
||||
// handle errors for each node
|
||||
...(tree.errors && tree.errors.length
|
||||
? {
|
||||
errors: tree.errors.map(error => ({
|
||||
code: error.code,
|
||||
...(error.path
|
||||
? { path: error.path }
|
||||
: {}),
|
||||
})),
|
||||
} : {}),
|
||||
...(tree.edgesIn && tree.edgesIn.size ? {
|
||||
edgesIn: new Set([...tree.edgesIn]
|
||||
.sort((a, b) => a.from.location.localeCompare(b.from.location))),
|
||||
} : {}),
|
||||
...(tree.edgesOut && tree.edgesOut.size ? {
|
||||
edgesOut: new Map([...tree.edgesOut.entries()]
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))),
|
||||
} : {}),
|
||||
...(tree.fsChildren && tree.fsChildren.size ? {
|
||||
fsChildren: new Set([...tree.fsChildren]
|
||||
.sort((a, b) => a.path.localeCompare(b.path))
|
||||
.map(tree => printableTree(tree, path))),
|
||||
} : {}),
|
||||
...(tree.target || !tree.children || !tree.children.size
|
||||
? {}
|
||||
: {
|
||||
children: new Map([...tree.children.entries()]
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(([name, tree]) => [name, printableTree(tree, path)])),
|
||||
}),
|
||||
})))
|
||||
const printableTree = require('./printable.js')
|
||||
|
||||
class Node {
|
||||
constructor (options) {
|
||||
@@ -527,6 +464,10 @@ class Node {
|
||||
return this === this.root
|
||||
}
|
||||
|
||||
get isProjectRoot () {
|
||||
return this === this.root || this === this.root.target
|
||||
}
|
||||
|
||||
set root (root) {
|
||||
// setting to null means this is the new root
|
||||
// should only ever be one step
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
// helper function to output a clearer visualization
|
||||
// of the current node and its descendents
|
||||
|
||||
const util = require('util')
|
||||
|
||||
class ArboristNode {
|
||||
constructor (tree, path) {
|
||||
this.name = tree.name
|
||||
if (tree.package.name && tree.package.name !== this.name)
|
||||
this.packageName = tree.package.name
|
||||
if (tree.version)
|
||||
this.version = tree.version
|
||||
this.location = tree.location
|
||||
this.path = tree.path
|
||||
if (tree.realpath !== this.path)
|
||||
this.realpath = tree.realpath
|
||||
if (tree.resolved !== null)
|
||||
this.resolved = tree.resolved
|
||||
if (tree.extraneous)
|
||||
this.extraneous = true
|
||||
if (tree.dev)
|
||||
this.dev = true
|
||||
if (tree.optional)
|
||||
this.optional = true
|
||||
if (tree.devOptional && !tree.dev && !tree.optional)
|
||||
this.devOptional = true
|
||||
if (tree.peer)
|
||||
this.peer = true
|
||||
if (tree.inBundle)
|
||||
this.bundled = true
|
||||
if (tree.error)
|
||||
this.error = treeError(tree.error)
|
||||
if (tree.errors && tree.errors.length)
|
||||
this.errors = tree.errors.map(treeError)
|
||||
|
||||
// edgesOut sorted by name
|
||||
if (tree.edgesOut.size) {
|
||||
this.edgesOut = new Map([...tree.edgesOut.entries()]
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([name, edge]) => [name, new EdgeOut(edge)]))
|
||||
}
|
||||
|
||||
// edgesIn sorted by location
|
||||
if (tree.edgesIn.size) {
|
||||
this.edgesIn = new Set([...tree.edgesIn]
|
||||
.sort((a, b) => a.from.location.localeCompare(b.from.location))
|
||||
.map(edge => new EdgeIn(edge)))
|
||||
}
|
||||
|
||||
// fsChildren sorted by path
|
||||
if (tree.fsChildren.size) {
|
||||
this.fsChildren = new Set([...tree.fsChildren]
|
||||
.sort(({path: a}, {path: b}) => a.localeCompare(b))
|
||||
.map(tree => printableTree(tree, path)))
|
||||
}
|
||||
|
||||
// children sorted by name
|
||||
if (tree.children.size) {
|
||||
this.children = new Map([...tree.children.entries()]
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([name, tree]) => [name, printableTree(tree, path)]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ArboristLink extends ArboristNode {
|
||||
constructor (tree, path) {
|
||||
super(tree, path)
|
||||
this.target = printableTree(tree.target, path)
|
||||
}
|
||||
}
|
||||
|
||||
const treeError = ({code, path}) => ({
|
||||
code,
|
||||
...(path ? { path } : {}),
|
||||
})
|
||||
|
||||
// print out edges without dumping the full node all over again
|
||||
// this base class will toJSON as a plain old object, but the
|
||||
// util.inspect() output will be a bit cleaner
|
||||
class Edge {
|
||||
constructor (edge) {
|
||||
this.type = edge.type
|
||||
this.name = edge.name
|
||||
this.spec = edge.spec || '*'
|
||||
if (edge.error)
|
||||
this.error = edge.error
|
||||
}
|
||||
}
|
||||
|
||||
// don't care about 'from' for edges out
|
||||
class EdgeOut extends Edge {
|
||||
constructor (edge) {
|
||||
super(edge)
|
||||
this.to = edge.to && edge.to.location
|
||||
}
|
||||
|
||||
[util.inspect.custom] () {
|
||||
return `{ ${this.type} ${this.name}@${this.spec}${
|
||||
this.to ? ' -> ' + this.to : ''
|
||||
}${
|
||||
this.error ? ' ' + this.error : ''
|
||||
} }`
|
||||
}
|
||||
}
|
||||
|
||||
// don't care about 'to' for edges in
|
||||
class EdgeIn extends Edge {
|
||||
constructor (edge) {
|
||||
super(edge)
|
||||
this.from = edge.from && edge.from.location
|
||||
}
|
||||
|
||||
[util.inspect.custom] () {
|
||||
return `{ ${this.from || '""'} ${this.type} ${this.name}@${this.spec}${
|
||||
this.error ? ' ' + this.error : ''
|
||||
} }`
|
||||
}
|
||||
}
|
||||
|
||||
const printableTree = (tree, path = []) => {
|
||||
if (path.includes(tree))
|
||||
return { location: tree.location }
|
||||
path.push(tree)
|
||||
const Cls = tree.isLink ? ArboristLink : ArboristNode
|
||||
return new Cls(tree, path)
|
||||
}
|
||||
|
||||
module.exports = printableTree
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
const signals = require('./signals.js')
|
||||
|
||||
// for testing, expose the process being used
|
||||
module.exports = Object.assign(fn => setup(fn), { process })
|
||||
|
||||
// do all of this in a setup function so that we can call it
|
||||
// multiple times for multiple reifies that might be going on.
|
||||
// Otherwise, Arborist.reify() is a global action, which is a
|
||||
// new constraint we'd be adding with this behavior.
|
||||
const setup = fn => {
|
||||
const { process } = module.exports
|
||||
|
||||
const sigListeners = { loaded: false }
|
||||
|
||||
const unload = () => {
|
||||
if (!sigListeners.loaded)
|
||||
return
|
||||
for (const sig of signals) {
|
||||
try {
|
||||
process.removeListener(sig, sigListeners[sig])
|
||||
} catch (er) {}
|
||||
}
|
||||
process.removeListener('beforeExit', onBeforeExit)
|
||||
sigListeners.loaded = false
|
||||
}
|
||||
|
||||
const onBeforeExit = () => {
|
||||
// this trick ensures that we exit with the same signal we caught
|
||||
// Ie, if you press ^C and npm gets a SIGINT, we'll do the rollback
|
||||
// and then exit with a SIGINT signal once we've removed the handler.
|
||||
// The timeout is there because signals are asynchronous, so we need
|
||||
// the process to NOT exit on its own, which means we have to have
|
||||
// something keeping the event loop looping. Hence this hack.
|
||||
unload()
|
||||
process.kill(process.pid, signalReceived)
|
||||
setTimeout(() => {}, 500)
|
||||
}
|
||||
|
||||
let signalReceived = null
|
||||
const listener = (sig, fn) => () => {
|
||||
signalReceived = sig
|
||||
|
||||
// if we exit normally, but caught a signal which would have been fatal,
|
||||
// then re-send it once we're done with whatever cleanup we have to do.
|
||||
unload()
|
||||
if (process.listeners(sig).length < 1)
|
||||
process.once('beforeExit', onBeforeExit)
|
||||
|
||||
fn({ signal: sig })
|
||||
}
|
||||
|
||||
// do the actual loading here
|
||||
for (const sig of signals) {
|
||||
sigListeners[sig] = listener(sig, fn)
|
||||
const max = process.getMaxListeners()
|
||||
try {
|
||||
// if we call this a bunch of times, avoid triggering the warning
|
||||
const { length } = process.listeners(sig)
|
||||
if (length >= max)
|
||||
process.setMaxListeners(length + 1)
|
||||
process.on(sig, sigListeners[sig])
|
||||
} catch (er) {}
|
||||
}
|
||||
sigListeners.loaded = true
|
||||
|
||||
return unload
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// copied from signal-exit
|
||||
|
||||
// This is not the set of all possible signals.
|
||||
//
|
||||
// It IS, however, the set of all signals that trigger
|
||||
// an exit on either Linux or BSD systems. Linux is a
|
||||
// superset of the signal names supported on BSD, and
|
||||
// the unknown signals just fail to register, so we can
|
||||
// catch that easily enough.
|
||||
//
|
||||
// Don't bother with SIGKILL. It's uncatchable, which
|
||||
// means that we can't fire any callbacks anyway.
|
||||
//
|
||||
// If a user does happen to register a handler on a non-
|
||||
// fatal signal like SIGWINCH or something, and then
|
||||
// exit, it'll end up firing `process.emit('exit')`, so
|
||||
// the handler will be fired anyway.
|
||||
//
|
||||
// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
|
||||
// artificially, inherently leave the process in a
|
||||
// state from which it is not safe to try and enter JS
|
||||
// listeners.
|
||||
|
||||
const platform = global.__ARBORIST_FAKE_PLATFORM__ || process.platform
|
||||
|
||||
module.exports = [
|
||||
'SIGABRT',
|
||||
'SIGALRM',
|
||||
'SIGHUP',
|
||||
'SIGINT',
|
||||
'SIGTERM',
|
||||
]
|
||||
|
||||
if (platform !== 'win32') {
|
||||
module.exports.push(
|
||||
'SIGVTALRM',
|
||||
'SIGXCPU',
|
||||
'SIGXFSZ',
|
||||
'SIGUSR2',
|
||||
'SIGTRAP',
|
||||
'SIGSYS',
|
||||
'SIGQUIT',
|
||||
'SIGIOT'
|
||||
// should detect profiler and enable/disable accordingly.
|
||||
// see #21
|
||||
// 'SIGPROF'
|
||||
)
|
||||
}
|
||||
|
||||
if (platform === 'linux') {
|
||||
module.exports.push(
|
||||
'SIGIO',
|
||||
'SIGPOLL',
|
||||
'SIGPWR',
|
||||
'SIGSTKFLT',
|
||||
'SIGUNUSED'
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@npmcli/arborist",
|
||||
"version": "2.0.6",
|
||||
"version": "2.1.0",
|
||||
"description": "Manage node_modules trees",
|
||||
"dependencies": {
|
||||
"@npmcli/installed-package-contents": "^1.0.5",
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial release
|
||||
Generated
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
Copyright (c) npm Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# @npmcli/disparity-colors
|
||||
|
||||
[](https://www.npmjs.com/package/@npmcli/disparity-colors)
|
||||
[](https://github.com/npm/disparity-colors)
|
||||
[](https://github.com/npm/disparity-colors/blob/master/LICENSE)
|
||||
|
||||
Spiritual sucessor to [disparity](https://www.npmjs.com/package/disparity). Colorizes [Diff Unified format](https://en.wikipedia.org/wiki/Diff#Unified_format) output using [ansi-styles](https://www.npmjs.com/package/ansi-styles).
|
||||
|
||||
## Install
|
||||
|
||||
`npm install @npmcli/disparity-colors`
|
||||
|
||||
## Usage:
|
||||
|
||||
```js
|
||||
const colorize = require('@npmcli/disparity-colors')
|
||||
mapWorkspaces(`--- a/src/index.js
|
||||
+++ b/src/index.js
|
||||
@@ -1,4 +1,5 @@
|
||||
"use strict";
|
||||
+"use foo";
|
||||
|
||||
const os = require("os");
|
||||
`)
|
||||
// [33m--- a/src/index.js[39m
|
||||
// [33m+++ b/src/index.js[39m
|
||||
// [35m@@ -1,4 +1,5 @@[39m
|
||||
// "use strict";
|
||||
// [32m+"use foo";[39m
|
||||
//
|
||||
// const os = require("os");
|
||||
```
|
||||
|
||||
## API:
|
||||
|
||||
### `colorize(str, opts = {}) -> String`
|
||||
|
||||
- `str`: A [Diff Unified format](https://en.wikipedia.org/wiki/Diff#Unified_format) string
|
||||
- `opts`:
|
||||
- `headerLength`: A **Number** defining how many lines should be colorized as header
|
||||
|
||||
#### Returns
|
||||
|
||||
A **String** including the appropriate [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles)
|
||||
|
||||
## LICENSE
|
||||
|
||||
[ISC](./LICENSE)
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
const ansi = require('ansi-styles')
|
||||
|
||||
const colors = {
|
||||
removed: ansi.red,
|
||||
added: ansi.green,
|
||||
header: ansi.yellow,
|
||||
section: ansi.magenta
|
||||
}
|
||||
|
||||
function colorize (str, opts) {
|
||||
let headerLength = (opts || {}).headerLength
|
||||
if (typeof headerLength !== 'number' || Number.isNaN(headerLength)) {
|
||||
headerLength = 2
|
||||
}
|
||||
|
||||
const color = (str, colorId) => {
|
||||
const { open, close } = colors[colorId]
|
||||
// avoid highlighting the "\n" (would highlight till the end of the line)
|
||||
return str.replace(/[^\n\r]+/g, open + '$&' + close)
|
||||
}
|
||||
|
||||
// this RegExp will include all the `\n` chars into the lines, easier to join
|
||||
const lines = ((typeof str === 'string' && str) || '').split(/^/m)
|
||||
|
||||
const start = color(lines.slice(0, headerLength).join(''), 'header')
|
||||
const end = lines.slice(headerLength).join('')
|
||||
.replace(/^-.*/gm, color('$&', 'removed'))
|
||||
.replace(/^\+.*/gm, color('$&', 'added'))
|
||||
.replace(/^@@.+@@/gm, color('$&', 'section'))
|
||||
|
||||
return start + end
|
||||
}
|
||||
|
||||
module.exports = colorize
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@npmcli/disparity-colors",
|
||||
"version": "1.0.1",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"description": "Colorizes unified diff output",
|
||||
"repository": "https://github.com/npm/disparity-colors",
|
||||
"keywords": [
|
||||
"disparity",
|
||||
"npm",
|
||||
"npmcli",
|
||||
"diff",
|
||||
"char",
|
||||
"unified",
|
||||
"multiline",
|
||||
"string",
|
||||
"color",
|
||||
"ansi",
|
||||
"terminal",
|
||||
"cli",
|
||||
"tty"
|
||||
],
|
||||
"author": "npm Inc. <support@npmjs.com>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Ruy Adorno",
|
||||
"url": "https://ruyadorno.com",
|
||||
"twitter": "ruyadorno"
|
||||
}
|
||||
],
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"lint": "standard index.js",
|
||||
"pretest": "npm run lint",
|
||||
"test": "tap",
|
||||
"snap": "tap",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags"
|
||||
},
|
||||
"tap": {
|
||||
"check-coverage": true
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"/tap-snapshots/"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^16.0.3",
|
||||
"tap": "^14.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.3.0"
|
||||
}
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
[](https://travis-ci.org/isaacs/rimraf) [](https://david-dm.org/isaacs/rimraf) [](https://david-dm.org/isaacs/rimraf#info=devDependencies)
|
||||
|
||||
The [UNIX command](http://en.wikipedia.org/wiki/Rm_(Unix)) `rm -rf` for node.
|
||||
|
||||
Install with `npm install rimraf`, or just drop rimraf.js somewhere.
|
||||
|
||||
## API
|
||||
|
||||
`rimraf(f, [opts], callback)`
|
||||
|
||||
The first parameter will be interpreted as a globbing pattern for files. If you
|
||||
want to disable globbing you can do so with `opts.disableGlob` (defaults to
|
||||
`false`). This might be handy, for instance, if you have filenames that contain
|
||||
globbing wildcard characters.
|
||||
|
||||
The callback will be called with an error if there is one. Certain
|
||||
errors are handled for you:
|
||||
|
||||
* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
|
||||
`opts.maxBusyTries` times before giving up, adding 100ms of wait
|
||||
between each attempt. The default `maxBusyTries` is 3.
|
||||
* `ENOENT` - If the file doesn't exist, rimraf will return
|
||||
successfully, since your desired outcome is already the case.
|
||||
* `EMFILE` - Since `readdir` requires opening a file descriptor, it's
|
||||
possible to hit `EMFILE` if too many file descriptors are in use.
|
||||
In the sync case, there's nothing to be done for this. But in the
|
||||
async case, rimraf will gradually back off with timeouts up to
|
||||
`opts.emfileWait` ms, which defaults to 1000.
|
||||
|
||||
## options
|
||||
|
||||
* unlink, chmod, stat, lstat, rmdir, readdir,
|
||||
unlinkSync, chmodSync, statSync, lstatSync, rmdirSync, readdirSync
|
||||
|
||||
In order to use a custom file system library, you can override
|
||||
specific fs functions on the options object.
|
||||
|
||||
If any of these functions are present on the options object, then
|
||||
the supplied function will be used instead of the default fs
|
||||
method.
|
||||
|
||||
Sync methods are only relevant for `rimraf.sync()`, of course.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
var myCustomFS = require('some-custom-fs')
|
||||
|
||||
rimraf('some-thing', myCustomFS, callback)
|
||||
```
|
||||
|
||||
* maxBusyTries
|
||||
|
||||
If an `EBUSY`, `ENOTEMPTY`, or `EPERM` error code is encountered
|
||||
on Windows systems, then rimraf will retry with a linear backoff
|
||||
wait of 100ms longer on each try. The default maxBusyTries is 3.
|
||||
|
||||
Only relevant for async usage.
|
||||
|
||||
* emfileWait
|
||||
|
||||
If an `EMFILE` error is encountered, then rimraf will retry
|
||||
repeatedly with a linear backoff of 1ms longer on each try, until
|
||||
the timeout counter hits this max. The default limit is 1000.
|
||||
|
||||
If you repeatedly encounter `EMFILE` errors, then consider using
|
||||
[graceful-fs](http://npm.im/graceful-fs) in your program.
|
||||
|
||||
Only relevant for async usage.
|
||||
|
||||
* glob
|
||||
|
||||
Set to `false` to disable [glob](http://npm.im/glob) pattern
|
||||
matching.
|
||||
|
||||
Set to an object to pass options to the glob module. The default
|
||||
glob options are `{ nosort: true, silent: true }`.
|
||||
|
||||
Glob version 6 is used in this module.
|
||||
|
||||
Relevant for both sync and async usage.
|
||||
|
||||
* disableGlob
|
||||
|
||||
Set to any non-falsey value to disable globbing entirely.
|
||||
(Equivalent to setting `glob: false`.)
|
||||
|
||||
## rimraf.sync
|
||||
|
||||
It can remove stuff synchronously, too. But that's not so good. Use
|
||||
the async API. It's better.
|
||||
|
||||
## CLI
|
||||
|
||||
If installed with `npm install rimraf -g` it can be used as a global
|
||||
command `rimraf <path> [<path> ...]` which is useful for cross platform support.
|
||||
|
||||
## mkdirp
|
||||
|
||||
If you need to create a directory recursively, check out
|
||||
[mkdirp](https://github.com/substack/node-mkdirp).
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var rimraf = require('./')
|
||||
|
||||
var help = false
|
||||
var dashdash = false
|
||||
var noglob = false
|
||||
var args = process.argv.slice(2).filter(function(arg) {
|
||||
if (dashdash)
|
||||
return !!arg
|
||||
else if (arg === '--')
|
||||
dashdash = true
|
||||
else if (arg === '--no-glob' || arg === '-G')
|
||||
noglob = true
|
||||
else if (arg === '--glob' || arg === '-g')
|
||||
noglob = false
|
||||
else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))
|
||||
help = true
|
||||
else
|
||||
return !!arg
|
||||
})
|
||||
|
||||
if (help || args.length === 0) {
|
||||
// If they didn't ask for help, then this is not a "success"
|
||||
var log = help ? console.log : console.error
|
||||
log('Usage: rimraf <path> [<path> ...]')
|
||||
log('')
|
||||
log(' Deletes all files and folders at "path" recursively.')
|
||||
log('')
|
||||
log('Options:')
|
||||
log('')
|
||||
log(' -h, --help Display this usage info')
|
||||
log(' -G, --no-glob Do not expand glob patterns in arguments')
|
||||
log(' -g, --glob Expand glob patterns in arguments (default)')
|
||||
process.exit(help ? 0 : 1)
|
||||
} else
|
||||
go(0)
|
||||
|
||||
function go (n) {
|
||||
if (n >= args.length)
|
||||
return
|
||||
var options = {}
|
||||
if (noglob)
|
||||
options = { glob: false }
|
||||
rimraf(args[n], options, function (er) {
|
||||
if (er)
|
||||
throw er
|
||||
go(n+1)
|
||||
})
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "rimraf",
|
||||
"version": "2.7.1",
|
||||
"main": "rimraf.js",
|
||||
"description": "A deep deletion module for node (like `rm -rf`)",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"license": "ISC",
|
||||
"repository": "git://github.com/isaacs/rimraf.git",
|
||||
"scripts": {
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags",
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"bin": "./bin.js",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"bin.js",
|
||||
"rimraf.js"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"tap": "^12.1.1"
|
||||
}
|
||||
}
|
||||
-372
@@ -1,372 +0,0 @@
|
||||
module.exports = rimraf
|
||||
rimraf.sync = rimrafSync
|
||||
|
||||
var assert = require("assert")
|
||||
var path = require("path")
|
||||
var fs = require("fs")
|
||||
var glob = undefined
|
||||
try {
|
||||
glob = require("glob")
|
||||
} catch (_err) {
|
||||
// treat glob as optional.
|
||||
}
|
||||
var _0666 = parseInt('666', 8)
|
||||
|
||||
var defaultGlobOpts = {
|
||||
nosort: true,
|
||||
silent: true
|
||||
}
|
||||
|
||||
// for EMFILE handling
|
||||
var timeout = 0
|
||||
|
||||
var isWindows = (process.platform === "win32")
|
||||
|
||||
function defaults (options) {
|
||||
var methods = [
|
||||
'unlink',
|
||||
'chmod',
|
||||
'stat',
|
||||
'lstat',
|
||||
'rmdir',
|
||||
'readdir'
|
||||
]
|
||||
methods.forEach(function(m) {
|
||||
options[m] = options[m] || fs[m]
|
||||
m = m + 'Sync'
|
||||
options[m] = options[m] || fs[m]
|
||||
})
|
||||
|
||||
options.maxBusyTries = options.maxBusyTries || 3
|
||||
options.emfileWait = options.emfileWait || 1000
|
||||
if (options.glob === false) {
|
||||
options.disableGlob = true
|
||||
}
|
||||
if (options.disableGlob !== true && glob === undefined) {
|
||||
throw Error('glob dependency not found, set `options.disableGlob = true` if intentional')
|
||||
}
|
||||
options.disableGlob = options.disableGlob || false
|
||||
options.glob = options.glob || defaultGlobOpts
|
||||
}
|
||||
|
||||
function rimraf (p, options, cb) {
|
||||
if (typeof options === 'function') {
|
||||
cb = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
assert(p, 'rimraf: missing path')
|
||||
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert.equal(typeof cb, 'function', 'rimraf: callback function required')
|
||||
assert(options, 'rimraf: invalid options argument provided')
|
||||
assert.equal(typeof options, 'object', 'rimraf: options should be object')
|
||||
|
||||
defaults(options)
|
||||
|
||||
var busyTries = 0
|
||||
var errState = null
|
||||
var n = 0
|
||||
|
||||
if (options.disableGlob || !glob.hasMagic(p))
|
||||
return afterGlob(null, [p])
|
||||
|
||||
options.lstat(p, function (er, stat) {
|
||||
if (!er)
|
||||
return afterGlob(null, [p])
|
||||
|
||||
glob(p, options.glob, afterGlob)
|
||||
})
|
||||
|
||||
function next (er) {
|
||||
errState = errState || er
|
||||
if (--n === 0)
|
||||
cb(errState)
|
||||
}
|
||||
|
||||
function afterGlob (er, results) {
|
||||
if (er)
|
||||
return cb(er)
|
||||
|
||||
n = results.length
|
||||
if (n === 0)
|
||||
return cb()
|
||||
|
||||
results.forEach(function (p) {
|
||||
rimraf_(p, options, function CB (er) {
|
||||
if (er) {
|
||||
if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
|
||||
busyTries < options.maxBusyTries) {
|
||||
busyTries ++
|
||||
var time = busyTries * 100
|
||||
// try again, with the same exact callback as this one.
|
||||
return setTimeout(function () {
|
||||
rimraf_(p, options, CB)
|
||||
}, time)
|
||||
}
|
||||
|
||||
// this one won't happen if graceful-fs is used.
|
||||
if (er.code === "EMFILE" && timeout < options.emfileWait) {
|
||||
return setTimeout(function () {
|
||||
rimraf_(p, options, CB)
|
||||
}, timeout ++)
|
||||
}
|
||||
|
||||
// already gone
|
||||
if (er.code === "ENOENT") er = null
|
||||
}
|
||||
|
||||
timeout = 0
|
||||
next(er)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Two possible strategies.
|
||||
// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR
|
||||
// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR
|
||||
//
|
||||
// Both result in an extra syscall when you guess wrong. However, there
|
||||
// are likely far more normal files in the world than directories. This
|
||||
// is based on the assumption that a the average number of files per
|
||||
// directory is >= 1.
|
||||
//
|
||||
// If anyone ever complains about this, then I guess the strategy could
|
||||
// be made configurable somehow. But until then, YAGNI.
|
||||
function rimraf_ (p, options, cb) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
assert(typeof cb === 'function')
|
||||
|
||||
// sunos lets the root user unlink directories, which is... weird.
|
||||
// so we have to lstat here and make sure it's not a dir.
|
||||
options.lstat(p, function (er, st) {
|
||||
if (er && er.code === "ENOENT")
|
||||
return cb(null)
|
||||
|
||||
// Windows can EPERM on stat. Life is suffering.
|
||||
if (er && er.code === "EPERM" && isWindows)
|
||||
fixWinEPERM(p, options, er, cb)
|
||||
|
||||
if (st && st.isDirectory())
|
||||
return rmdir(p, options, er, cb)
|
||||
|
||||
options.unlink(p, function (er) {
|
||||
if (er) {
|
||||
if (er.code === "ENOENT")
|
||||
return cb(null)
|
||||
if (er.code === "EPERM")
|
||||
return (isWindows)
|
||||
? fixWinEPERM(p, options, er, cb)
|
||||
: rmdir(p, options, er, cb)
|
||||
if (er.code === "EISDIR")
|
||||
return rmdir(p, options, er, cb)
|
||||
}
|
||||
return cb(er)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function fixWinEPERM (p, options, er, cb) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
assert(typeof cb === 'function')
|
||||
if (er)
|
||||
assert(er instanceof Error)
|
||||
|
||||
options.chmod(p, _0666, function (er2) {
|
||||
if (er2)
|
||||
cb(er2.code === "ENOENT" ? null : er)
|
||||
else
|
||||
options.stat(p, function(er3, stats) {
|
||||
if (er3)
|
||||
cb(er3.code === "ENOENT" ? null : er)
|
||||
else if (stats.isDirectory())
|
||||
rmdir(p, options, er, cb)
|
||||
else
|
||||
options.unlink(p, cb)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function fixWinEPERMSync (p, options, er) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
if (er)
|
||||
assert(er instanceof Error)
|
||||
|
||||
try {
|
||||
options.chmodSync(p, _0666)
|
||||
} catch (er2) {
|
||||
if (er2.code === "ENOENT")
|
||||
return
|
||||
else
|
||||
throw er
|
||||
}
|
||||
|
||||
try {
|
||||
var stats = options.statSync(p)
|
||||
} catch (er3) {
|
||||
if (er3.code === "ENOENT")
|
||||
return
|
||||
else
|
||||
throw er
|
||||
}
|
||||
|
||||
if (stats.isDirectory())
|
||||
rmdirSync(p, options, er)
|
||||
else
|
||||
options.unlinkSync(p)
|
||||
}
|
||||
|
||||
function rmdir (p, options, originalEr, cb) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
if (originalEr)
|
||||
assert(originalEr instanceof Error)
|
||||
assert(typeof cb === 'function')
|
||||
|
||||
// try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
|
||||
// if we guessed wrong, and it's not a directory, then
|
||||
// raise the original error.
|
||||
options.rmdir(p, function (er) {
|
||||
if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
|
||||
rmkids(p, options, cb)
|
||||
else if (er && er.code === "ENOTDIR")
|
||||
cb(originalEr)
|
||||
else
|
||||
cb(er)
|
||||
})
|
||||
}
|
||||
|
||||
function rmkids(p, options, cb) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
assert(typeof cb === 'function')
|
||||
|
||||
options.readdir(p, function (er, files) {
|
||||
if (er)
|
||||
return cb(er)
|
||||
var n = files.length
|
||||
if (n === 0)
|
||||
return options.rmdir(p, cb)
|
||||
var errState
|
||||
files.forEach(function (f) {
|
||||
rimraf(path.join(p, f), options, function (er) {
|
||||
if (errState)
|
||||
return
|
||||
if (er)
|
||||
return cb(errState = er)
|
||||
if (--n === 0)
|
||||
options.rmdir(p, cb)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// this looks simpler, and is strictly *faster*, but will
|
||||
// tie up the JavaScript thread and fail on excessively
|
||||
// deep directory trees.
|
||||
function rimrafSync (p, options) {
|
||||
options = options || {}
|
||||
defaults(options)
|
||||
|
||||
assert(p, 'rimraf: missing path')
|
||||
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert(options, 'rimraf: missing options')
|
||||
assert.equal(typeof options, 'object', 'rimraf: options should be object')
|
||||
|
||||
var results
|
||||
|
||||
if (options.disableGlob || !glob.hasMagic(p)) {
|
||||
results = [p]
|
||||
} else {
|
||||
try {
|
||||
options.lstatSync(p)
|
||||
results = [p]
|
||||
} catch (er) {
|
||||
results = glob.sync(p, options.glob)
|
||||
}
|
||||
}
|
||||
|
||||
if (!results.length)
|
||||
return
|
||||
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
var p = results[i]
|
||||
|
||||
try {
|
||||
var st = options.lstatSync(p)
|
||||
} catch (er) {
|
||||
if (er.code === "ENOENT")
|
||||
return
|
||||
|
||||
// Windows can EPERM on stat. Life is suffering.
|
||||
if (er.code === "EPERM" && isWindows)
|
||||
fixWinEPERMSync(p, options, er)
|
||||
}
|
||||
|
||||
try {
|
||||
// sunos lets the root user unlink directories, which is... weird.
|
||||
if (st && st.isDirectory())
|
||||
rmdirSync(p, options, null)
|
||||
else
|
||||
options.unlinkSync(p)
|
||||
} catch (er) {
|
||||
if (er.code === "ENOENT")
|
||||
return
|
||||
if (er.code === "EPERM")
|
||||
return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
|
||||
if (er.code !== "EISDIR")
|
||||
throw er
|
||||
|
||||
rmdirSync(p, options, er)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rmdirSync (p, options, originalEr) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
if (originalEr)
|
||||
assert(originalEr instanceof Error)
|
||||
|
||||
try {
|
||||
options.rmdirSync(p)
|
||||
} catch (er) {
|
||||
if (er.code === "ENOENT")
|
||||
return
|
||||
if (er.code === "ENOTDIR")
|
||||
throw originalEr
|
||||
if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
|
||||
rmkidsSync(p, options)
|
||||
}
|
||||
}
|
||||
|
||||
function rmkidsSync (p, options) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
options.readdirSync(p).forEach(function (f) {
|
||||
rimrafSync(path.join(p, f), options)
|
||||
})
|
||||
|
||||
// We only end up here once we got ENOTEMPTY at least once, and
|
||||
// at this point, we are guaranteed to have removed all the kids.
|
||||
// So, we know that it won't be ENOENT or ENOTDIR or anything else.
|
||||
// try really hard to delete stuff on windows, because it has a
|
||||
// PROFOUNDLY annoying habit of not closing handles promptly when
|
||||
// files are deleted, resulting in spurious ENOTEMPTY errors.
|
||||
var retries = isWindows ? 100 : 1
|
||||
var i = 0
|
||||
do {
|
||||
var threw = true
|
||||
try {
|
||||
var ret = options.rmdirSync(p, options)
|
||||
threw = false
|
||||
return ret
|
||||
} finally {
|
||||
if (++i < retries && threw)
|
||||
continue
|
||||
}
|
||||
} while (true)
|
||||
}
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@npmcli/move-file",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"description": "move a file (fork of move-file)",
|
||||
"dependencies": {
|
||||
"mkdirp": "^1.0.4",
|
||||
"rimraf": "^2.7.1"
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"require-inject": "^1.4.4",
|
||||
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
[
|
||||
"3dm",
|
||||
"3ds",
|
||||
"3g2",
|
||||
"3gp",
|
||||
"7z",
|
||||
"a",
|
||||
"aac",
|
||||
"adp",
|
||||
"ai",
|
||||
"aif",
|
||||
"aiff",
|
||||
"alz",
|
||||
"ape",
|
||||
"apk",
|
||||
"appimage",
|
||||
"ar",
|
||||
"arj",
|
||||
"asf",
|
||||
"au",
|
||||
"avi",
|
||||
"bak",
|
||||
"baml",
|
||||
"bh",
|
||||
"bin",
|
||||
"bk",
|
||||
"bmp",
|
||||
"btif",
|
||||
"bz2",
|
||||
"bzip2",
|
||||
"cab",
|
||||
"caf",
|
||||
"cgm",
|
||||
"class",
|
||||
"cmx",
|
||||
"cpio",
|
||||
"cr2",
|
||||
"cur",
|
||||
"dat",
|
||||
"dcm",
|
||||
"deb",
|
||||
"dex",
|
||||
"djvu",
|
||||
"dll",
|
||||
"dmg",
|
||||
"dng",
|
||||
"doc",
|
||||
"docm",
|
||||
"docx",
|
||||
"dot",
|
||||
"dotm",
|
||||
"dra",
|
||||
"DS_Store",
|
||||
"dsk",
|
||||
"dts",
|
||||
"dtshd",
|
||||
"dvb",
|
||||
"dwg",
|
||||
"dxf",
|
||||
"ecelp4800",
|
||||
"ecelp7470",
|
||||
"ecelp9600",
|
||||
"egg",
|
||||
"eol",
|
||||
"eot",
|
||||
"epub",
|
||||
"exe",
|
||||
"f4v",
|
||||
"fbs",
|
||||
"fh",
|
||||
"fla",
|
||||
"flac",
|
||||
"flatpak",
|
||||
"fli",
|
||||
"flv",
|
||||
"fpx",
|
||||
"fst",
|
||||
"fvt",
|
||||
"g3",
|
||||
"gh",
|
||||
"gif",
|
||||
"graffle",
|
||||
"gz",
|
||||
"gzip",
|
||||
"h261",
|
||||
"h263",
|
||||
"h264",
|
||||
"icns",
|
||||
"ico",
|
||||
"ief",
|
||||
"img",
|
||||
"ipa",
|
||||
"iso",
|
||||
"jar",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"jpgv",
|
||||
"jpm",
|
||||
"jxr",
|
||||
"key",
|
||||
"ktx",
|
||||
"lha",
|
||||
"lib",
|
||||
"lvp",
|
||||
"lz",
|
||||
"lzh",
|
||||
"lzma",
|
||||
"lzo",
|
||||
"m3u",
|
||||
"m4a",
|
||||
"m4v",
|
||||
"mar",
|
||||
"mdi",
|
||||
"mht",
|
||||
"mid",
|
||||
"midi",
|
||||
"mj2",
|
||||
"mka",
|
||||
"mkv",
|
||||
"mmr",
|
||||
"mng",
|
||||
"mobi",
|
||||
"mov",
|
||||
"movie",
|
||||
"mp3",
|
||||
"mp4",
|
||||
"mp4a",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"mpga",
|
||||
"mxu",
|
||||
"nef",
|
||||
"npx",
|
||||
"numbers",
|
||||
"nupkg",
|
||||
"o",
|
||||
"odp",
|
||||
"ods",
|
||||
"odt",
|
||||
"oga",
|
||||
"ogg",
|
||||
"ogv",
|
||||
"otf",
|
||||
"ott",
|
||||
"pages",
|
||||
"pbm",
|
||||
"pcx",
|
||||
"pdb",
|
||||
"pdf",
|
||||
"pea",
|
||||
"pgm",
|
||||
"pic",
|
||||
"png",
|
||||
"pnm",
|
||||
"pot",
|
||||
"potm",
|
||||
"potx",
|
||||
"ppa",
|
||||
"ppam",
|
||||
"ppm",
|
||||
"pps",
|
||||
"ppsm",
|
||||
"ppsx",
|
||||
"ppt",
|
||||
"pptm",
|
||||
"pptx",
|
||||
"psd",
|
||||
"pya",
|
||||
"pyc",
|
||||
"pyo",
|
||||
"pyv",
|
||||
"qt",
|
||||
"rar",
|
||||
"ras",
|
||||
"raw",
|
||||
"resources",
|
||||
"rgb",
|
||||
"rip",
|
||||
"rlc",
|
||||
"rmf",
|
||||
"rmvb",
|
||||
"rpm",
|
||||
"rtf",
|
||||
"rz",
|
||||
"s3m",
|
||||
"s7z",
|
||||
"scpt",
|
||||
"sgi",
|
||||
"shar",
|
||||
"snap",
|
||||
"sil",
|
||||
"sketch",
|
||||
"slk",
|
||||
"smv",
|
||||
"snk",
|
||||
"so",
|
||||
"stl",
|
||||
"suo",
|
||||
"sub",
|
||||
"swf",
|
||||
"tar",
|
||||
"tbz",
|
||||
"tbz2",
|
||||
"tga",
|
||||
"tgz",
|
||||
"thmx",
|
||||
"tif",
|
||||
"tiff",
|
||||
"tlz",
|
||||
"ttc",
|
||||
"ttf",
|
||||
"txz",
|
||||
"udf",
|
||||
"uvh",
|
||||
"uvi",
|
||||
"uvm",
|
||||
"uvp",
|
||||
"uvs",
|
||||
"uvu",
|
||||
"viv",
|
||||
"vob",
|
||||
"war",
|
||||
"wav",
|
||||
"wax",
|
||||
"wbmp",
|
||||
"wdp",
|
||||
"weba",
|
||||
"webm",
|
||||
"webp",
|
||||
"whl",
|
||||
"wim",
|
||||
"wm",
|
||||
"wma",
|
||||
"wmv",
|
||||
"wmx",
|
||||
"woff",
|
||||
"woff2",
|
||||
"wrm",
|
||||
"wvx",
|
||||
"xbm",
|
||||
"xif",
|
||||
"xla",
|
||||
"xlam",
|
||||
"xls",
|
||||
"xlsb",
|
||||
"xlsm",
|
||||
"xlsx",
|
||||
"xlt",
|
||||
"xltm",
|
||||
"xltx",
|
||||
"xm",
|
||||
"xmind",
|
||||
"xpi",
|
||||
"xpm",
|
||||
"xwd",
|
||||
"xz",
|
||||
"z",
|
||||
"zip",
|
||||
"zipx"
|
||||
]
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare const binaryExtensionsJson: readonly string[];
|
||||
|
||||
export = binaryExtensionsJson;
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
List of binary file extensions.
|
||||
|
||||
@example
|
||||
```
|
||||
import binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
*/
|
||||
declare const binaryExtensions: readonly string[];
|
||||
|
||||
export = binaryExtensions;
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = require('./binary-extensions.json');
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com), Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "binary-extensions",
|
||||
"version": "2.2.0",
|
||||
"description": "List of binary file extensions",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/binary-extensions",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"binary-extensions.json",
|
||||
"binary-extensions.json.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"binary",
|
||||
"extensions",
|
||||
"extension",
|
||||
"file",
|
||||
"json",
|
||||
"list",
|
||||
"array"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"tsd": "^0.7.2",
|
||||
"xo": "^0.24.0"
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# binary-extensions
|
||||
|
||||
> List of binary file extensions
|
||||
|
||||
The list is just a [JSON file](binary-extensions.json) and can be used anywhere.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install binary-extensions
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file
|
||||
- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions
|
||||
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<b>
|
||||
<a href="https://tidelift.com/subscription/pkg/npm-binary-extensions?utm_source=npm-binary-extensions&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
|
||||
</b>
|
||||
<br>
|
||||
<sub>
|
||||
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
|
||||
</sub>
|
||||
</div>
|
||||
+10
@@ -2,6 +2,16 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
<a name="3.0.8"></a>
|
||||
## [3.0.8](https://github.com/npm/hosted-git-info/compare/v3.0.7...v3.0.8) (2021-01-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* simplify the regular expression for shortcut matching ([bede0dc](https://github.com/npm/hosted-git-info/commit/bede0dc)), closes [#76](https://github.com/npm/hosted-git-info/issues/76)
|
||||
|
||||
|
||||
|
||||
<a name="3.0.7"></a>
|
||||
## [3.0.7](https://github.com/npm/hosted-git-info/compare/v3.0.6...v3.0.7) (2020-10-15)
|
||||
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ function fromUrl (giturl, opts) {
|
||||
isGitHubShorthand(giturl) ? 'github:' + giturl : giturl
|
||||
)
|
||||
var parsed = parseGitUrl(url)
|
||||
var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)'))
|
||||
var shortcutMatch = url.match(/^([^:]+):(?:[^@]+@)?(?:([^/]*)\/)?([^#]+)/)
|
||||
var matches = Object.keys(gitHosts).map(function (gitHostName) {
|
||||
try {
|
||||
var gitHostInfo = gitHosts[gitHostName]
|
||||
@@ -55,7 +55,7 @@ function fromUrl (giturl, opts) {
|
||||
var defaultRepresentation = null
|
||||
if (shortcutMatch && shortcutMatch[1] === gitHostName) {
|
||||
user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2])
|
||||
project = decodeURIComponent(shortcutMatch[3])
|
||||
project = decodeURIComponent(shortcutMatch[3].replace(/\.git$/, ''))
|
||||
defaultRepresentation = 'shortcut'
|
||||
} else {
|
||||
if (parsed.host && parsed.host !== gitHostInfo.domain && parsed.host.replace(/^www[.]/, '') !== gitHostInfo.domain) return
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hosted-git-info",
|
||||
"version": "3.0.7",
|
||||
"version": "3.0.8",
|
||||
"description": "Provides metadata and conversions from repository urls for Github, Bitbucket and Gitlab",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## 2.0.3
|
||||
|
||||
- fix name of options sent by the npm cli
|
||||
|
||||
## 2.0.2
|
||||
|
||||
- fix matching basename file filter
|
||||
|
||||
## 2.0.1
|
||||
|
||||
- fix for tarballs not listing folder names
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- API rewrite:
|
||||
- normalized all options
|
||||
- specs to compare are now an array
|
||||
- fix context=0
|
||||
- added support to filtering by folder names
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- fixed nameOnly option
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial release
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) GitHub Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
# libnpmdiff
|
||||
|
||||
[](https://npm.im/libnpmdiff)
|
||||
[](https://npm.im/libnpmdiff)
|
||||
[](https://github.com/npm/libnpmdiff/actions?query=workflow%3Anode-ci)
|
||||
[](https://coveralls.io/github/npm/libnpmdiff?branch=main)
|
||||
|
||||
The registry diff lib.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Example](#example)
|
||||
* [Install](#install)
|
||||
* [Contributing](#contributing)
|
||||
* [API](#api)
|
||||
* [LICENSE](#license)
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const libdiff = require('libnpmdiff')
|
||||
|
||||
const patch = await libdiff([
|
||||
'abbrev@1.1.0',
|
||||
'abbrev@1.1.1'
|
||||
])
|
||||
console.log(
|
||||
patch
|
||||
)
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```patch
|
||||
diff --git a/package.json b/package.json
|
||||
index v1.1.0..v1.1.1 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
- "version": "1.1.0",
|
||||
+ "version": "1.1.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"main": "abbrev.js",
|
||||
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
`$ npm install libnpmdiff`
|
||||
|
||||
### Contributing
|
||||
|
||||
The npm team enthusiastically welcomes contributions and project participation!
|
||||
There's a bunch of things you can do if you want to contribute! The
|
||||
[Contributor Guide](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md)
|
||||
outlines the process for community interaction and contribution. Please don't
|
||||
hesitate to jump in if you'd like to, or even ask us questions if something
|
||||
isn't clear.
|
||||
|
||||
All participants and maintainers in this project are expected to follow the
|
||||
[npm Code of Conduct](https://www.npmjs.com/policies/conduct), and just
|
||||
generally be excellent to each other.
|
||||
|
||||
Please refer to the [Changelog](CHANGELOG.md) for project history details, too.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
### API
|
||||
|
||||
#### `> libnpmdif([ a, b ], [opts]) -> Promise<String>`
|
||||
|
||||
Fetches the registry tarballs and compare files between a spec `a` and spec `b`. **npm** spec types are usually described in `<pkg-name>@<version>` form but multiple other types are alsos supported, for more info on valid specs take a look at [`npm-package-arg`](https://github.com/npm/npm-package-arg).
|
||||
|
||||
**Options**:
|
||||
|
||||
- `color <Boolean>`: Should add ANSI colors to string output? Defaults to `false`.
|
||||
- `tagVersionPrefix <Sring>`: What prefix should be used to define version numbers. Defaults to `v`
|
||||
- `diffUnified <Number>`: How many lines of code to print before/after each diff. Defaults to `3`.
|
||||
- `diffFiles <Array<String>>`: If set only prints patches for the files listed in this array (also accepts globs). Defaults to `undefined`.
|
||||
- `diffIgnoreAllSpace <Boolean>`: Whether or not should ignore changes in whitespace (very useful to avoid indentation changes extra diff lines). Defaults to `false`.
|
||||
- `diffNameOnly <Boolean>`: Prints only file names and no patch diffs. Defaults to `false`.
|
||||
- `diffNoPrefix <Boolean>`: If true then skips printing any prefixes in filenames. Defaults to `false`.
|
||||
- `diffSrcPrefix <String>`: Prefix to be used in the filenames from `a`. Defaults to `a/`.
|
||||
- `diffDstPrefix <String>`: Prefix to be used in the filenames from `b`. Defaults to `b/`.
|
||||
- `diffText <Boolean>`: Should treat all files as text and try to print diff for binary files. Defaults to `false`.
|
||||
- ...`cache`, `registry` and other common options accepted by [pacote](https://github.com/npm/pacote#options)
|
||||
|
||||
Returns a `Promise` that fullfils with a `String` containing the resulting patch diffs.
|
||||
|
||||
Throws an error if either `a` or `b` are missing or if trying to diff more than two specs.
|
||||
|
||||
## LICENSE
|
||||
|
||||
[ISC](./LICENSE)
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
const pacote = require('pacote')
|
||||
|
||||
const formatDiff = require('./lib/format-diff.js')
|
||||
const untar = require('./lib/untar.js')
|
||||
|
||||
const argsError = () =>
|
||||
Object.assign(
|
||||
new TypeError('libnpmdiff needs two arguments to compare'),
|
||||
{ code: 'EDIFFARGS' }
|
||||
)
|
||||
const diff = async (specs, opts = {}) => {
|
||||
if (specs.length !== 2)
|
||||
throw argsError()
|
||||
|
||||
const [
|
||||
aManifest,
|
||||
bManifest,
|
||||
] =
|
||||
await Promise.all(specs.map(spec => pacote.manifest(spec, opts)))
|
||||
|
||||
const versions = {
|
||||
a: aManifest.version,
|
||||
b: bManifest.version,
|
||||
}
|
||||
|
||||
// fetches tarball using pacote
|
||||
const [a, b] = await Promise.all([
|
||||
pacote.tarball(aManifest._resolved, opts),
|
||||
pacote.tarball(bManifest._resolved, opts),
|
||||
])
|
||||
|
||||
// read all files
|
||||
// populates `files` and `refs`
|
||||
const {
|
||||
files,
|
||||
refs,
|
||||
} = await untar([
|
||||
{
|
||||
prefix: 'a/',
|
||||
item: a,
|
||||
},
|
||||
{
|
||||
prefix: 'b/',
|
||||
item: b,
|
||||
},
|
||||
], opts)
|
||||
|
||||
return formatDiff({
|
||||
files,
|
||||
opts,
|
||||
refs,
|
||||
versions,
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = diff
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
const EOL = '\n'
|
||||
|
||||
const colorizeDiff = require('@npmcli/disparity-colors')
|
||||
const jsDiff = require('diff')
|
||||
|
||||
const shouldPrintPatch = require('./should-print-patch.js')
|
||||
|
||||
const formatDiff = ({ files, opts = {}, refs, versions }) => {
|
||||
let res = ''
|
||||
const srcPrefix = opts.diffNoPrefix ? '' : opts.diffSrcPrefix || 'a/'
|
||||
const dstPrefix = opts.diffNoPrefix ? '' : opts.diffDstPrefix || 'b/'
|
||||
|
||||
for (const filename of files.values()) {
|
||||
const names = {
|
||||
a: `${srcPrefix}${filename}`,
|
||||
b: `${dstPrefix}${filename}`,
|
||||
}
|
||||
|
||||
let fileMode = ''
|
||||
const filenames = {
|
||||
a: refs.get(`a/${filename}`),
|
||||
b: refs.get(`b/${filename}`),
|
||||
}
|
||||
const contents = {
|
||||
a: filenames.a && filenames.a.content,
|
||||
b: filenames.b && filenames.b.content,
|
||||
}
|
||||
const modes = {
|
||||
a: filenames.a && filenames.a.mode,
|
||||
b: filenames.b && filenames.b.mode,
|
||||
}
|
||||
|
||||
if (contents.a === contents.b && modes.a === modes.b)
|
||||
continue
|
||||
|
||||
if (opts.diffNameOnly) {
|
||||
res += `${filename}${EOL}`
|
||||
continue
|
||||
}
|
||||
|
||||
let patch = ''
|
||||
let headerLength = 0
|
||||
const header = str => {
|
||||
headerLength++
|
||||
patch += `${str}${EOL}`
|
||||
}
|
||||
|
||||
// manually build a git diff-compatible header
|
||||
header(`diff --git ${names.a} ${names.b}`)
|
||||
if (modes.a === modes.b)
|
||||
fileMode = filenames.a.mode
|
||||
else {
|
||||
if (modes.a && !modes.b)
|
||||
header(`deleted file mode ${modes.a}`)
|
||||
else if (!modes.a && modes.b)
|
||||
header(`new file mode ${modes.b}`)
|
||||
else {
|
||||
header(`old mode ${modes.a}`)
|
||||
header(`new mode ${modes.b}`)
|
||||
}
|
||||
}
|
||||
header(`index ${opts.tagVersionPrefix || 'v'}${versions.a}..${opts.tagVersionPrefix || 'v'}${versions.b} ${fileMode}`)
|
||||
|
||||
if (shouldPrintPatch(filename)) {
|
||||
patch += jsDiff.createTwoFilesPatch(
|
||||
names.a,
|
||||
names.b,
|
||||
contents.a || '',
|
||||
contents.b || '',
|
||||
'',
|
||||
'',
|
||||
{
|
||||
context: opts.diffUnified === 0 ? 0 : opts.diffUnified || 3,
|
||||
ignoreWhitespace: opts.diffIgnoreAllSpace,
|
||||
}
|
||||
).replace(
|
||||
'===================================================================\n',
|
||||
''
|
||||
).replace(/\t\n/g, '\n') // strip trailing tabs
|
||||
headerLength += 2
|
||||
} else {
|
||||
header(`--- ${names.a}`)
|
||||
header(`+++ ${names.b}`)
|
||||
}
|
||||
|
||||
res += (opts.color
|
||||
? colorizeDiff(patch, { headerLength })
|
||||
: patch)
|
||||
}
|
||||
|
||||
return res.trim()
|
||||
}
|
||||
|
||||
module.exports = formatDiff
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
const { basename, extname } = require('path')
|
||||
|
||||
const binaryExtensions = require('binary-extensions')
|
||||
|
||||
// we should try to print patches as long as the
|
||||
// extension is not identified as binary files
|
||||
const shouldPrintPatch = (path, opts = {}) => {
|
||||
if (opts.diffText)
|
||||
return true
|
||||
|
||||
const filename = basename(path)
|
||||
const extension = (
|
||||
filename.startsWith('.')
|
||||
? filename
|
||||
: extname(filename)
|
||||
).substr(1)
|
||||
|
||||
return !binaryExtensions.includes(extension)
|
||||
}
|
||||
|
||||
module.exports = shouldPrintPatch
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
const tar = require('tar')
|
||||
const minimatch = require('minimatch')
|
||||
|
||||
const normalizeMatch = str => str
|
||||
.replace(/\\+/g, '/')
|
||||
.replace(/^\.\/|^\./, '')
|
||||
|
||||
// files and refs are mutating params
|
||||
// filterFiles, item, prefix and opts are read-only options
|
||||
const untar = ({ files, refs }, { filterFiles, item, prefix }) => {
|
||||
tar.list({
|
||||
filter: (path, entry) => {
|
||||
const fileMatch = () =>
|
||||
(!filterFiles.length ||
|
||||
filterFiles.some(f => {
|
||||
const pattern = normalizeMatch(f)
|
||||
return minimatch(
|
||||
normalizeMatch(path),
|
||||
`{package/,}${pattern}`,
|
||||
{ matchBase: pattern.startsWith('*') }
|
||||
)
|
||||
}))
|
||||
|
||||
// expands usage of simple path filters, e.g: lib or src/
|
||||
const folderMatch = () =>
|
||||
filterFiles.some(f =>
|
||||
normalizeMatch(path).startsWith(normalizeMatch(f)) ||
|
||||
normalizeMatch(path).startsWith(`package/${normalizeMatch(f)}`))
|
||||
|
||||
if (
|
||||
entry.type === 'File' &&
|
||||
(fileMatch() || folderMatch())
|
||||
) {
|
||||
const key = path.replace(/^[^/]+\/?/, '')
|
||||
files.add(key)
|
||||
|
||||
// should skip reading file when using --name-only option
|
||||
let content
|
||||
try {
|
||||
entry.setEncoding('utf8')
|
||||
content = entry.concat()
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
throw Object.assign(
|
||||
new Error('failed to read files'),
|
||||
{ code: 'EDIFFUNTAR' }
|
||||
)
|
||||
}
|
||||
|
||||
refs.set(`${prefix}${key}`, {
|
||||
content,
|
||||
mode: `100${entry.mode.toString(8)}`,
|
||||
})
|
||||
return true
|
||||
}
|
||||
},
|
||||
})
|
||||
.on('error', /* istanbul ignore next */ e => {
|
||||
throw e
|
||||
})
|
||||
.end(item)
|
||||
}
|
||||
|
||||
const readTarballs = async (tarballs, opts = {}) => {
|
||||
const files = new Set()
|
||||
const refs = new Map()
|
||||
const arr = [].concat(tarballs)
|
||||
|
||||
const filterFiles = opts.diffFiles || []
|
||||
|
||||
for (const i of arr) {
|
||||
untar({
|
||||
files,
|
||||
refs,
|
||||
}, {
|
||||
item: i.item,
|
||||
prefix: i.prefix,
|
||||
filterFiles,
|
||||
})
|
||||
}
|
||||
|
||||
// await to read all content from included files
|
||||
const allRefs = [...refs.values()]
|
||||
const contents = await Promise.all(allRefs.map(async ref => ref.content))
|
||||
|
||||
contents.forEach((content, index) => {
|
||||
allRefs[index].content = content
|
||||
})
|
||||
|
||||
return {
|
||||
files,
|
||||
refs,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = readTarballs
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
# How to Contribute
|
||||
|
||||
## Pull Requests
|
||||
|
||||
We also accept [pull requests][pull-request]!
|
||||
|
||||
Generally we like to see pull requests that
|
||||
|
||||
- Maintain the existing code style
|
||||
- Are focused on a single change (i.e. avoid large refactoring or style adjustments in untouched code if not the primary goal of the pull request)
|
||||
- Have [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
|
||||
- Have tests
|
||||
- Don't decrease the current code coverage (see coverage/lcov-report/index.html)
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
npm install
|
||||
npm test
|
||||
```
|
||||
|
||||
The `npm test -- dev` implements watching for tests within Node and `karma start` may be used for manual testing in browsers.
|
||||
|
||||
If you notice any problems, please report them to the GitHub issue tracker at
|
||||
[http://github.com/kpdecker/jsdiff/issues](http://github.com/kpdecker/jsdiff/issues).
|
||||
|
||||
## Releasing
|
||||
|
||||
JsDiff utilizes the [release yeoman generator][generator-release] to perform most release tasks.
|
||||
|
||||
A full release may be completed with the following:
|
||||
|
||||
```
|
||||
yo release
|
||||
npm publish
|
||||
```
|
||||
|
||||
[generator-release]: https://github.com/walmartlabs/generator-release
|
||||
[pull-request]: https://github.com/kpdecker/jsdiff/pull/new/master
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2009-2015, Kevin Decker <kpdecker@gmail.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of Kevin Decker nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
# jsdiff
|
||||
|
||||
[](http://travis-ci.org/kpdecker/jsdiff)
|
||||
[](https://saucelabs.com/u/jsdiff)
|
||||
|
||||
A javascript text differencing implementation.
|
||||
|
||||
Based on the algorithm proposed in
|
||||
["An O(ND) Difference Algorithm and its Variations" (Myers, 1986)](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927).
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
npm install diff --save
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
* `Diff.diffChars(oldStr, newStr[, options])` - diffs two blocks of text, comparing character by character.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
Options
|
||||
* `ignoreCase`: `true` to ignore casing difference. Defaults to `false`.
|
||||
|
||||
* `Diff.diffWords(oldStr, newStr[, options])` - diffs two blocks of text, comparing word by word, ignoring whitespace.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
Options
|
||||
* `ignoreCase`: Same as in `diffChars`.
|
||||
|
||||
* `Diff.diffWordsWithSpace(oldStr, newStr[, options])` - diffs two blocks of text, comparing word by word, treating whitespace as significant.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffLines(oldStr, newStr[, options])` - diffs two blocks of text, comparing line by line.
|
||||
|
||||
Options
|
||||
* `ignoreWhitespace`: `true` to ignore leading and trailing whitespace. This is the same as `diffTrimmedLines`
|
||||
* `newlineIsToken`: `true` to treat newline characters as separate tokens. This allows for changes to the newline structure to occur independently of the line content and to be treated as such. In general this is the more human friendly form of `diffLines` and `diffLines` is better suited for patches and other computer friendly output.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffTrimmedLines(oldStr, newStr[, options])` - diffs two blocks of text, comparing line by line, ignoring leading and trailing whitespace.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffSentences(oldStr, newStr[, options])` - diffs two blocks of text, comparing sentence by sentence.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffCss(oldStr, newStr[, options])` - diffs two blocks of text, comparing CSS tokens.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffJson(oldObj, newObj[, options])` - diffs two JSON objects, comparing the fields defined on each. The order of fields, etc does not matter in this comparison.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.diffArrays(oldArr, newArr[, options])` - diffs two arrays, comparing each item for strict equality (===).
|
||||
|
||||
Options
|
||||
* `comparator`: `function(left, right)` for custom equality checks
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `Diff.createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader)` - creates a unified diff patch.
|
||||
|
||||
Parameters:
|
||||
* `oldFileName` : String to be output in the filename section of the patch for the removals
|
||||
* `newFileName` : String to be output in the filename section of the patch for the additions
|
||||
* `oldStr` : Original string value
|
||||
* `newStr` : New string value
|
||||
* `oldHeader` : Additional information to include in the old file header
|
||||
* `newHeader` : Additional information to include in the new file header
|
||||
* `options` : An object with options. Currently, only `context` is supported and describes how many lines of context should be included.
|
||||
|
||||
* `Diff.createPatch(fileName, oldStr, newStr, oldHeader, newHeader)` - creates a unified diff patch.
|
||||
|
||||
Just like Diff.createTwoFilesPatch, but with oldFileName being equal to newFileName.
|
||||
|
||||
|
||||
* `Diff.structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)` - returns an object with an array of hunk objects.
|
||||
|
||||
This method is similar to createTwoFilesPatch, but returns a data structure
|
||||
suitable for further processing. Parameters are the same as createTwoFilesPatch. The data structure returned may look like this:
|
||||
|
||||
```js
|
||||
{
|
||||
oldFileName: 'oldfile', newFileName: 'newfile',
|
||||
oldHeader: 'header1', newHeader: 'header2',
|
||||
hunks: [{
|
||||
oldStart: 1, oldLines: 3, newStart: 1, newLines: 3,
|
||||
lines: [' line2', ' line3', '-line4', '+line5', '\\ No newline at end of file'],
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
* `Diff.applyPatch(source, patch[, options])` - applies a unified diff patch.
|
||||
|
||||
Return a string containing new version of provided data. `patch` may be a string diff or the output from the `parsePatch` or `structuredPatch` methods.
|
||||
|
||||
The optional `options` object may have the following keys:
|
||||
|
||||
- `fuzzFactor`: Number of lines that are allowed to differ before rejecting a patch. Defaults to 0.
|
||||
- `compareLine(lineNumber, line, operation, patchContent)`: Callback used to compare to given lines to determine if they should be considered equal when patching. Defaults to strict equality but may be overridden to provide fuzzier comparison. Should return false if the lines should be rejected.
|
||||
|
||||
* `Diff.applyPatches(patch, options)` - applies one or more patches.
|
||||
|
||||
This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is:
|
||||
|
||||
- `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution.
|
||||
- `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution.
|
||||
|
||||
Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made.
|
||||
|
||||
* `Diff.parsePatch(diffStr)` - Parses a patch into structured data
|
||||
|
||||
Return a JSON object representation of the a patch, suitable for use with the `applyPatch` method. This parses to the same structure returned by `Diff.structuredPatch`.
|
||||
|
||||
* `convertChangesToXML(changes)` - converts a list of changes to a serialized XML format
|
||||
|
||||
|
||||
All methods above which accept the optional `callback` method will run in sync mode when that parameter is omitted and in async mode when supplied. This allows for larger diffs without blocking the event loop. This may be passed either directly as the final parameter or as the `callback` field in the `options` object.
|
||||
|
||||
### Change Objects
|
||||
Many of the methods above return change objects. These objects consist of the following fields:
|
||||
|
||||
* `value`: Text content
|
||||
* `added`: True if the value was inserted into the new string
|
||||
* `removed`: True if the value was removed from the old string
|
||||
|
||||
Note that some cases may omit a particular flag field. Comparison on the flag fields should always be done in a truthy or falsy manner.
|
||||
|
||||
## Examples
|
||||
|
||||
Basic example in Node
|
||||
|
||||
```js
|
||||
require('colors');
|
||||
const Diff = require('diff');
|
||||
|
||||
const one = 'beep boop';
|
||||
const other = 'beep boob blah';
|
||||
|
||||
const diff = Diff.diffChars(one, other);
|
||||
|
||||
diff.forEach((part) => {
|
||||
// green for additions, red for deletions
|
||||
// grey for common parts
|
||||
const color = part.added ? 'green' :
|
||||
part.removed ? 'red' : 'grey';
|
||||
process.stderr.write(part.value[color]);
|
||||
});
|
||||
|
||||
console.log();
|
||||
```
|
||||
Running the above program should yield
|
||||
|
||||
<img src="images/node_example.png" alt="Node Example">
|
||||
|
||||
Basic example in a web page
|
||||
|
||||
```html
|
||||
<pre id="display"></pre>
|
||||
<script src="diff.js"></script>
|
||||
<script>
|
||||
const one = 'beep boop',
|
||||
other = 'beep boob blah',
|
||||
color = '';
|
||||
|
||||
let span = null;
|
||||
|
||||
const diff = Diff.diffChars(one, other),
|
||||
display = document.getElementById('display'),
|
||||
fragment = document.createDocumentFragment();
|
||||
|
||||
diff.forEach((part) => {
|
||||
// green for additions, red for deletions
|
||||
// grey for common parts
|
||||
const color = part.added ? 'green' :
|
||||
part.removed ? 'red' : 'grey';
|
||||
span = document.createElement('span');
|
||||
span.style.color = color;
|
||||
span.appendChild(document
|
||||
.createTextNode(part.value));
|
||||
fragment.appendChild(span);
|
||||
});
|
||||
|
||||
display.appendChild(fragment);
|
||||
</script>
|
||||
```
|
||||
|
||||
Open the above .html file in a browser and you should see
|
||||
|
||||
<img src="images/web_example.png" alt="Node Example">
|
||||
|
||||
**[Full online demo](http://kpdecker.github.com/jsdiff)**
|
||||
|
||||
## Compatibility
|
||||
|
||||
[](https://saucelabs.com/u/jsdiff)
|
||||
|
||||
jsdiff supports all ES3 environments with some known issues on IE8 and below. Under these browsers some diff algorithms such as word diff and others may fail due to lack of support for capturing groups in the `split` operation.
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](https://github.com/kpdecker/jsdiff/blob/master/LICENSE).
|
||||
+1582
File diff suppressed because it is too large.
Load diff
+32
@@ -0,0 +1,32 @@
|
||||
/*istanbul ignore start*/
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.convertChangesToDMP = convertChangesToDMP;
|
||||
|
||||
/*istanbul ignore end*/
|
||||
// See: http://code.google.com/p/google-diff-match-patch/wiki/API
|
||||
function convertChangesToDMP(changes) {
|
||||
var ret = [],
|
||||
change,
|
||||
operation;
|
||||
|
||||
for (var i = 0; i < changes.length; i++) {
|
||||
change = changes[i];
|
||||
|
||||
if (change.added) {
|
||||
operation = 1;
|
||||
} else if (change.removed) {
|
||||
operation = -1;
|
||||
} else {
|
||||
operation = 0;
|
||||
}
|
||||
|
||||
ret.push([operation, change.value]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb252ZXJ0L2RtcC5qcyJdLCJuYW1lcyI6WyJjb252ZXJ0Q2hhbmdlc1RvRE1QIiwiY2hhbmdlcyIsInJldCIsImNoYW5nZSIsIm9wZXJhdGlvbiIsImkiLCJsZW5ndGgiLCJhZGRlZCIsInJlbW92ZWQiLCJwdXNoIiwidmFsdWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ08sU0FBU0EsbUJBQVQsQ0FBNkJDLE9BQTdCLEVBQXNDO0FBQzNDLE1BQUlDLEdBQUcsR0FBRyxFQUFWO0FBQUEsTUFDSUMsTUFESjtBQUFBLE1BRUlDLFNBRko7O0FBR0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHSixPQUFPLENBQUNLLE1BQTVCLEVBQW9DRCxDQUFDLEVBQXJDLEVBQXlDO0FBQ3ZDRixJQUFBQSxNQUFNLEdBQUdGLE9BQU8sQ0FBQ0ksQ0FBRCxDQUFoQjs7QUFDQSxRQUFJRixNQUFNLENBQUNJLEtBQVgsRUFBa0I7QUFDaEJILE1BQUFBLFNBQVMsR0FBRyxDQUFaO0FBQ0QsS0FGRCxNQUVPLElBQUlELE1BQU0sQ0FBQ0ssT0FBWCxFQUFvQjtBQUN6QkosTUFBQUEsU0FBUyxHQUFHLENBQUMsQ0FBYjtBQUNELEtBRk0sTUFFQTtBQUNMQSxNQUFBQSxTQUFTLEdBQUcsQ0FBWjtBQUNEOztBQUVERixJQUFBQSxHQUFHLENBQUNPLElBQUosQ0FBUyxDQUFDTCxTQUFELEVBQVlELE1BQU0sQ0FBQ08sS0FBbkIsQ0FBVDtBQUNEOztBQUNELFNBQU9SLEdBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIFNlZTogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2dvb2dsZS1kaWZmLW1hdGNoLXBhdGNoL3dpa2kvQVBJXG5leHBvcnQgZnVuY3Rpb24gY29udmVydENoYW5nZXNUb0RNUChjaGFuZ2VzKSB7XG4gIGxldCByZXQgPSBbXSxcbiAgICAgIGNoYW5nZSxcbiAgICAgIG9wZXJhdGlvbjtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICBvcGVyYXRpb24gPSAxO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIG9wZXJhdGlvbiA9IC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcGVyYXRpb24gPSAwO1xuICAgIH1cblxuICAgIHJldC5wdXNoKFtvcGVyYXRpb24sIGNoYW5nZS52YWx1ZV0pO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG4iXX0=
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*istanbul ignore start*/
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.convertChangesToXML = convertChangesToXML;
|
||||
|
||||
/*istanbul ignore end*/
|
||||
function convertChangesToXML(changes) {
|
||||
var ret = [];
|
||||
|
||||
for (var i = 0; i < changes.length; i++) {
|
||||
var change = changes[i];
|
||||
|
||||
if (change.added) {
|
||||
ret.push('<ins>');
|
||||
} else if (change.removed) {
|
||||
ret.push('<del>');
|
||||
}
|
||||
|
||||
ret.push(escapeHTML(change.value));
|
||||
|
||||
if (change.added) {
|
||||
ret.push('</ins>');
|
||||
} else if (change.removed) {
|
||||
ret.push('</del>');
|
||||
}
|
||||
}
|
||||
|
||||
return ret.join('');
|
||||
}
|
||||
|
||||
function escapeHTML(s) {
|
||||
var n = s;
|
||||
n = n.replace(/&/g, '&');
|
||||
n = n.replace(/</g, '<');
|
||||
n = n.replace(/>/g, '>');
|
||||
n = n.replace(/"/g, '"');
|
||||
return n;
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb252ZXJ0L3htbC5qcyJdLCJuYW1lcyI6WyJjb252ZXJ0Q2hhbmdlc1RvWE1MIiwiY2hhbmdlcyIsInJldCIsImkiLCJsZW5ndGgiLCJjaGFuZ2UiLCJhZGRlZCIsInB1c2giLCJyZW1vdmVkIiwiZXNjYXBlSFRNTCIsInZhbHVlIiwiam9pbiIsInMiLCJuIiwicmVwbGFjZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQU8sU0FBU0EsbUJBQVQsQ0FBNkJDLE9BQTdCLEVBQXNDO0FBQzNDLE1BQUlDLEdBQUcsR0FBRyxFQUFWOztBQUNBLE9BQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsT0FBTyxDQUFDRyxNQUE1QixFQUFvQ0QsQ0FBQyxFQUFyQyxFQUF5QztBQUN2QyxRQUFJRSxNQUFNLEdBQUdKLE9BQU8sQ0FBQ0UsQ0FBRCxDQUFwQjs7QUFDQSxRQUFJRSxNQUFNLENBQUNDLEtBQVgsRUFBa0I7QUFDaEJKLE1BQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTLE9BQVQ7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDRyxPQUFYLEVBQW9CO0FBQ3pCTixNQUFBQSxHQUFHLENBQUNLLElBQUosQ0FBUyxPQUFUO0FBQ0Q7O0FBRURMLElBQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTRSxVQUFVLENBQUNKLE1BQU0sQ0FBQ0ssS0FBUixDQUFuQjs7QUFFQSxRQUFJTCxNQUFNLENBQUNDLEtBQVgsRUFBa0I7QUFDaEJKLE1BQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTLFFBQVQ7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDRyxPQUFYLEVBQW9CO0FBQ3pCTixNQUFBQSxHQUFHLENBQUNLLElBQUosQ0FBUyxRQUFUO0FBQ0Q7QUFDRjs7QUFDRCxTQUFPTCxHQUFHLENBQUNTLElBQUosQ0FBUyxFQUFULENBQVA7QUFDRDs7QUFFRCxTQUFTRixVQUFULENBQW9CRyxDQUFwQixFQUF1QjtBQUNyQixNQUFJQyxDQUFDLEdBQUdELENBQVI7QUFDQUMsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE9BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE1BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE1BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLFFBQWhCLENBQUo7QUFFQSxTQUFPRCxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gY29udmVydENoYW5nZXNUb1hNTChjaGFuZ2VzKSB7XG4gIGxldCByZXQgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGNoYW5nZSA9IGNoYW5nZXNbaV07XG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgcmV0LnB1c2goJzxpbnM+Jyk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgcmV0LnB1c2goJzxkZWw+Jyk7XG4gICAgfVxuXG4gICAgcmV0LnB1c2goZXNjYXBlSFRNTChjaGFuZ2UudmFsdWUpKTtcblxuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8L2lucz4nKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICByZXQucHVzaCgnPC9kZWw+Jyk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQuam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZUhUTUwocykge1xuICBsZXQgbiA9IHM7XG4gIG4gPSBuLnJlcGxhY2UoLyYvZywgJyZhbXA7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoLzwvZywgJyZsdDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvPi9nLCAnJmd0OycpO1xuICBuID0gbi5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG5cbiAgcmV0dXJuIG47XG59XG4iXX0=
|
||||
Loaded 100 of 133 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user