Skip to content

Commit

Permalink
npa: Update to npm@5 semantics per the local-specifier RFC
Browse files Browse the repository at this point in the history
There are also a number of other changes to improve the experience of using
this library. `realize-package-specifier` should no longer be needed.

* New properties:
  * `registry` - If true this specifier refers to a resource hosted on a
    registry.  This is true for `tag`, `version` and `range` types.
  * `saveSpec` - A normalized form of the specifier that can be fed back
    into `npm-package-arg` to get identical results.
  * `fetchSpec` - The information necessary to fetch this resource without
    further processing.  For git sources, this can be passed directly to git
    clone, for files, `fs.readFile`, and so on.
  * `gitRange` - If the user requested a git URL with a semver range, eg
    `git+ssh://site.com/foo.git#semver:^1.0.0` then this holds the range part.
  * `gitCommittish' - If the user requested a git URL with a specific
    branch, tag or commit then this holds that value.

* Removed properties:
  * `spec` - Has been replaced by `saveSpec` and `fetchSpec` respectively.

* Changed properties:
  * `type` indicates what sort of specifier this is, values are: `file`,
    `directory`, `git`, `remote`, `version`, `range`, `tag`.
  * `hosted` is now a `hosted-git-info` object, not a map containing strings.

* Changes to local specifiers:
  * Trailing spaces on local specifiers are no longer trimmed.
  * The `spec` field for local specifiers is now a fully resolved path.
  * The type is now `file` or `directory, never `local`.
* Changes to git specifiers:
  * `saveSpec` does not remove the `git+` prefix. `fetchSpec` does.
* Changes to hosted git specifiers:
  * The `type` is now _git_.  You can check if something is hosted by
    looking at the `hosted` property.
  • Loading branch information
iarna committed Apr 14, 2017
1 parent f32cf53 commit 1ae38e5
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 349 deletions.
117 changes: 44 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
# npm-package-arg

Parse package name and specifier passed to commands like `npm install` or
`npm cache add`. This just parses the text given-- it's worth noting that
`npm` has further logic it applies by looking at your disk to figure out
what ambiguous specifiers are. If you want that logic, please see
[realize-package-specifier].

[realize-package-specifier]: https://www.npmjs.org/package/realize-package-specifier

Arguments look like: `[email protected]`, `@bar/[email protected]`, `foo@user/foo`, `http://x.com/foo.tgz`,
`git+https://github.com/user/foo`, `bitbucket:user/foo`, `foo.tar.gz` or `bar`
Parses package name and specifier passed to commands like `npm install` or
`npm cache add`, or as found in `package.json` dependency sections.

## EXAMPLES

Expand All @@ -18,93 +10,72 @@ var assert = require("assert")
var npa = require("npm-package-arg")

// Pass in the descriptor, and it'll return an object
var parsed = npa("@bar/[email protected]")

// Returns an object like:
{
raw: '@bar/[email protected]', // what was passed in
name: '@bar/foo', // the name of the package
escapedName: '@bar%2ffoo', // the escaped name, for making requests against a registry
scope: '@bar', // the scope of the package, or null
type: 'range', // the type of specifier this is
spec: '>=1.2.0 <1.3.0', // the expanded specifier
rawSpec: '1.2' // the specifier as passed in
}

// Parsing urls pointing at hosted git services produces a variation:
var parsed = npa("git+https://github.com/user/foo")

// Returns an object like:
{
raw: 'git+https://github.com/user/foo',
scope: null,
name: null,
escapedName: null,
rawSpec: 'git+https://github.com/user/foo',
spec: 'user/foo',
type: 'hosted',
hosted: {
type: 'github',
ssh: '[email protected]:user/foo.git',
sshurl: 'git+ssh://[email protected]/user/foo.git',
https: 'https://github.com/user/foo.git',
directUrl: 'https://raw.githubusercontent.com/user/foo/master/package.json'
}
try {
var parsed = npa("@bar/[email protected]")
} catch (ex) {
}

// Completely unreasonable invalid garbage throws an error
// Make sure you wrap this in a try/catch if you have not
// already sanitized the inputs!
assert.throws(function() {
npa("this is not \0 a valid package name or url")
})
```

## USING

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

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

Parses *arg* and returns a result object detailing what *arg* is.
* *arg* - a string that you might pass to `npm install`, like:
`[email protected]`, `@bar/[email protected]`, `foo@user/foo`, `http://x.com/foo.tgz`,
`git+https://github.com/user/foo`, `bitbucket:user/foo`, `foo.tar.gz`,
`../foo/bar/` or `bar`. If the *arg* you provide doesn't have a specifier
part, eg `foo` then the specifier will default to `latest`.
* *where* - Optionally the path to resolve file paths relative to. Defaults to `process.cwd()`

*arg* -- a package descriptor, like: `[email protected]`, or `foo@user/foo`, or
`http://x.com/foo.tgz`, or `git+https://github.com/user/foo`
**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*])

* *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:
`1.2`, `^1.7.17`, `http://x.com/foo.tgz`, `git+https://github.com/user/foo`,
`bitbucket:user/foo`, `file:foo.tar.gz` or `file:../foo/bar/`. If not
included then the default is `latest`.
* *where* - Optionally the path to resolve file paths relative to. Defaults to `process.cwd()`

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

## RESULT OBJECT

The objects that are returned by npm-package-arg contain the following
keys:

* `name` - If known, the `name` field expected in the resulting pkg.
* `type` - One of the following strings:
* `git` - A git repo
* `hosted` - A hosted project, from github, bitbucket or gitlab. Originally
either a full url pointing at one of these services or a shorthand like
`user/project` or `github:user/project` for github or `bitbucket:user/project`
for bitbucket.
* `tag` - A tagged version, like `"foo@latest"`
* `version` - A specific version number, like `"[email protected]"`
* `range` - A version range, like `"[email protected]"`
* `local` - A local file or folder path
* `file` - A local `.tar.gz`, `.tar` or `.tgz` file.
* `directory` - A local directory.
* `remote` - An http url (presumably to a tgz)
* `spec` - The "thing". URL, the range, git repo, etc.
* `hosted` - If type=hosted this will be an object with the following keys:
* `type` - github, bitbucket or gitlab
* `ssh` - The ssh path for this git repo
* `sshUrl` - The ssh URL for this git repo
* `httpsUrl` - The HTTPS URL for this git repo
* `directUrl` - The URL for the package.json in this git repo
* `raw` - The original un-modified string that was provided.
* `rawSpec` - The part after the `name@...`, as it was originally
provided.
* `registry` - If true this specifier refers to a resource hosted on a
registry. This is true for `tag`, `version` and `range` types.
* `name` - If known, the `name` field expected in the resulting pkg.
* `scope` - If a name is something like `@org/module` then the `scope`
field will be set to `@org`. If it doesn't have a scoped name, then
scope is `null`.
* `escapedName` - A version of `name` escaped to match the npm scoped packages
specification. Mostly used when making requests against a registry. When
`name` is `null`, `escapedName` will also be `null`.

If you only include a name and no specifier part, eg, `foo` or `foo@` then
a default of `latest` will be used (as of 4.1.0). This is contrast with
previous behavior where `*` was used.
* `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).
* `saveSpec` - The normalized specifier, for saving to package.json files.
`null` for registry dependencies.
* `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.
* `gitRange` - If set, this is a semver specifier to match against git tags with
* `gitCommittish` - If set, this is the specific committish to use with a git dependency.
* `hosted` - If `from === 'hosted'` then this will be a `hosted-git-info`
object. This property is not included when serializing the object as
JSON.
* `raw` - The original un-modified string that was provided. If called as
`npa.resolve(name, spec)` then this will be `name + '@' + spec`.
Loading

0 comments on commit 1ae38e5

Please sign in to comment.