Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly parse non-url encoded file specs #200

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ Parses package name and specifier passed to commands like `npm install` or
## EXAMPLES

```javascript
var assert = require("assert")
var npa = require("npm-package-arg")
const assert = require("assert")
const npa = require("npm-package-arg")

// Pass in the descriptor, and it'll return an object
try {
var parsed = npa("@bar/foo@1.2")
const parsed = npa("@bar/foo@1.2")
} catch (ex) {
}
```

## USING

`var npa = require('npm-package-arg')`
`const npa = require('npm-package-arg')`

### var result = npa(*arg*[, *where*])
### const result = npa(*arg*[, *where*])

* *arg* - a string that you might pass to `npm install`, like:
`foo@1.2`, `@bar/foo@1.2`, `foo@user/foo`, `http://x.com/foo.tgz`,
Expand All @@ -34,7 +34,7 @@ part, eg `foo` then the specifier will default to `latest`.

**Throws** if the package name is invalid, a dist-tag is invalid or a URL's protocol is not supported.

### var result = npa.resolve(*name*, *spec*[, *where*])
### const result = npa.resolve(*name*, *spec*[, *where*])

* *name* - The name of the module you want to install. For example: `foo` or `@bar/foo`.
* *spec* - The specifier indicating where and how you can get this module. Something like:
Expand All @@ -45,7 +45,7 @@ included then the default is `latest`.

**Throws** if the package name is invalid, a dist-tag is invalid or a URL's protocol is not supported.

### var purl = npa.toPurl(*arg*, *reg*)
### const purl = npa.toPurl(*arg*, *reg*)

Returns the [purl (package URL)](https://github.com/package-url/purl-spec) form of the given package name/spec.

Expand Down Expand Up @@ -79,9 +79,9 @@ keys:
specification. Mostly used when making requests against a registry. When
`name` is `null`, `escapedName` will also be `null`.
* `rawSpec` - The specifier part that was parsed out in calls to `npa(arg)`,
or the value of `spec` in calls to `npa.resolve(name, spec).
or the value of `spec` in calls to `npa.resolve(name, spec)`.
* `saveSpec` - The normalized specifier, for saving to package.json files.
`null` for registry dependencies.
`null` for registry dependencies. See note below about how this is (not) encoded.
* `fetchSpec` - The version of the specifier to be used to fetch this
resource. `null` for shortcuts to hosted git dependencies as there isn't
just one URL to try with them.
Expand All @@ -94,3 +94,11 @@ keys:
`npa.resolve(name, spec)` then this will be `name + '@' + spec`.
* `subSpec` - If `type === 'alias'`, this is a Result Object for parsing the
target specifier for the alias.

## SAVE SPECS

TLDR: `file:` urls are NOT uri encoded.

Historically, npm would uri decode file package args, but did not do any uri encoding for the `saveSpec`. This meant that it generated incorrect saveSpecs for directories with characters that *looked* like encoded uri characters, and also that it could not parse directories with some unencoded uri characters (such as `%`).

In order to fix this, and to not break all existing versions of npm, this module now parses all file package args as not being uri encoded. And in order to not break all of the package.json files npm has made in the past, it also does not uri encode the saveSpec. This includes package args that start with `file:`. This does mean that npm `file:` package args are not RFC compliant, and making them so constitutes quite a breaking change.
Loading
Loading