diff options
author | Forrest L Norvell <ogd@aoaioxxysz.net> | 2015-01-22 05:12:40 +0300 |
---|---|---|
committer | Forrest L Norvell <forrest@npmjs.com> | 2015-01-23 15:48:00 +0300 |
commit | e9f8ab3cd6324fbf2678132324d4cd8579209442 (patch) | |
tree | f7dbcd88bc061963d6df193f8408a1c38ae59b8e /node_modules/npm-registry-client | |
parent | 168a2505e8584d4ff78987705d7a809ac125c322 (diff) |
npm-registry-client@6.0.0
* support /-/package/:name/access endpoint
* support /-/package/:name/dist-tags endpoint
* mandatory `access` parameter for publishes, with no default (because
the client doesn't know which is appropriate).
* registry client has atypical inheritance, so npm.client.distTags.*
can be in their own little namespace.
Diffstat (limited to 'node_modules/npm-registry-client')
46 files changed, 2521 insertions, 20 deletions
diff --git a/node_modules/npm-registry-client/README.md b/node_modules/npm-registry-client/README.md index a35c48311..aecd64786 100644 --- a/node_modules/npm-registry-client/README.md +++ b/node_modules/npm-registry-client/README.md @@ -55,6 +55,19 @@ for authorization. These credentials always look the same: ## API +### client.access(uri, params, cb) + +* `uri` {String} Registry URL for the package's access API endpoint. + Looks like `/-/package/<package name>/access`. +* `params` {Object} Object containing per-request properties. + * `access` {String} New access level for the package. Can be either + `public` or `restricted`. Registry will raise an error if trying + to change the access level of an unscoped package. + * `auth` {Credentials} + +Set the access level for scoped packages. For now, there are only two +access levels: "public" and "restricted". + ### client.adduser(uri, params, cb) * `uri` {String} Base registry URL. @@ -79,6 +92,67 @@ Add a user account to the registry, or verify the credentials. Deprecate a version of a package in the registry. +### client.distTags.fetch(uri, params, cb) + +* `uri` {String} Base URL for the registry. +* `params` {Object} Object containing per-request properties. + * `package` {String} Name of the package. + * `auth` {Credentials} +* `cb` {Function} + +Fetch all of the `dist-tags` for the named package. + +### client.distTags.add(uri, params, cb) + +* `uri` {String} Base URL for the registry. +* `params` {Object} Object containing per-request properties. + * `package` {String} Name of the package. + * `distTag` {String} Name of the new `dist-tag`. + * `version` {String} Exact version to be mapped to the `dist-tag`. + * `auth` {Credentials} +* `cb` {Function} + +Add (or replace) a single dist-tag onto the named package. + +### client.distTags.set(uri, params, cb) + +* `uri` {String} Base URL for the registry. +* `params` {Object} Object containing per-request properties. + * `package` {String} Name of the package. + * `distTags` {Object} Object containing a map from tag names to package + versions. + * `auth` {Credentials} +* `cb` {Function} + +Set all of the `dist-tags` for the named package at once, creating any +`dist-tags` that do not already exit. Any `dist-tags` not included in the +`distTags` map will be removed. + +### client.distTags.update(uri, params, cb) + +* `uri` {String} Base URL for the registry. +* `params` {Object} Object containing per-request properties. + * `package` {String} Name of the package. + * `distTags` {Object} Object containing a map from tag names to package + versions. + * `auth` {Credentials} +* `cb` {Function} + +Update the values of multiple `dist-tags`, creating any `dist-tags` that do +not already exist. Any pre-existing `dist-tags` not included in the `distTags` +map will be left alone. + +### client.distTags.rm(uri, params, cb) + +* `uri` {String} Base URL for the registry. +* `params` {Object} Object containing per-request properties. + * `package` {String} Name of the package. + * `distTag` {String} Name of the new `dist-tag`. + * `auth` {Credentials} +* `cb` {Function} + +Remove a single `dist-tag` from the named package. + ### client.get(uri, params, cb) * `uri` {String} The complete registry URI to fetch @@ -100,6 +174,7 @@ with the ETag or the "Last Modified" timestamp. * `uri` {String} The registry URI for the package to publish. * `params` {Object} Object containing per-request properties. * `metadata` {Object} Package metadata. + * `access` {String} Access for the package. Can be `public` or `restricted` (no default). * `body` {Stream} Stream of the package body / tarball. * `auth` {Credentials} * `cb` {Function} diff --git a/node_modules/npm-registry-client/index.js b/node_modules/npm-registry-client/index.js index 801d00f8e..6ea288b0a 100644 --- a/node_modules/npm-registry-client/index.js +++ b/node_modules/npm-registry-client/index.js @@ -46,11 +46,34 @@ function RegClient (config) { this.log = this.config.log || npmlog delete this.config.log + + var client = this + fs.readdirSync(join(__dirname, "lib")).forEach(function (f) { + var entry = join(__dirname, "lib", f) + + // lib/group-name/operation.js -> client.groupName.operation + var stat = fs.statSync(entry) + if (stat.isDirectory()) { + var groupName = f.replace(/-([a-z])/, dashToCamel) + fs.readdirSync(entry).forEach(function (f) { + if (!f.match(/\.js$/)) return + + if (!client[groupName]) { + // keep client.groupName.operation from stomping client.operation + client[groupName] = Object.create(client) + } + var name = f.replace(/\.js$/, "").replace(/-([a-z])/, dashToCamel) + client[groupName][name] = require(join(entry, f)) + }) + return + } + + if (!f.match(/\.js$/)) return + var name = f.replace(/\.js$/, "").replace(/-([a-z])/, dashToCamel) + client[name] = require(entry) + }) } -fs.readdirSync(join(__dirname, "lib")).forEach(function (f) { - if (!f.match(/\.js$/)) return - var name = f.replace(/\.js$/, "") - .replace(/-([a-z])/, function (_, l) { return l.toUpperCase() }) - RegClient.prototype[name] = require(join(__dirname, "lib", f)) -}) +function dashToCamel (_, l) { + return l.toUpperCase() +} diff --git a/node_modules/npm-registry-client/lib/access.js b/node_modules/npm-registry-client/lib/access.js new file mode 100644 index 000000000..c642d16f3 --- /dev/null +++ b/node_modules/npm-registry-client/lib/access.js @@ -0,0 +1,30 @@ +module.exports = access + +var assert = require("assert") + +function access (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to access") + assert(params && typeof params === "object", "must pass params to access") + assert(typeof cb === "function", "muss pass callback to access") + + assert(typeof params.level === "string", "must pass level to access") + assert( + ["public", "restricted"].indexOf(params.level) !== -1, + "access level must be either 'public' or 'restricted'" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to access" + ) + + var body = { + access : params.level + } + + var options = { + method : "POST", + body : JSON.stringify(body), + auth : params.auth + } + this.request(uri, options, cb) +} diff --git a/node_modules/npm-registry-client/lib/dist-tags/add.js b/node_modules/npm-registry-client/lib/dist-tags/add.js new file mode 100644 index 000000000..280a97950 --- /dev/null +++ b/node_modules/npm-registry-client/lib/dist-tags/add.js @@ -0,0 +1,43 @@ +module.exports = add + +var assert = require("assert") +var url = require("url") + +var npa = require("npm-package-arg") + +function add (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to distTags.add") + assert( + params && typeof params === "object", + "must pass params to distTags.add" + ) + assert(typeof cb === "function", "muss pass callback to distTags.add") + + assert( + typeof params.package === "string", + "must pass package name to distTags.add" + ) + assert( + typeof params.distTag === "string", + "must pass package distTag name to distTags.add" + ) + assert( + typeof params.version === "string", + "must pass version to be mapped to distTag to distTags.add" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to distTags.add" + ) + + var p = npa(params.package) + var package = p.scope ? params.package.replace("/", "%2f") : params.package + var rest = "-/package/"+package+"/dist-tags/"+params.distTag + + var options = { + method : "PUT", + body : params.version, + auth : params.auth + } + this.request(url.resolve(uri, rest), options, cb) +} diff --git a/node_modules/npm-registry-client/lib/dist-tags/fetch.js b/node_modules/npm-registry-client/lib/dist-tags/fetch.js new file mode 100644 index 000000000..85dde8b79 --- /dev/null +++ b/node_modules/npm-registry-client/lib/dist-tags/fetch.js @@ -0,0 +1,34 @@ +module.exports = fetch + +var assert = require("assert") +var url = require("url") + +var npa = require("npm-package-arg") + +function fetch (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to distTags.fetch") + assert( + params && typeof params === "object", + "must pass params to distTags.fetch" + ) + assert(typeof cb === "function", "muss pass callback to distTags.fetch") + + assert( + typeof params.package === "string", + "must pass package name to distTags.fetch" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to distTags.fetch" + ) + + var p = npa(params.package) + var package = p.scope ? params.package.replace("/", "%2f") : params.package + var rest = "-/package/"+package+"/dist-tags" + + var options = { + method : "GET", + auth : params.auth + } + this.request(url.resolve(uri, rest), options, cb) +} diff --git a/node_modules/npm-registry-client/lib/dist-tags/rm.js b/node_modules/npm-registry-client/lib/dist-tags/rm.js new file mode 100644 index 000000000..dbae245ec --- /dev/null +++ b/node_modules/npm-registry-client/lib/dist-tags/rm.js @@ -0,0 +1,38 @@ +module.exports = rm + +var assert = require("assert") +var url = require("url") + +var npa = require("npm-package-arg") + +function rm (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to distTags.rm") + assert( + params && typeof params === "object", + "must pass params to distTags.rm" + ) + assert(typeof cb === "function", "muss pass callback to distTags.rm") + + assert( + typeof params.package === "string", + "must pass package name to distTags.rm" + ) + assert( + typeof params.distTag === "string", + "must pass package distTag name to distTags.rm" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to distTags.rm" + ) + + var p = npa(params.package) + var package = p.scope ? params.package.replace("/", "%2f") : params.package + var rest = "-/package/"+package+"/dist-tags/"+params.distTag + + var options = { + method : "DELETE", + auth : params.auth + } + this.request(url.resolve(uri, rest), options, cb) +} diff --git a/node_modules/npm-registry-client/lib/dist-tags/set.js b/node_modules/npm-registry-client/lib/dist-tags/set.js new file mode 100644 index 000000000..e1e17cde5 --- /dev/null +++ b/node_modules/npm-registry-client/lib/dist-tags/set.js @@ -0,0 +1,39 @@ +module.exports = set + +var assert = require("assert") +var url = require("url") + +var npa = require("npm-package-arg") + +function set (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to distTags.set") + assert( + params && typeof params === "object", + "must pass params to distTags.set" + ) + assert(typeof cb === "function", "muss pass callback to distTags.set") + + assert( + typeof params.package === "string", + "must pass package name to distTags.set" + ) + assert( + params.distTags && typeof params.distTags === "object", + "must pass distTags map to distTags.set" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to distTags.set" + ) + + var p = npa(params.package) + var package = p.scope ? params.package.replace("/", "%2f") : params.package + var rest = "-/package/"+package+"/dist-tags" + + var options = { + method : "PUT", + body : JSON.stringify(params.distTags), + auth : params.auth + } + this.request(url.resolve(uri, rest), options, cb) +} diff --git a/node_modules/npm-registry-client/lib/dist-tags/update.js b/node_modules/npm-registry-client/lib/dist-tags/update.js new file mode 100644 index 000000000..6c46fc532 --- /dev/null +++ b/node_modules/npm-registry-client/lib/dist-tags/update.js @@ -0,0 +1,39 @@ +module.exports = update + +var assert = require("assert") +var url = require("url") + +var npa = require("npm-package-arg") + +function update (uri, params, cb) { + assert(typeof uri === "string", "must pass registry URI to distTags.update") + assert( + params && typeof params === "object", + "must pass params to distTags.update" + ) + assert(typeof cb === "function", "muss pass callback to distTags.update") + + assert( + typeof params.package === "string", + "must pass package name to distTags.update" + ) + assert( + params.distTags && typeof params.distTags === "object", + "must pass distTags map to distTags.update" + ) + assert( + params.auth && typeof params.auth === "object", + "must pass auth to distTags.update" + ) + + var p = npa(params.package) + var package = p.scope ? params.package.replace("/", "%2f") : params.package + var rest = "-/package/"+package+"/dist-tags" + + var options = { + method : "POST", + body : JSON.stringify(params.distTags), + auth : params.auth + } + this.request(url.resolve(uri, rest), options, cb) +} diff --git a/node_modules/npm-registry-client/lib/publish.js b/node_modules/npm-registry-client/lib/publish.js index ea9dcaef7..24034a6b8 100644 --- a/node_modules/npm-registry-client/lib/publish.js +++ b/node_modules/npm-registry-client/lib/publish.js @@ -17,6 +17,13 @@ function publish (uri, params, cb) { assert(params && typeof params === "object", "must pass params to publish") assert(typeof cb === "function", "must pass callback to publish") + var access = params.access + assert(access && typeof access === "string", "must pass access for package") + assert( + ["public", "restricted"].indexOf(access) !== -1, + "access level must be either 'public' or 'restricted'" + ) + var auth = params.auth assert(auth && typeof auth === "object", "must pass auth to publish") if (!(auth.token || @@ -46,13 +53,13 @@ function publish (uri, params, cb) { assert(body instanceof Stream, "package body passed to publish must be a stream") var client = this var sink = concat(function (tarbuffer) { - putFirst.call(client, uri, metadata, tarbuffer, auth, cb) + putFirst.call(client, uri, metadata, tarbuffer, access, auth, cb) }) sink.on("error", cb) body.pipe(sink) } -function putFirst (registry, data, tarbuffer, auth, cb) { +function putFirst (registry, data, tarbuffer, access, auth, cb) { // optimistically try to PUT all in one single atomic thing. // If 409, then GET and merge, try again. // If other error, then fail. @@ -61,6 +68,7 @@ function putFirst (registry, data, tarbuffer, auth, cb) { { _id : data.name , name : data.name , description : data.description + , access : access , "dist-tags" : {} , versions : {} , readme: data.readme || "" diff --git a/node_modules/npm-registry-client/lib/tag.js b/node_modules/npm-registry-client/lib/tag.js index 8b4219907..cad5154d7 100644 --- a/node_modules/npm-registry-client/lib/tag.js +++ b/node_modules/npm-registry-client/lib/tag.js @@ -9,7 +9,10 @@ function tag (uri, params, cb) { assert(typeof params.version === "string", "must pass version to tag") assert(typeof params.tag === "string", "must pass tag name to tag") - assert(params.auth && typeof params.auth === "object", "must pass auth to tag") + assert( + params.auth && typeof params.auth === "object", + "must pass auth to tag" + ) var options = { method : "PUT", diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/LICENSE b/node_modules/npm-registry-client/node_modules/npm-package-arg/LICENSE new file mode 100644 index 000000000..05eeeb88c --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +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. diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/README.md b/node_modules/npm-registry-client/node_modules/npm-package-arg/README.md new file mode 100644 index 000000000..21683f5e5 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/README.md @@ -0,0 +1,101 @@ +# 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: `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 +var assert = require("assert") +var npa = require("npm-package-arg") + +// Pass in the descriptor, and it'll return an object +var parsed = npa("@bar/foo@1.2") + +// Returns an object like: +{ + 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 +// 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*) + +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 +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 `"foo@1.2.3"` + * `range` - A version range, like `"foo@2.x"` + * `local` - A local file or folder path + * `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. +* `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`. diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.npmignore b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.npmignore new file mode 100644 index 000000000..58e97a787 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.npmignore @@ -0,0 +1,3 @@ +*~ +.# +node_modules diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.travis.yml b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.travis.yml new file mode 100644 index 000000000..7dc661917 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.11" + - "0.10" +script: "npm test" diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md new file mode 100644 index 000000000..ebf40a2ab --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md @@ -0,0 +1,82 @@ +# hosted-git-info + +This will let you identify and transform various git hosts URLs between +protocols. It also can tell you what the URL is for the raw path for +particular file for direct access without git. + +## Usage + +```javascript +var hostedGitInfo = require("hosted-git-info") +var info = hostedGitInfo.fromUrl("git@github.com:npm/hosted-git-info.git") +/* info looks like: +{ + type: "github", + domain: "github.com", + user: "npm", + project: "hosted-git-info" +} +*/ +``` + +If the URL can't be matched with a git host, `null` will be returned. We +can match git, ssh and https urls. Additionally, we can match ssh connect +strings (`git@github.com:npm/hosted-git-info`) and shortcuts (eg, +`github:npm/hosted-git-info`). Github specifically, is detected in the case +of a third, unprefixed, form: `npm/hosted-git-info`. + +If it does match, the returned object has properties of: + +* info.type -- The short name of the service +* info.domain -- The domain for git protocol use +* info.user -- The name of the user/org on the git host +* info.project -- The name of the project on the git host + +And methods of: + +* info.file(path) + +Given the path of a file relative to the repository, returns a URL for +directly fetching it from the githost. If no comittish was set then +`master` will be used as the default. + +For example `hostedGitInfo.fromUrl("git@github.com:npm/hosted-git-info.git#v1.0.0").file("package.json")` +would return `https://raw.githubusercontent.com/npm/hosted-git-info/v1.0.0/package.json` + +* info.shortcut() + +eg, `github:npm/hosted-git-info` + +* info.browse() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0` + +* info.bugs() + +eg, `https://github.com/npm/hosted-git-info/issues` + +* info.docs() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0#readme` + +* info.https() + +eg, `https://github.com/npm/hosted-git-info.git` + +* info.sshurl() + +eg, `git+ssh://git@github.com/npm/hosted-git-info.git` + +* info.ssh() + +eg, `git@github.com:npm/hosted-git-info.git` + +* info.path() + +eg, `npm/hosted-git-info` + +## Supported hosts + +Currently this supports Github, Bitbucket and Gitlab. Pull requests for +additional hosts welcome. + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md~ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md~ new file mode 100644 index 000000000..f246bdb8d --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/README.md~ @@ -0,0 +1,82 @@ +# hosted-git-info + +This will let you identify and transform various git hosts URLs between +protocols. It also can tell you what the URL is for the raw path for +particular file for direct access without git. + +## Usage + +```javascript +var hostedGitInfo = require("hosted-git-info") +var info = hostedGitInfo("git@github.com:npm/hosted-git-info.git") +/* info looks like: +{ + type: "github", + domain: "github.com", + user: "npm", + project: "hosted-git-info" +} +*/ +``` + +If the URL can't be matched with a git host, `null` will be returned. We +can match git, ssh and https urls. Additionally, we can match ssh connect +strings (`git@github.com:npm/hosted-git-info`) and shortcuts (eg, +`github:npm/hosted-git-info`). Github specifically, is detected in the case +of a third, unprefixed, form: `npm/hosted-git-info`. + +If it does match, the returned object has properties of: + +* info.type -- The short name of the service +* info.domain -- The domain for git protocol use +* info.user -- The name of the user/org on the git host +* info.project -- The name of the project on the git host + +And methods of: + +* info.file(path) + +Given the path of a file relative to the repository, returns a URL for +directly fetching it from the githost. If no comittish was set then +`master` will be used as the default. + +For example `hostedGitInfo("git@github.com:npm/hosted-git-info.git#v1.0.0").file("package.json")` +would return `https://raw.githubusercontent.com/npm/hosted-git-info/v1.0.0/package.json` + +* info.shortcut() + +eg, `github:npm/hosted-git-info` + +* info.browse() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0` + +* info.bugs() + +eg, `https://github.com/npm/hosted-git-info/issues` + +* info.docs() + +eg, `https://github.com/npm/hosted-git-info/tree/v1.2.0#readme` + +* info.https() + +eg, `https://github.com/npm/hosted-git-info.git` + +* info.sshurl() + +eg, `git+ssh://git@github.com/npm/hosted-git-info.git` + +* info.ssh() + +eg, `git@github.com:npm/hosted-git-info.git` + +* info.path() + +eg, `npm/hosted-git-info` + +## Supported hosts + +Currently this supports Github, Bitbucket and Gitlab. Pull requests for +additional hosts welcome. + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/index.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/index.js new file mode 100644 index 000000000..299f50c59 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/index.js @@ -0,0 +1,200 @@ +"use strict" +var url = require("url") + +var GitHost = exports = module.exports = function (type, user, project, comittish) { + this.type = type + this.domain = gitHosts[type].domain + this.filetemplate = gitHosts[type].filetemplate + this.sshtemplate = gitHosts[type].sshtemplate + this.sshurltemplate = gitHosts[type].sshurltemplate + this.browsetemplate = gitHosts[type].browsetemplate + this.docstemplate = gitHosts[type].docstemplate + this.bugstemplate = gitHosts[type].bugstemplate + this.gittemplate = gitHosts[type].gittemplate + this.httpstemplate = gitHosts[type].httpstemplate + this.treepath = gitHosts[type].treepath + this.user = user + this.project = project + this.comittish = comittish +} +GitHost.prototype = {} + +exports.fromUrl = function (giturl) { + if (giturl == null || giturl == "") return + var parsed = parseGitUrl(maybeGitHubShorthand(giturl) ? "github:" + giturl : giturl) + var matches = Object.keys(gitHosts).map(function(V) { + var gitHost = gitHosts[V] + var comittish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null + if (parsed.protocol == V + ":") { + return new GitHost(V, + decodeURIComponent(parsed.host), decodeURIComponent(parsed.path.replace(/^[/](.*?)(?:[.]git)?$/, "$1")), comittish) + } + if (parsed.host != gitHost.domain) return + if (! gitHost.protocols_re.test(parsed.protocol)) return + var matched = parsed.path.match(gitHost.pathmatch) + if (! matched) return + return new GitHost( + V, + matched[1]!=null && decodeURIComponent(matched[1]), + matched[2]!=null && decodeURIComponent(matched[2]), + comittish) + }).filter(function(V){ return V }) + if (matches.length != 1) return + return matches[0] +} + +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) +} + +var parseGitUrl = function (giturl) { + if (typeof giturl != "string") giturl = "" + giturl + var matched = giturl.match(/^([^@]+)@([^:]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) + if (! matched) return url.parse(giturl) + return { + protocol: "git+ssh:", + slashes: true, + auth: matched[1], + host: matched[2], + port: null, + hostname: matched[2], + hash: matched[4], + search: null, + query: null, + pathname: "/" + matched[3], + path: "/" + matched[3], + href: "git+ssh://" + matched[1] + "@" + matched[2] + "/" + matched[3] + (matched[4]||"") + } +} + +var gitHosts = { + github: { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + "protocols": [ "git", "http", "git+ssh", "git+https", "ssh", "https" ], + "domain": "github.com", + "pathmatch": /^[/]([^/]+)[/]([^/]+?)(?:[.]git)?$/, + "treepath": "tree", + "filetemplate": "https://raw.githubusercontent.com/{user}/{project}/{comittish}/{path}", + "bugstemplate": "https://{domain}/{user}/{project}/issues", + "gittemplate": "git://{domain}/{user}/{project}.git{#comittish}" + }, + bitbucket: { + "protocols": [ "git+ssh", "git+https", "ssh", "https" ], + "domain": "bitbucket.org", + "pathmatch": /^[/]([^/]+)[/]([^/]+?)(?:[.]git)?$/, + "treepath": "src" + }, + gitlab: { + "protocols": [ "git+ssh", "git+https", "ssh", "https" ], + "domain": "gitlab.com", + "pathmatch": /^[/]([^/]+)[/]([^/]+?)(?:[.]git)?$/, + "treepath": "tree", + "docstemplate": "https://{domain}/{user}/{project}{/tree/comittish}#README", + "bugstemplate": "https://{domain}/{user}/{project}/issues" + }, + gist: { + "protocols": [ "git", "git+ssh", "git+https", "ssh", "https" ], + "domain": "gist.github.com", + "pathmatch": /^[/](?:([^/]+)[/])?(\d+)(?:[.]git)?$/, + "filetemplate": "https://gist.githubusercontent.com/{user}/{project}/raw{/comittish}/{path}", + "bugstemplate": "https://{domain}/{project}", + "gittemplate": "git://{domain}/{project}.git{#comittish}", + "sshtemplate": "git@{domain}:/{project}.git{#comittish}", + "sshurltemplate": "git+ssh://git@{domain}/{project}.git{#comittish}", + "browsetemplate": "https://{domain}/{project}{/comittish}", + "docstemplate": "https://{domain}/{project}{/comittish}", + "httpstemplate": "https://{domain}/{project}.git{#comittish}", + }, +} + +Object.keys(gitHosts).forEach(function(host) { + gitHosts[host].protocols_re = RegExp("^(" + + gitHosts[host].protocols.map(function(P){ + return P.replace(/([\\+*{}()\[\]$^|])/g, "\\$1") + }).join("|") + "):$") +}) + +GitHost.prototype.shortcut = function () { + return this.type + ":" + this.path() +} + +GitHost.prototype.hash = function () { + return this.comittish ? "#" + this.comittish : "" +} + +GitHost.prototype.path = function () { + return this.user + "/" + this.project + this.hash() +} + +GitHost.prototype._fill = function (template, vars) { + if (! template) throw new Error("BOOM") + if (!vars) vars = {} + var self = this + Object.keys(this).forEach(function(K){ if (self[K]!=null && vars[K]==null) vars[K] = self[K] }) + var rawComittish = vars.comittish + Object.keys(vars).forEach(function(K){ (K[0]!='#') && (vars[K] = encodeURIComponent(vars[K])) }) + vars["#comittish"] = rawComittish ? "#" + rawComittish : "" + vars["/tree/comittish"] = vars.comittish ? "/"+vars.treepath+"/" + vars.comittish : "", + vars["/comittish"] = vars.comittish ? "/" + vars.comittish : "" + vars.comittish = vars.comittish || "master" + var res = template + Object.keys(vars).forEach(function(K){ + res = res.replace(new RegExp("[{]" + K + "[}]", "g"), vars[K]) + }) + return res +} + +GitHost.prototype.ssh = function () { + var sshtemplate = this.sshtemplate || "git@{domain}:{user}/{project}.git{#comittish}" + return this._fill(sshtemplate) +} + +GitHost.prototype.sshurl = function () { + var sshurltemplate = this.sshurltemplate || "git+ssh://git@{domain}/{user}/{project}.git{#comittish}" + return this._fill(sshurltemplate) +} + +GitHost.prototype.browse = function () { + var browsetemplate = this.browsetemplate || "https://{domain}/{user}/{project}{/tree/comittish}" + return this._fill(browsetemplate) +} + +GitHost.prototype.docs = function () { + var docstemplate = this.docstemplate || "https://{domain}/{user}/{project}{/tree/comittish}#readme" + return this._fill(docstemplate) +} + +GitHost.prototype.bugs = function() { + if (! this.bugstemplate) return + return this._fill(this.bugstemplate) +} + +GitHost.prototype.https = function () { + var httpstemplate = this.httpstemplate || "https://{domain}/{user}/{project}.git{#comittish}" + return this._fill(httpstemplate) +} + +GitHost.prototype.git = function () { + if (! this.gittemplate) return + return this._fill(this.gittemplate) +} + +GitHost.prototype.file = function (P) { + var filetemplate = this.filetemplate || "https://{domain}/{user}/{project}/raw/{comittish}/{path}" + return this._fill(filetemplate, { + path: P.replace(/^[/]+/g, "") + }) +} + +GitHost.prototype.toString = function () { + return this[this.default||"sshurl"]() +} diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json new file mode 100644 index 000000000..2819b3941 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/package.json @@ -0,0 +1,55 @@ +{ + "name": "hosted-git-info", + "version": "1.5.2", + "description": "Provides metadata and conversions from repository urls for Github, Bitbucket and Gitlab", + "main": "index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/hosted-git-info.git" + }, + "keywords": [ + "git", + "github", + "bitbucket", + "gitlab" + ], + "author": { + "name": "Rebecca Turner", + "email": "me@re-becca.org", + "url": "http://re-becca.org" + }, + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/hosted-git-info/issues" + }, + "homepage": "https://github.com/npm/hosted-git-info", + "scripts": { + "test": "tap test/*.js" + }, + "devDependencies": { + "tap": "^0.4.13" + }, + "gitHead": "d891b7a59fa4c73b604ea8690eedc48757c76c42", + "_id": "hosted-git-info@1.5.2", + "_shasum": "15cdfd09ab6d4d87700437ca695f12d1580f6658", + "_from": "hosted-git-info@>=1.4.0 <2.0.0", + "_npmVersion": "2.1.11", + "_nodeVersion": "0.10.33", + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "dist": { + "shasum": "15cdfd09ab6d4d87700437ca695f12d1580f6658", + "tarball": "http://registry.npmjs.org/hosted-git-info/-/hosted-git-info-1.5.2.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-1.5.2.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/basic.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/basic.js new file mode 100644 index 000000000..e56ef9a05 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/basic.js @@ -0,0 +1,9 @@ +"use strict" +var HostedGit = require("../index") +var test = require("tap").test + +test("basic", function (t) { + t.is(HostedGit.fromUrl("https://google.com"), undefined, "null on failure") + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/bitbucket.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/bitbucket.js new file mode 100644 index 000000000..089cb2819 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/bitbucket.js @@ -0,0 +1,24 @@ +"use strict" +var HostedGit = require("../index") +var test = require("tap").test + +test("fromUrl(bitbucket url)", function (t) { + function verify(host, label, branch) { + var hostinfo = HostedGit.fromUrl(host) + var hash = branch ? "#" + branch : "" + t.ok(hostinfo, label) + if (! hostinfo) return + t.is( hostinfo.https(), "https://bitbucket.org/111/222.git" + hash, label + " -> https" ) + t.is( hostinfo.browse(), "https://bitbucket.org/111/222" + (branch ? "/src/" + branch : ""), label + " -> browse" ) + t.is( hostinfo.docs(), "https://bitbucket.org/111/222" + (branch ? "/src/" + branch : "") + "#readme", label + " -> docs" ) + t.is( hostinfo.ssh(), "git@bitbucket.org:111/222.git" + hash, label + " -> ssh" ) + t.is( hostinfo.sshurl(), "git+ssh://git@bitbucket.org/111/222.git" + hash, label + " -> sshurl" ) + t.is( (""+hostinfo), "git+ssh://git@bitbucket.org/111/222.git" + hash, label + " -> stringify" ) + t.is( hostinfo.file("C"), "https://bitbucket.org/111/222/raw/"+(branch||"master")+"/C", label + " -> file" ) + } + + require('./lib/standard-tests')(verify, "bitbucket.org", "bitbucket") + + t.end() +}) + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gist.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gist.js new file mode 100644 index 000000000..697ee6b7d --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gist.js @@ -0,0 +1,36 @@ +"use strict" +var HostedGit = require("../index") +var test = require("tap").test + + +test("fromUrl(gist url)", function (t) { + function verify(host, label, branch) { + var hostinfo = HostedGit.fromUrl(host) + var hash = branch ? "#" + branch : "" + t.ok(hostinfo, label) + if (! hostinfo) return + t.is( hostinfo.https(), "https://gist.github.com/222.git" + hash, label + " -> https" ) + t.is( hostinfo.git(), "git://gist.github.com/222.git" + hash, label + " -> git" ) + t.is( hostinfo.browse(), "https://gist.github.com/222" + (branch ? "/" + branch : ""), label + " -> browse" ) + t.is( hostinfo.bugs(), "https://gist.github.com/222", label + " -> bugs" ) + t.is( hostinfo.docs(), "https://gist.github.com/222" + (branch ? "/" + branch : ""), label + " -> docs" ) + t.is( hostinfo.ssh(), "git@gist.github.com:/222.git" + hash, label + " -> ssh" ) + t.is( hostinfo.sshurl(), "git+ssh://git@gist.github.com/222.git" + hash, label + " -> sshurl" ) + t.is( (""+hostinfo), "git+ssh://git@gist.github.com/222.git" + hash, label + " -> stringify" ) + if (hostinfo.user) { + t.is( hostinfo.file("C"), "https://gist.githubusercontent.com/111/222/raw/"+(branch?branch+"/":"")+"C", label + " -> file" ) + } + } + + verify("git@gist.github.com:222.git", "git@") + verify("git@gist.github.com:/222.git", "git@/") + verify("git://gist.github.com/222", "git") + verify("git://gist.github.com/222.git", "git.git") + verify("git://gist.github.com/222#branch", "git#branch", "branch") + verify("git://gist.github.com/222.git#branch", "git.git#branch", "branch") + + require('./lib/standard-tests')(verify, "gist.github.com", "gist") + + t.end() +}) + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/github.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/github.js new file mode 100644 index 000000000..e551c45d7 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/github.js @@ -0,0 +1,42 @@ +"use strict" +var HostedGit = require("../index") +var test = require("tap").test + + +test("fromUrl(github url)", function (t) { + function verify(host, label, branch) { + var hostinfo = HostedGit.fromUrl(host) + var hash = branch ? "#" + branch : "" + t.ok(hostinfo, label) + if (! hostinfo) return + t.is( hostinfo.https(), "https://github.com/111/222.git" + hash, label + " -> https" ) + t.is( hostinfo.git(), "git://github.com/111/222.git" + hash, label + " -> git" ) + t.is( hostinfo.browse(), "https://github.com/111/222" + (branch ? "/tree/" + branch : ""), label + " -> browse" ) + t.is( hostinfo.bugs(), "https://github.com/111/222/issues", label + " -> bugs" ) + t.is( hostinfo.docs(), "https://github.com/111/222" + (branch ? "/tree/" + branch : "") + "#readme", label + " -> docs" ) + t.is( hostinfo.ssh(), "git@github.com:111/222.git" + hash, label + " -> ssh" ) + t.is( hostinfo.sshurl(), "git+ssh://git@github.com/111/222.git" + hash, label + " -> sshurl" ) + t.is( (""+hostinfo), "git+ssh://git@github.com/111/222.git" + hash, label + " -> stringify" ) + t.is( hostinfo.file("C"), "https://raw.githubusercontent.com/111/222/"+(branch||"master")+"/C", label + " -> file" ) + } + + // github shorturls + verify("111/222", "github-short") + verify("111/222#branch", "github-short#branch", "branch") + + // insecure protocols + verify("git://github.com/111/222", "git") + verify("git://github.com/111/222.git", "git.git") + verify("git://github.com/111/222#branch", "git#branch", "branch") + verify("git://github.com/111/222.git#branch", "git.git#branch", "branch") + + verify("http://github.com/111/222", "http") + verify("http://github.com/111/222.git", "http.git") + verify("http://github.com/111/222#branch", "http#branch", "branch") + verify("http://github.com/111/222.git#branch", "http.git#branch", "branch") + + require('./lib/standard-tests')(verify, "github.com", "github") + + t.end() +}) + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gitlab.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gitlab.js new file mode 100644 index 000000000..1a4e07096 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/gitlab.js @@ -0,0 +1,25 @@ +"use strict" +var HostedGit = require("../index") +var test = require("tap").test + + +test("fromUrl(gitlab url)", function (t) { + function verify(host, label, branch) { + var hostinfo = HostedGit.fromUrl(host) + var hash = branch ? "#" + branch : "" + t.ok(hostinfo, label) + if (! hostinfo) return + t.is( hostinfo.https(), "https://gitlab.com/111/222.git" + hash, label + " -> https" ) + t.is( hostinfo.browse(), "https://gitlab.com/111/222" + (branch ? "/tree/" + branch : ""), label + " -> browse" ) + t.is( hostinfo.docs(), "https://gitlab.com/111/222" + (branch ? "/tree/" + branch : "") + "#README", label + " -> docs" ) + t.is( hostinfo.ssh(), "git@gitlab.com:111/222.git" + hash, label + " -> ssh" ) + t.is( hostinfo.sshurl(), "git+ssh://git@gitlab.com/111/222.git" + hash, label + " -> sshurl" ) + t.is( (""+hostinfo), "git+ssh://git@gitlab.com/111/222.git" + hash, label + " -> stringify" ) + t.is( hostinfo.file("C"), "https://gitlab.com/111/222/raw/"+(branch||"master")+"/C", label + " -> file" ) + } + + require('./lib/standard-tests')(verify, "gitlab.com", "gitlab") + + t.end() +}) + diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/lib/standard-tests.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/lib/standard-tests.js new file mode 100644 index 000000000..c505342fa --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/node_modules/hosted-git-info/test/lib/standard-tests.js @@ -0,0 +1,28 @@ +"use strict" +module.exports = function (verify, domain, shortname) { + verify("https://" + domain + "/111/222", "https") + verify("https://" + domain + "/111/222.git", "https.git") + verify("https://" + domain + "/111/222#branch", "https#branch", "branch") + verify("https://" + domain + "/111/222.git#branch", "https.git#branch", "branch") + + verify("git+https://" + domain + "/111/222", "git+https") + verify("git+https://" + domain + "/111/222.git", "git+https.git") + verify("git+https://" + domain + "/111/222#branch", "git+https#branch", "branch") + verify("git+https://" + domain + "/111/222.git#branch", "git+https.git#branch", "branch") + + verify("git@" + domain + ":111/222", "ssh") + verify("git@" + domain + ":111/222.git", "ssh.git") + verify("git@" + domain + ":111/222#branch", "ssh", "branch") + verify("git@" + domain + ":111/222.git#branch", "ssh.git", "branch") + + + verify("git+ssh://git@" + domain + "/111/222", "ssh url") + verify("git+ssh://git@" + domain + "/111/222.git", "ssh url.git") + verify("git+ssh://git@" + domain + "/111/222#branch", "ssh url#branch", "branch") + verify("git+ssh://git@" + domain + "/111/222.git#branch", "ssh url.git#branch", "branch") + + verify(shortname + ":111/222", "shortcut") + verify(shortname + ":111/222.git", "shortcut.git") + verify(shortname + ":111/222#branch", "shortcut#branch", "branch") + verify(shortname + ":111/222.git#branch", "shortcut.git#branch", "branch") +} diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/npa.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/npa.js new file mode 100644 index 000000000..883c5401b --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/npa.js @@ -0,0 +1,181 @@ +var url = require("url") +var assert = require("assert") +var util = require("util") +var semver = require("semver") +var path = require("path") +var HostedGit = require("hosted-git-info") + +module.exports = npa + +var isWindows = process.platform === "win32" || global.FAKE_WINDOWS +var slashRe = isWindows ? /\\|[/]/ : /[/]/ + +var parseName = /^(?:@([^/]+?)[/])?([^/]+?)$/ +var nameAt = /^(@([^/]+?)[/])?([^/]+?)@/ +var debug = util.debuglog ? util.debuglog("npa") + : /\bnpa\b/i.test(process.env.NODE_DEBUG || "") + ? function () { + console.error("NPA: " + util.format.apply(util, arguments).split("\n").join("\nNPA: ")) + } : function () {} + +function validName (name) { + if (!name) { + debug("not a name %j", name) + return false + } + var n = name.trim() + if (!n || n.charAt(0) === "." + || !n.match(/^[a-zA-Z0-9]/) + || n.match(/[/()&?#|<>@:%\s\\*'"!~`]/) + || n.toLowerCase() === "node_modules" + || n !== encodeURIComponent(n) + || n.toLowerCase() === "favicon.ico") { + debug("not a valid name %j", name) + return false + } + return n +} + +function npa (arg) { + assert.equal(typeof arg, "string") + arg = arg.trim() + + var res = new Result + res.raw = arg + res.scope = null + + // See if it's something like foo@... + var nameparse = arg.match(nameAt) + debug("nameparse", nameparse) + if (nameparse && validName(nameparse[3]) && + (!nameparse[2] || validName(nameparse[2]))) { + res.name = (nameparse[1] || "") + nameparse[3] + if (nameparse[2]) + res.scope = "@" + nameparse[2] + arg = arg.substr(nameparse[0].length) + } else { + res.name = null + } + + res.rawSpec = arg + res.spec = arg + + var urlparse = url.parse(arg) + debug("urlparse", urlparse) + + // windows paths look like urls + // don't be fooled! + if (isWindows && urlparse && urlparse.protocol && + urlparse.protocol.match(/^[a-zA-Z]:$/)) { + debug("windows url-ish local path", urlparse) + urlparse = {} + } + + if (urlparse.protocol || HostedGit.fromUrl(arg)) { + return parseUrl(res, arg, urlparse) + } + + // 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 + // $name@"" range + // + // if it's got / chars in it, then assume that it's local. + + if (res.name) { + var version = semver.valid(arg, true) + var range = semver.validRange(arg, true) + // foo@... + if (version) { + res.spec = version + res.type = "version" + } else if (range) { + res.spec = range + res.type = "range" + } else if (slashRe.test(arg)) { + parseLocal(res, arg) + } else { + res.type = "tag" + res.spec = arg + } + } else { + var p = arg.match(parseName) + if (p && validName(p[2]) && + (!p[1] || validName(p[1]))) { + res.type = "range" + res.spec = "*" + res.rawSpec = "" + res.name = arg + if (p[1]) + res.scope = "@" + p[1] + } else { + parseLocal(res, arg) + } + } + + return res +} + +function parseLocal (res, arg) { + // turns out nearly every character is allowed in fs paths + if (/\0/.test(arg)) { + throw new Error("Invalid Path: " + JSON.stringify(arg)) + } + res.type = "local" + res.spec = path.resolve(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 + switch (urlparse.protocol) { + case "git:": + case "git+http:": + case "git+https:": + case "git+rsync:": + case "git+ftp:": + case "git+ssh:": + case "git+file:": + res.type = "git" + res.spec = arg.replace(/^git[+]/, "") + break + + case "http:": + case "https:": + res.type = "remote" + res.spec = arg + break + + case "file:": + res.type = "local" + res.spec = urlparse.pathname + break + + default: + throw new Error("Unsupported URL Type: " + arg) + break + } + + return res +} + + +function Result () { + if (!(this instanceof Result)) return new Result +} +Result.prototype.name = null +Result.prototype.type = null +Result.prototype.spec = null +Result.prototype.raw = null +Result.prototype.hosted = null diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/package.json b/node_modules/npm-registry-client/node_modules/npm-package-arg/package.json new file mode 100644 index 000000000..d5b72e01c --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/package.json @@ -0,0 +1,62 @@ +{ + "name": "npm-package-arg", + "version": "3.0.0", + "description": "Parse the things that can be arguments to `npm install`", + "main": "npa.js", + "directories": { + "test": "test" + }, + "dependencies": { + "hosted-git-info": "^1.4.0", + "semver": "4" + }, + "devDependencies": { + "tap": "^0.4.9" + }, + "scripts": { + "test": "tap test/*.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/npm-package-arg" + }, + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/npm-package-arg/issues" + }, + "homepage": "https://github.com/npm/npm-package-arg", + "gitHead": "263fd43295ac8f6eca046be108782cfbf9a78bfe", + "_id": "npm-package-arg@3.0.0", + "_shasum": "84e91836fa2e4e35ae26dc984440b1e5b5aee1ee", + "_from": "npm-package-arg@>=3.0.0 <4.0.0", + "_npmVersion": "1.4.28", + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "dist": { + "shasum": "84e91836fa2e4e35ae26dc984440b1e5b5aee1ee", + "tarball": "http://registry.npmjs.org/npm-package-arg/-/npm-package-arg-3.0.0.tgz" + }, + "_resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-3.0.0.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/test/basic.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/basic.js new file mode 100644 index 000000000..4991ffcd3 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/basic.js @@ -0,0 +1,168 @@ +var npa = require("../npa.js") +var path = require("path") + +require("tap").test("basic", function (t) { + t.setMaxListeners(999) + + var tests = { + "foo@1.2": { + name: "foo", + type: "range", + spec: ">=1.2.0 <1.3.0", + raw: "foo@1.2", + rawSpec: "1.2" + }, + + "@foo/bar": { + raw: "@foo/bar", + name: "@foo/bar", + scope: "@foo", + rawSpec: "", + spec: "*", + type: "range" + }, + + "@foo/bar@": { + raw: "@foo/bar@", + name: "@foo/bar", + scope: "@foo", + rawSpec: "", + spec: "*", + type: "range" + }, + + "@foo/bar@baz": { + raw: "@foo/bar@baz", + name: "@foo/bar", + scope: "@foo", + rawSpec: "baz", + spec: "baz", + type: "tag" + }, + + "@f fo o al/ a d s ;f ": { + raw: "@f fo o al/ a d s ;f", + name: null, + rawSpec: "@f fo o al/ a d s ;f", + spec: path.resolve("@f fo o al/ a d s ;f"), + type: "local" + }, + + "foo@1.2.3": { + name: "foo", + type: "version", + spec: "1.2.3", + raw: "foo@1.2.3" + }, + + "foo@=v1.2.3": { + name: "foo", + type: "version", + spec: "1.2.3", + raw: "foo@=v1.2.3", + rawSpec: "=v1.2.3" + }, + + "git+ssh://git@notgithub.com/user/foo#1.2.3": { + name: null, + type: "git", + spec: "ssh://git@notgithub.com/user/foo#1.2.3", + raw: "git+ssh://git@notgithub.com/user/foo#1.2.3" + }, + + "git+file://path/to/repo#1.2.3": { + name: null, + type: "git", + spec: "file://path/to/repo#1.2.3", + raw: "git+file://path/to/repo#1.2.3" + }, + + "git://notgithub.com/user/foo": { + name: null, + type: "git", + spec: "git://notgithub.com/user/foo", + raw: "git://notgithub.com/user/foo" + }, + + "@foo/bar@git+ssh://notgithub.com/user/foo": { + name: "@foo/bar", + scope: "@foo", + spec: "ssh://notgithub.com/user/foo", + rawSpec: "git+ssh://notgithub.com/user/foo", + raw: "@foo/bar@git+ssh://notgithub.com/user/foo" + }, + + "/path/to/foo": { + name: null, + type: "local", + spec: "/path/to/foo", + raw: "/path/to/foo" + }, + + "file:path/to/foo": { + name: null, + type: "local", + spec: "path/to/foo", + raw: "file:path/to/foo" + }, + + "file:~/path/to/foo": { + name: null, + type: "local", + spec: "~/path/to/foo", + raw: "file:~/path/to/foo" + }, + + "file:../path/to/foo": { + name: null, + type: "local", + spec: "../path/to/foo", + raw: "file:../path/to/foo" + }, + + "file:///path/to/foo": { + name: null, + type: "local", + spec: "/path/to/foo", + raw: "file:///path/to/foo" + }, + + "https://server.com/foo.tgz": { + name: null, + type: "remote", + spec: "https://server.com/foo.tgz", + raw: "https://server.com/foo.tgz" + }, + + "foo@latest": { + name: "foo", + type: "tag", + spec: "latest", + raw: "foo@latest" + }, + + "foo": { + name: "foo", + type: "range", + spec: "*", + raw: "foo" + } + } + + Object.keys(tests).forEach(function (arg) { + var res = npa(arg) + t.type(res, "Result", arg + " is result") + t.has(res, tests[arg], arg + " matches expectations") + }) + + // Completely unreasonable invalid garbage throws an error + t.throws(function() { + npa("this is not a \0 valid package name or url") + }) + + t.throws(function() { + npa("gopher://yea right") + }, "Unsupported URL Type: gopher://yea right") + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/test/bitbucket.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/bitbucket.js new file mode 100644 index 000000000..48bbdbcf9 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/bitbucket.js @@ -0,0 +1,82 @@ +var npa = require("../npa.js") +var path = require("path") + +require("tap").test("basic", function (t) { + t.setMaxListeners(999) + + var tests = { + "bitbucket:user/foo-js": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo-js.git", + raw: "bitbucket:user/foo-js" + }, + + "bitbucket:user/foo-js#bar/baz": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo-js.git#bar/baz", + raw: "bitbucket:user/foo-js#bar/baz" + }, + + "bitbucket:user..blerg--/..foo-js# . . . . . some . tags / / /": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user..blerg--/..foo-js.git# . . . . . some . tags / / /", + raw: "bitbucket:user..blerg--/..foo-js# . . . . . some . tags / / /" + }, + + "bitbucket:user/foo-js#bar/baz/bin": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo-js.git#bar/baz/bin", + raw: "bitbucket:user/foo-js#bar/baz/bin" + }, + + "foo@bitbucket:user/foo-js": { + name: "foo", + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo-js.git", + raw: "foo@bitbucket:user/foo-js" + }, + + "git+ssh://git@bitbucket.org/user/foo#1.2.3": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo.git#1.2.3", + raw: "git+ssh://git@bitbucket.org/user/foo#1.2.3" + }, + + "https://bitbucket.org/user/foo.git": { + name: null, + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo.git", + raw: "https://bitbucket.org/user/foo.git" + }, + + "@foo/bar@git+ssh://bitbucket.org/user/foo": { + name: "@foo/bar", + scope: "@foo", + type: "hosted", + hosted: { type: "bitbucket" }, + spec: "git+ssh://git@bitbucket.org/user/foo.git", + rawSpec: "git+ssh://bitbucket.org/user/foo", + raw: "@foo/bar@git+ssh://bitbucket.org/user/foo" + } + } + + Object.keys(tests).forEach(function (arg) { + var res = npa(arg) + t.type(res, "Result", arg + " is a result") + t.has(res, tests[arg], arg + " matches expectations") + }) + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/test/github.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/github.js new file mode 100644 index 000000000..63fd26c10 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/github.js @@ -0,0 +1,106 @@ +var npa = require("../npa.js") +var path = require("path") + +require("tap").test("basic", function (t) { + t.setMaxListeners(999) + + var tests = { + "user/foo-js": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo-js.git", + raw: "user/foo-js" + }, + + "user/foo-js#bar/baz": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo-js.git#bar/baz", + raw: "user/foo-js#bar/baz" + }, + + "user..blerg--/..foo-js# . . . . . some . tags / / /": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user..blerg--/..foo-js.git# . . . . . some . tags / / /", + raw: "user..blerg--/..foo-js# . . . . . some . tags / / /" + }, + + "user/foo-js#bar/baz/bin": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo-js.git#bar/baz/bin", + raw: "user/foo-js#bar/baz/bin" + }, + + "foo@user/foo-js": { + name: "foo", + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo-js.git", + raw: "foo@user/foo-js" + }, + + "github:user/foo-js": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo-js.git", + raw: "github:user/foo-js" + }, + + "git+ssh://git@github.com/user/foo#1.2.3": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo.git#1.2.3", + raw: "git+ssh://git@github.com/user/foo#1.2.3" + }, + + "git://github.com/user/foo": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo.git", + raw: "git://github.com/user/foo" + }, + + "https://github.com/user/foo.git": { + name: null, + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo.git", + raw: "https://github.com/user/foo.git" + }, + + "@foo/bar@git+ssh://github.com/user/foo": { + name: "@foo/bar", + scope: "@foo", + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/user/foo.git", + rawSpec: "git+ssh://github.com/user/foo", + raw: "@foo/bar@git+ssh://github.com/user/foo" + }, + + "foo@bar/foo": { + name: "foo", + type: "hosted", + hosted: { type: "github" }, + spec: "git+ssh://git@github.com/bar/foo.git", + raw: "foo@bar/foo" + } + } + + Object.keys(tests).forEach(function (arg) { + var res = npa(arg) + t.type(res, "Result", arg + " is a result") + t.has(res, tests[arg], arg + " matches expectations") + }) + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/test/gitlab.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/gitlab.js new file mode 100644 index 000000000..36ea016db --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/gitlab.js @@ -0,0 +1,82 @@ +var npa = require("../npa.js") +var path = require("path") + +require("tap").test("basic", function (t) { + t.setMaxListeners(999) + + var tests = { + "gitlab:user/foo-js": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo-js.git", + raw: "gitlab:user/foo-js" + }, + + "gitlab:user/foo-js#bar/baz": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo-js.git#bar/baz", + raw: "gitlab:user/foo-js#bar/baz" + }, + + "gitlab:user..blerg--/..foo-js# . . . . . some . tags / / /": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user..blerg--/..foo-js.git# . . . . . some . tags / / /", + raw: "gitlab:user..blerg--/..foo-js# . . . . . some . tags / / /" + }, + + "gitlab:user/foo-js#bar/baz/bin": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo-js.git#bar/baz/bin", + raw: "gitlab:user/foo-js#bar/baz/bin" + }, + + "foo@gitlab:user/foo-js": { + name: "foo", + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo-js.git", + raw: "foo@gitlab:user/foo-js" + }, + + "git+ssh://git@gitlab.com/user/foo#1.2.3": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo.git#1.2.3", + raw: "git+ssh://git@gitlab.com/user/foo#1.2.3" + }, + + "https://gitlab.com/user/foo.git": { + name: null, + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo.git", + raw: "https://gitlab.com/user/foo.git" + }, + + "@foo/bar@git+ssh://gitlab.com/user/foo": { + name: "@foo/bar", + scope: "@foo", + type: "hosted", + hosted: { type: "gitlab" }, + spec: "git+ssh://git@gitlab.com/user/foo.git", + rawSpec: "git+ssh://gitlab.com/user/foo", + raw: "@foo/bar@git+ssh://gitlab.com/user/foo" + } + } + + Object.keys(tests).forEach(function (arg) { + var res = npa(arg) + t.type(res, "Result", arg + " is a result") + t.has(res, tests[arg], arg + " matches expectations") + }) + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/npm-package-arg/test/windows.js b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/windows.js new file mode 100644 index 000000000..e3c8ba6b5 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/npm-package-arg/test/windows.js @@ -0,0 +1,41 @@ +global.FAKE_WINDOWS = true + +var npa = require("../npa.js") +var test = require("tap").test +var path = require("path") + +var cases = { + "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" + }, + "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" + }, + "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" + } +} + +test("parse a windows path", function (t) { + Object.keys(cases).forEach(function (c) { + var expect = cases[c] + var actual = npa(c) + t.same(actual, expect, c) + }) + t.end() +}) diff --git a/node_modules/npm-registry-client/package.json b/node_modules/npm-registry-client/package.json index 9d4178c57..698cc7581 100644 --- a/node_modules/npm-registry-client/package.json +++ b/node_modules/npm-registry-client/package.json @@ -6,7 +6,7 @@ }, "name": "npm-registry-client", "description": "Client for the npm registry", - "version": "5.0.0", + "version": "6.0.0", "repository": { "url": "git://github.com/isaacs/npm-registry-client" }, @@ -20,6 +20,7 @@ "graceful-fs": "^3.0.0", "mkdirp": "^0.5.0", "normalize-package-data": "~1.0.1", + "npm-package-arg": "^3.0.0", "once": "^1.3.0", "request": "^2.47.0", "retry": "^0.6.1", @@ -37,14 +38,14 @@ "npmlog": "" }, "license": "ISC", - "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(config)\nvar uri = \"npm://registry.npmjs.org/npm\"\nvar params = {timeout: 1000}\n\nclient.get(uri, params, function (error, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Registry URLs\n\nThe registry calls take either a full URL pointing to a resource in the\nregistry, or a base URL for the registry as a whole (including the registry\npath – but be sure to terminate the path with `/`). `http` and `https` URLs are\nthe only ones supported.\n\n## Using the client\n\nEvery call to the client follows the same pattern:\n\n* `uri` {String} The *fully-qualified* URI of the registry API method being\n invoked.\n* `params` {Object} Per-request parameters.\n* `callback` {Function} Callback to be invoked when the call is complete.\n\n### Credentials\n\nMany requests to the registry can by authenticated, and require credentials\nfor authorization. These credentials always look the same:\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `alwaysAuth` {Boolean} Whether calls to the target registry are always\n authed.\n\n**or**\n\n* `token` {String}\n* `alwaysAuth` {Boolean} Whether calls to the target registry are always\n authed.\n\n## API\n\n### client.adduser(uri, params, cb)\n\n* `uri` {String} Base registry URL.\n* `params` {Object} Object containing per-request properties.\n * `auth` {Credentials}\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nAdd a user account to the registry, or verify the credentials.\n\n### client.deprecate(uri, params, cb)\n\n* `uri` {String} Full registry URI for the deprecated package.\n* `params` {Object} Object containing per-request properties.\n * `version` {String} Semver version range.\n * `message` {String} The message to use as a deprecation warning.\n * `auth` {Credentials}\n* `cb` {Function}\n\nDeprecate a version of a package in the registry.\n\n### client.get(uri, params, cb)\n\n* `uri` {String} The complete registry URI to fetch\n* `params` {Object} Object containing per-request properties.\n * `timeout` {Number} Duration before the request times out. Optional\n (default: never).\n * `follow` {Boolean} Follow 302/301 responses. Optional (default: true).\n * `staleOk` {Boolean} If there's cached data available, then return that to\n the callback quickly, and update the cache the background. Optional\n (default: false).\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n\nFetches data from the registry via a GET request, saving it in the cache folder\nwith the ETag or the \"Last Modified\" timestamp.\n\n### client.publish(uri, params, cb)\n\n* `uri` {String} The registry URI for the package to publish.\n* `params` {Object} Object containing per-request properties.\n * `metadata` {Object} Package metadata.\n * `body` {Stream} Stream of the package body / tarball.\n * `auth` {Credentials}\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder.\n\n### client.star(uri, params, cb)\n\n* `uri` {String} The complete registry URI for the package to star.\n* `params` {Object} Object containing per-request properties.\n * `starred` {Boolean} True to star the package, false to unstar it. Optional\n (default: false).\n * `auth` {Credentials}\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or unstar a\npackage, though other writes do require that the user be the package owner.\n\n### client.stars(uri, params, cb)\n\n* `uri` {String} The base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `username` {String} Name of user to fetch starred packages for. Optional\n (default: user in `auth`).\n * `auth` {Credentials} Optional (required if `username` is omitted).\n* `cb` {Function}\n\nView your own or another user's starred packages.\n\n### client.tag(uri, params, cb)\n\n* `uri` {String} The complete registry URI to tag\n* `params` {Object} Object containing per-request properties.\n * `version` {String} Version to tag.\n * `tag` {String} Tag name to apply.\n * `auth` {Credentials}\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag` will fetch the\nspecified version.\n\n### client.unpublish(uri, params, cb)\n\n* `uri` {String} The complete registry URI of the package to unpublish.\n* `params` {Object} Object containing per-request properties.\n * `version` {String} version to unpublish. Optional – omit to unpublish all\n versions.\n * `auth` {Credentials}\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When the\nlast version us unpublished, the entire document is removed from the database.\n\n### client.whoami(uri, params, cb)\n\n* `uri` {String} The base registry for the URI.\n* `params` {Object} Object containing per-request properties.\n * `auth` {Credentials}\n* `cb` {Function}\n\nSimple call to see who the registry thinks you are. Especially useful with\ntoken-based auth.\n\n\n## PLUMBING\n\nThe below are primarily intended for use by the rest of the API, or by the npm\ncaching logic directly.\n\n### client.request(uri, params, cb)\n\n* `uri` {String} URI pointing to the resource to request.\n* `params` {Object} Object containing per-request properties.\n * `method` {String} HTTP method. Optional (default: \"GET\").\n * `body` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON. Optional – body\n only used for write operations.\n * `etag` {String} The cached ETag. Optional.\n * `lastModified` {String} The cached Last-Modified timestamp. Optional.\n * `follow` {Boolean} Follow 302/301 responses. Optional (default: true).\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a generic request to the registry. All the other methods are wrappers\naround `client.request`.\n\n### client.fetch(uri, params, cb)\n\n* `uri` {String} The complete registry URI to upload to\n* `params` {Object} Object containing per-request properties.\n * `headers` {Stream} HTTP headers to be included with the request. Optional.\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n\nFetch a package from a URL, with auth set appropriately if included. Used to\ncache remote tarballs as well as request package tarballs from the registry.\n\n# Configuration\n\nThe client uses its own configuration, which is just passed in as a simple\nnested object. The following are the supported values (with their defaults, if\nany):\n\n* `proxy.http` {URL} The URL to proxy HTTP requests through.\n* `proxy.https` {URL} The URL to proxy HTTPS requests through. Defaults to be\n the same as `proxy.http` if unset.\n* `proxy.localAddress` {IP} The local address to use on multi-homed systems.\n* `ssl.ca` {String} Cerficate signing authority certificates to trust.\n* `ssl.certificate` {String} Client certificate (PEM encoded). Enable access\n to servers that require client certificates.\n* `ssl.key` {String} Private key (PEM encoded) for client certificate.\n* `ssl.strict` {Boolean} Whether or not to be strict with SSL certificates.\n Default = `true`\n* `retry.count` {Number} Number of times to retry on GET failures. Default = 2.\n* `retry.factor` {Number} `factor` setting for `node-retry`. Default = 10.\n* `retry.minTimeout` {Number} `minTimeout` setting for `node-retry`.\n Default = 10000 (10 seconds)\n* `retry.maxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default = 60000 (60 seconds)\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `defaultTag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `couchToken` {Object} A token for use with\n [couch-login](https://npmjs.org/package/couch-login).\n* `sessionToken` {string} A random identifier for this set of client requests.\n Default = 8 random hexadecimal bytes.\n", + "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(config)\nvar uri = \"npm://registry.npmjs.org/npm\"\nvar params = {timeout: 1000}\n\nclient.get(uri, params, function (error, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Registry URLs\n\nThe registry calls take either a full URL pointing to a resource in the\nregistry, or a base URL for the registry as a whole (including the registry\npath – but be sure to terminate the path with `/`). `http` and `https` URLs are\nthe only ones supported.\n\n## Using the client\n\nEvery call to the client follows the same pattern:\n\n* `uri` {String} The *fully-qualified* URI of the registry API method being\n invoked.\n* `params` {Object} Per-request parameters.\n* `callback` {Function} Callback to be invoked when the call is complete.\n\n### Credentials\n\nMany requests to the registry can by authenticated, and require credentials\nfor authorization. These credentials always look the same:\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `alwaysAuth` {Boolean} Whether calls to the target registry are always\n authed.\n\n**or**\n\n* `token` {String}\n* `alwaysAuth` {Boolean} Whether calls to the target registry are always\n authed.\n\n## API\n\n### client.access(uri, params, cb)\n\n* `uri` {String} Registry URL for the package's access API endpoint.\n Looks like `/-/package/<package name>/access`.\n* `params` {Object} Object containing per-request properties.\n * `access` {String} New access level for the package. Can be either\n `public` or `restricted`. Registry will raise an error if trying\n to change the access level of an unscoped package.\n * `auth` {Credentials}\n\nSet the access level for scoped packages. For now, there are only two\naccess levels: \"public\" and \"restricted\".\n\n### client.adduser(uri, params, cb)\n\n* `uri` {String} Base registry URL.\n* `params` {Object} Object containing per-request properties.\n * `auth` {Credentials}\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nAdd a user account to the registry, or verify the credentials.\n\n### client.deprecate(uri, params, cb)\n\n* `uri` {String} Full registry URI for the deprecated package.\n* `params` {Object} Object containing per-request properties.\n * `version` {String} Semver version range.\n * `message` {String} The message to use as a deprecation warning.\n * `auth` {Credentials}\n* `cb` {Function}\n\nDeprecate a version of a package in the registry.\n\n### client.distTags.fetch(uri, params, cb)\n\n* `uri` {String} Base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `package` {String} Name of the package.\n * `auth` {Credentials}\n* `cb` {Function}\n\nFetch all of the `dist-tags` for the named package.\n\n### client.distTags.add(uri, params, cb)\n\n* `uri` {String} Base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `package` {String} Name of the package.\n * `distTag` {String} Name of the new `dist-tag`.\n * `version` {String} Exact version to be mapped to the `dist-tag`.\n * `auth` {Credentials}\n* `cb` {Function}\n\nAdd (or replace) a single dist-tag onto the named package.\n\n### client.distTags.set(uri, params, cb)\n\n* `uri` {String} Base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `package` {String} Name of the package.\n * `distTags` {Object} Object containing a map from tag names to package\n versions.\n * `auth` {Credentials}\n* `cb` {Function}\n\nSet all of the `dist-tags` for the named package at once, creating any\n`dist-tags` that do not already exit. Any `dist-tags` not included in the\n`distTags` map will be removed.\n\n### client.distTags.update(uri, params, cb)\n\n* `uri` {String} Base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `package` {String} Name of the package.\n * `distTags` {Object} Object containing a map from tag names to package\n versions.\n * `auth` {Credentials}\n* `cb` {Function}\n\nUpdate the values of multiple `dist-tags`, creating any `dist-tags` that do\nnot already exist. Any pre-existing `dist-tags` not included in the `distTags`\nmap will be left alone.\n\n### client.distTags.rm(uri, params, cb)\n\n* `uri` {String} Base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `package` {String} Name of the package.\n * `distTag` {String} Name of the new `dist-tag`.\n * `auth` {Credentials}\n* `cb` {Function}\n\nRemove a single `dist-tag` from the named package.\n\n### client.get(uri, params, cb)\n\n* `uri` {String} The complete registry URI to fetch\n* `params` {Object} Object containing per-request properties.\n * `timeout` {Number} Duration before the request times out. Optional\n (default: never).\n * `follow` {Boolean} Follow 302/301 responses. Optional (default: true).\n * `staleOk` {Boolean} If there's cached data available, then return that to\n the callback quickly, and update the cache the background. Optional\n (default: false).\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n\nFetches data from the registry via a GET request, saving it in the cache folder\nwith the ETag or the \"Last Modified\" timestamp.\n\n### client.publish(uri, params, cb)\n\n* `uri` {String} The registry URI for the package to publish.\n* `params` {Object} Object containing per-request properties.\n * `metadata` {Object} Package metadata.\n * `access` {String} Access for the package. Can be `public` or `restricted` (no default).\n * `body` {Stream} Stream of the package body / tarball.\n * `auth` {Credentials}\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder.\n\n### client.star(uri, params, cb)\n\n* `uri` {String} The complete registry URI for the package to star.\n* `params` {Object} Object containing per-request properties.\n * `starred` {Boolean} True to star the package, false to unstar it. Optional\n (default: false).\n * `auth` {Credentials}\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or unstar a\npackage, though other writes do require that the user be the package owner.\n\n### client.stars(uri, params, cb)\n\n* `uri` {String} The base URL for the registry.\n* `params` {Object} Object containing per-request properties.\n * `username` {String} Name of user to fetch starred packages for. Optional\n (default: user in `auth`).\n * `auth` {Credentials} Optional (required if `username` is omitted).\n* `cb` {Function}\n\nView your own or another user's starred packages.\n\n### client.tag(uri, params, cb)\n\n* `uri` {String} The complete registry URI to tag\n* `params` {Object} Object containing per-request properties.\n * `version` {String} Version to tag.\n * `tag` {String} Tag name to apply.\n * `auth` {Credentials}\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag` will fetch the\nspecified version.\n\n### client.unpublish(uri, params, cb)\n\n* `uri` {String} The complete registry URI of the package to unpublish.\n* `params` {Object} Object containing per-request properties.\n * `version` {String} version to unpublish. Optional – omit to unpublish all\n versions.\n * `auth` {Credentials}\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When the\nlast version us unpublished, the entire document is removed from the database.\n\n### client.whoami(uri, params, cb)\n\n* `uri` {String} The base registry for the URI.\n* `params` {Object} Object containing per-request properties.\n * `auth` {Credentials}\n* `cb` {Function}\n\nSimple call to see who the registry thinks you are. Especially useful with\ntoken-based auth.\n\n\n## PLUMBING\n\nThe below are primarily intended for use by the rest of the API, or by the npm\ncaching logic directly.\n\n### client.request(uri, params, cb)\n\n* `uri` {String} URI pointing to the resource to request.\n* `params` {Object} Object containing per-request properties.\n * `method` {String} HTTP method. Optional (default: \"GET\").\n * `body` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON. Optional – body\n only used for write operations.\n * `etag` {String} The cached ETag. Optional.\n * `lastModified` {String} The cached Last-Modified timestamp. Optional.\n * `follow` {Boolean} Follow 302/301 responses. Optional (default: true).\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a generic request to the registry. All the other methods are wrappers\naround `client.request`.\n\n### client.fetch(uri, params, cb)\n\n* `uri` {String} The complete registry URI to upload to\n* `params` {Object} Object containing per-request properties.\n * `headers` {Stream} HTTP headers to be included with the request. Optional.\n * `auth` {Credentials} Optional.\n* `cb` {Function}\n\nFetch a package from a URL, with auth set appropriately if included. Used to\ncache remote tarballs as well as request package tarballs from the registry.\n\n# Configuration\n\nThe client uses its own configuration, which is just passed in as a simple\nnested object. The following are the supported values (with their defaults, if\nany):\n\n* `proxy.http` {URL} The URL to proxy HTTP requests through.\n* `proxy.https` {URL} The URL to proxy HTTPS requests through. Defaults to be\n the same as `proxy.http` if unset.\n* `proxy.localAddress` {IP} The local address to use on multi-homed systems.\n* `ssl.ca` {String} Cerficate signing authority certificates to trust.\n* `ssl.certificate` {String} Client certificate (PEM encoded). Enable access\n to servers that require client certificates.\n* `ssl.key` {String} Private key (PEM encoded) for client certificate.\n* `ssl.strict` {Boolean} Whether or not to be strict with SSL certificates.\n Default = `true`\n* `retry.count` {Number} Number of times to retry on GET failures. Default = 2.\n* `retry.factor` {Number} `factor` setting for `node-retry`. Default = 10.\n* `retry.minTimeout` {Number} `minTimeout` setting for `node-retry`.\n Default = 10000 (10 seconds)\n* `retry.maxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default = 60000 (60 seconds)\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `defaultTag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `couchToken` {Object} A token for use with\n [couch-login](https://npmjs.org/package/couch-login).\n* `sessionToken` {string} A random identifier for this set of client requests.\n Default = 8 random hexadecimal bytes.\n", "readmeFilename": "README.md", - "gitHead": "b22f38992087e57f263c269dcd52ff290565d401", + "gitHead": "1998560b0800562d6b9b39ed27ca418ed6d6fdc6", "bugs": { "url": "https://github.com/isaacs/npm-registry-client/issues" }, "homepage": "https://github.com/isaacs/npm-registry-client", - "_id": "npm-registry-client@5.0.0", - "_shasum": "0425db2fc3dcd322e74fe95029d2c49a41e4b6cf", - "_from": "npm-registry-client@>=5.0.0 <5.1.0" + "_id": "npm-registry-client@6.0.0", + "_shasum": "15303d0bcc5499a9d50064d3ad1f5ba1ea9f90bd", + "_from": "npm-registry-client@>=6.0.0 <6.1.0" } diff --git a/node_modules/npm-registry-client/test/access.js b/node_modules/npm-registry-client/test/access.js new file mode 100644 index 000000000..52ecdda4a --- /dev/null +++ b/node_modules/npm-registry-client/test/access.js @@ -0,0 +1,96 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var URI = "http://localhost:1337/-/package/underscore/access" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var LEVEL = "public" +var PARAMS = { + level : LEVEL, + auth : AUTH +} + +test("access call contract", function (t) { + t.throws(function () { + client.access(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.access([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.access(URI, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.access(URI, "", nop) + }, "params must be object") + + t.throws(function () { + client.access(URI, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.access(URI, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + auth : AUTH + } + client.access(URI, params, nop) + }, + { name : "AssertionError", message : "must pass level to access" }, + "access must include level" + ) + + t.throws( + function () { + var params = { + level : LEVEL + } + client.access(URI, params, nop) + }, + { name : "AssertionError", message : "must pass auth to access" }, + "access must include auth" + ) + + t.end() +}) + +test("set access level on a package", function (t) { + server.expect("POST", "/-/package/underscore/access", function (req, res) { + t.equal(req.method, "POST") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + var updated = JSON.parse(b) + + t.deepEqual(updated, { access : "public" }) + + res.statusCode = 201 + res.json({accessChanged : true}) + }) + }) + + client.access(URI, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.ok(data.accessChanged, "access level set") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/dist-tags-add.js b/node_modules/npm-registry-client/test/dist-tags-add.js new file mode 100644 index 000000000..31e93fc68 --- /dev/null +++ b/node_modules/npm-registry-client/test/dist-tags-add.js @@ -0,0 +1,138 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var BASE_URL = "http://localhost:1337/" +var URI = "/-/package/underscore/dist-tags/test" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var PACKAGE = "underscore" +var DIST_TAG = "test" +var VERSION = "3.1.3" +var PARAMS = { + package : PACKAGE, + distTag : DIST_TAG, + version : VERSION, + auth : AUTH +} + +test("distTags.add call contract", function (t) { + t.throws(function () { + client.distTags.add(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.distTags.add([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.distTags.add(BASE_URL, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.distTags.add(BASE_URL, "", nop) + }, "params must be object") + + t.throws(function () { + client.distTags.add(BASE_URL, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.distTags.add(BASE_URL, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + distTag : DIST_TAG, + version : VERSION, + auth : AUTH + } + client.distTags.add(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package name to distTags.add" + }, + "distTags.add must include package name" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + version : VERSION, + auth : AUTH + } + client.distTags.add(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package distTag name to distTags.add" + }, + "distTags.add must include dist-tag" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + distTag : DIST_TAG, + auth : AUTH + } + client.distTags.add(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass version to be mapped to distTag to distTags.add" + }, + "distTags.add must include version" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + distTag : DIST_TAG, + version : VERSION + } + client.distTags.add(BASE_URL, params, nop) + }, + { name : "AssertionError", message : "must pass auth to distTags.add" }, + "distTags.add must include auth" + ) + + t.end() +}) + +test("add a new dist-tag to a package", function (t) { + server.expect("PUT", URI, function (req, res) { + t.equal(req.method, "PUT") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + t.deepEqual(b, VERSION) + + res.statusCode = 200 + res.json({ "test" : VERSION }) + }) + }) + + client.distTags.add(BASE_URL, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.ok(data.test, "dist-tag added") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/dist-tags-fetch.js b/node_modules/npm-registry-client/test/dist-tags-fetch.js new file mode 100644 index 000000000..783f3e5c5 --- /dev/null +++ b/node_modules/npm-registry-client/test/dist-tags-fetch.js @@ -0,0 +1,98 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var BASE_URL = "http://localhost:1337/" +var URI = "/-/package/underscore/dist-tags" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var PACKAGE = "underscore" +var PARAMS = { + package : PACKAGE, + auth : AUTH +} + +test("distTags.fetch call contract", function (t) { + t.throws(function () { + client.distTags.fetch(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.distTags.fetch([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.distTags.fetch(BASE_URL, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.distTags.fetch(BASE_URL, "", nop) + }, "params must be object") + + t.throws(function () { + client.distTags.fetch(BASE_URL, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.distTags.fetch(BASE_URL, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + auth : AUTH + } + client.distTags.fetch(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package name to distTags.fetch" + }, + "distTags.fetch must include package name" + ) + + t.throws( + function () { + var params = { + package : PACKAGE + } + client.distTags.fetch(BASE_URL, params, nop) + }, + { name : "AssertionError", message : "must pass auth to distTags.fetch" }, + "distTags.fetch must include auth" + ) + + t.end() +}) + +test("fetch dist-tags for a package", function (t) { + server.expect("GET", URI, function (req, res) { + t.equal(req.method, "GET") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + t.notOk(b, "no request body") + + res.statusCode = 200 + res.json({ a : "1.0.0", b : "2.0.0" }) + }) + }) + + client.distTags.fetch(BASE_URL, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.notOk(data.test, "dist-tag removed") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/dist-tags-rm.js b/node_modules/npm-registry-client/test/dist-tags-rm.js new file mode 100644 index 000000000..6268a06aa --- /dev/null +++ b/node_modules/npm-registry-client/test/dist-tags-rm.js @@ -0,0 +1,117 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var BASE_URL = "http://localhost:1337/" +var URI = "/-/package/underscore/dist-tags/test" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var PACKAGE = "underscore" +var DIST_TAG = "test" +var PARAMS = { + package : PACKAGE, + distTag : DIST_TAG, + auth : AUTH +} + +test("distTags.rm call contract", function (t) { + t.throws(function () { + client.distTags.rm(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.distTags.rm([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.distTags.rm(BASE_URL, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.distTags.rm(BASE_URL, "", nop) + }, "params must be object") + + t.throws(function () { + client.distTags.rm(BASE_URL, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.distTags.rm(BASE_URL, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + distTag : DIST_TAG, + auth : AUTH + } + client.distTags.rm(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package name to distTags.rm" + }, + "distTags.rm must include package name" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + auth : AUTH + } + client.distTags.rm(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package distTag name to distTags.rm" + }, + "distTags.rm must include dist-tag" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + distTag : DIST_TAG + } + client.distTags.rm(BASE_URL, params, nop) + }, + { name : "AssertionError", message : "must pass auth to distTags.rm" }, + "distTags.rm must include auth" + ) + + t.end() +}) + +test("remove a dist-tag from a package", function (t) { + server.expect("DELETE", URI, function (req, res) { + t.equal(req.method, "DELETE") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + t.notOk(b, "got no message body") + + res.statusCode = 200 + res.json({}) + }) + }) + + client.distTags.rm(BASE_URL, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.notOk(data.test, "dist-tag removed") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/dist-tags-set.js b/node_modules/npm-registry-client/test/dist-tags-set.js new file mode 100644 index 000000000..ff5591dbd --- /dev/null +++ b/node_modules/npm-registry-client/test/dist-tags-set.js @@ -0,0 +1,121 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var BASE_URL = "http://localhost:1337/" +var URI = "/-/package/underscore/dist-tags" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var PACKAGE = "underscore" +var DIST_TAGS = { + "a" : "8.0.8", + "b" : "3.0.3" +} +var PARAMS = { + package : PACKAGE, + distTags : DIST_TAGS, + auth : AUTH +} + +test("distTags.set call contract", function (t) { + t.throws(function () { + client.distTags.set(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.distTags.set([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.distTags.set(BASE_URL, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.distTags.set(BASE_URL, "", nop) + }, "params must be object") + + t.throws(function () { + client.distTags.set(BASE_URL, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.distTags.set(BASE_URL, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + distTags : DIST_TAGS, + auth : AUTH + } + client.distTags.set(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package name to distTags.set" + }, + "distTags.set must include package name" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + auth : AUTH + } + client.distTags.set(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass distTags map to distTags.set" + }, + "distTags.set must include dist-tags" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + distTags : DIST_TAGS + } + client.distTags.set(BASE_URL, params, nop) + }, + { name : "AssertionError", message : "must pass auth to distTags.set" }, + "distTags.set must include auth" + ) + + t.end() +}) + +test("set dist-tags for a package", function (t) { + server.expect("PUT", URI, function (req, res) { + t.equal(req.method, "PUT") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + var d = JSON.parse(b) + t.deepEqual(d, DIST_TAGS, "got back tags") + + res.statusCode = 200 + res.json(DIST_TAGS) + }) + }) + + client.distTags.set(BASE_URL, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.ok(data.a && data.b, "dist-tags set") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/dist-tags-update.js b/node_modules/npm-registry-client/test/dist-tags-update.js new file mode 100644 index 000000000..7c29e1114 --- /dev/null +++ b/node_modules/npm-registry-client/test/dist-tags-update.js @@ -0,0 +1,121 @@ +var test = require("tap").test + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient() + +function nop() {} + +var BASE_URL = "http://localhost:1337/" +var URI = "/-/package/underscore/dist-tags" +var TOKEN = "foo" +var AUTH = { + token : TOKEN +} +var PACKAGE = "underscore" +var DIST_TAGS = { + "a" : "8.0.8", + "b" : "3.0.3" +} +var PARAMS = { + package : PACKAGE, + distTags : DIST_TAGS, + auth : AUTH +} + +test("distTags.update call contract", function (t) { + t.throws(function () { + client.distTags.update(undefined, AUTH, nop) + }, "requires a URI") + + t.throws(function () { + client.distTags.update([], PARAMS, nop) + }, "requires URI to be a string") + + t.throws(function () { + client.distTags.update(BASE_URL, undefined, nop) + }, "requires params object") + + t.throws(function () { + client.distTags.update(BASE_URL, "", nop) + }, "params must be object") + + t.throws(function () { + client.distTags.update(BASE_URL, PARAMS, undefined) + }, "requires callback") + + t.throws(function () { + client.distTags.update(BASE_URL, PARAMS, "callback") + }, "callback must be function") + + t.throws( + function () { + var params = { + distTags : DIST_TAGS, + auth : AUTH + } + client.distTags.update(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass package name to distTags.update" + }, + "distTags.update must include package name" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + auth : AUTH + } + client.distTags.update(BASE_URL, params, nop) + }, + { + name : "AssertionError", + message : "must pass distTags map to distTags.update" + }, + "distTags.update must include dist-tags" + ) + + t.throws( + function () { + var params = { + package : PACKAGE, + distTags : DIST_TAGS + } + client.distTags.update(BASE_URL, params, nop) + }, + { name : "AssertionError", message : "must pass auth to distTags.update" }, + "distTags.update must include auth" + ) + + t.end() +}) + +test("update dist-tags for a package", function (t) { + server.expect("POST", URI, function (req, res) { + t.equal(req.method, "POST") + + var b = "" + req.setEncoding("utf8") + req.on("data", function (d) { + b += d + }) + + req.on("end", function () { + var d = JSON.parse(b) + t.deepEqual(d, DIST_TAGS, "got back tags") + + res.statusCode = 200 + res.json(DIST_TAGS) + }) + }) + + client.distTags.update(BASE_URL, PARAMS, function (error, data) { + t.ifError(error, "no errors") + t.ok(data.a && data.b, "dist-tags set") + + t.end() + }) +}) diff --git a/node_modules/npm-registry-client/test/publish-again-scoped.js b/node_modules/npm-registry-client/test/publish-again-scoped.js index 10b127505..b9d9a24d6 100644 --- a/node_modules/npm-registry-client/test/publish-again-scoped.js +++ b/node_modules/npm-registry-client/test/publish-again-scoped.js @@ -78,6 +78,7 @@ tap.test("publish again", function (t) { var params = { metadata : pkg, + access : "restricted", body : tarball, auth : auth } diff --git a/node_modules/npm-registry-client/test/publish-again.js b/node_modules/npm-registry-client/test/publish-again.js index 9c547ca01..f5da5b243 100644 --- a/node_modules/npm-registry-client/test/publish-again.js +++ b/node_modules/npm-registry-client/test/publish-again.js @@ -76,6 +76,7 @@ tap.test("publish again", function (t) { var params = { metadata : pkg, + access : "public", body : tarball, auth : auth } diff --git a/node_modules/npm-registry-client/test/publish-failed-no-message.js b/node_modules/npm-registry-client/test/publish-failed-no-message.js index cce6fcbc7..50b3f9349 100644 --- a/node_modules/npm-registry-client/test/publish-failed-no-message.js +++ b/node_modules/npm-registry-client/test/publish-failed-no-message.js @@ -12,6 +12,7 @@ var USERNAME = "username" var PASSWORD = "%1234@asdf%" var EMAIL = "i@izs.me" var METADATA = require("../package.json") +var ACCESS = "public" // not really a tarball, but doesn't matter var BODY_PATH = require.resolve("../package.json") var BODY = createReadStream(BODY_PATH, "base64") @@ -22,6 +23,7 @@ var AUTH = { } var PARAMS = { metadata : METADATA, + access : ACCESS, body : BODY, auth : AUTH } diff --git a/node_modules/npm-registry-client/test/publish-scoped-auth-token.js b/node_modules/npm-registry-client/test/publish-scoped-auth-token.js index 70ff1e93f..203c80004 100644 --- a/node_modules/npm-registry-client/test/publish-scoped-auth-token.js +++ b/node_modules/npm-registry-client/test/publish-scoped-auth-token.js @@ -44,6 +44,7 @@ tap.test("publish", function (t) { var params = { metadata : pkg, + access : "restricted", body : tarball, auth : auth } diff --git a/node_modules/npm-registry-client/test/publish-scoped.js b/node_modules/npm-registry-client/test/publish-scoped.js index b21e33f41..6bb48617d 100644 --- a/node_modules/npm-registry-client/test/publish-scoped.js +++ b/node_modules/npm-registry-client/test/publish-scoped.js @@ -51,6 +51,7 @@ tap.test("publish", function (t) { var params = { metadata : pkg, + access : "restricted", body : tarball, auth : auth } diff --git a/node_modules/npm-registry-client/test/publish.js b/node_modules/npm-registry-client/test/publish.js index 9292a94c7..40bfdf2bb 100644 --- a/node_modules/npm-registry-client/test/publish.js +++ b/node_modules/npm-registry-client/test/publish.js @@ -13,6 +13,7 @@ var USERNAME = "username" var PASSWORD = "%1234@asdf%" var EMAIL = "i@izs.me" var METADATA = require("../package.json") +var ACCESS = "public" // not really a tarball, but doesn't matter var BODY_PATH = require.resolve("../package.json") var BODY = fs.createReadStream(BODY_PATH, "base64") @@ -23,6 +24,7 @@ var AUTH = { } var PARAMS = { metadata : METADATA, + access : ACCESS, body : BODY, auth : AUTH } @@ -55,6 +57,7 @@ test("publish call contract", function (t) { t.throws( function () { var params = { + access : ACCESS, body : BODY, auth : AUTH } @@ -68,6 +71,20 @@ test("publish call contract", function (t) { function () { var params = { metadata : METADATA, + body : BODY, + auth : AUTH + } + client.publish(URI, params, nop) + }, + { name : "AssertionError", message : "must pass access for package" }, + "params must include access for package" + ) + + t.throws( + function () { + var params = { + metadata : METADATA, + access : ACCESS, auth : AUTH } client.publish(URI, params, nop) @@ -80,6 +97,7 @@ test("publish call contract", function (t) { function () { var params = { metadata : METADATA, + access : ACCESS, body : BODY } client.publish(URI, params, nop) @@ -92,6 +110,7 @@ test("publish call contract", function (t) { function () { var params = { metadata : -1, + access : ACCESS, body : BODY, auth : AUTH } @@ -105,6 +124,24 @@ test("publish call contract", function (t) { function () { var params = { metadata : METADATA, + access : "hamchunx", + body : BODY, + auth : AUTH + } + client.publish(URI, params, nop) + }, + { + name : "AssertionError", + message : "access level must be either 'public' or 'restricted'" + }, + "access level must be 'public' or 'restricted'" + ) + + t.throws( + function () { + var params = { + metadata : METADATA, + access : ACCESS, body : -1, auth : AUTH } @@ -122,6 +159,7 @@ test("publish call contract", function (t) { metadata.version = "%!@#$" var params = { metadata : metadata, + access : ACCESS, message : BODY, auth : AUTH } @@ -153,6 +191,7 @@ test("publish", function (t) { var o = JSON.parse(b) t.equal(o._id, "npm-registry-client") t.equal(o["dist-tags"].latest, METADATA.version) + t.equal(o.access, ACCESS) t.has(o.versions[METADATA.version], METADATA) t.same(o.maintainers, [{ name : "username", email : "i@izs.me" }]) t.same(o.maintainers, o.versions[METADATA.version].maintainers) diff --git a/node_modules/npm-registry-client/test/tag.js b/node_modules/npm-registry-client/test/tag.js index 687df5d7d..4116586ee 100644 --- a/node_modules/npm-registry-client/test/tag.js +++ b/node_modules/npm-registry-client/test/tag.js @@ -57,7 +57,7 @@ test("tag call contract", function (t) { client.tag(URI, params, nop) }, { name : "AssertionError", message : "must pass version to tag" }, - "auth must include username" + "tag must include version" ) t.throws( @@ -69,7 +69,7 @@ test("tag call contract", function (t) { client.tag(URI, params, nop) }, { name : "AssertionError", message : "must pass tag name to tag" }, - "auth must include username" + "tag must include name" ) t.throws( @@ -81,7 +81,7 @@ test("tag call contract", function (t) { client.tag(URI, params, nop) }, { name : "AssertionError", message : "must pass auth to tag" }, - "auth must include username" + "params must include auth" ) t.end() diff --git a/node_modules/npm-registry-client/test/whoami.js b/node_modules/npm-registry-client/test/whoami.js index ccb173a09..21b70e82f 100644 --- a/node_modules/npm-registry-client/test/whoami.js +++ b/node_modules/npm-registry-client/test/whoami.js @@ -49,10 +49,13 @@ test("whoami call contract", function (t) { }) test("whoami", function (t) { - server.expect("GET", "/whoami", function (req, res) { + server.expect("GET", "/-/whoami", function (req, res) { t.equal(req.method, "GET") // only available for token-based auth for now - t.equal(req.headers.authorization, "Bearer not-bad-meaning-bad-but-bad-meaning-wombat") + t.equal( + req.headers.authorization, + "Bearer not-bad-meaning-bad-but-bad-meaning-wombat" + ) res.json({username : WHOIAM}) }) |