npm-package-arg
Advanced tools
Comparing version 2.1.3 to 3.0.0
74
npa.js
@@ -6,2 +6,3 @@ var url = require("url") | ||
var path = require("path") | ||
var HostedGit = require("hosted-git-info") | ||
@@ -11,6 +12,6 @@ module.exports = npa | ||
var isWindows = process.platform === "win32" || global.FAKE_WINDOWS | ||
var slashRe = isWindows ? /\\|\// : /\// | ||
var slashRe = isWindows ? /\\|[/]/ : /[/]/ | ||
var parseName = /^(?:@([^\/]+?)\/)?([^\/]+?)$/ | ||
var nameAt = /^(@([^\/]+?)\/)?([^\/]+?)@/ | ||
var parseName = /^(?:@([^/]+?)[/])?([^/]+?)$/ | ||
var nameAt = /^(@([^/]+?)[/])?([^/]+?)@/ | ||
var debug = util.debuglog ? util.debuglog("npa") | ||
@@ -30,3 +31,3 @@ : /\bnpa\b/i.test(process.env.NODE_DEBUG || "") | ||
|| !n.match(/^[a-zA-Z0-9]/) | ||
|| n.match(/[\/\(\)&\?#\|<>@:%\s\\\*'"!~`]/) | ||
|| n.match(/[/()&?#|<>@:%\s\\*'"!~`]/) | ||
|| n.toLowerCase() === "node_modules" | ||
@@ -76,16 +77,7 @@ || n !== encodeURIComponent(n) | ||
if (urlparse.protocol) { | ||
if (urlparse.protocol || HostedGit.fromUrl(arg)) { | ||
return parseUrl(res, arg, urlparse) | ||
} | ||
// parse git stuff | ||
// parse tag/range/local/remote | ||
if (maybeGitHubShorthand(arg)) { | ||
res.type = "github" | ||
res.spec = arg | ||
return res | ||
} | ||
// at this point, it's not a url, and not github | ||
// at this point, it's not a url, and not hosted | ||
// If it's a valid name, and doesn't already have a name, then assume | ||
@@ -139,15 +131,16 @@ // $name@"" range | ||
function maybeGitHubShorthand (arg) { | ||
// Note: This does not fully test the git ref format. | ||
// See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html | ||
// | ||
// The only way to do this properly would be to shell out to | ||
// git-check-ref-format, and as this is a fast sync function, | ||
// we don't want to do that. Just let git fail if it turns | ||
// out that the commit-ish is invalid. | ||
// GH usernames cannot start with . or - | ||
return /^[^@%\/\s\.-][^@%\/\s]*\/[^@\s\/%]+(?:#.*)?$/.test(arg) | ||
} | ||
function parseUrl (res, arg, urlparse) { | ||
var gitHost = HostedGit.fromUrl(arg) | ||
if (gitHost) { | ||
res.type = "hosted" | ||
res.spec = gitHost.toString(), | ||
res.hosted = { | ||
type: gitHost.type, | ||
ssh: gitHost.ssh(), | ||
sshUrl: gitHost.sshurl(), | ||
httpsUrl: gitHost.https(), | ||
directUrl: gitHost.file("package.json") | ||
} | ||
return res | ||
} | ||
// check the protocol, and then see if it's git or not | ||
@@ -162,19 +155,19 @@ switch (urlparse.protocol) { | ||
case "git+file:": | ||
res.type = 'git' | ||
res.spec = arg.replace(/^git\+/, '') | ||
res.type = "git" | ||
res.spec = arg.replace(/^git[+]/, "") | ||
break | ||
case 'http:': | ||
case 'https:': | ||
res.type = 'remote' | ||
case "http:": | ||
case "https:": | ||
res.type = "remote" | ||
res.spec = arg | ||
break | ||
case 'file:': | ||
res.type = 'local' | ||
case "file:": | ||
res.type = "local" | ||
res.spec = urlparse.pathname | ||
break; | ||
break | ||
default: | ||
throw new Error('Unsupported URL Type: ' + arg) | ||
throw new Error("Unsupported URL Type: " + arg) | ||
break | ||
@@ -190,5 +183,6 @@ } | ||
} | ||
Result.prototype.name = null | ||
Result.prototype.type = null | ||
Result.prototype.spec = null | ||
Result.prototype.raw = null | ||
Result.prototype.name = null | ||
Result.prototype.type = null | ||
Result.prototype.spec = null | ||
Result.prototype.raw = null | ||
Result.prototype.hosted = null |
{ | ||
"name": "npm-package-arg", | ||
"version": "2.1.3", | ||
"version": "3.0.0", | ||
"description": "Parse the things that can be arguments to `npm install`", | ||
@@ -10,2 +10,3 @@ "main": "npa.js", | ||
"dependencies": { | ||
"hosted-git-info": "^1.4.0", | ||
"semver": "4" | ||
@@ -12,0 +13,0 @@ }, |
# npm-package-arg | ||
Parse the things that can be arguments to `npm install` | ||
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]. | ||
Takes an argument like `foo@1.2`, or `foo@user/foo`, or | ||
`http://x.com/foo.tgz`, or `git+https://github.com/user/foo`, and | ||
figures out what type of thing it is. | ||
[realize-package-specifier]: https://www.npmjs.org/package/realize-package-specifier | ||
## USAGE | ||
Arguments look like: `foo@1.2`, `@bar/foo@1.2`, `foo@user/foo`, `http://x.com/foo.tgz`, | ||
`git+https://github.com/user/foo`, `bitbucket:user/foo`, `foo.tar.gz` or `bar` | ||
## EXAMPLES | ||
```javascript | ||
@@ -16,11 +21,34 @@ var assert = require("assert") | ||
// Pass in the descriptor, and it'll return an object | ||
var parsed = npa("foo@1.2") | ||
var parsed = npa("@bar/foo@1.2") | ||
// Returns an object like: | ||
// { | ||
// name: "foo", // The bit in front of the @ | ||
// type: "range", // the type of descriptor this is | ||
// spec: "1.2" // the specifier for this descriptor | ||
// } | ||
{ | ||
raw: '@bar/foo@1.2', // what was passed in | ||
name: "foo", // the name of the package | ||
scope: "@bar", // the private 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, | ||
rawSpec: 'git+https://github.com/user/foo', | ||
spec: 'user/foo', | ||
type: 'hosted', | ||
hosted: { | ||
type: 'github', | ||
ssh: 'git@github.com:user/foo.git', | ||
sshurl: 'git+ssh://git@github.com/user/foo.git', | ||
https: 'https://github.com/user/foo.git', | ||
directUrl: 'https://raw.githubusercontent.com/user/foo/master/package.json' | ||
} | ||
} | ||
// Completely unreasonable invalid garbage throws an error | ||
@@ -34,8 +62,17 @@ // Make sure you wrap this in a try/catch if you have not | ||
For more examples, see the test file. | ||
## USING | ||
## Result Objects | ||
`var npa = require('npm-package-arg')` | ||
* var result = npa(*arg*) | ||
Parses *arg* and returns a result object detailing what *arg* is. | ||
*arg* -- a package descriptor, like: `foo@1.2`, or `foo@user/foo`, or | ||
`http://x.com/foo.tgz`, or `git+https://github.com/user/foo` | ||
## RESULT OBJECT | ||
The objects that are returned by npm-package-arg contain the following | ||
fields: | ||
keys: | ||
@@ -45,3 +82,6 @@ * `name` - If known, the `name` field expected in the resulting pkg. | ||
* `git` - A git repo | ||
* `github` - A github shorthand, like `user/project` | ||
* `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"` | ||
@@ -53,2 +93,8 @@ * `version` - A specific version number, like `"foo@1.2.3"` | ||
* `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. | ||
@@ -55,0 +101,0 @@ * `rawSpec` - The part after the `name@...`, as it was originally |
@@ -66,7 +66,7 @@ var npa = require("../npa.js") | ||
"git+ssh://git@github.com/user/foo#1.2.3": { | ||
"git+ssh://git@notgithub.com/user/foo#1.2.3": { | ||
name: null, | ||
type: "git", | ||
spec: "ssh://git@github.com/user/foo#1.2.3", | ||
raw: "git+ssh://git@github.com/user/foo#1.2.3" | ||
spec: "ssh://git@notgithub.com/user/foo#1.2.3", | ||
raw: "git+ssh://git@notgithub.com/user/foo#1.2.3" | ||
}, | ||
@@ -81,15 +81,15 @@ | ||
"git://github.com/user/foo": { | ||
"git://notgithub.com/user/foo": { | ||
name: null, | ||
type: "git", | ||
spec: "git://github.com/user/foo", | ||
raw: "git://github.com/user/foo" | ||
spec: "git://notgithub.com/user/foo", | ||
raw: "git://notgithub.com/user/foo" | ||
}, | ||
"@foo/bar@git+ssh://github.com/user/foo": { | ||
"@foo/bar@git+ssh://notgithub.com/user/foo": { | ||
name: "@foo/bar", | ||
scope: "@foo", | ||
spec: "ssh://github.com/user/foo", | ||
rawSpec: "git+ssh://github.com/user/foo", | ||
raw: "@foo/bar@git+ssh://github.com/user/foo" | ||
spec: "ssh://notgithub.com/user/foo", | ||
rawSpec: "git+ssh://notgithub.com/user/foo", | ||
raw: "@foo/bar@git+ssh://notgithub.com/user/foo" | ||
}, | ||
@@ -139,37 +139,2 @@ | ||
"user/foo-js": { | ||
name: null, | ||
type: "github", | ||
spec: "user/foo-js", | ||
raw: "user/foo-js" | ||
}, | ||
"user/foo-js#bar/baz": { | ||
name: null, | ||
type: "github", | ||
spec: "user/foo-js#bar/baz", | ||
raw: "user/foo-js#bar/baz" | ||
}, | ||
"user..blerg--/..foo-js# . . . . . some . tags / / /": { | ||
name: null, | ||
type: "github", | ||
spec: "user..blerg--/..foo-js# . . . . . some . tags / / /", | ||
raw: "user..blerg--/..foo-js# . . . . . some . tags / / /" | ||
}, | ||
"user/foo-js#bar/baz/bin": { | ||
name: null, | ||
type: "github", | ||
spec: "user/foo-js#bar/baz/bin", | ||
raw: "user/foo-js#bar/baz/bin" | ||
}, | ||
"foo@user/foo-js": { | ||
name: "foo", | ||
type: "github", | ||
spec: "user/foo-js", | ||
raw: "foo@user/foo-js" | ||
}, | ||
"foo@latest": { | ||
@@ -192,4 +157,4 @@ name: "foo", | ||
var res = npa(arg) | ||
t.type(res, "Result") | ||
t.has(res, tests[arg]) | ||
t.type(res, "Result", arg + " is result") | ||
t.has(res, tests[arg], arg + " matches expectations") | ||
}) | ||
@@ -196,0 +161,0 @@ |
@@ -9,24 +9,24 @@ global.FAKE_WINDOWS = true | ||
"C:\\x\\y\\z": { | ||
raw: 'C:\\x\\y\\z', | ||
raw: "C:\\x\\y\\z", | ||
scope: null, | ||
name: null, | ||
rawSpec: 'C:\\x\\y\\z', | ||
spec: path.resolve('C:\\x\\y\\z'), | ||
type: 'local' | ||
rawSpec: "C:\\x\\y\\z", | ||
spec: path.resolve("C:\\x\\y\\z"), | ||
type: "local" | ||
}, | ||
"foo@C:\\x\\y\\z": { | ||
raw: 'foo@C:\\x\\y\\z', | ||
raw: "foo@C:\\x\\y\\z", | ||
scope: null, | ||
name: 'foo', | ||
rawSpec: 'C:\\x\\y\\z', | ||
spec: path.resolve('C:\\x\\y\\z'), | ||
type: 'local' | ||
name: "foo", | ||
rawSpec: "C:\\x\\y\\z", | ||
spec: path.resolve("C:\\x\\y\\z"), | ||
type: "local" | ||
}, | ||
"foo@/foo/bar/baz": { | ||
raw: 'foo@/foo/bar/baz', | ||
raw: "foo@/foo/bar/baz", | ||
scope: null, | ||
name: 'foo', | ||
rawSpec: '/foo/bar/baz', | ||
spec: path.resolve('/foo/bar/baz'), | ||
type: 'local' | ||
name: "foo", | ||
rawSpec: "/foo/bar/baz", | ||
spec: path.resolve("/foo/bar/baz"), | ||
type: "local" | ||
} | ||
@@ -33,0 +33,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
21270
9
575
102
0
2
+ Addedhosted-git-info@^1.4.0
+ Addedhosted-git-info@1.6.0(transitive)