diff options
46 files changed, 2024 insertions, 52 deletions
diff --git a/.gitignore b/.gitignore index 1d9fa90f6..903f3da7a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ npm-debug.log /test/root /node_modules/ronn /node_modules/tap +/node_modules/nock /node_modules/.bin /node_modules/npm-registry-mock /node_modules/marked diff --git a/lib/publish.js b/lib/publish.js index ccad3ea82..b3622b693 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -9,6 +9,7 @@ var npm = require("./npm.js") , chain = require("slide").chain , Conf = require("npmconf").Conf , RegClient = require("npm-registry-client") + , isOrganized = require("./utils/is-organized.js") publish.usage = "npm publish <tarball>" + "\nnpm publish <folder>" @@ -66,21 +67,37 @@ function cacheAddPublish (dir, didPre, isRetry, cb) { function publish_ (arg, data, isRetry, cachedir, cb) { if (!data) return cb(new Error("no package.json file found")) - // check for publishConfig hash var registry = npm.registry - var registryURI = npm.config.get("registry") + var config = npm.config + + // check for publishConfig hash if (data.publishConfig) { - var pubConf = new Conf(npm.config) - pubConf.save = npm.config.save.bind(npm.config) + config = new Conf(npm.config) + config.save = npm.config.save.bind(npm.config) // don't modify the actual publishConfig object, in case we have // to set a login token or some other data. - pubConf.unshift(Object.keys(data.publishConfig).reduce(function (s, k) { + config.unshift(Object.keys(data.publishConfig).reduce(function (s, k) { s[k] = data.publishConfig[k] return s }, {})) - registry = new RegClient(pubConf) - registryURI = pubConf.get("registry") + registry = new RegClient(config) + } + + var registryURI + if (isOrganized(data.name)) { + var org = data.name.match(/^(@[^@\/]+)\//)[1] + if (!org) return cb(new Error("No organization found in scoped package name")) + log.silly("publish", "@org", org) + + var base = config.get(org + ":registry-base-url") + if (!base) { + return cb(new Error("no registry URL found for scope " + org)) + } + registryURI = base + } + else { + registryURI = config.get("registry") } data._npmVersion = npm.version diff --git a/node_modules/npm-registry-client/lib/publish.js b/node_modules/npm-registry-client/lib/publish.js index 5504658d3..745d93297 100644 --- a/node_modules/npm-registry-client/lib/publish.js +++ b/node_modules/npm-registry-client/lib/publish.js @@ -5,6 +5,11 @@ var url = require("url") , semver = require("semver") , crypto = require("crypto") , fs = require("fs") + , fixNameField = require("normalize-package-data/lib/fixer.js").fixNameField + +function escaped(name) { + return name.replace("/", "%2f") +} function publish (uri, data, tarball, cb) { var email = this.conf.get('email') @@ -17,8 +22,12 @@ function publish (uri, data, tarball, cb) { return cb(er) } - if (data.name !== encodeURIComponent(data.name)) - return cb(new Error('invalid name: must be url-safe')) + try { + fixNameField(data, true) + } + catch (er) { + return cb(er) + } var ver = semver.clean(data.version) if (!ver) @@ -75,7 +84,7 @@ function putFirst (registry, data, tarbuffer, stat, username, email, cb) { length: stat.size }; - var fixed = url.resolve(registry, data.name) + var fixed = url.resolve(registry, escaped(data.name)) this.request("PUT", fixed, { body : root }, function (er, parsed, json, res) { var r409 = "must supply latest _rev to update existing package" var r409b = "Document update conflict." @@ -143,7 +152,8 @@ function putNext(registry, newVersion, root, current, cb) { var maint = JSON.parse(JSON.stringify(root.maintainers)) root.versions[newVersion].maintainers = maint - this.request("PUT", url.resolve(registry, root.name), { body : current }, cb) + var uri = url.resolve(registry, escaped(root.name)) + this.request("PUT", uri, { body : current }, cb) } function conflictError (pkgid, version) { diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/.gitignore b/node_modules/npm-registry-client/node_modules/normalize-package-data/.gitignore new file mode 100644 index 000000000..096746c14 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/.gitignore @@ -0,0 +1 @@ +/node_modules/
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/.travis.yml b/node_modules/npm-registry-client/node_modules/normalize-package-data/.travis.yml new file mode 100644 index 000000000..6e5919de3 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/AUTHORS b/node_modules/npm-registry-client/node_modules/normalize-package-data/AUTHORS new file mode 100644 index 000000000..10860f72b --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/AUTHORS @@ -0,0 +1,4 @@ +# Names sorted by how much code was originally theirs. +Isaac Z. Schlueter <i@izs.me> +Meryn Stol <merynstol@gmail.com> +Robert Kowalski <rok@kowalski.gd>
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/LICENSE b/node_modules/npm-registry-client/node_modules/normalize-package-data/LICENSE new file mode 100644 index 000000000..9cea2e3c9 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/LICENSE @@ -0,0 +1,30 @@ +This package contains code originally written by Isaac Z. Schlueter. +Used with permission. + +Copyright (c) Meryn Stol ("Author") +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/README.md b/node_modules/npm-registry-client/node_modules/normalize-package-data/README.md new file mode 100644 index 000000000..9b9adcc2d --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/README.md @@ -0,0 +1,101 @@ +# normalize-package-data [![Build Status](https://travis-ci.org/meryn/normalize-package-data.png?branch=master)](https://travis-ci.org/meryn/normalize-package-data) + +normalize-package data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry. + +normalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools. + +## Installation + +``` +npm install normalize-package-data +``` + +## Usage + +Basic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`. + +```javascript +normalizeData = require('normalize-package-data') +packageData = fs.readfileSync("package.json") +normalizeData(packageData) +// packageData is now normalized +``` + +#### Strict mode + +You may activate strict validation by passing true as the second argument. + +```javascript +normalizeData = require('normalize-package-data') +packageData = fs.readfileSync("package.json") +warnFn = function(msg) { console.error(msg) } +normalizeData(packageData, true) +// packageData is now normalized +``` + +If strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace. + +#### Warnings + +Optionally, you may pass a "warning" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data. + +```javascript +normalizeData = require('normalize-package-data') +packageData = fs.readfileSync("package.json") +warnFn = function(msg) { console.error(msg) } +normalizeData(packageData, warnFn) +// packageData is now normalized. Any number of warnings may have been logged. +``` + +You may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third. + +When `private` field is set to `true`, warnings will be suppressed. + +### Potential exceptions + +If the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback. + +## What normalization (currently) entails + +* The value of `name` field gets trimmed (unless in strict mode). +* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver). +* If `name` and/or `version` fields are missing, they are set to empty strings. +* If `files` field is not an array, it will be removed. +* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value. +* If `man` field is a string, it will become an array with the original string as its sole member. +* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\s+`. +* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties. +* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`. +* If the value of any of the dependencies fields (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs. +* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched. +* If `description` field does not exists, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`. +* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `"git"`. +* If `repository.url` is not a valid url, but in the style of "[owner-name]/[repo-name]", `repository.url` will be set to git://github.com/[owner-name]/[repo-name] +* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value. +* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen. +* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed. +* If `homepage` field is not a string, it will be removed. +* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`. +* If `homepage` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `homepage` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/ . If the repository field points to a GitHub Gist repo url, the associated http url is chosen. + +### Rules for name field + +If `name` field is given, the value of the name field must be a string. The string may not: + +* start with a period. +* contain the following characters: `/@\s+%` +* contain and characters that would need to be encoded for use in urls. +* resemble the word `node_modules` or `favicon.ico` (case doesn't matter). + +### Rules for version field + +If `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver). + +## Credits + +This package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson. + +## License + +normalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT). +Copyright (c) 2013 Meryn Stol
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/core_module_names.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/core_module_names.json new file mode 100644 index 000000000..637c2f073 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/core_module_names.json @@ -0,0 +1,29 @@ +[ +"http", +"events", +"util", +"domain", +"cluster", +"buffer", +"stream", +"crypto", +"tls", +"fs", +"string_decoder", +"path", +"net", +"dgram", +"dns", +"https", +"url", +"punycode", +"readline", +"repl", +"vm", +"child_process", +"assert", +"zlib", +"tty", +"os", +"querystring" +] diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/extract_description.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/extract_description.js new file mode 100644 index 000000000..83f10aa0a --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/extract_description.js @@ -0,0 +1,14 @@ +module.exports = extractDescription + +// Extracts description from contents of a readme file in markdown format +function extractDescription (d) { + if (!d) return; + if (d === "ERROR: No README data found!") return; + // the first block of text before the first heading + // that isn't the first line heading + d = d.trim().split('\n') + for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); + var l = d.length + for (var e = s + 1; e < l && d[e].trim(); e ++); + return d.slice(s, e).join(' ').trim() +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/fixer.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/fixer.js new file mode 100644 index 000000000..82c1348be --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/fixer.js @@ -0,0 +1,396 @@ +var semver = require("semver") +var parseGitHubURL = require("github-url-from-git") +var depTypes = ["dependencies","devDependencies","optionalDependencies"] +var extractDescription = require("./extract_description") +var url = require("url") +var typos = require("./typos") +var coreModuleNames = require("./core_module_names") +var githubUserRepo = require("github-url-from-username-repo") + +var fixer = module.exports = { + // default warning function + warn: function() {}, + + fixRepositoryField: function(data) { + if (data.repositories) { + this.warn("repositories"); + data.repository = data.repositories[0] + } + if (!data.repository) return this.warn("missingRepository") + if (typeof data.repository === "string") { + data.repository = { + type: "git", + url: data.repository + } + } + var r = data.repository.url || "" + if (r) { + var ghurl = parseGitHubURL(r) + if (ghurl) { + r = ghurl.replace(/^https?:\/\//, 'git://') + } else if (githubUserRepo(r)) { + // repo has 'user/reponame' filled in as repo + data.repository.url = githubUserRepo(r) + } + } + + if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) { + this.warn("brokenGitUrl", r) + } + } + +, fixTypos: function(data) { + Object.keys(typos.topLevel).forEach(function (d) { + if (data.hasOwnProperty(d)) { + this.warn("typo", d, typos.topLevel[d]) + } + }, this) + } + +, fixScriptsField: function(data) { + if (!data.scripts) return + if (typeof data.scripts !== "object") { + this.warn("nonObjectScripts") + delete data.scripts + } + Object.keys(data.scripts).forEach(function (k) { + if (typeof data.scripts[k] !== "string") { + this.warn("nonStringScript") + delete data.scripts[k] + } else if (typos.script[k]) { + this.warn("typo", k, typos.script[k], "scripts") + } + }, this) + } + +, fixFilesField: function(data) { + var files = data.files + if (files && !Array.isArray(files)) { + this.warn("nonArrayFiles") + delete data.files + } else if (data.files) { + data.files = data.files.filter(function(file) { + if (!file || typeof file !== "string") { + this.warn("invalidFilename", file) + return false + } else { + return true + } + }, this) + } + } + +, fixBinField: function(data) { + if (!data.bin) return; + if (typeof data.bin === "string") { + var b = {} + b[data.name] = data.bin + data.bin = b + } + } + +, fixManField: function(data) { + if (!data.man) return; + if (typeof data.man === "string") { + data.man = [ data.man ] + } + } +, fixBundleDependenciesField: function(data) { + var bdd = "bundledDependencies" + var bd = "bundleDependencies" + if (data[bdd] && !data[bd]) { + data[bd] = data[bdd] + delete data[bdd] + } + if (data[bd] && !Array.isArray(data[bd])) { + this.warn("nonArrayBundleDependencies") + delete data[bd] + } else if (data[bd]) { + data[bd] = data[bd].filter(function(bd) { + if (!bd || typeof bd !== 'string') { + this.warn("nonStringBundleDependency", bd) + return false + } else { + return true + } + }, this) + } + } + +, fixDependencies: function(data, strict) { + var loose = !strict + objectifyDeps(data, this.warn) + addOptionalDepsToDeps(data, this.warn) + this.fixBundleDependenciesField(data) + + ;['dependencies','devDependencies'].forEach(function(deps) { + if (!(deps in data)) return + if (!data[deps] || typeof data[deps] !== "object") { + this.warn("nonObjectDependencies", deps) + delete data[deps] + return + } + Object.keys(data[deps]).forEach(function (d) { + var r = data[deps][d] + if (typeof r !== 'string') { + this.warn("nonStringDependency", d, JSON.stringify(r)) + delete data[deps][d] + } + // "/" is not allowed as packagename for publishing, but for git-urls + // normalize shorthand-urls + if (githubUserRepo(data[deps][d])) { + data[deps][d] = 'git+' + githubUserRepo(data[deps][d]) + } + }, this) + }, this) + } + +, fixModulesField: function (data) { + if (data.modules) { + this.warn("deprecatedModules") + delete data.modules + } + } + +, fixKeywordsField: function (data) { + if (typeof data.keywords === "string") { + data.keywords = data.keywords.split(/,\s+/) + } + if (data.keywords && !Array.isArray(data.keywords)) { + delete data.keywords + this.warn("nonArrayKeywords") + } else if (data.keywords) { + data.keywords = data.keywords.filter(function(kw) { + if (typeof kw !== "string" || !kw) { + this.warn("nonStringKeyword"); + return false + } else { + return true + } + }, this) + } + } + +, fixVersionField: function(data, strict) { + // allow "loose" semver 1.0 versions in non-strict mode + // enforce strict semver 2.0 compliance in strict mode + var loose = !strict + if (!data.version) { + data.version = "" + return true + } + if (!semver.valid(data.version, loose)) { + throw new Error('Invalid version: "'+ data.version + '"') + } + data.version = semver.clean(data.version, loose) + return true + } + +, fixPeople: function(data) { + modifyPeople(data, unParsePerson) + modifyPeople(data, parsePerson) + } + +, fixNameField: function(data, strict) { + if (!data.name && !strict) { + data.name = "" + return + } + if (typeof data.name !== "string") { + throw new Error("name field must be a string.") + } + if (!strict) + data.name = data.name.trim() + ensureValidName(data.name, strict) + if (coreModuleNames.indexOf(data.name) !== -1) + this.warn("conflictingName", data.name) + } + + +, fixDescriptionField: function (data) { + if (data.description && typeof data.description !== 'string') { + this.warn("nonStringDescription") + delete data.description + } + if (data.readme && !data.description) + data.description = extractDescription(data.readme) + if(data.description === undefined) delete data.description; + if (!data.description) this.warn("missingDescription") + } + +, fixReadmeField: function (data) { + if (!data.readme) { + this.warn("missingReadme") + data.readme = "ERROR: No README data found!" + } + } + +, fixBugsField: function(data) { + if (!data.bugs && data.repository && data.repository.url) { + var gh = parseGitHubURL(data.repository.url) + if(gh) { + if(gh.match(/^https:\/\/github.com\//)) + data.bugs = {url: gh + "/issues"} + else // gist url + data.bugs = {url: gh} + } + } + else if(data.bugs) { + var emailRe = /^.+@.*\..+$/ + if(typeof data.bugs == "string") { + if(emailRe.test(data.bugs)) + data.bugs = {email:data.bugs} + else if(url.parse(data.bugs).protocol) + data.bugs = {url: data.bugs} + else + this.warn("nonEmailUrlBugsString") + } + else { + bugsTypos(data.bugs, this.warn) + var oldBugs = data.bugs + data.bugs = {} + if(oldBugs.url) { + if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol) + data.bugs.url = oldBugs.url + else + this.warn("nonUrlBugsUrlField") + } + if(oldBugs.email) { + if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email)) + data.bugs.email = oldBugs.email + else + this.warn("nonEmailBugsEmailField") + } + } + if(!data.bugs.email && !data.bugs.url) { + delete data.bugs + this.warn("emptyNormalizedBugs") + } + } + } + +, fixHomepageField: function(data) { + if (!data.homepage && data.repository && data.repository.url) { + var gh = parseGitHubURL(data.repository.url) + if (gh) + data.homepage = gh + else + return true + } else if (!data.homepage) + return true + + if(typeof data.homepage !== "string") { + this.warn("nonUrlHomepage") + return delete data.homepage + } + if(!url.parse(data.homepage).protocol) { + this.warn("missingProtocolHomepage") + data.homepage = "http://" + data.homepage + } + } +} + +function ensureValidName (name, strict) { + function scoped(spec) { + if (spec.charAt(0) !== '@') return false + + var rest = spec.slice(1).split('/') + if (rest.length !== 2) return false + + return rest[0] === encodeURIComponent(rest[0]) && + rest[1] === encodeURIComponent(rest[1]) + } + + function scopedOrEncoded(spec) { + return !scoped(spec) && + (spec.match(/[\/@\s\+%:]/) || spec !== encodeURIComponent(spec)) + } + + if (name.charAt(0) === "." || + scopedOrEncoded(name) || + (strict && name !== name.toLowerCase()) || + name.toLowerCase() === "node_modules" || + name.toLowerCase() === "favicon.ico") { + throw new Error("Invalid name: " + JSON.stringify(name)) + } +} + +function modifyPeople (data, fn) { + if (data.author) data.author = fn(data.author) + ;["maintainers", "contributors"].forEach(function (set) { + if (!Array.isArray(data[set])) return; + data[set] = data[set].map(fn) + }) + return data +} + +function unParsePerson (person) { + if (typeof person === "string") return person + var name = person.name || "" + var u = person.url || person.web + var url = u ? (" ("+u+")") : "" + var e = person.email || person.mail + var email = e ? (" <"+e+">") : "" + return name+email+url +} + +function parsePerson (person) { + if (typeof person !== "string") return person + var name = person.match(/^([^\(<]+)/) + var url = person.match(/\(([^\)]+)\)/) + var email = person.match(/<([^>]+)>/) + var obj = {} + if (name && name[0].trim()) obj.name = name[0].trim() + if (email) obj.email = email[1]; + if (url) obj.url = url[1]; + return obj +} + +function addOptionalDepsToDeps (data, warn) { + var o = data.optionalDependencies + if (!o) return; + var d = data.dependencies || {} + Object.keys(o).forEach(function (k) { + d[k] = o[k] + }) + data.dependencies = d +} + +function depObjectify (deps, type, warn) { + if (!deps) return {} + if (typeof deps === "string") { + deps = deps.trim().split(/[\n\r\s\t ,]+/) + } + if (!Array.isArray(deps)) return deps + warn("deprecatedArrayDependencies", type) + var o = {} + deps.filter(function (d) { + return typeof d === "string" + }).forEach(function(d) { + d = d.trim().split(/(:?[@\s><=])/) + var dn = d.shift() + var dv = d.join("") + dv = dv.trim() + dv = dv.replace(/^@/, "") + o[dn] = dv + }) + return o +} + +function objectifyDeps (data, warn) { + depTypes.forEach(function (type) { + if (!data[type]) return; + data[type] = depObjectify(data[type], type, warn) + }) +} + +function bugsTypos(bugs, warn) { + if (!bugs) return + Object.keys(bugs).forEach(function (k) { + if (typos.bugs[k]) { + warn("typo", k, typos.bugs[k], "bugs") + bugs[typos.bugs[k]] = bugs[k] + delete bugs[k] + } + }) +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/make_warning.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/make_warning.js new file mode 100644 index 000000000..0f3aad5f5 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/make_warning.js @@ -0,0 +1,23 @@ +var util = require("util") +var messages = require("./warning_messages.json") + +module.exports = function() { + var args = Array.prototype.slice.call(arguments, 0) + var warningName = args.shift() + if (warningName == "typo") { + return makeTypoWarning.apply(null,args) + } + else { + var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" + args.unshift(msgTemplate) + return util.format.apply(null, args) + } +} + +function makeTypoWarning (providedName, probableName, field) { + if (field) { + providedName = field + "['" + providedName + "']" + probableName = field + "['" + probableName + "']" + } + return util.format(messages.typo, providedName, probableName) +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/normalize.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/normalize.js new file mode 100644 index 000000000..7e6beefda --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/normalize.js @@ -0,0 +1,37 @@ +module.exports = normalize + +var fixer = require("./fixer") +var makeWarning = require("./make_warning") + +var fieldsToFix = ['name','version','description','repository','modules','scripts' + ,'files','bin','man','bugs','keywords','readme','homepage'] +var otherThingsToFix = ['dependencies','people', 'typos'] + +var thingsToFix = fieldsToFix.map(function(fieldName) { + return ucFirst(fieldName) + "Field" +}) +// two ways to do this in CoffeeScript on only one line, sub-70 chars: +// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" +// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) +thingsToFix = thingsToFix.concat(otherThingsToFix) + +function normalize (data, warn, strict) { + if(warn === true) warn = null, strict = true + if(!strict) strict = false + if(!warn || data.private) warn = function(msg) { /* noop */ } + + if (data.scripts && + data.scripts.install === "node-gyp rebuild" && + !data.scripts.preinstall) { + data.gypfile = true + } + fixer.warn = function() { warn(makeWarning.apply(null, arguments)) } + thingsToFix.forEach(function(thingName) { + fixer["fix" + ucFirst(thingName)](data, strict) + }) + data._id = data.name + "@" + data.version +} + +function ucFirst (string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/safe_format.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/safe_format.js new file mode 100644 index 000000000..08517f142 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/safe_format.js @@ -0,0 +1,9 @@ +var util = require('util') + +module.exports = function() { + var args = Array.prototype.slice.call(arguments, 0) + args.forEach(function(arg) { + if (!arg) throw new TypeError('Bad arguments.') + }) + return util.format.apply(null, arguments) +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/typos.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/typos.json new file mode 100644 index 000000000..73590c0a2 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/typos.json @@ -0,0 +1,25 @@ +{ + "topLevel": { + "dependancies": "dependencies" + ,"dependecies": "dependencies" + ,"depdenencies": "dependencies" + ,"devEependencies": "devDependencies" + ,"depends": "dependencies" + ,"dev-dependencies": "devDependencies" + ,"devDependences": "devDependencies" + ,"devDepenencies": "devDependencies" + ,"devdependencies": "devDependencies" + ,"repostitory": "repository" + ,"repo": "repository" + ,"prefereGlobal": "preferGlobal" + ,"hompage": "homepage" + ,"hampage": "homepage" + ,"autohr": "author" + ,"autor": "author" + ,"contributers": "contributors" + ,"publicationConfig": "publishConfig" + ,"script": "scripts" + }, + "bugs": { "web": "url", "name": "url" }, + "script": { "server": "start", "tests": "test" } +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/warning_messages.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/warning_messages.json new file mode 100644 index 000000000..9605f5cc6 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/lib/warning_messages.json @@ -0,0 +1,28 @@ +{ + "repositories": "'repositories' (plural) Not supported. Please pick one as the 'repository' field" + ,"missingRepository": "No repository field." + ,"brokenGitUrl": "Probably broken git url: %s" + ,"nonObjectScripts": "scripts must be an object" + ,"nonStringScript": "script values must be string commands" + ,"nonArrayFiles": "Invalid 'files' member" + ,"invalidFilename": "Invalid filename in 'files' list: %s" + ,"nonArrayBundleDependencies": "Invalid 'bundleDependencies' list. Must be array of package names" + ,"nonStringBundleDependency": "Invalid bundleDependencies member: %s" + ,"nonObjectDependencies": "%s field must be an object" + ,"nonStringDependency": "Invalid dependency: %s %s" + ,"deprecatedArrayDependencies": "specifying %s as array is deprecated" + ,"deprecatedModules": "modules field is deprecated" + ,"nonArrayKeywords": "keywords should be an array of strings" + ,"nonStringKeyword": "keywords should be an array of strings" + ,"conflictingName": "%s is also the name of a node core module." + ,"nonStringDescription": "'description' field should be a string" + ,"missingDescription": "No description" + ,"missingReadme": "No README data" + ,"nonEmailUrlBugsString": "Bug string field must be url, email, or {email,url}" + ,"nonUrlBugsUrlField": "bugs.url field must be a string url. Deleted." + ,"nonEmailBugsEmailField": "bugs.email field must be a string email. Deleted." + ,"emptyNormalizedBugs": "Normalized value of bugs field is an empty object. Deleted." + ,"nonUrlHomepage": "homepage field must be a string url. Deleted." + ,"missingProtocolHomepage": "homepage field must start with a protocol." + ,"typo": "%s should probably be %s." +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/package.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/package.json new file mode 100644 index 000000000..3c1737d50 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/package.json @@ -0,0 +1,51 @@ +{ + "name": "normalize-package-data", + "version": "0.3.0", + "author": { + "name": "Meryn Stol", + "email": "merynstol@gmail.com" + }, + "description": "Normalizes data that can be found in package.json files.", + "repository": { + "type": "git", + "url": "git://github.com/meryn/normalize-package-data.git" + }, + "main": "lib/normalize.js", + "scripts": { + "test": "tap test/*.js" + }, + "dependencies": { + "github-url-from-git": "~1.1.1", + "github-url-from-username-repo": "^0.2.0", + "semver": "2" + }, + "devDependencies": { + "tap": "~0.2.5", + "underscore": "~1.4.4", + "async": "~0.2.7" + }, + "contributors": [ + { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + { + "name": "Meryn Stol", + "email": "merynstol@gmail.com" + }, + { + "name": "Robert Kowalski", + "email": "rok@kowalski.gd" + } + ], + "readme": "# normalize-package-data [![Build Status](https://travis-ci.org/meryn/normalize-package-data.png?branch=master)](https://travis-ci.org/meryn/normalize-package-data)\n\nnormalize-package data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry.\n\nnormalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools.\n\n## Installation\n\n```\nnpm install normalize-package-data\n```\n\n## Usage\n\nBasic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nnormalizeData(packageData)\n// packageData is now normalized\n```\n\n#### Strict mode\n\nYou may activate strict validation by passing true as the second argument.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, true)\n// packageData is now normalized\n```\n\nIf strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace.\n\n#### Warnings\n\nOptionally, you may pass a \"warning\" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, warnFn)\n// packageData is now normalized. Any number of warnings may have been logged.\n```\n\nYou may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third.\n\nWhen `private` field is set to `true`, warnings will be suppressed.\n\n### Potential exceptions\n\nIf the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback.\n\n## What normalization (currently) entails\n\n* The value of `name` field gets trimmed (unless in strict mode).\n* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n* If `name` and/or `version` fields are missing, they are set to empty strings.\n* If `files` field is not an array, it will be removed.\n* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value.\n* If `man` field is a string, it will become an array with the original string as its sole member.\n* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\\s+`.\n* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties.\n* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`.\n* If the value of any of the dependencies fields (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs.\n* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched.\n* If `description` field does not exists, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`.\n* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `\"git\"`.\n* If `repository.url` is not a valid url, but in the style of \"[owner-name]/[repo-name]\", `repository.url` will be set to git://github.com/[owner-name]/[repo-name]\n* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value.\n* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed.\n* If `homepage` field is not a string, it will be removed.\n* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`.\n* If `homepage` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `homepage` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/ . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n\n### Rules for name field\n\nIf `name` field is given, the value of the name field must be a string. The string may not:\n\n* start with a period.\n* contain the following characters: `/@\\s+%`\n* contain and characters that would need to be encoded for use in urls.\n* resemble the word `node_modules` or `favicon.ico` (case doesn't matter).\n\n### Rules for version field\n\nIf `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n\n## Credits\n\nThis package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson.\n\n## License\n\nnormalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT). \nCopyright (c) 2013 Meryn Stol ", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/meryn/normalize-package-data/issues" + }, + "homepage": "https://github.com/meryn/normalize-package-data", + "_id": "normalize-package-data@0.3.0", + "_shasum": "d763a0bdb2bc4f4cf9d355aab9991bd7585e0c57", + "_resolved": "git://github.com/npm/normalize-package-data#15869dc14c1ac8e3b202586f62f755c69443e403", + "_from": "normalize-package-data@git://github.com/npm/normalize-package-data#othiym23/scoped" +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/basic.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/basic.js new file mode 100644 index 000000000..12c403ec7 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/basic.js @@ -0,0 +1,34 @@ +var tap = require("tap") +var normalize = require("../lib/normalize") +var path = require("path") +var fs = require("fs") + +tap.test("basic test", function (t) { + var p = path.resolve(__dirname, "./fixtures/read-package-json.json") + fs.readFile (p, function (err, contents) { + if (err) throw err; + var originalData = JSON.parse(contents.toString()) + var data = JSON.parse(contents.toString()) + normalize(data) + t.ok(data) + verifyFields(t, data, originalData) + t.end() + }) +}) + +function verifyFields (t, normalized, original) { + t.equal(normalized.version, original.version, "Version field stays same") + t.equal(normalized._id, normalized.name + "@" + normalized.version, "It gets good id.") + t.equal(normalized.name, original.name, "Name stays the same.") + t.type(normalized.author, "object", "author field becomes object") + t.deepEqual(normalized.scripts, original.scripts, "scripts field (object) stays same") + t.equal(normalized.main, original.main) + // optional deps are folded in. + t.deepEqual(normalized.optionalDependencies, + original.optionalDependencies) + t.has(normalized.dependencies, original.optionalDependencies, "opt depedencies are copied into dependencies") + t.has(normalized.dependencies, original.dependencies, "regular depedencies stay in place") + t.deepEqual(normalized.devDependencies, original.devDependencies) + t.type(normalized.bugs, "object", "bugs should become object") + t.equal(normalized.bugs.url, "https://github.com/isaacs/read-package-json/issues") +} diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/consistency.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/consistency.js new file mode 100644 index 000000000..4082be25c --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/consistency.js @@ -0,0 +1,36 @@ +var tap = require("tap") +var normalize = require("../lib/normalize") +var path = require("path") +var fs = require("fs") +var _ = require("underscore") +var async = require("async") + +var data, clonedData +var warn + +tap.test("consistent normalization", function(t) { + path.resolve(__dirname, "./fixtures/read-package-json.json") + fs.readdir (__dirname + "/fixtures", function (err, entries) { + // entries = ['coffee-script.json'] // uncomment to limit to a specific file + verifyConsistency = function(entryName, next) { + warn = function(msg) { + // t.equal("",msg) // uncomment to have some kind of logging of warnings + } + filename = __dirname + "/fixtures/" + entryName + fs.readFile(filename, function(err, contents) { + if (err) return next(err) + data = JSON.parse(contents.toString()) + normalize(data, warn) + clonedData = _.clone(data) + normalize(data, warn) + t.deepEqual(clonedData, data, + "Normalization of " + entryName + " is consistent.") + next(null) + }) // fs.readFile + } // verifyConsistency + async.forEach(entries, verifyConsistency, function(err) { + if (err) throw err + t.end() + }) + }) // fs.readdir +}) // tap.test
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/dependencies.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/dependencies.js new file mode 100644 index 000000000..dda24dc4f --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/dependencies.js @@ -0,0 +1,43 @@ +var tap = require("tap") +var normalize = require("../lib/normalize") + +var warningMessages = require("../lib/warning_messages.json") +var safeFormat = require("../lib/safe_format") + +tap.test("warn if dependency contains anything else but a string", function(t) { + var a + var warnings = [] + function warn(w) { + warnings.push(w) + } + normalize(a={ + dependencies: { "a": 123}, + devDependencies: { "b": 456}, + optionalDependencies: { "c": 789} + }, warn) + + var wanted1 = safeFormat(warningMessages.nonStringDependency, "a", 123) + var wanted2 = safeFormat(warningMessages.nonStringDependency, "b", 456) + var wanted3 = safeFormat(warningMessages.nonStringDependency, "c", 789) + t.ok(~warnings.indexOf(wanted1), wanted1) + t.ok(~warnings.indexOf(wanted2), wanted2) + t.ok(~warnings.indexOf(wanted3), wanted3) + t.end() +}) + +tap.test("warn if bundleDependencies array contains anything else but strings", function(t) { + var a + var warnings = [] + function warn(w) { + warnings.push(w) + } + normalize(a={ + bundleDependencies: ["abc", 123, {foo:"bar"}] + }, warn) + + var wanted1 = safeFormat(warningMessages.nonStringBundleDependency, 123) + var wanted2 = safeFormat(warningMessages.nonStringBundleDependency, {foo:"bar"}) + t.ok(~warnings.indexOf(wanted1), wanted1) + t.ok(~warnings.indexOf(wanted2), wanted2) + t.end() +})
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/async.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/async.json new file mode 100644 index 000000000..5e652a6c6 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/async.json @@ -0,0 +1,36 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "main": "./lib/async", + "author": "Caolan McMahon", + "version": "0.2.6", + "repository" : { + "type" : "git", + "url" : "http://github.com/caolan/async.git" + }, + "bugs" : { + "url" : "http://github.com/caolan/async/issues" + }, + "licenses" : [ + { + "type" : "MIT", + "url" : "http://github.com/caolan/async/raw/master/LICENSE" + } + ], + "devDependencies": { + "nodeunit": ">0.0.0", + "uglify-js": "1.2.x", + "nodelint": ">0.0.0" + }, + "jam": { + "main": "lib/async.js", + "include": [ + "lib/async.js", + "README.md", + "LICENSE" + ] + }, + "scripts": { + "test": "nodeunit test/test-async.js" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/bcrypt.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/bcrypt.json new file mode 100644 index 000000000..56e6d81b3 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/bcrypt.json @@ -0,0 +1,56 @@ +{ + "name": "bcrypt", + "description": "A bcrypt library for NodeJS.", + "keywords": [ + "bcrypt", + "password", + "auth", + "authentication", + "encryption", + "crypt", + "crypto" + ], + "main": "./bcrypt", + "version": "0.7.5", + "author": "Nick Campbell (http://github.com/ncb000gt)", + "engines": { + "node": ">= 0.6.0" + }, + "repository": { + "type": "git", + "url": "http://github.com/ncb000gt/node.bcrypt.js.git" + }, + "licenses": [ + { + "type": "MIT" + } + ], + "bugs": { + "url": "http://github.com/ncb000gt/node.bcrypt.js/issues" + }, + "scripts": { + "test": "node-gyp configure build && nodeunit test" + }, + "dependencies": { + "bindings": "1.0.0" + }, + "devDependencies": { + "nodeunit": ">=0.6.4" + }, + "contributors": [ + "Antonio Salazar Cardozo <savedfastcool@gmail.com> (https://github.com/Shadowfiend)", + "Van Nguyen <the.gol.effect@gmail.com> (https://github.com/thegoleffect)", + "David Trejo <david@dtrejo.com> (https://github.com/dtrejo)", + "Ben Glow <glen.low@pixelglow.com> (https://github.com/pixelglow)", + "NewITFarmer.com <> (https://github.com/newitfarmer)", + "Alfred Westerveld <alfredwesterveld@gmail.com> (https://github.com/alfredwesterveld)", + "Vincent Côté-Roy <vincentcr@gmail.com> (https://github.com/vincentcr)", + "Lloyd Hilaiel <lloyd@hilaiel.com> (https://github.com/lloyd)", + "Roman Shtylman <shtylman@gmail.com> (https://github.com/shtylman)", + "Vadim Graboys <dimva13@gmail.com> (https://github.com/vadimg)", + "Ben Noorduis <> (https://github.com/bnoordhuis)", + "Nate Rajlich <nathan@tootallnate.net> (https://github.com/tootallnate)", + "Sean McArthur <sean.monstar@gmail.com> (https://github.com/seanmonstar)", + "Fanie Oosthuysen <fanie.oosthuysen@gmail.com> (https://github.com/weareu)" + ] +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/coffee-script.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/coffee-script.json new file mode 100644 index 000000000..a0b60a9d3 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/coffee-script.json @@ -0,0 +1,35 @@ +{ + "name": "coffee-script", + "description": "Unfancy JavaScript", + "keywords": ["javascript", "language", "coffeescript", "compiler"], + "author": "Jeremy Ashkenas", + "version": "1.6.2", + "licenses": [{ + "type": "MIT", + "url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE" + }], + "engines": { + "node": ">=0.8.0" + }, + "directories" : { + "lib" : "./lib/coffee-script" + }, + "main" : "./lib/coffee-script/coffee-script", + "bin": { + "coffee": "./bin/coffee", + "cake": "./bin/cake" + }, + "scripts": { + "test": "node ./bin/cake test" + }, + "homepage": "http://coffeescript.org", + "bugs": "https://github.com/jashkenas/coffee-script/issues", + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/coffee-script.git" + }, + "devDependencies": { + "uglify-js": "~2.2", + "jison": ">=0.2.0" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/http-server.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/http-server.json new file mode 100644 index 000000000..90c28863a --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/http-server.json @@ -0,0 +1,53 @@ +{ + "name": "http-server", + "preferGlobal": true, + "version": "0.3.0", + "author": "Nodejitsu <support@nodejitsu.com>", + "description": "a simple zero-configuration command-line http server", + "contributors": [ + { + "name": "Marak Squires", + "email": "marak@nodejitsu.com" + } + ], + "bin": { + "http-server": "./bin/http-server" + }, + "scripts": { + "start": "node ./bin/http-server", + "test": "vows --spec --isolate", + "predeploy": "echo This will be run before deploying the app", + "postdeploy": "echo This will be run after deploying the app" + }, + "main": "./lib/http-server", + "repository": { + "type": "git", + "url": "https://github.com/nodejitsu/http-server.git" + }, + "keywords": [ + "cli", + "http", + "server" + ], + "dependencies" : { + "colors" : "*", + "flatiron" : "0.1.x", + "optimist" : "0.2.x", + "union" : "0.1.x", + "ecstatic" : "0.1.x", + "plates" : "https://github.com/flatiron/plates/tarball/master" + }, + "analyze": false, + "devDependencies": { + "vows" : "0.5.x", + "request" : "2.1.x" + }, + "bundledDependencies": [ + "union", + "ecstatic" + ], + "license": "MIT", + "engines": { + "node": ">=0.6" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/movefile.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/movefile.json new file mode 100644 index 000000000..593387570 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/movefile.json @@ -0,0 +1,21 @@ +{ + "name": "movefile", + "description": "rename implementation working over devices", + "version": "0.2.0", + "author": "yazgazan <yazgazan@gmail.com>", + "main": "./build/Release/movefile", + "keywords": ["move", "file", "rename"], + "repository": "git://github.com/yazgazan/movefile.git", + "directories": { + "lib": "./build/Release/" + }, + "scripts": { + "install": "./node_modules/node-gyp/bin/node-gyp.js configure && ./node_modules/node-gyp/bin/node-gyp.js build" + }, + "engines": { + "node": "*" + }, + "dependencies": { + "node-gyp": "~0.9.1" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/no-description.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/no-description.json new file mode 100644 index 000000000..9ea70b6bf --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/no-description.json @@ -0,0 +1,4 @@ +{ + "name": "foo-bar-package", + "version": "0.0.1" +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/node-module_exist.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/node-module_exist.json new file mode 100644 index 000000000..acc053825 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/node-module_exist.json @@ -0,0 +1,26 @@ +{ + "name": "node-module_exist", + "description": "Find if a NodeJS module is available to require or not", + "version": "0.0.1", + "main": "module_exist.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@gist.github.com:3135914.git" + }, + "homepage": "https://github.com/FGRibreau", + "author": { + "name": "Francois-Guillaume Ribreau", + "url": "http://fgribreau.com.com/" + }, + "devDependencies": { + "nodeunit": "~0.7.4" + }, + "keywords": [ + "core", + "modules" + ], + "license": "MIT" +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/npm.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/npm.json new file mode 100644 index 000000000..2262b3139 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/npm.json @@ -0,0 +1,135 @@ +{ + "version": "1.2.17", + "name": "npm", + "publishConfig": { + "proprietary-attribs": false + }, + "description": "A package manager for node", + "keywords": [ + "package manager", + "modules", + "install", + "package.json" + ], + "preferGlobal": true, + "config": { + "publishtest": false + }, + "homepage": "https://npmjs.org/doc/", + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", + "repository": { + "type": "git", + "url": "https://github.com/isaacs/npm" + }, + "bugs": { + "email": "npm-@googlegroups.com", + "url": "http://github.com/isaacs/npm/issues" + }, + "directories": { + "doc": "./doc", + "man": "./man", + "lib": "./lib", + "bin": "./bin" + }, + "main": "./lib/npm.js", + "bin": "./bin/npm-cli.js", + "dependencies": { + "semver": "~1.1.2", + "ini": "~1.1.0", + "slide": "1", + "abbrev": "~1.0.4", + "graceful-fs": "~1.2.0", + "minimatch": "~0.2.11", + "nopt": "~2.1.1", + "rimraf": "2", + "request": "~2.9", + "which": "1", + "tar": "~0.1.17", + "fstream": "~0.1.22", + "block-stream": "*", + "inherits": "1", + "mkdirp": "~0.3.3", + "read": "~1.0.4", + "lru-cache": "~2.3.0", + "node-gyp": "~0.9.3", + "fstream-npm": "~0.1.3", + "uid-number": "0", + "archy": "0", + "chownr": "0", + "npmlog": "0", + "ansi": "~0.1.2", + "npm-registry-client": "~0.2.18", + "read-package-json": "~0.3.0", + "read-installed": "0", + "glob": "~3.1.21", + "init-package-json": "0.0.6", + "osenv": "0", + "lockfile": "~0.3.0", + "retry": "~0.6.0", + "once": "~1.1.1", + "npmconf": "0", + "opener": "~1.3.0", + "chmodr": "~0.1.0", + "cmd-shim": "~1.1.0" + }, + "bundleDependencies": [ + "semver", + "ini", + "slide", + "abbrev", + "graceful-fs", + "minimatch", + "nopt", + "rimraf", + "request", + "which", + "tar", + "fstream", + "block-stream", + "inherits", + "mkdirp", + "read", + "lru-cache", + "node-gyp", + "fstream-npm", + "uid-number", + "archy", + "chownr", + "npmlog", + "ansi", + "npm-registry-client", + "read-package-json", + "read-installed", + "glob", + "init-package-json", + "osenv", + "lockfile", + "retry", + "once", + "npmconf", + "opener", + "chmodr", + "cmd-shim" + ], + "devDependencies": { + "ronn": "~0.3.6", + "tap": "~0.4.0" + }, + "engines": { + "node": ">=0.6", + "npm": "1" + }, + "scripts": { + "test": "node ./test/run.js && tap test/tap/*.js", + "tap": "tap test/tap/*.js", + "prepublish": "node bin/npm-cli.js prune ; rm -rf test/*/*/node_modules ; make -j4 doc", + "dumpconf": "env | grep npm | sort | uniq", + "echo": "node bin/npm-cli.js" + }, + "licenses": [ + { + "type": "MIT +no-false-attribs", + "url": "https://github.com/isaacs/npm/raw/master/LICENSE" + } + ] +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/read-package-json.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/read-package-json.json new file mode 100644 index 000000000..f4a2b96f4 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/read-package-json.json @@ -0,0 +1,27 @@ +{ + "name": "read-package-json", + "version": "0.1.1", + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "description": "The thing npm uses to read package.json files with semantics and defaults and validation", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/read-package-json.git" + }, + "main": "read-json.js", + "scripts": { + "test": "tap test/*.js" + }, + "dependencies": { + "glob": "~3.1.9", + "lru-cache": "~1.1.0", + "semver": "~1.0.14", + "slide": "~1.1.3" + }, + "devDependencies": { + "tap": "~0.2.5" + }, + "optionalDependencies": { + "npmlog": "0", + "graceful-fs": "~1.1.8" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/request.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/request.json new file mode 100644 index 000000000..24189a551 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/request.json @@ -0,0 +1,39 @@ +{ + "name": "request", + "description": "Simplified HTTP request client.", + "tags": [ + "http", + "simple", + "util", + "utility" + ], + "version": "2.16.7", + "author": "Mikeal Rogers <mikeal.rogers@gmail.com>", + "repository": { + "type": "git", + "url": "http://github.com/mikeal/request.git" + }, + "bugs": { + "url": "http://github.com/mikeal/request/issues" + }, + "engines": [ + "node >= 0.8.0" + ], + "main": "index.js", + "dependencies": { + "form-data": "~0.0.3", + "mime": "~1.2.7", + "hawk": "~0.10.2", + "node-uuid": "~1.4.0", + "cookie-jar": "~0.2.0", + "aws-sign": "~0.2.0", + "oauth-sign": "~0.2.0", + "forever-agent": "~0.2.0", + "tunnel-agent": "~0.2.0", + "json-stringify-safe": "~3.0.0", + "qs": "~0.5.4" + }, + "scripts": { + "test": "node tests/run.js" + } +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/underscore.json b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/underscore.json new file mode 100644 index 000000000..bfc8b3d26 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/fixtures/underscore.json @@ -0,0 +1,17 @@ +{ + "name" : "underscore", + "description" : "JavaScript's functional programming helper library.", + "homepage" : "http://underscorejs.org", + "keywords" : ["util", "functional", "server", "client", "browser"], + "author" : "Jeremy Ashkenas <jeremy@documentcloud.org>", + "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, + "main" : "underscore.js", + "version" : "1.4.4", + "devDependencies": { + "phantomjs": "1.9.0-1" + }, + "scripts": { + "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true" + }, + "license" : "MIT" +}
\ No newline at end of file diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/github-urls.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/github-urls.js new file mode 100644 index 000000000..da78160a0 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/github-urls.js @@ -0,0 +1,44 @@ +var tap = require("tap") +var normalize = require("../lib/normalize") +var fs = require("fs") +var async = require("async") + +var data +var warn + +tap.test("consistent normalization", function(t) { + var entries = [ + 'read-package-json.json', + 'http-server.json', + "movefile.json", + "node-module_exist.json" + ] + var verifyConsistency = function(entryName, next) { + warn = function(msg) { + // t.equal("",msg) // uncomment to have some kind of logging of warnings + } + var filename = __dirname + "/fixtures/" + entryName + fs.readFile(filename, function(err, contents) { + if (err) return next(err) + data = JSON.parse(contents.toString()) + normalize(data, warn) + if(data.name == "node-module_exist") { + t.same(data.bugs.url, "https://gist.github.com/3135914") + } + if(data.name == "read-package-json") { + t.same(data.bugs.url, "https://github.com/isaacs/read-package-json/issues") + } + if(data.name == "http-server") { + t.same(data.bugs.url, "https://github.com/nodejitsu/http-server/issues") + } + if(data.name == "movefile") { + t.same(data.bugs.url, "https://github.com/yazgazan/movefile/issues") + } + next(null) + }) // fs.readFile + } // verifyConsistency + async.forEach(entries, verifyConsistency, function(err) { + if (err) throw err + t.end() + }) +}) // tap.test diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/normalize.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/normalize.js new file mode 100644 index 000000000..b35eed765 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/normalize.js @@ -0,0 +1,226 @@ +var tap = require("tap") +var fs = require("fs") +var path = require("path") + +var globals = Object.keys(global) + +var normalize = require("../lib/normalize") +var warningMessages = require("../lib/warning_messages.json") +var safeFormat = require("../lib/safe_format") + +var rpjPath = path.resolve(__dirname,"./fixtures/read-package-json.json") +tap.test("normalize some package data", function(t) { + var packageData = require(rpjPath) + var warnings = [] + normalize(packageData, function(warning) { + warnings.push(warning) + }) + // there's no readme data in this particular object + t.equal( warnings.length, 1, "There's exactly one warning.") + fs.readFile(rpjPath, function(err, data) { + if(err) throw err + // Various changes have been made + t.notEqual(packageData, JSON.parse(data), "Output is different from input.") + t.end() + }) +}) + +tap.test("runs without passing warning function", function(t) { + var packageData = require(rpjPath) + fs.readFile(rpjPath, function(err, data) { + if(err) throw err + normalize(JSON.parse(data)) + t.ok(true, "If you read this, this means I'm still alive.") + t.end() + }) +}) + +tap.test("empty object", function(t) { + var packageData = {} + var expect = + { name: '', + version: '', + readme: 'ERROR: No README data found!', + _id: '@' } + + var warnings = [] + function warn(m) { + warnings.push(m) + } + normalize(packageData, warn) + t.same(packageData, expect) + t.same(warnings, [ + warningMessages.missingDescription, + warningMessages.missingRepository, + warningMessages.missingReadme + ]) + t.end() +}) + +tap.test("core module name", function(t) { + var warnings = [] + function warn(m) { + warnings.push(m) + } + var a + normalize(a={ + name: "http", + readme: "read yourself how about", + homepage: 123, + bugs: "what is this i don't even", + repository: "Hello." + }, warn) + + var expect = [ + safeFormat(warningMessages.conflictingName, 'http'), + warningMessages.nonEmailUrlBugsString, + warningMessages.emptyNormalizedBugs, + warningMessages.nonUrlHomepage + ] + t.same(warnings, expect) + t.end() +}) + +tap.test("urls required", function(t) { + var warnings = [] + function warn(w) { + warnings.push(w) + } + normalize({ + bugs: { + url: "/1", + email: "not an email address" + } + }, warn) + var a + normalize(a={ + readme: "read yourself how about", + homepage: 123, + bugs: "what is this i don't even", + repository: "Hello." + }, warn) + + console.error(a) + + var expect = + [ warningMessages.missingDescription, + warningMessages.missingRepository, + warningMessages.nonUrlBugsUrlField, + warningMessages.nonEmailBugsEmailField, + warningMessages.emptyNormalizedBugs, + warningMessages.missingReadme, + warningMessages.nonEmailUrlBugsString, + warningMessages.emptyNormalizedBugs, + warningMessages.nonUrlHomepage ] + t.same(warnings, expect) + t.end() +}) + +tap.test("homepage field must start with a protocol.", function(t) { + var warnings = [] + function warn(w) { + warnings.push(w) + } + var a + normalize(a={ + homepage: 'example.org' + }, warn) + + console.error(a) + + var expect = + [ warningMessages.missingDescription, + warningMessages.missingRepository, + warningMessages.missingReadme, + warningMessages.missingProtocolHomepage ] + t.same(warnings, expect) + t.same(a.homepage, 'http://example.org') + t.end() +}) + +tap.test("gist bugs url", function(t) { + var d = { + repository: "git@gist.github.com:123456.git" + } + normalize(d) + t.same(d.repository, { type: 'git', url: 'git@gist.github.com:123456.git' }) + t.same(d.bugs, { url: 'https://gist.github.com/123456' }) + t.end(); +}); + +tap.test("singularize repositories", function(t) { + var d = {repositories:["git@gist.github.com:123456.git"]} + normalize(d) + t.same(d.repository, { type: 'git', url: 'git@gist.github.com:123456.git' }) + t.end() +}); + +tap.test("treat visionmedia/express as github repo", function(t) { + var d = {repository: {type: "git", url: "visionmedia/express"}} + normalize(d) + t.same(d.repository, { type: "git", url: "https://github.com/visionmedia/express" }) + t.end() +}); + +tap.test("treat isaacs/node-graceful-fs as github repo", function(t) { + var d = {repository: {type: "git", url: "isaacs/node-graceful-fs"}} + normalize(d) + t.same(d.repository, { type: "git", url: "https://github.com/isaacs/node-graceful-fs" }) + t.end() +}); + +tap.test("homepage field will set to github url if repository is a github repo", function(t) { + var a + normalize(a={ + repository: { type: "git", url: "https://github.com/isaacs/node-graceful-fs" } + }) + t.same(a.homepage, 'https://github.com/isaacs/node-graceful-fs') + t.end() +}) + +tap.test("homepage field will set to github gist url if repository is a gist", function(t) { + var a + normalize(a={ + repository: { type: "git", url: "git@gist.github.com:123456.git" } + }) + t.same(a.homepage, 'https://gist.github.com/123456') + t.end() +}) + +tap.test("homepage field will set to github gist url if repository is a shorthand reference", function(t) { + var a + normalize(a={ + repository: { type: "git", url: "sindresorhus/chalk" } + }) + t.same(a.homepage, 'https://github.com/sindresorhus/chalk') + t.end() +}) + +tap.test("treat isaacs/node-graceful-fs as github repo in dependencies", function(t) { + var d = {dependencies: {"node-graceful-fs": "isaacs/node-graceful-fs"}} + normalize(d) + t.same(d.dependencies, {"node-graceful-fs": "git+https://github.com/isaacs/node-graceful-fs" }) + t.end() +}); + +tap.test("deprecation warning for array in dependencies fields", function(t) { + var a + var warnings = [] + function warn(w) { + warnings.push(w) + } + normalize(a={ + dependencies: [], + devDependencies: [], + optionalDependencies: [] + }, warn) + t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'dependencies')), "deprecation warning") + t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'devDependencies')), "deprecation warning") + t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'optionalDependencies')), "deprecation warning") + t.end() +}) + +tap.test('no new globals', function(t) { + t.same(Object.keys(global), globals) + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/scoped.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/scoped.js new file mode 100644 index 000000000..0f17e9f5b --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/scoped.js @@ -0,0 +1,38 @@ +var test = require("tap").test + +var fixNameField = require("../lib/fixer.js").fixNameField + +test("a simple scoped module has a valid name", function (t) { + var data = {name : "@org/package"} + fixNameField(data, false) + t.equal(data.name, "@org/package", "name was unchanged") + + t.end() +}) + +test("'org@package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "org@package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) + +test("'org=package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "org=package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) + +test("'@org=sub/package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "@org=sub/package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/strict.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/strict.js new file mode 100644 index 000000000..40e09dcf2 --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/strict.js @@ -0,0 +1,54 @@ +var test = require("tap").test + +var normalize = require("../") + +test("strict", function(t) { + var threw + + try { + threw = false + normalize({name: "X"}, true) + } catch (er) { + threw = true + t.equal(er.message, 'Invalid name: "X"') + } finally { + t.equal(threw, true) + } + + try { + threw = false + normalize({name:" x "}, true) + } catch (er) { + threw = true + t.equal(er.message, 'Invalid name: " x "') + } finally { + t.equal(threw, true) + } + + try { + threw = false + normalize({name:"x",version:"01.02.03"}, true) + } catch (er) { + threw = true + t.equal(er.message, 'Invalid version: "01.02.03"') + } finally { + t.equal(threw, true) + } + + // these should not throw + var slob = {name:" X ",version:"01.02.03",dependencies:{ + y:">01.02.03", + z:"! 99 $$ASFJ(Aawenf90awenf as;naw.3j3qnraw || an elephant" + }} + normalize(slob, false) + t.same(slob, + { name: 'X', + version: '1.2.3', + dependencies: + { y: '>01.02.03', + z: '! 99 $$ASFJ(Aawenf90awenf as;naw.3j3qnraw || an elephant' }, + readme: 'ERROR: No README data found!', + _id: 'X@1.2.3' }) + + t.end() +}) diff --git a/node_modules/npm-registry-client/node_modules/normalize-package-data/test/typo.js b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/typo.js new file mode 100644 index 000000000..eda75545e --- /dev/null +++ b/node_modules/npm-registry-client/node_modules/normalize-package-data/test/typo.js @@ -0,0 +1,115 @@ +var test = require('tap').test + +var normalize = require('../') +var typos = require('../lib/typos.json') +var warningMessages = require("../lib/warning_messages.json") +var safeFormat = require("../lib/safe_format") + +test('typos', function(t) { + var warnings = [] + function warn(m) { + warnings.push(m) + } + + var typoMessage = safeFormat.bind(undefined, warningMessages.typo) + + var expect = + [ warningMessages.missingRepository, + typoMessage('dependancies', 'dependencies'), + typoMessage('dependecies', 'dependencies'), + typoMessage('depdenencies', 'dependencies'), + typoMessage('devEependencies', 'devDependencies'), + typoMessage('depends', 'dependencies'), + typoMessage('dev-dependencies', 'devDependencies'), + typoMessage('devDependences', 'devDependencies'), + typoMessage('devDepenencies', 'devDependencies'), + typoMessage('devdependencies', 'devDependencies'), + typoMessage('repostitory', 'repository'), + typoMessage('repo', 'repository'), + typoMessage('prefereGlobal', 'preferGlobal'), + typoMessage('hompage', 'homepage'), + typoMessage('hampage', 'homepage'), + typoMessage('autohr', 'author'), + typoMessage('autor', 'author'), + typoMessage('contributers', 'contributors'), + typoMessage('publicationConfig', 'publishConfig') ] + + normalize({"dependancies": "dependencies" + ,"dependecies": "dependencies" + ,"depdenencies": "dependencies" + ,"devEependencies": "devDependencies" + ,"depends": "dependencies" + ,"dev-dependencies": "devDependencies" + ,"devDependences": "devDependencies" + ,"devDepenencies": "devDependencies" + ,"devdependencies": "devDependencies" + ,"repostitory": "repository" + ,"repo": "repository" + ,"prefereGlobal": "preferGlobal" + ,"hompage": "homepage" + ,"hampage": "homepage" + ,"autohr": "author" + ,"autor": "author" + ,"contributers": "contributors" + ,"publicationConfig": "publishConfig" + ,readme:"asdf" + ,name:"name" + ,version:"1.2.5"}, warn) + + t.same(warnings, expect) + + warnings.length = 0 + var expect = + [ warningMessages.missingDescription, + warningMessages.missingRepository, + typoMessage("bugs['web']", "bugs['url']"), + typoMessage("bugs['name']", "bugs['url']"), + warningMessages.nonUrlBugsUrlField, + warningMessages.emptyNormalizedBugs, + warningMessages.missingReadme ] + + normalize({name:"name" + ,version:"1.2.5" + ,bugs:{web:"url",name:"url"}}, warn) + + t.same(warnings, expect) + + warnings.length = 0 + var expect = + [ warningMessages.missingDescription, + warningMessages.missingRepository, + warningMessages.missingReadme, + typoMessage('script', 'scripts') ] + + normalize({name:"name" + ,version:"1.2.5" + ,script:{server:"start",tests:"test"}}, warn) + + t.same(warnings, expect) + + warnings.length = 0 + expect = + [ warningMessages.missingDescription, + warningMessages.missingRepository, + typoMessage("scripts['server']", "scripts['start']"), + typoMessage("scripts['tests']", "scripts['test']"), + warningMessages.missingReadme ] + + normalize({name:"name" + ,version:"1.2.5" + ,scripts:{server:"start",tests:"test"}}, warn) + + t.same(warnings, expect) + + warnings.length = 0 + expect = [] + + normalize({private: true + ,name:"name" + ,version:"1.2.5" + ,scripts:{server:"start",tests:"test"}}, warn) + + t.same(warnings, expect) + + t.end(); +}) diff --git a/node_modules/npm-registry-client/package.json b/node_modules/npm-registry-client/package.json index f9322c408..0809c4c1a 100644 --- a/node_modules/npm-registry-client/package.json +++ b/node_modules/npm-registry-client/package.json @@ -18,6 +18,7 @@ "chownr": "0", "graceful-fs": "^3.0.0", "mkdirp": "~0.3.3", + "normalize-package-data": "git://github.com/npm/normalize-package-data#othiym23/scoped", "npm-cache-filename": "^1.0.0", "request": "2 >=2.25.0", "retry": "0.6.0", @@ -40,7 +41,7 @@ }, "homepage": "https://github.com/isaacs/npm-registry-client", "_id": "npm-registry-client@2.0.2", - "_shasum": "a8db62535b23a6d1da8634c33fe37368de4d8a03", - "_resolved": "git://github.com/npm/npm-registry-client#893ee18eb079390d6de5456500104c161c0f1da2", + "_shasum": "d0d8bbb8ff165a7d10caa22b76da77237fe0129a", + "_resolved": "git://github.com/npm/npm-registry-client#b6691a9ef44bc35b7e09f3e96abb97551287dc8b", "_from": "git://github.com/npm/npm-registry-client#othiym23/multi-registry" } diff --git a/node_modules/npm-registry-client/test/publish-scoped.js b/node_modules/npm-registry-client/test/publish-scoped.js new file mode 100644 index 000000000..9b83341dd --- /dev/null +++ b/node_modules/npm-registry-client/test/publish-scoped.js @@ -0,0 +1,51 @@ +var tap = require("tap") +var crypto = require("crypto") +var fs = require("fs") + +var server = require("./lib/server.js") +var common = require("./lib/common.js") +var client = common.freshClient({ + username: "username", + password: "password", + email: "i@izs.me", + _auth: new Buffer("username:password").toString("base64"), + "always-auth": true +}) + + +tap.test("publish", function (t) { + server.expect("/@npm%2fnpm-registry-client", 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 o = JSON.parse(b) + t.equal(o._id, "@npm/npm-registry-client") + t.equal(o["dist-tags"].latest, pkg.version) + t.has(o.versions[pkg.version], pkg) + t.same(o.maintainers, [ { name: "username", email: "i@izs.me" } ]) + t.same(o.maintainers, o.versions[pkg.version].maintainers) + var att = o._attachments[ pkg.name + "-" + pkg.version + ".tgz" ] + t.same(att.data, pd) + var hash = crypto.createHash("sha1").update(pd, "base64").digest("hex") + t.equal(o.versions[pkg.version].dist.shasum, hash) + res.statusCode = 201 + res.json({created:true}) + }) + }) + + // not really a tarball, but doesn't matter + var tarball = require.resolve("../package.json") + var pd = fs.readFileSync(tarball, "base64") + var pkg = require("../package.json") + pkg.name = '@npm/npm-registry-client' + client.publish("http://localhost:1337/", pkg, tarball, function (er, data) { + if (er) throw er + t.deepEqual(data, { created: true }) + t.end() + }) +}) diff --git a/node_modules/read-package-json/node_modules/normalize-package-data/lib/fixer.js b/node_modules/read-package-json/node_modules/normalize-package-data/lib/fixer.js index cc560f30e..82c1348be 100644 --- a/node_modules/read-package-json/node_modules/normalize-package-data/lib/fixer.js +++ b/node_modules/read-package-json/node_modules/normalize-package-data/lib/fixer.js @@ -291,9 +291,23 @@ var fixer = module.exports = { } function ensureValidName (name, strict) { + function scoped(spec) { + if (spec.charAt(0) !== '@') return false + + var rest = spec.slice(1).split('/') + if (rest.length !== 2) return false + + return rest[0] === encodeURIComponent(rest[0]) && + rest[1] === encodeURIComponent(rest[1]) + } + + function scopedOrEncoded(spec) { + return !scoped(spec) && + (spec.match(/[\/@\s\+%:]/) || spec !== encodeURIComponent(spec)) + } + if (name.charAt(0) === "." || - name.match(/[\/@\s\+%:]/) || - name !== encodeURIComponent(name) || + scopedOrEncoded(name) || (strict && name !== name.toLowerCase()) || name.toLowerCase() === "node_modules" || name.toLowerCase() === "favicon.ico") { diff --git a/node_modules/read-package-json/node_modules/normalize-package-data/package.json b/node_modules/read-package-json/node_modules/normalize-package-data/package.json index d368d4af5..5a8661802 100644 --- a/node_modules/read-package-json/node_modules/normalize-package-data/package.json +++ b/node_modules/read-package-json/node_modules/normalize-package-data/package.json @@ -38,33 +38,14 @@ "email": "rok@kowalski.gd" } ], - "gitHead": "f4d4268894a23d6f37a335d4ae28bd90b14e4ef9", + "readme": "# normalize-package-data [![Build Status](https://travis-ci.org/meryn/normalize-package-data.png?branch=master)](https://travis-ci.org/meryn/normalize-package-data)\n\nnormalize-package data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry.\n\nnormalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools.\n\n## Installation\n\n```\nnpm install normalize-package-data\n```\n\n## Usage\n\nBasic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nnormalizeData(packageData)\n// packageData is now normalized\n```\n\n#### Strict mode\n\nYou may activate strict validation by passing true as the second argument.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, true)\n// packageData is now normalized\n```\n\nIf strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace.\n\n#### Warnings\n\nOptionally, you may pass a \"warning\" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, warnFn)\n// packageData is now normalized. Any number of warnings may have been logged.\n```\n\nYou may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third.\n\nWhen `private` field is set to `true`, warnings will be suppressed.\n\n### Potential exceptions\n\nIf the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback.\n\n## What normalization (currently) entails\n\n* The value of `name` field gets trimmed (unless in strict mode).\n* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n* If `name` and/or `version` fields are missing, they are set to empty strings.\n* If `files` field is not an array, it will be removed.\n* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value.\n* If `man` field is a string, it will become an array with the original string as its sole member.\n* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\\s+`.\n* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties.\n* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`.\n* If the value of any of the dependencies fields (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs.\n* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched.\n* If `description` field does not exists, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`.\n* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `\"git\"`.\n* If `repository.url` is not a valid url, but in the style of \"[owner-name]/[repo-name]\", `repository.url` will be set to git://github.com/[owner-name]/[repo-name]\n* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value.\n* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed.\n* If `homepage` field is not a string, it will be removed.\n* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`.\n* If `homepage` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `homepage` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/ . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n\n### Rules for name field\n\nIf `name` field is given, the value of the name field must be a string. The string may not:\n\n* start with a period.\n* contain the following characters: `/@\\s+%`\n* contain and characters that would need to be encoded for use in urls.\n* resemble the word `node_modules` or `favicon.ico` (case doesn't matter).\n\n### Rules for version field\n\nIf `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n\n## Credits\n\nThis package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson.\n\n## License\n\nnormalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT). \nCopyright (c) 2013 Meryn Stol ", + "readmeFilename": "README.md", "bugs": { "url": "https://github.com/meryn/normalize-package-data/issues" }, "homepage": "https://github.com/meryn/normalize-package-data", "_id": "normalize-package-data@0.3.0", - "_shasum": "70ea9e5b6caf69faa9d83e42f71489642372d815", - "_from": "normalize-package-data@^0.3.0", - "_npmVersion": "1.4.14", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "meryn", - "email": "merynstol@gmail.com" - }, - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "70ea9e5b6caf69faa9d83e42f71489642372d815", - "tarball": "http://registry.npmjs.org/normalize-package-data/-/normalize-package-data-0.3.0.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-0.3.0.tgz" + "_shasum": "d763a0bdb2bc4f4cf9d355aab9991bd7585e0c57", + "_resolved": "git://github.com/npm/normalize-package-data.git#15869dc14c1ac8e3b202586f62f755c69443e403", + "_from": "normalize-package-data@git://github.com/npm/normalize-package-data.git#othiym23/scoped" } diff --git a/node_modules/read-package-json/node_modules/normalize-package-data/test/github-urls.js b/node_modules/read-package-json/node_modules/normalize-package-data/test/github-urls.js index fd68d76e2..da78160a0 100644 --- a/node_modules/read-package-json/node_modules/normalize-package-data/test/github-urls.js +++ b/node_modules/read-package-json/node_modules/normalize-package-data/test/github-urls.js @@ -1,25 +1,23 @@ var tap = require("tap") var normalize = require("../lib/normalize") -var path = require("path") var fs = require("fs") -var _ = require("underscore") var async = require("async") -var data, clonedData +var data var warn tap.test("consistent normalization", function(t) { - entries = [ + var entries = [ 'read-package-json.json', 'http-server.json', "movefile.json", "node-module_exist.json" ] - verifyConsistency = function(entryName, next) { - warn = function(msg) { + var verifyConsistency = function(entryName, next) { + warn = function(msg) { // t.equal("",msg) // uncomment to have some kind of logging of warnings } - filename = __dirname + "/fixtures/" + entryName + var filename = __dirname + "/fixtures/" + entryName fs.readFile(filename, function(err, contents) { if (err) return next(err) data = JSON.parse(contents.toString()) @@ -43,4 +41,4 @@ tap.test("consistent normalization", function(t) { if (err) throw err t.end() }) -}) // tap.test
\ No newline at end of file +}) // tap.test diff --git a/node_modules/read-package-json/node_modules/normalize-package-data/test/scoped.js b/node_modules/read-package-json/node_modules/normalize-package-data/test/scoped.js new file mode 100644 index 000000000..0f17e9f5b --- /dev/null +++ b/node_modules/read-package-json/node_modules/normalize-package-data/test/scoped.js @@ -0,0 +1,38 @@ +var test = require("tap").test + +var fixNameField = require("../lib/fixer.js").fixNameField + +test("a simple scoped module has a valid name", function (t) { + var data = {name : "@org/package"} + fixNameField(data, false) + t.equal(data.name, "@org/package", "name was unchanged") + + t.end() +}) + +test("'org@package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "org@package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) + +test("'org=package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "org=package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) + +test("'@org=sub/package' is not a valid name", function (t) { + t.throws(function () { + var data = {name : "@org=sub/package"} + fixNameField(data, false) + }, "blows up as expected") + + t.end() +}) diff --git a/node_modules/read-package-json/package.json b/node_modules/read-package-json/package.json index 5d64ff0e3..885d63a15 100644 --- a/node_modules/read-package-json/package.json +++ b/node_modules/read-package-json/package.json @@ -18,7 +18,7 @@ "dependencies": { "glob": "^4.0.2", "lru-cache": "2", - "normalize-package-data": "^0.3.0", + "normalize-package-data": "git://github.com/npm/normalize-package-data.git#othiym23/scoped", "graceful-fs": "2 || 3" }, "devDependencies": { @@ -30,12 +30,12 @@ "license": "ISC", "readme": "# read-package-json\n\nThis is the thing that npm uses to read package.json files. It\nvalidates some stuff, and loads some default things.\n\nIt keeps a cache of the files you've read, so that you don't end\nup reading the same package.json file multiple times.\n\nNote that if you just want to see what's literally in the package.json\nfile, you can usually do `var data = require('some-module/package.json')`.\n\nThis module is basically only needed by npm, but it's handy to see what\nnpm will see when it looks at your package.\n\n## Usage\n\n```javascript\nvar readJson = require('read-package-json')\n\n// readJson(filename, [logFunction=noop], [strict=false], cb)\nreadJson('/path/to/package.json', console.error, false, function (er, data) {\n if (er) {\n console.error(\"There was an error reading the file\")\n return\n }\n\n console.error('the package data is', data)\n});\n```\n\n## readJson(file, [logFn = noop], [strict = false], cb)\n\n* `file` {String} The path to the package.json file\n* `logFn` {Function} Function to handle logging. Defaults to a noop.\n* `strict` {Boolean} True to enforce SemVer 2.0 version strings, and\n other strict requirements.\n* `cb` {Function} Gets called with `(er, data)`, as is The Node Way.\n\nReads the JSON file and does the things.\n\n## `package.json` Fields\n\nSee `man 5 package.json` or `npm help json`.\n\n## readJson.log\n\nBy default this is a reference to the `npmlog` module. But if that\nmodule can't be found, then it'll be set to just a dummy thing that does\nnothing.\n\nReplace with your own `{log,warn,error}` object for fun loggy time.\n\n## readJson.extras(file, data, cb)\n\nRun all the extra stuff relative to the file, with the parsed data.\n\nModifies the data as it does stuff. Calls the cb when it's done.\n\n## readJson.extraSet = [fn, fn, ...]\n\nArray of functions that are called by `extras`. Each one receives the\narguments `fn(file, data, cb)` and is expected to call `cb(er, data)`\nwhen done or when an error occurs.\n\nOrder is indeterminate, so each function should be completely\nindependent.\n\nMix and match!\n\n## readJson.cache\n\nThe `lru-cache` object that readJson uses to not read the same file over\nand over again. See\n[lru-cache](https://github.com/isaacs/node-lru-cache) for details.\n\n## Other Relevant Files Besides `package.json`\n\nSome other files have an effect on the resulting data object, in the\nfollowing ways:\n\n### `README?(.*)`\n\nIf there is a `README` or `README.*` file present, then npm will attach\na `readme` field to the data with the contents of this file.\n\nOwing to the fact that roughly 100% of existing node modules have\nMarkdown README files, it will generally be assumed to be Markdown,\nregardless of the extension. Please plan accordingly.\n\n### `server.js`\n\nIf there is a `server.js` file, and there is not already a\n`scripts.start` field, then `scripts.start` will be set to `node\nserver.js`.\n\n### `AUTHORS`\n\nIf there is not already a `contributors` field, then the `contributors`\nfield will be set to the contents of the `AUTHORS` file, split by lines,\nand parsed.\n\n### `bindings.gyp`\n\nIf a bindings.gyp file exists, and there is not already a\n`scripts.install` field, then the `scripts.install` field will be set to\n`node-gyp rebuild`.\n\n### `wscript`\n\nIf a wscript file exists, and there is not already a `scripts.install`\nfield, then the `scripts.install` field will be set to `node-waf clean ;\nnode-waf configure build`.\n\nNote that the `bindings.gyp` file supercedes this, since node-waf has\nbeen deprecated in favor of node-gyp.\n\n### `index.js`\n\nIf the json file does not exist, but there is a `index.js` file\npresent instead, and that file has a package comment, then it will try\nto parse the package comment, and use that as the data instead.\n\nA package comment looks like this:\n\n```javascript\n/**package\n * { \"name\": \"my-bare-module\"\n * , \"version\": \"1.2.3\"\n * , \"description\": \"etc....\" }\n **/\n\n// or...\n\n/**package\n{ \"name\": \"my-bare-module\"\n, \"version\": \"1.2.3\"\n, \"description\": \"etc....\" }\n**/\n```\n\nThe important thing is that it starts with `/**package`, and ends with\n`**/`. If the package.json file exists, then the index.js is not\nparsed.\n\n### `{directories.man}/*.[0-9]`\n\nIf there is not already a `man` field defined as an array of files or a\nsingle file, and\nthere is a `directories.man` field defined, then that directory will\nbe searched for manpages.\n\nAny valid manpages found in that directory will be assigned to the `man`\narray, and installed in the appropriate man directory at package install\ntime, when installed globally on a Unix system.\n\n### `{directories.bin}/*`\n\nIf there is not already a `bin` field defined as a string filename or a\nhash of `<name> : <filename>` pairs, then the `directories.bin`\ndirectory will be searched and all the files within it will be linked as\nexecutables at install time.\n\nWhen installing locally, npm links bins into `node_modules/.bin`, which\nis in the `PATH` environ when npm runs scripts. When\ninstalling globally, they are linked into `{prefix}/bin`, which is\npresumably in the `PATH` environment variable.\n", "readmeFilename": "README.md", - "gitHead": "ed8df916a4432b3317e4d3c7154aac2a790844cb", "bugs": { "url": "https://github.com/isaacs/read-package-json/issues" }, "homepage": "https://github.com/isaacs/read-package-json", "_id": "read-package-json@1.2.2", - "_shasum": "545fc9044d135bf5fe0a67c6eab368c3186cbafe", - "_from": "read-package-json@latest" + "_shasum": "6610e6743faaa5f95dd88ce689abf39df2398578", + "_resolved": "git://github.com/npm/read-package-json.git#5b343eca60ff00041aa88802753d0bef20a0cb03", + "_from": "git://github.com/npm/read-package-json.git#othiym23/scoped" } diff --git a/package.json b/package.json index 6f5ff8f35..1ed7180ff 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "path-is-inside": "~1.0.0", "read": "~1.0.4", "read-installed": "~2.0.5", - "read-package-json": "~1.2.2", + "read-package-json": "git://github.com/npm/read-package-json.git#othiym23/scoped", "request": "~2.30.0", "retry": "~0.6.0", "rimraf": "~2.2.8", @@ -144,6 +144,7 @@ ], "devDependencies": { "marked": "~0.3.2", + "nock": "~0.34.1", "npm-registry-couchapp": "~2.3.6", "npm-registry-mock": "~0.6.3", "ronn": "~0.3.6", diff --git a/test/tap/config-meta.js b/test/tap/config-meta.js index 5c2fa8308..935438720 100644 --- a/test/tap/config-meta.js +++ b/test/tap/config-meta.js @@ -17,6 +17,7 @@ var DOC = {} var exceptions = [ path.resolve(lib, "config.js"), + path.resolve(lib, "publish.js"), path.resolve(lib, "utils", "lifecycle.js"), path.resolve(lib, "utils", "map-name-to-registry.js") ] diff --git a/test/tap/publish-organized.js b/test/tap/publish-organized.js new file mode 100644 index 000000000..0e3496958 --- /dev/null +++ b/test/tap/publish-organized.js @@ -0,0 +1,69 @@ +var fs = require('fs') +var path = require("path") + +var test = require("tap").test +var mkdirp = require("mkdirp") +var rimraf = require("rimraf") +var nock = require("nock") + +var npm = require('../../') +var common = require('../common-tap.js') + +var pkg = path.join(__dirname, "prepublish_package") + +test("setup", function (t) { + mkdirp(path.join(pkg, "cache"), next) + + function next () { + console.log("in next") + process.chdir(pkg) + fs.writeFile( + path.join(pkg, "package.json"), + JSON.stringify({ + name: "@bigco/publish-organized", + version: "1.2.5" + }), + "ascii", + function (er) { + t.ifError(er) + + t.pass("setup done") + t.end() + } + ) + } +}) + +test("npm publish should honor scoping", function (t) { + var put = nock(common.registry).put("/@bigco%2fpublish-organized").reply(201, {ok: true}) + + var configuration = { + cache : path.join(pkg, "cache"), + loglevel : "silent", + registry : "http://nonexistent.lvh.me" + } + + function onload (er) { + t.ifError(er, "npm bootstrapped successfully") + + npm.config.set("@bigco:registry-base-url", common.registry) + npm.commands.publish([], false, function (er) { + t.ifError(er, "published without error") + + put.done() + + t.end() + }) + } + + npm.load(configuration, onload) +}) + +test("cleanup", function(t) { + process.chdir(__dirname) + rimraf(pkg, function (er) { + t.ifError(er) + + t.end() + }) +}) |