diff options
Diffstat (limited to 'deps/npm/node_modules')
142 files changed, 7184 insertions, 254 deletions
diff --git a/deps/npm/node_modules/ansi/examples/beep/index.js b/deps/npm/node_modules/ansi/examples/beep/index.js new file mode 100755 index 0000000000..c1ec929d0b --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/beep/index.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +/** + * Invokes the terminal "beep" sound once per second on every exact second. + */ + +process.title = 'beep' + +var cursor = require('../../')(process.stdout) + +function beep () { + cursor.beep() + setTimeout(beep, 1000 - (new Date()).getMilliseconds()) +} + +setTimeout(beep, 1000 - (new Date()).getMilliseconds()) diff --git a/deps/npm/node_modules/ansi/examples/clear/index.js b/deps/npm/node_modules/ansi/examples/clear/index.js new file mode 100755 index 0000000000..6ac21ffa99 --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/clear/index.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node + +/** + * Like GNU ncurses "clear" command. + * https://github.com/mscdex/node-ncurses/blob/master/deps/ncurses/progs/clear.c + */ + +process.title = 'clear' + +function lf () { return '\n' } + +require('../../')(process.stdout) + .write(Array.apply(null, Array(process.stdout.getWindowSize()[1])).map(lf).join('')) + .eraseData(2) + .goto(1, 1) diff --git a/deps/npm/node_modules/ansi/examples/cursorPosition.js b/deps/npm/node_modules/ansi/examples/cursorPosition.js new file mode 100755 index 0000000000..0f45bdbe58 --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/cursorPosition.js @@ -0,0 +1,24 @@ +#!/usr/bin/env node + +var tty = require('tty') +var cursor = require('../')(process.stdout) + +// listen for the queryPosition report on stdin +process.stdin.resume() +tty.setRawMode(true) + +process.stdin.once('data', function (b) { + var match = /\[(\d+)\;(\d+)R$/.exec(b.toString()) + if (match) { + var xy = match.slice(1, 3).reverse().map(Number) + console.error(xy) + } + + // cleanup and close stdin + tty.setRawMode(false) + process.stdin.pause() +}) + + +// send the query position request code to stdout +cursor.queryPosition() diff --git a/deps/npm/node_modules/ansi/examples/imgcat/index.js b/deps/npm/node_modules/ansi/examples/imgcat/index.js new file mode 100755 index 0000000000..5ff2c13943 --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/imgcat/index.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node + +process.title = 'imgcat' + +var ansi = require('../../') + , cursor = ansi(process.stdout, { enabled: true }) + , tty = require('tty') + , Canvas = require('canvas') + , imageFile = process.argv[2] || __dirname + '/yoshi.png' + , screenWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity + , maxWidth = parseInt(process.argv[3], 10) || screenWidth + , image = require('fs').readFileSync(imageFile) + , pixel = ' ' + , alphaThreshold = 0 + +var img = new Canvas.Image(); +img.src = image; + +function draw () { + var width = maxWidth / pixel.length + , scaleW = img.width > width ? width / img.width : 1 + , w = Math.floor(img.width * scaleW) + , h = Math.floor(img.height * scaleW); + + var canvas = new Canvas(w, h) + , ctx = canvas.getContext('2d'); + + ctx.drawImage(img, 0, 0, w, h); + + var data = ctx.getImageData(0, 0, w, h).data; + + for (var i=0, l=data.length; i<l; i+=4) { + var r = data[i] + , g = data[i+1] + , b = data[i+2] + , alpha = data[i+3]; + if (alpha > alphaThreshold) { + cursor.bg.rgb(r, g, b); + } else { + cursor.bg.reset(); + } + process.stdout.write(pixel); + if ((i/4|0) % w === (w-1)) { + cursor.bg.reset(); + process.stdout.write('\n'); + } + } +} + +draw(); diff --git a/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png b/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png Binary files differnew file mode 100644 index 0000000000..267ede2541 --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/imgcat/yoshi.png diff --git a/deps/npm/node_modules/ansi/examples/progress/index.js b/deps/npm/node_modules/ansi/examples/progress/index.js new file mode 100644 index 0000000000..d28dbda27f --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/progress/index.js @@ -0,0 +1,87 @@ +#!/usr/bin/env node + +var assert = require('assert') + , ansi = require('../../') + +function Progress (stream, width) { + this.cursor = ansi(stream) + this.delta = this.cursor.newlines + this.width = width | 0 || 10 + this.open = '[' + this.close = ']' + this.complete = '█' + this.incomplete = '_' + + // initial render + this.progress = 0 +} + +Object.defineProperty(Progress.prototype, 'progress', { + get: get + , set: set + , configurable: true + , enumerable: true +}) + +function get () { + return this._progress +} + +function set (v) { + this._progress = Math.max(0, Math.min(v, 100)) + + var w = this.width - this.complete.length - this.incomplete.length + , n = w * (this._progress / 100) | 0 + , i = w - n + , com = c(this.complete, n) + , inc = c(this.incomplete, i) + , delta = this.cursor.newlines - this.delta + + assert.equal(com.length + inc.length, w) + + if (delta > 0) { + this.cursor.up(delta) + this.delta = this.cursor.newlines + } + + this.cursor + .horizontalAbsolute(0) + .eraseLine(2) + .fg.white() + .write(this.open) + .fg.grey() + .bold() + .write(com) + .resetBold() + .write(inc) + .fg.white() + .write(this.close) + .fg.reset() + .write('\n') +} + +function c (char, length) { + return Array.apply(null, Array(length)).map(function () { + return char + }).join('') +} + + + + +// Usage +var width = parseInt(process.argv[2], 10) || process.stdout.getWindowSize()[0] / 2 + , p = new Progress(process.stdout, width) + +;(function tick () { + p.progress += Math.random() * 5 + p.cursor + .eraseLine(2) + .write('Progress: ') + .bold().write(p.progress.toFixed(2)) + .write('%') + .resetBold() + .write('\n') + if (p.progress < 100) + setTimeout(tick, 100) +})() diff --git a/deps/npm/node_modules/ansi/examples/starwars.js b/deps/npm/node_modules/ansi/examples/starwars.js new file mode 100755 index 0000000000..a1fcad42a6 --- /dev/null +++ b/deps/npm/node_modules/ansi/examples/starwars.js @@ -0,0 +1,39 @@ +#!/usr/bin/env node + +/** + * A little script to play the ASCII Star Wars, but with a hidden cursor, + * since over `telnet(1)` the cursor remains visible which is annoying. + */ + +process.title = 'starwars' + +var net = require('net') + , cursor = require('../')(process.stdout) + +// enable "raw mode" so that keystrokes aren't visible +process.stdin.resume() +if (process.stdin.setRawMode) { + process.stdin.setRawMode(true) +} else { + require('tty').setRawMode(true) +} + +// connect to the ASCII Star Wars server +var socket = net.connect(23, 'towel.blinkenlights.nl') + +socket.on('connect', function () { + cursor.hide() + socket.pipe(process.stdout) +}) + +process.stdin.on('data', function (data) { + if (data.toString() === '\u0003') { + // Ctrl+C; a.k.a SIGINT + socket.destroy() + process.stdin.pause() + } +}) + +process.on('exit', function () { + cursor.show().write('\n') +}) diff --git a/deps/npm/node_modules/couch-login/README.md b/deps/npm/node_modules/couch-login/README.md new file mode 100644 index 0000000000..0b6c75d949 --- /dev/null +++ b/deps/npm/node_modules/couch-login/README.md @@ -0,0 +1,241 @@ +# couch-login + +This module lets you log into couchdb to get a session token, then make +requests using that session. It is basically just a thin wrapper around +[@mikeal's request module](https://github.com/mikeal/request). + +This is handy if you want a user to take actions in a couchdb database +on behalf of a user, without having to store their couchdb username and +password anywhere. (You do need to store the AuthSession token +somewhere, though.) + +## Usage + +```javascript +var CouchLogin = require('couch-login') + +// Nothing about this module is http-server specific of course. +// You could also use it to do authenticated requests against +// a couchdb using sessions and storing the token somewhere else. + +http.createServer(function (req, res) { + var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/') + + // .. look up the token in the user's session or whatever .. + // Look at couch.decorate(req, res) for more on doing that + // automatically, below. + + if (sessionToken) { + // this user already logged in. + couch.token = sessionToken + + // now we can do things on their behalf, like: + // 1. View their session info. + // like doing request.get({ uri: couch + '/_session', ... }) + // but with the cookie and whatnot + + couch.get('/_session', function (er, resp, data) { + // er = some kind of communication error. + // resp = response object from the couchdb request. + // data = parsed JSON response body. + if (er || resp.statusCode !== 200) { + res.statusCode = resp.statusCode || 403 + return res.end('Invalid login or something') + } + + // now we have the session info, we know who this user is. + // hitting couchdb for this on every request is kinda costly, + // so maybe you should store the username wherever you're storing + // the sessionToken. RedSess is a good util for this, if you're + // into redis. And if you're not into redis, you're crazy, + // because it is awesome. + + // now let's get the user record. + // note that this will 404 for anyone other than the user, + // unless they're a server admin. + couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc) + + // PUTs and DELETEs will also use their session, of course, so + // your validate_doc_update's will see their info in userCtx + }) + + } else { + // don't have a sessionToken. + // get a username and password from the post body or something. + // maybe redirect to a /login page or something to ask for that. + var login = { name: name, password: password } + couch.login(login, function (er, resp, data) { + // again, er is an error, resp is the response obj, data is the json + if (er || resp.statusCode !== 200) { + res.statusCode = resp.statusCode || 403 + return res.end('Invalid login or something') + } + + // the data is something like + // {"ok":true,"name":"testuser","roles":[]} + // and couch.token is the token you'll need to save somewhere. + + // at this point, you can start making authenticated requests to + // couchdb, or save data in their session, or do whatever it is + // that you need to do. + + res.statusCode = 200 + res.write("Who's got two thumbs and just logged you into couch?\n") + setTimeout(function () { + res.end("THIS GUY!") + }, 500) + }) + } +}) +``` + +## Class: CouchLogin +### new CouchLogin(couchdbUrl, token) + +Create a new CouchLogin object bound to the couchdb url. + +In addition to these, the `get`, `post`, `put`, and `del` methods all +proxy to the associated method on [request](https://github.com/mikeal/request). + +However, as you'll note in the example above, only the pathname portion +of the url is required. Urls will be appended to the couchdb url passed +into the constructor. + +If you have to talk to more than one couchdb, then you'll need more than +one CouchLogin object, for somewhat obvious reasons. + +All callbacks get called with the following arguments, which are exactly +identical to the arguments passed to a `request` callback. + +* `er` {Error | null} Set if a communication error happens. +* `resp` {HTTP Response} The response from the request to couchdb +* `data` {Object} The parsed JSON data from couch + +If the token is the string "anonymous", then it will not attempt to log +in before making requests. If the token is not "anonymous", then it +must be an object with the appropriate fields. + +### couch.token + +* {Object} + +An object representing the couchdb session token. (Basically just a +cookie and a timeout.) + +If the token has already timed out, then setting it will have no effect. + +### couch.tokenSet + +If set, this method is called whenever the token is saved. + +For example, you could assign a function to this method to save the +token into a redis session, a cookie, or in some other database. + +Takes a callback which should be called when the token is saved. + +### couch.tokenGet + +If set, this method is called to look up the token on demand. + +The inverse of couch.tokenSet. Takes a callback which is called with +the `cb(er || null, token)`. + +### couch.tokenDel + +If set, this method is called to delete the token when it should be +discarded. + +Related to tokenGet and tokenSet. Takes a callback which should be +called when the token is deleted. + +### couch.anonymous() + +Return a new CouchLogin object that points at the same couchdb server, +but doesn't try to log in before making requests. + +This is handy for situations where the user is not logged in at the +moment, but a request needs to be made anyway, and does not require +authorization. + +### couch.login(auth, callback) + +* `auth` {Object} The login details + * `name` {String} + * `password` {String} +* `callback` {Function} + +When the callback is called, the `couch.token` will already have been +set (assuming it worked!), so subsequent requests will be done as that +user. + +### couch.get(path, callback) + +GET the supplied path from the couchdb using the credentials on the +token. + +Fails if the token is invalid or expired. + +### couch.del(path, callback) + +DELETE the supplied path from the couchdb using the credentials on the +token. + +Fails if the token is invalid or expired. + +### couch.post(path, data, callback) + +POST the data to the supplied path in the couchdb, using the credentials +on the token. + +Fails if the token is invalid or expired. + +### couch.put(path, data, callback) + +PUT the data to the supplied path in the couchdb, using the credentials +on the token. + +Fails if the token is invalid or expired. + +### couch.changePass(newAuth, callback) + +Must already be logged in. Updates the `_users` document with new salt +and hash, and re-logs in with the new credentials. Callback is called +with the same arguments as login, or the first step of the process that +failed. + +### couch.signup(userData, callback) + +Create a new user account. The userData must contain at least a `name` +and `password` field. Any additional data will be copied to the user +record. The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and +`date` fields are generated. + +Also signs in as the newly created user, on successful account creation. + +### couch.deleteAccount(name, callback) + +Deletes a user account. If not logged in as the user, or a server +admin, then the request will fail. + +Note that this immediately invalidates any session tokens for the +deleted user account. If you are deleting the user's record, then you +ought to follow this with `couch.logout(callback)` so that it won't try +to re-use the invalid session. + +### couch.logout(callback) + +Delete the session out of couchdb. This makes the token permanently +invalid, and deletes it. + +### couch.decorate(req, res) + +Set up `req.couch` and `res.couch` as references to this couch login +instance. + +Additionall, if `req.session` or `res.session` is set, then it'll call +`session.get('couch_token', cb)` as the tokenGet method, +`session.set('couch_token', token, cb)` as the tokenSet method, and +`session.del('couch_token', cb)` as the tokenDel method. + +This works really nice with +[RedSess](https://github.com/isaacs/redsess). diff --git a/deps/npm/node_modules/couch-login/couch-login.js b/deps/npm/node_modules/couch-login/couch-login.js new file mode 100644 index 0000000000..d240da0258 --- /dev/null +++ b/deps/npm/node_modules/couch-login/couch-login.js @@ -0,0 +1,287 @@ +var request = require('request') +, url = require('url') +, crypto = require('crypto') + +module.exports = CouchLogin + +function CouchLogin (couch, tok) { + if (!(this instanceof CouchLogin)) { + return new CouchLogin(couch) + } + + if (!couch) throw new Error( + "Need to pass a couch url to CouchLogin constructor") + + // having auth completely defeats the purpose + couch = url.parse(couch) + delete couch.auth + + if (tok === 'anonymous') tok = NaN + this.token = tok + this.couch = url.format(couch) +} + +CouchLogin.prototype = +{ get: makeReq('GET') +, del: makeReq('DELETE') +, put: makeReq('PUT', true) +, post: makeReq('POST', true) +, login: login +, logout: logout +, decorate: decorate +, changePass: changePass +, signup: signup +, deleteAccount: deleteAccount +, anon: anon +, anonymous: anon +, valid: valid +} + +Object.defineProperty(CouchLogin.prototype, 'constructor', + { value: CouchLogin, enumerable: false }) + +function decorate (req, res) { + req.couch = res.couch = this + + // backed by some sort of set(k,v,cb), get(k,cb) session storage. + var session = req.session || res.session || null + if (session) { + this.tokenGet = function (cb) { + session.get('couch_token', cb) + } + + // don't worry about it failing. it'll just mean a login next time. + this.tokenSet = function (tok, cb) { + session.set('couch_token', tok, cb || function () {}) + } + + this.tokenDel = function (cb) { + session.del('couch_token', cb || function () {}) + } + } + + return this +} + +function anon () { + return new CouchLogin(this.couch, NaN) +} + +function makeReq (meth, body, f) { return function madeReq (p, d, cb) { + f = f || (this.token !== this.token) + if (!f && !valid(this.token)) { + // lazily get the token. + if (this.tokenGet) return this.tokenGet(function (er, tok) { + if (er || !valid(tok)) { + if (!body) cb = d, d = null + return cb(new Error('auth token expired or invalid')) + } + this.token = tok + return madeReq.call(this, p, d, cb) + }.bind(this)) + + // no getter, no token, no business. + return process.nextTick(function () { + if (!body) cb = d, d = null + cb(new Error('auth token expired or invalid')) + }) + } + + if (!body) cb = d, d = null + + var h = {} + , u = url.resolve(this.couch, p) + , req = { uri: u, headers: h, json: true, body: d, method: meth } + + if (this.token) { + h.cookie = 'AuthSession=' + this.token.AuthSession + } + + request(req, function (er, res, data) { + // update cookie. + if (er || res.statusCode !== 200) return cb(er, res, data) + addToken.call(this, res) + return cb(er, res, data) + }.bind(this)) +}} + +function login (auth, cb) { + var a = { name: auth.name, password: auth.password } + makeReq('post', true, true).call(this, '/_session', a, cb) +} + +function changePass (auth, cb) { + if (!auth.name || !auth.password) return cb(new Error('invalid auth')) + + var u = '/_users/org.couchdb.user:' + auth.name + this.get(u, function (er, res, data) { + if (er || res.statusCode !== 200) return cb(er, res, data) + + // copy any other keys we're setting here. + // note that name, password_sha, salt, and date + // are all set explicitly below. + Object.keys(auth).filter(function (k) { + return k.charAt(0) !== '_' + && k !== 'password' + && k !== 'password_sha' + && k !== 'salt' + }).forEach(function (k) { + data[k] = auth[k] + }) + + var newSalt = crypto.randomBytes(30).toString('hex') + , newPass = auth.password + , newSha = sha(newPass + newSalt) + + data.password_sha = newSha + data.salt = newSalt + data.date = new Date().toISOString() + + this.put(u + '?rev=' + data._rev, data, function (er, res, data) { + if (er || res.statusCode >= 400) return cb(er, res, data) + this.login(auth, cb) + }.bind(this)) + }.bind(this)) +} + +// They said that there should probably be a warning before +// deleting the user's whole account, so here it is: +// +// WATCH OUT! +function deleteAccount (name, cb) { + var u = '/_users/org.couchdb.user:' + name + this.get(u, thenPut.bind(this)) + + function thenPut (er, res, data) { + if (er || res.statusCode !== 200) { + return cb(er, res, data) + } + + // user accts can't be just DELETE'd by non-admins + // so we take the existing doc and just slap a _deleted + // flag on it to fake it. Works the same either way + // in couch. + data._deleted = true + this.put(u + '?rev=' + data._rev, data, cb) + } +} + + + +function signup (auth, cb) { + if (this.token) return this.logout(function (er, res, data) { + if (er || res.statusCode !== 200) { + return cb(er, res, data) + } + + if (this.token) { + return cb(new Error('failed to delete token'), res, data) + } + + this.signup(auth, cb) + }.bind(this)) + + // make a new user record. + var newSalt = crypto.randomBytes(30).toString('hex') + , newSha = sha(auth.password + newSalt) + , user = { _id: 'org.couchdb.user:' + auth.name + , name: auth.name + , roles: [] + , type: 'user' + , password_sha: newSha + , salt: newSalt + , date: new Date().toISOString() } + + Object.keys(auth).forEach(function (k) { + if (k === 'name' || k === 'password') return + user[k] = auth[k] + }) + + var u = '/_users/' + user._id + makeReq('put', true, true).call(this, u, user, function (er, res, data) { + if (er || res.statusCode >= 400) { + return cb(er, res, data) + } + + // it worked! log in as that user and get their record + this.login(auth, function (er, res, data) { + if (er || (res && res.statusCode >= 400) || data && data.error) { + return cb(er, res, data) + } + this.get(u, cb) + }.bind(this)) + }.bind(this)) +} + +function addToken (res) { + // attach the token, if a new one was provided. + var sc = res.headers['set-cookie'] + if (!sc) return + if (!Array.isArray(sc)) sc = [sc] + + sc = sc.filter(function (c) { + return c.match(/^AuthSession=/) + })[0] + + if (!sc.length) return + + sc = sc.split(/\s*;\s*/).map(function (p) { + return p.split('=') + }).reduce(function (set, p) { + var k = p[0] === 'AuthSession' ? p[0] : p[0].toLowerCase() + , v = k === 'expires' ? Date.parse(p[1]) + : p[1] === '' || p[1] === undefined ? true // HttpOnly + : p[1] + set[k] = v + return set + }, {}) + + if (sc.hasOwnProperty('max-age')) { + var ma = sc['max-age'] + sc.expires = (ma <= 0) ? 0 : Date.now() + (ma * 1000) + delete sc['max-age'] + } + + this.token = sc + if (this.tokenSet) this.tokenSet(this.token) +} + + +function logout (cb) { + if (!this.token && this.tokenGet) { + return this.tokenGet(function (er, tok) { + if (er || !tok) return cb() + this.token = tok + this.logout(cb) + }.bind(this)) + } + + if (!valid(this.token)) { + this.token = null + if (this.tokenDel) this.tokenDel() + return process.nextTick(cb) + } + + var h = { cookie: 'AuthSession=' + this.token.AuthSession } + , u = url.resolve(this.couch, '/_session') + , req = { uri: u, headers: h, json: true } + + request.del(req, function (er, res, data) { + if (er || res.statusCode !== 200) { + return cb(er, res, data) + } + + this.token = null + if (this.tokenDel) this.tokenDel() + cb(er, res, data) + }.bind(this)) +} + +function valid (token) { + var d = token && token.expires + return token && token.expires > Date.now() +} + +function sha (s) { + return crypto.createHash("sha1").update(s).digest("hex") +} diff --git a/deps/npm/node_modules/couch-login/package.json b/deps/npm/node_modules/couch-login/package.json new file mode 100644 index 0000000000..f39660aace --- /dev/null +++ b/deps/npm/node_modules/couch-login/package.json @@ -0,0 +1,27 @@ +{ + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "name": "couch-login", + "description": "A module for doing logged-in requests to a couchdb server", + "version": "0.1.6", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/couch-login.git" + }, + "main": "couch-login.js", + "scripts": { + "test": "tap test/*.js" + }, + "dependencies": { + "request": "~2.9.202" + }, + "devDependencies": { + "tap": "~0.2.4" + }, + "readme": "# couch-login\n\nThis module lets you log into couchdb to get a session token, then make\nrequests using that session. It is basically just a thin wrapper around\n[@mikeal's request module](https://github.com/mikeal/request).\n\nThis is handy if you want a user to take actions in a couchdb database\non behalf of a user, without having to store their couchdb username and\npassword anywhere. (You do need to store the AuthSession token\nsomewhere, though.)\n\n## Usage\n\n```javascript\nvar CouchLogin = require('couch-login')\n\n// Nothing about this module is http-server specific of course.\n// You could also use it to do authenticated requests against\n// a couchdb using sessions and storing the token somewhere else.\n\nhttp.createServer(function (req, res) {\n var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')\n\n // .. look up the token in the user's session or whatever ..\n // Look at couch.decorate(req, res) for more on doing that\n // automatically, below.\n\n if (sessionToken) {\n // this user already logged in.\n couch.token = sessionToken\n\n // now we can do things on their behalf, like:\n // 1. View their session info.\n // like doing request.get({ uri: couch + '/_session', ... })\n // but with the cookie and whatnot\n\n couch.get('/_session', function (er, resp, data) {\n // er = some kind of communication error.\n // resp = response object from the couchdb request.\n // data = parsed JSON response body.\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // now we have the session info, we know who this user is.\n // hitting couchdb for this on every request is kinda costly,\n // so maybe you should store the username wherever you're storing\n // the sessionToken. RedSess is a good util for this, if you're\n // into redis. And if you're not into redis, you're crazy,\n // because it is awesome.\n\n // now let's get the user record.\n // note that this will 404 for anyone other than the user,\n // unless they're a server admin.\n couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)\n\n // PUTs and DELETEs will also use their session, of course, so\n // your validate_doc_update's will see their info in userCtx\n })\n\n } else {\n // don't have a sessionToken.\n // get a username and password from the post body or something.\n // maybe redirect to a /login page or something to ask for that.\n var login = { name: name, password: password }\n couch.login(login, function (er, resp, data) {\n // again, er is an error, resp is the response obj, data is the json\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // the data is something like\n // {\"ok\":true,\"name\":\"testuser\",\"roles\":[]}\n // and couch.token is the token you'll need to save somewhere.\n\n // at this point, you can start making authenticated requests to\n // couchdb, or save data in their session, or do whatever it is\n // that you need to do.\n\n res.statusCode = 200\n res.write(\"Who's got two thumbs and just logged you into couch?\\n\")\n setTimeout(function () {\n res.end(\"THIS GUY!\")\n }, 500)\n })\n }\n})\n```\n\n## Class: CouchLogin\n### new CouchLogin(couchdbUrl, token)\n\nCreate a new CouchLogin object bound to the couchdb url.\n\nIn addition to these, the `get`, `post`, `put`, and `del` methods all\nproxy to the associated method on [request](https://github.com/mikeal/request).\n\nHowever, as you'll note in the example above, only the pathname portion\nof the url is required. Urls will be appended to the couchdb url passed\ninto the constructor.\n\nIf you have to talk to more than one couchdb, then you'll need more than\none CouchLogin object, for somewhat obvious reasons.\n\nAll callbacks get called with the following arguments, which are exactly\nidentical to the arguments passed to a `request` callback.\n\n* `er` {Error | null} Set if a communication error happens.\n* `resp` {HTTP Response} The response from the request to couchdb\n* `data` {Object} The parsed JSON data from couch\n\nIf the token is the string \"anonymous\", then it will not attempt to log\nin before making requests. If the token is not \"anonymous\", then it\nmust be an object with the appropriate fields.\n\n### couch.token\n\n* {Object}\n\nAn object representing the couchdb session token. (Basically just a\ncookie and a timeout.)\n\nIf the token has already timed out, then setting it will have no effect.\n\n### couch.tokenSet\n\nIf set, this method is called whenever the token is saved.\n\nFor example, you could assign a function to this method to save the\ntoken into a redis session, a cookie, or in some other database.\n\nTakes a callback which should be called when the token is saved.\n\n### couch.tokenGet\n\nIf set, this method is called to look up the token on demand.\n\nThe inverse of couch.tokenSet. Takes a callback which is called with\nthe `cb(er || null, token)`.\n\n### couch.tokenDel\n\nIf set, this method is called to delete the token when it should be\ndiscarded.\n\nRelated to tokenGet and tokenSet. Takes a callback which should be\ncalled when the token is deleted.\n\n### couch.anonymous()\n\nReturn a new CouchLogin object that points at the same couchdb server,\nbut doesn't try to log in before making requests.\n\nThis is handy for situations where the user is not logged in at the\nmoment, but a request needs to be made anyway, and does not require\nauthorization.\n\n### couch.login(auth, callback)\n\n* `auth` {Object} The login details\n * `name` {String}\n * `password` {String}\n* `callback` {Function}\n\nWhen the callback is called, the `couch.token` will already have been\nset (assuming it worked!), so subsequent requests will be done as that\nuser.\n\n### couch.get(path, callback)\n\nGET the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.del(path, callback)\n\nDELETE the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.post(path, data, callback)\n\nPOST the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.put(path, data, callback)\n\nPUT the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.changePass(newAuth, callback)\n\nMust already be logged in. Updates the `_users` document with new salt\nand hash, and re-logs in with the new credentials. Callback is called\nwith the same arguments as login, or the first step of the process that\nfailed.\n\n### couch.signup(userData, callback)\n\nCreate a new user account. The userData must contain at least a `name`\nand `password` field. Any additional data will be copied to the user\nrecord. The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and\n`date` fields are generated.\n\nAlso signs in as the newly created user, on successful account creation.\n\n### couch.deleteAccount(name, callback)\n\nDeletes a user account. If not logged in as the user, or a server\nadmin, then the request will fail.\n\nNote that this immediately invalidates any session tokens for the\ndeleted user account. If you are deleting the user's record, then you\nought to follow this with `couch.logout(callback)` so that it won't try\nto re-use the invalid session.\n\n### couch.logout(callback)\n\nDelete the session out of couchdb. This makes the token permanently\ninvalid, and deletes it.\n\n### couch.decorate(req, res)\n\nSet up `req.couch` and `res.couch` as references to this couch login\ninstance.\n\nAdditionall, if `req.session` or `res.session` is set, then it'll call\n`session.get('couch_token', cb)` as the tokenGet method,\n`session.set('couch_token', token, cb)` as the tokenSet method, and\n`session.del('couch_token', cb)` as the tokenDel method.\n\nThis works really nice with\n[RedSess](https://github.com/isaacs/redsess).\n", + "_id": "couch-login@0.1.6", + "_from": "couch-login@~0.1.6" +} diff --git a/deps/npm/node_modules/couch-login/test/basic.js b/deps/npm/node_modules/couch-login/test/basic.js new file mode 100644 index 0000000000..b81a5e61f9 --- /dev/null +++ b/deps/npm/node_modules/couch-login/test/basic.js @@ -0,0 +1,286 @@ +var tap = require('tap') +, CouchLogin = require('../couch-login.js') + +// Yeah, go ahead and abuse my staging server, whatevs. + +var auth = { name: 'testuser', password: 'test' } +, newAuth = { name: 'testuser', password: 'asdfasdf' } +, couch = new CouchLogin('https://isaacs-staging.couch.xxx/') +, u = '/_users/org.couchdb.user:' + auth.name +, userRecordMarker + +// simulate the 'must change password on next login' thing +newAuth.mustChangePass = true +auth.mustChangePass = false + + +function okStatus (t, res) { + var x = { found: res.statusCode, wanted: 'around 200' } + var r = res.statusCode + x.ok = (r >= 200 && r < 300) + return t.ok(x.ok, 'Status code should be 200-ish', x) +} + +tap.test('login', function (t) { + couch.login(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.deepEqual(data, { ok: true, name: 'testuser', roles: [] }) + t.ok(couch.token) + t.deepEqual(couch.token, + { AuthSession: couch.token && couch.token.AuthSession, + version: '1', + expires: couch.token && couch.token.expires, + path: '/', + httponly: true }) + t.ok(couch.token, 'has token') + t.end() + }) +}) + +var userRecord +tap.test('get', function (t) { + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + t.ok(data, 'data') + t.ok(couch.token, 'token') + userRecord = data + okStatus(t, res) + t.end() + }) +}) + +var userRecordMarker = require('crypto').randomBytes(30).toString('base64') +tap.test('add key to user record', function (t) { + userRecord.testingCouchLogin = userRecordMarker + var revved = u + '?rev=' + userRecord._rev + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + // get again so we have the current rev + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data) + t.ok(userRecord) + t.equal(data.testingCouchLogin, userRecord.testingCouchLogin) + userRecord = data + t.end() + }) + }) +}) + +tap.test('remove key', function (t) { + var revved = u + '?rev=' + userRecord._rev + delete userRecord.testingCouchLogin + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(couch.token, 'token') + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + userRecord = data + t.end() + }) + }) +}) + +var crypto = require('crypto') +function sha (s) { + return crypto.createHash("sha1").update(s).digest("hex") +} + +tap.test('change password manually', function (t) { + var revved = u + '?rev=' + userRecord._rev + , newPass = newAuth.password + , newSalt = 'test-salt-two' + , newSha = sha(newPass + newSalt) + + userRecord.salt = newSalt + userRecord.password_sha = newSha + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + // changing password invalidates session. + // need to re-login + couch.login(newAuth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + userRecord = data + t.end() + }) + }) + }) +}) + +tap.test('change password back manually', function (t) { + var revved = u + '?rev=' + userRecord._rev + , newPass = auth.password + , newSalt = 'test-salt' + , newSha = sha(newPass + newSalt) + + userRecord.salt = newSalt + userRecord.password_sha = newSha + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + + couch.login(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + userRecord = data + t.end() + }) + }) + }) +}) + +tap.test('change password easy', function (t) { + couch.changePass(newAuth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + t.equal(data.mustChangePass, true) + userRecord = data + t.end() + }) + }) +}) + +tap.test('change password back easy', function (t) { + couch.changePass(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + t.equal(data.mustChangePass, false) + userRecord = data + t.end() + }) + }) +}) + + +tap.test('logout', function (t) { + couch.logout(function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.notOk(couch.token, 'token') + t.end() + }) +}) + +// now try some logged out monkey business! +tap.test('logged out post', function (t) { + couch.post('/yeah-right', {foo: 100}, function (er, res, data) { + t.ok(er, 'should get an error') + t.notOk(couch.token, 'token') + t.end() + }) +}) + +tap.test('anonymous put', function (t) { + var guy = couch.anonymous() + guy.put('/remember', {november:5}, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + t.equal(res.statusCode, 401) + t.deepEqual(data, { error: 'unauthorized' + , reason: 'You are not a server admin.' }) + t.end() + }) +}) + +tap.test('anonymous get', function (t) { + var guy = couch.anonymous() + guy.get('/', function (er, res, data) { + t.ifError(er) + if (er) return t.end() + t.equal(res.statusCode, 200) + t.deepEqual(data, { couchdb: 'Welcome', version: '1.2.0' }) + t.end() + }) +}) + + + +var signupUser = { name: 'test-user-signup', password: 'signup-test' } + +tap.test('sign up as new user', function (t) { + couch.signup(signupUser, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.has(data, + { _id: 'org.couchdb.user:test-user-signup', + name: 'test-user-signup', + roles: [], + type: 'user' }) + t.ok(data._rev, 'rev') + t.ok(data.date, 'date') + t.ok(data.password_sha, 'hash') + t.ok(data.salt, 'salt') + t.ok(couch.token, 'token') + // now delete account + var name = signupUser.name + couch.deleteAccount(name, function (er, res, data) { + t.ifError(er, 'should be no error deleting account') + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.end() + }) + }) +}) diff --git a/deps/npm/node_modules/couch-login/test/registry.js b/deps/npm/node_modules/couch-login/test/registry.js new file mode 100644 index 0000000000..56a21f6b18 --- /dev/null +++ b/deps/npm/node_modules/couch-login/test/registry.js @@ -0,0 +1,254 @@ +// Should be able to use this module to log into the registry, as well. + +var tap = require('tap') +, CouchLogin = require('../couch-login.js') + +// Yeah, go ahead and abuse my staging server, whatevs. + +var auth = { name: 'testuser', password: 'test' } +, newAuth = { name: 'testuser', password: 'asdfasdf' } +, couch = new CouchLogin('https://staging.npmjs.org/') +, u = '/_users/org.couchdb.user:' + auth.name +, userRecordMarker + +// simulate the 'must change password on next login' thing +newAuth.mustChangePass = true +auth.mustChangePass = false + + +function okStatus (t, res) { + var x = { found: res.statusCode, wanted: 'around 200' } + var r = res.statusCode + x.ok = (r >= 200 && r < 300) + return t.ok(x.ok, 'Status code should be 200-ish', x) +} + +tap.test('login', function (t) { + couch.login(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.deepEqual(data, { ok: true, name: 'testuser', roles: [] }) + t.ok(couch.token) + t.deepEqual(couch.token, + { AuthSession: couch.token && couch.token.AuthSession, + version: '1', + expires: couch.token && couch.token.expires, + path: '/', + httponly: true }) + t.ok(couch.token, 'has token') + t.end() + }) +}) + +var userRecord +tap.test('get', function (t) { + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + t.ok(data, 'data') + t.ok(couch.token, 'token') + userRecord = data + okStatus(t, res) + t.end() + }) +}) + +var userRecordMarker = require('crypto').randomBytes(30).toString('base64') +tap.test('add key to user record', function (t) { + userRecord.testingCouchLogin = userRecordMarker + var revved = u + '?rev=' + userRecord._rev + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + // get again so we have the current rev + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data) + t.ok(userRecord) + t.equal(data.testingCouchLogin, userRecord.testingCouchLogin) + userRecord = data + t.end() + }) + }) +}) + +tap.test('remove key', function (t) { + var revved = u + '?rev=' + userRecord._rev + delete userRecord.testingCouchLogin + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(couch.token, 'token') + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + userRecord = data + t.end() + }) + }) +}) + +var crypto = require('crypto') +function sha (s) { + return crypto.createHash("sha1").update(s).digest("hex") +} + +tap.test('change password manually', function (t) { + var revved = u + '?rev=' + userRecord._rev + , newPass = newAuth.password + , newSalt = 'test-salt-two' + , newSha = sha(newPass + newSalt) + + userRecord.salt = newSalt + userRecord.password_sha = newSha + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + // changing password invalidates session. + // need to re-login + couch.login(newAuth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + userRecord = data + t.end() + }) + }) + }) +}) + +tap.test('change password back manually', function (t) { + var revved = u + '?rev=' + userRecord._rev + , newPass = auth.password + , newSalt = 'test-salt' + , newSha = sha(newPass + newSalt) + + userRecord.salt = newSalt + userRecord.password_sha = newSha + couch.put(revved, userRecord, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + + couch.login(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + userRecord = data + t.end() + }) + }) + }) +}) + +tap.test('change password easy', function (t) { + couch.changePass(newAuth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + t.equal(data.mustChangePass, true) + userRecord = data + t.end() + }) + }) +}) + +tap.test('change password back easy', function (t) { + couch.changePass(auth, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + + couch.get(u, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.ok(couch.token, 'token') + t.equal(data.testingCouchLogin, undefined) + t.equal(data.mustChangePass, false) + userRecord = data + t.end() + }) + }) +}) + + +tap.test('logout', function (t) { + couch.logout(function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.notOk(couch.token, 'token') + t.end() + }) +}) + +var signupUser = { name: 'test-user-signup', password: 'signup-test' } + +tap.test('sign up as new user', function (t) { + couch.signup(signupUser, function (er, res, data) { + t.ifError(er) + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.has(data, + { _id: 'org.couchdb.user:test-user-signup', + name: 'test-user-signup', + roles: [], + type: 'user' }) + t.ok(data._rev, 'rev') + t.ok(data.date, 'date') + t.ok(data.password_sha, 'hash') + t.ok(data.salt, 'salt') + t.ok(couch.token, 'token') + // now delete account + var name = signupUser.name + couch.deleteAccount(name, function (er, res, data) { + t.ifError(er, 'should be no error deleting account') + if (er) return t.end() + okStatus(t, res) + t.ok(data, 'data') + t.end() + }) + }) +}) diff --git a/deps/npm/node_modules/fstream-npm/example/bundle.js b/deps/npm/node_modules/fstream-npm/example/bundle.js new file mode 100644 index 0000000000..159e4f7b65 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/bundle.js @@ -0,0 +1,13 @@ +// this example will bundle every dependency +var P = require("../") +P({ path: "./" }) + .on("package", bundleIt) + .on("entry", function (e) { + console.error(e.constructor.name, e.path.substr(e.root.dirname.length + 1)) + e.on("package", bundleIt) + }) + +function bundleIt (p) { + p.bundleDependencies = Object.keys(p.dependencies || {}) +} + diff --git a/deps/npm/node_modules/fstream-npm/example/dir-tar.js b/deps/npm/node_modules/fstream-npm/example/dir-tar.js new file mode 100644 index 0000000000..f2bad92e0d --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/dir-tar.js @@ -0,0 +1,19 @@ +// this will show what ends up in the fstream-npm package +var P = require("fstream").DirReader +var tar = require("tar") +function f (entry) { + return entry.basename !== ".git" +} + +new P({ path: "./", type: "Directory", Directory: true, filter: f }) + .on("package", function (p) { + console.error("package", p) + }) + .on("ignoreFile", function (e) { + console.error("ignoreFile", e) + }) + .on("entry", function (e) { + console.error(e.constructor.name, e.path.substr(e.root.path.length + 1)) + }) + .pipe(tar.Pack()) + .pipe(process.stdout) diff --git a/deps/npm/node_modules/fstream-npm/example/dir.js b/deps/npm/node_modules/fstream-npm/example/dir.js new file mode 100644 index 0000000000..75e2eed0ff --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/dir.js @@ -0,0 +1,25 @@ +// this will show what ends up in the fstream-npm package +var P = require("../") +var DW = require("fstream").DirWriter + +var target = new DW({ Directory: true, type: "Directory", + path: __dirname + "/output"}) + +function f (entry) { + return entry.basename !== ".git" +} + +P({ path: "./", type: "Directory", isDirectory: true, filter: f }) + .on("package", function (p) { + console.error("package", p) + }) + .on("ignoreFile", function (e) { + console.error("ignoreFile", e) + }) + .on("entry", function (e) { + console.error(e.constructor.name, e.path) + }) + .pipe(target) + .on("end", function () { + console.error("ended") + }) diff --git a/deps/npm/node_modules/fstream-npm/example/example.js b/deps/npm/node_modules/fstream-npm/example/example.js new file mode 100644 index 0000000000..0b53931caa --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/example.js @@ -0,0 +1,12 @@ +// this will show what ends up in the fstream-npm package +var P = require("../") +P({ path: "./" }) + .on("package", function (p) { + console.error("package", p) + }) + .on("ignoreFile", function (e) { + console.error("ignoreFile", e) + }) + .on("entry", function (e) { + console.error(e.constructor.name, e.path.substr(e.root.dirname.length + 1)) + }) diff --git a/deps/npm/node_modules/fstream-npm/example/ig-tar.js b/deps/npm/node_modules/fstream-npm/example/ig-tar.js new file mode 100644 index 0000000000..c1db81050a --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/ig-tar.js @@ -0,0 +1,19 @@ +// this will show what ends up in the fstream-npm package +var P = require("fstream-ignore") +var tar = require("tar") +function f (entry) { + return entry.basename !== ".git" +} + +new P({ path: "./", type: "Directory", Directory: true, filter: f }) + .on("package", function (p) { + console.error("package", p) + }) + .on("ignoreFile", function (e) { + console.error("ignoreFile", e) + }) + .on("entry", function (e) { + console.error(e.constructor.name, e.path.substr(e.root.path.length + 1)) + }) + .pipe(tar.Pack()) + .pipe(process.stdout) diff --git a/deps/npm/node_modules/fstream-npm/example/tar.js b/deps/npm/node_modules/fstream-npm/example/tar.js new file mode 100644 index 0000000000..f9bcaea816 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/example/tar.js @@ -0,0 +1,25 @@ +// this will show what ends up in the fstream-npm package +var P = require("../") +var tar = require("tar") +function f () { + return true +} +// function f (entry) { +// return entry.basename !== ".git" +// } + +new P({ path: "./", type: "Directory", isDirectory: true, filter: f }) + .on("package", function (p) { + console.error("package", p) + }) + .on("ignoreFile", function (e) { + console.error("ignoreFile", e) + }) + .on("entry", function (e) { + console.error(e.constructor.name, e.path) + }) + .on("end", function () { + console.error("ended") + }) + .pipe(tar.Pack()) + .pipe(process.stdout) diff --git a/deps/npm/node_modules/fstream-npm/fstream-npm.js b/deps/npm/node_modules/fstream-npm/fstream-npm.js index 43c0f169f6..5678347b08 100644 --- a/deps/npm/node_modules/fstream-npm/fstream-npm.js +++ b/deps/npm/node_modules/fstream-npm/fstream-npm.js @@ -90,6 +90,9 @@ Packer.prototype.applyIgnores = function (entry, partial, entryObj) { // package.json files can never be ignored. if (entry === "package.json") return true + // readme files should never be ignored. + if (entry.match(/^readme(\.[^\.]*)$/i)) return true + // special rules. see below. if (entry === "node_modules" && this.packageRoot) return true diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js new file mode 100644 index 0000000000..ff4534289c --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/example/basic.js @@ -0,0 +1,13 @@ +var Ignore = require("../") +Ignore({ path: __dirname + , ignoreFiles: [".ignore", ".gitignore"] + }) + .on("child", function (c) { + console.error(c.path.substr(c.root.path.length + 1)) + c.on("ignoreFile", onIgnoreFile) + }) + .on("ignoreFile", onIgnoreFile) + +function onIgnoreFile (e) { + console.error("adding ignore file", e.path) +} diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/package.json b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/package.json index ed82c65433..773e797d6c 100644 --- a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/package.json +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/package.json @@ -25,18 +25,7 @@ "rimraf": "", "mkdirp": "" }, - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, + "readme": "# fstream-ignore\n\nA fstream DirReader that filters out files that match globs in `.ignore`\nfiles throughout the tree, like how git ignores files based on a\n`.gitignore` file.\n\nHere's an example:\n\n```javascript\nvar Ignore = require(\"fstream-ignore\")\nIgnore({ path: __dirname\n , ignoreFiles: [\".ignore\", \".gitignore\"]\n })\n .on(\"child\", function (c) {\n console.error(c.path.substr(c.root.path.length + 1))\n })\n .pipe(tar.Pack())\n .pipe(fs.createWriteStream(\"foo.tar\"))\n```\n\nThis will tar up the files in __dirname into `foo.tar`, ignoring\nanything matched by the globs in any .iginore or .gitignore file.\n", "_id": "fstream-ignore@0.0.5", - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "_engineSupported": true, - "_npmVersion": "1.1.23", - "_nodeVersion": "v0.7.10-pre", - "_defaultsLoaded": true, "_from": "fstream-ignore@~0.0.5" } diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore new file mode 100644 index 0000000000..773679d45e --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.ignore @@ -0,0 +1,2 @@ +.gitignore +.*.swp diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore new file mode 100644 index 0000000000..1b26d0de59 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/.npmignore @@ -0,0 +1 @@ +*/a diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js new file mode 100644 index 0000000000..7d7e4a1b78 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/00-setup.js @@ -0,0 +1,71 @@ +// The test fixtures work like this: +// These dirs are all created: {a,b,c}/{a,b,c}/{a,b,c}/ +// in each one, these files are created: +// {.,}{a,b,c}{a,b,c}{a,b,c} +// +// So, there'll be a/b/c/abc, a/b/c/aba, etc., and dot-versions of each. +// +// Each test then writes their own ignore file rules for their purposes, +// and is responsible for removing them afterwards. + +var mkdirp = require("mkdirp") +var path = require("path") +var i = 0 +var tap = require("tap") +var fs = require("fs") +var rimraf = require("rimraf") +var fixtures = path.resolve(__dirname, "fixtures") + +var chars = ['a', 'b', 'c'] +var dirs = [] + +for (var i = 0; i < 3; i ++) { + for (var j = 0; j < 3; j ++) { + for (var k = 0; k < 3; k ++) { + dirs.push(chars[i] + '/' + chars[j] + '/' + chars[k]) + } + } +} + +var files = [] + +for (var i = 0; i < 3; i ++) { + for (var j = 0; j < 3; j ++) { + for (var k = 0; k < 3; k ++) { + files.push(chars[i] + chars[j] + chars[k]) + files.push('.' + chars[i] + chars[j] + chars[k]) + } + } +} + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "fixtures"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) + +tap.test("create fixtures", function (t) { + dirs.forEach(function (dir) { + dir = path.resolve(fixtures, dir) + t.test("mkdir "+dir, function (t) { + mkdirp(dir, function (er) { + t.ifError(er, "mkdir "+dir) + if (er) return t.end() + + files.forEach(function (file) { + file = path.resolve(dir, file) + t.test("writeFile "+file, function (t) { + fs.writeFile(file, path.basename(file), function (er) { + t.ifError(er, "writing "+file) + t.end() + }) + }) + }) + t.end() + }) + }) + }) + t.end() +}) + diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js new file mode 100644 index 0000000000..3718076eed --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/basic.js @@ -0,0 +1,28 @@ +var IgnoreFile = require("../") + +// set the ignores just for this test +var c = require("./common.js") +c.ignores({ "a/.basic-ignore": ["b/", "aca"] }) + +// the files that we expect to not see +var notAllowed = + [ /^\/a\/b\/.*/ + , /^\/a\/.*\/aca$/ ] + + +require("tap").test("basic ignore rules", function (t) { + t.pass("start") + + IgnoreFile({ path: __dirname + "/fixtures" + , ignoreFiles: [".basic-ignore"] }) + .on("ignoreFile", function (e) { + console.error("ignore file!", e) + }) + .on("child", function (e) { + var p = e.path.substr(e.root.path.length) + notAllowed.forEach(function (na) { + t.dissimilar(p, na) + }) + }) + .on("close", t.end.bind(t)) +}) diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js new file mode 100644 index 0000000000..0e6cd989c9 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/common.js @@ -0,0 +1,40 @@ +if (require.main === module) { + console.log("0..1") + console.log("ok 1 trivial pass") + return +} + +var fs = require("fs") +var path = require("path") +var rimraf = require("rimraf") + +exports.ignores = ignores +exports.writeIgnoreFile = writeIgnoreFile +exports.writeIgnores = writeIgnores +exports.clearIgnores = clearIgnores + +function writeIgnoreFile (file, rules) { + file = path.resolve(__dirname, "fixtures", file) + if (Array.isArray(rules)) { + rules = rules.join("\n") + } + fs.writeFileSync(file, rules) + console.error(file, rules) +} + +function writeIgnores (set) { + Object.keys(set).forEach(function (f) { + writeIgnoreFile(f, set[f]) + }) +} + +function clearIgnores (set) { + Object.keys(set).forEach(function (file) { + fs.unlinkSync(path.resolve(__dirname, "fixtures", file)) + }) +} + +function ignores (set) { + writeIgnores(set) + process.on("exit", clearIgnores.bind(null, set)) +} diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js new file mode 100644 index 0000000000..43eec4b546 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/ignore-most.js @@ -0,0 +1,41 @@ +// ignore most things +var IgnoreFile = require("../") + +// set the ignores just for this test +var c = require("./common.js") +c.ignores({ ".ignore": ["*", "!a/b/c/.abc", "!/c/b/a/cba"] }) + +// the only files we expect to see +var expected = + [ "/a/b/c/.abc" + , "/a" + , "/a/b" + , "/a/b/c" + , "/c/b/a/cba" + , "/c" + , "/c/b" + , "/c/b/a" ] + +require("tap").test("basic ignore rules", function (t) { + t.pass("start") + + IgnoreFile({ path: __dirname + "/fixtures" + , ignoreFiles: [".ignore"] }) + .on("ignoreFile", function (e) { + console.error("ignore file!", e) + }) + .on("child", function (e) { + var p = e.path.substr(e.root.path.length) + var i = expected.indexOf(p) + if (i === -1) { + t.fail("unexpected file found", {file: p}) + } else { + t.pass(p) + expected.splice(i, 1) + } + }) + .on("close", function () { + t.notOk(expected.length, "all expected files should be seen") + t.end() + }) +}) diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js new file mode 100644 index 0000000000..a9ede59ca7 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/nested-ignores.js @@ -0,0 +1,51 @@ +// ignore most things +var IgnoreFile = require("../") + +// set the ignores just for this test +var c = require("./common.js") +c.ignores( + { ".ignore": ["*", "a", "c", "!a/b/c/.abc", "!/c/b/a/cba"] + , "a/.ignore": [ "!*", ".ignore" ] // unignore everything + , "a/a/.ignore": [ "*" ] // re-ignore everything + , "a/b/.ignore": [ "*", "!/c/.abc" ] // original unignore + , "a/c/.ignore": [ "*" ] // ignore everything again + , "c/b/a/.ignore": [ "!cba", "!.cba", "!/a{bc,cb}" ] + }) + +// the only files we expect to see +var expected = + [ "/a" + , "/a/a" + , "/a/b" + , "/a/b/c" + , "/a/b/c/.abc" + , "/a/c" + , "/c" + , "/c/b" + , "/c/b/a" + , "/c/b/a/cba" + , "/c/b/a/.cba" + , "/c/b/a/abc" + , "/c/b/a/acb" ] + +require("tap").test("basic ignore rules", function (t) { + t.pass("start") + + IgnoreFile({ path: __dirname + "/fixtures" + , ignoreFiles: [".ignore"] }) + .on("child", function (e) { + var p = e.path.substr(e.root.path.length) + var i = expected.indexOf(p) + if (i === -1) { + console.log("not ok "+p) + t.fail("unexpected file found", {found: p}) + } else { + t.pass(p) + expected.splice(i, 1) + } + }) + .on("close", function () { + t.deepEqual(expected, [], "all expected files should be seen") + t.end() + }) +}) diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js new file mode 100644 index 0000000000..5812354df7 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/unignore-child.js @@ -0,0 +1,38 @@ +// ignore most things +var IgnoreFile = require("../") + +// set the ignores just for this test +var c = require("./common.js") +c.ignores({ ".ignore": ["*", "a", "c", "!a/b/c/.abc", "!/c/b/a/cba"] }) + +// the only files we expect to see +var expected = + [ "/a/b/c/.abc" + , "/a" + , "/a/b" + , "/a/b/c" + , "/c/b/a/cba" + , "/c" + , "/c/b" + , "/c/b/a" ] + +require("tap").test("basic ignore rules", function (t) { + t.pass("start") + + IgnoreFile({ path: __dirname + "/fixtures" + , ignoreFiles: [".ignore"] }) + .on("child", function (e) { + var p = e.path.substr(e.root.path.length) + var i = expected.indexOf(p) + if (i === -1) { + t.fail("unexpected file found", {f: p}) + } else { + t.pass(p) + expected.splice(i, 1) + } + }) + .on("close", function () { + t.notOk(expected.length, "all expected files should be seen") + t.end() + }) +}) diff --git a/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js new file mode 100644 index 0000000000..82f064a421 --- /dev/null +++ b/deps/npm/node_modules/fstream-npm/node_modules/fstream-ignore/test/zz-cleanup.js @@ -0,0 +1,10 @@ +var tap = require("tap") +, rimraf = require("rimraf") +, path = require("path") + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "fixtures"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) diff --git a/deps/npm/node_modules/fstream-npm/package.json b/deps/npm/node_modules/fstream-npm/package.json index fa46c74e6c..edb1922487 100644 --- a/deps/npm/node_modules/fstream-npm/package.json +++ b/deps/npm/node_modules/fstream-npm/package.json @@ -6,7 +6,7 @@ }, "name": "fstream-npm", "description": "fstream class for creating npm packages", - "version": "0.1.0", + "version": "0.1.1", "repository": { "type": "git", "url": "git://github.com/isaacs/fstream-npm.git" @@ -17,19 +17,7 @@ "inherits": "" }, "license": "BSD", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "_id": "fstream-npm@0.1.0", - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "_engineSupported": true, - "_npmVersion": "1.1.23", - "_nodeVersion": "v0.7.10-pre", - "_defaultsLoaded": true, + "readme": "# fstream-npm\n\nThis is an fstream DirReader class that will read a directory and filter\nthings according to the semantics of what goes in an npm package.\n\nFor example:\n\n```javascript\n// This will print out all the files that would be included\n// by 'npm publish' or 'npm install' of this directory.\n\nvar FN = require(\"fstream-npm\")\nFN({ path: \"./\" })\n .on(\"child\", function (e) {\n console.error(e.path.substr(e.root.path.length + 1))\n })\n```\n\n", + "_id": "fstream-npm@0.1.1", "_from": "fstream-npm@0.1" } diff --git a/deps/npm/node_modules/glob/examples/g.js b/deps/npm/node_modules/glob/examples/g.js new file mode 100644 index 0000000000..be122df002 --- /dev/null +++ b/deps/npm/node_modules/glob/examples/g.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "test/a/**/[cg]/../[cg]" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/deps/npm/node_modules/glob/examples/usr-local.js b/deps/npm/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000000..327a425e47 --- /dev/null +++ b/deps/npm/node_modules/glob/examples/usr-local.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "{./*/*,/*,/usr/local/*}" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/deps/npm/node_modules/glob/test/00-setup.js b/deps/npm/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000000..2b606432a1 --- /dev/null +++ b/deps/npm/node_modules/glob/test/00-setup.js @@ -0,0 +1,61 @@ +// just a little pre-run script to set up the fixtures. +// zz-finish cleans it up + +var mkdirp = require("mkdirp") +var path = require("path") +var i = 0 +var tap = require("tap") +var fs = require("fs") +var rimraf = require("rimraf") + +var files = +[ "a/.abcdef/x/y/z/a" +, "a/abcdef/g/h" +, "a/abcfed/g/h" +, "a/b/c/d" +, "a/bc/e/f" +, "a/c/d/c/b" +, "a/cb/e/f" +] + +var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") +var symlinkFrom = "../.." + +files = files.map(function (f) { + return path.resolve(__dirname, f) +}) + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) + +files.forEach(function (f) { + tap.test(f, function (t) { + var d = path.dirname(f) + mkdirp(d, 0755, function (er) { + if (er) { + t.fail(er) + return t.bailout() + } + fs.writeFile(f, "i like tests", function (er) { + t.ifError(er, "make file") + t.end() + }) + }) + }) +}) + +tap.test("symlinky", function (t) { + var d = path.dirname(symlinkTo) + console.error("mkdirp", d) + mkdirp(d, 0755, function (er) { + t.ifError(er) + fs.symlink(symlinkFrom, symlinkTo, function (er) { + t.ifError(er, "make symlink") + t.end() + }) + }) +}) diff --git a/deps/npm/node_modules/glob/test/bash-comparison.js b/deps/npm/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000000..fbadc314cc --- /dev/null +++ b/deps/npm/node_modules/glob/test/bash-comparison.js @@ -0,0 +1,119 @@ +// basic test +// show that it does the same thing by default as the shell. +var tap = require("tap") +, child_process = require("child_process") + +// put more patterns here. +, globs = + [ + "test/a/*/+(c|g)/./d" + ,"test/a/**/[cg]/../[cg]" + ,"test/a/{b,c,d,e,f}/**/g" + ,"test/a/b/**" + ,"test/**/g" + ,"test/a/abc{fed,def}/g/h" + ,"test/a/abc{fed/g,def}/**/" + ,"test/a/abc{fed/g,def}/**///**/" + ,"test/**/a/**/" + ,"test/+(a|b|c)/a{/,bc*}/**" + ,"test/*/*/*/f" + ,"test/**/f" + ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" + ,"{./*/*,/usr/local/*}" + ,"{/*,*}" // evil owl face! how you taunt me! + ] +, glob = require("../") +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +globs.forEach(function (pattern) { + var echoOutput + tap.test(pattern, function (t) { + var bashPattern = pattern + , cmd = "shopt -s globstar && " + + "shopt -s extglob && " + + "shopt -s nullglob && " + + // "shopt >&2; " + + "eval \'for i in " + bashPattern + "; do echo $i; done\'" + , cp = child_process.spawn("bash", ["-c",cmd]) + , out = [] + , globResult + cp.stdout.on("data", function (c) { + out.push(c) + }) + cp.stderr.on("data", function (c) { + process.stderr.write(c) + }) + cp.stdout.on("close", function () { + echoOutput = flatten(out) + if (!echoOutput) echoOutput = [] + else { + echoOutput = echoOutput.split(/\r*\n/).map(function (m) { + // Bash is a oddly inconsistent with slashes in the + // the results. This implementation is a bit more + // normalized. Account for this in the test results. + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort) + } + next() + }) + + glob(pattern, function (er, matches) { + // sort and unpark, just to match the shell results + matches = matches.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort) + + t.ifError(er, pattern + " should not error") + globResult = matches + next() + }) + + function next () { + if (!echoOutput || !globResult) return + + t.deepEqual(globResult, echoOutput, "should match shell") + t.end() + } + }) + + tap.test(pattern + " sync", function (t) { + var matches = glob.sync(pattern).map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort) + + t.deepEqual(matches, echoOutput, "should match shell") + t.end() + }) +}) + +function flatten (chunks) { + var s = 0 + chunks.forEach(function (c) { s += c.length }) + var out = new Buffer(s) + s = 0 + chunks.forEach(function (c) { + c.copy(out, s) + s += c.length + }) + + return out.toString().trim() +} diff --git a/deps/npm/node_modules/glob/test/cwd-test.js b/deps/npm/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000000..352c27efad --- /dev/null +++ b/deps/npm/node_modules/glob/test/cwd-test.js @@ -0,0 +1,55 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing cwd and searching for **/d", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('**/d', function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('a', function (t) { + glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'b/c/d', 'c/d' ]) + t.end() + }) + }) + + t.test('a/b', function (t) { + glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('a/b/', function (t) { + glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('.', function (t) { + glob('**/d', {cwd: process.cwd()}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/deps/npm/node_modules/glob/test/pause-resume.js b/deps/npm/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000000..481d1aae4c --- /dev/null +++ b/deps/npm/node_modules/glob/test/pause-resume.js @@ -0,0 +1,98 @@ +// show that no match events happen while paused. +var tap = require("tap") +, child_process = require("child_process") +// just some gnarly pattern with lots of matches +, pattern = "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" +, glob = require("../") +, Glob = glob.Glob +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort) +} + +function flatten (chunks) { + var s = 0 + chunks.forEach(function (c) { s += c.length }) + var out = new Buffer(s) + s = 0 + chunks.forEach(function (c) { + c.copy(out, s) + s += c.length + }) + + return out.toString().trim() +} +var bashResults +tap.test("get bash output", function (t) { + var bashPattern = pattern + , cmd = "shopt -s globstar && " + + "shopt -s extglob && " + + "shopt -s nullglob && " + + // "shopt >&2; " + + "eval \'for i in " + bashPattern + "; do echo $i; done\'" + , cp = child_process.spawn("bash", ["-c",cmd]) + , out = [] + , globResult + cp.stdout.on("data", function (c) { + out.push(c) + }) + cp.stderr.on("data", function (c) { + process.stderr.write(c) + }) + cp.stdout.on("close", function () { + bashResults = flatten(out) + if (!bashResults) return t.fail("Didn't get results from bash") + else { + bashResults = cleanResults(bashResults.split(/\r*\n/)) + } + t.ok(bashResults.length, "got some results") + t.end() + }) +}) + +var globResults = [] +tap.test("use a Glob object, and pause/resume it", function (t) { + var g = new Glob(pattern) + , paused = false + , res = [] + + g.on("match", function (m) { + t.notOk(g.paused, "must not be paused") + globResults.push(m) + g.pause() + t.ok(g.paused, "must be paused") + setTimeout(g.resume.bind(g), 1) + }) + + g.on("end", function (matches) { + t.pass("reached glob end") + globResults = cleanResults(globResults) + matches = cleanResults(matches) + t.deepEqual(matches, globResults, + "end event matches should be the same as match events") + + t.deepEqual(matches, bashResults, + "glob matches should be the same as bash results") + + t.end() + }) +}) + diff --git a/deps/npm/node_modules/glob/test/root-nomount.js b/deps/npm/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000000..3ac5979b05 --- /dev/null +++ b/deps/npm/node_modules/glob/test/root-nomount.js @@ -0,0 +1,39 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing root and searching for /b*/**", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) + }) + + t.test('a', function (t) { + glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/deps/npm/node_modules/glob/test/root.js b/deps/npm/node_modules/glob/test/root.js new file mode 100644 index 0000000000..5ccdd0e947 --- /dev/null +++ b/deps/npm/node_modules/glob/test/root.js @@ -0,0 +1,43 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing root and searching for /b*/**", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) + }) + + t.test('a', function (t) { + glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { + return path.join(path.resolve('a'), m) + })) + t.end() + }) + }) + + t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { + return path.join(path.resolve('a'), m) + })) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/deps/npm/node_modules/glob/test/zz-cleanup.js b/deps/npm/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000000..e085f0fa77 --- /dev/null +++ b/deps/npm/node_modules/glob/test/zz-cleanup.js @@ -0,0 +1,11 @@ +// remove the fixtures +var tap = require("tap") +, rimraf = require("rimraf") +, path = require("path") + +tap.test("cleanup fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "removed") + t.end() + }) +}) diff --git a/deps/npm/node_modules/graceful-fs/graceful-fs.js b/deps/npm/node_modules/graceful-fs/graceful-fs.js index ecbda31a5a..856fc66bf7 100644 --- a/deps/npm/node_modules/graceful-fs/graceful-fs.js +++ b/deps/npm/node_modules/graceful-fs/graceful-fs.js @@ -151,14 +151,6 @@ if (constants.hasOwnProperty('O_SYMLINK') && } -// lstat on windows, missing from early 0.5 versions -// replacing with stat isn't quite perfect, but good enough to get by. -if (process.platform === "win32" && !process.binding("fs").lstat) { - fs.lstat = fs.stat - fs.lstatSync = fs.statSync -} - - // lutimes implementation, or no-op if (!fs.lutimes) { if (constants.hasOwnProperty("O_SYMLINK")) { @@ -255,6 +247,22 @@ function chownErOk (er) { } +// if lchmod/lchown do not exist, then make them no-ops +if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + process.nextTick(cb) + } + fs.lchmodSync = function () {} +} +if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + process.nextTick(cb) + } + fs.lchownSync = function () {} +} + + + // on Windows, A/V software can lock the directory, causing this // to fail with an EACCES or EPERM if the directory contains newly diff --git a/deps/npm/node_modules/graceful-fs/package.json b/deps/npm/node_modules/graceful-fs/package.json index 757d3014c8..fe4de9e585 100644 --- a/deps/npm/node_modules/graceful-fs/package.json +++ b/deps/npm/node_modules/graceful-fs/package.json @@ -6,7 +6,7 @@ }, "name": "graceful-fs", "description": "fs monkey-patching to avoid EMFILE and other problems", - "version": "1.1.8", + "version": "1.1.9", "repository": { "type": "git", "url": "git://github.com/isaacs/node-graceful-fs.git" @@ -16,16 +16,7 @@ "node": ">=0.4.0" }, "devDependencies": {}, - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "_id": "graceful-fs@1.1.8", - "dependencies": {}, - "optionalDependencies": {}, - "_engineSupported": true, - "_npmVersion": "1.1.10", - "_nodeVersion": "v0.7.7-pre", - "_defaultsLoaded": true, + "readme": "Just like node's `fs` module, but it does an incremental back-off when\nEMFILE is encountered.\n\nUseful in asynchronous situations where one needs to try to open lots\nand lots of files.\n", + "_id": "graceful-fs@1.1.9", "_from": "graceful-fs@~1.1.1" } diff --git a/deps/npm/node_modules/init-package-json/example.js b/deps/npm/node_modules/init-package-json/example.js new file mode 100644 index 0000000000..ebab729cab --- /dev/null +++ b/deps/npm/node_modules/init-package-json/example.js @@ -0,0 +1,14 @@ +var init = require('./init-package-json.js') +var path = require('path') +var initFile = path.resolve(process.env.HOME, '.npm-init') +var dir = process.cwd() + +var npm = require('npm') +npm.load(function (er, npm) { + if (er) throw er + init(dir, initFile, npm.config.get(), function (er, data) { + if (er) throw er + console.log('written successfully') + }) +}) + diff --git a/deps/npm/node_modules/init-package-json/test/basic.input b/deps/npm/node_modules/init-package-json/test/basic.input new file mode 100644 index 0000000000..b41ba5040c --- /dev/null +++ b/deps/npm/node_modules/init-package-json/test/basic.input @@ -0,0 +1,15 @@ +var assert = require('assert') + +exports.name = prompt('name', package.name || basename) +exports.version = '1.2.5' +exports.description = prompt('description', package.description) +exports.author = 'me <em@i.l> (http://url)' +exports.scripts = package.scripts || {} +exports.scripts.test = 'make test' +exports.main = package.main || 'main.js' +exports.config = JSON.parse(JSON.stringify(config)) +try {delete exports.config.config}catch(e){} +try {delete exports.package.config}catch(e){} +try {delete exports.package.package}catch(e){} +try {delete exports.config.package}catch(e){} +exports.package = JSON.parse(JSON.stringify(package)) diff --git a/deps/npm/node_modules/init-package-json/test/basic.js b/deps/npm/node_modules/init-package-json/test/basic.js new file mode 100644 index 0000000000..e1c4486566 --- /dev/null +++ b/deps/npm/node_modules/init-package-json/test/basic.js @@ -0,0 +1,35 @@ +var tap = require('tap') +var init = require('../') +var rimraf = require('rimraf') + +tap.test('the basics', function (t) { + var i = __dirname + '/basic.input' + var dir = __dirname + init(dir, i, {foo:'bar'}, function (er, data) { + if (er) throw er + var expect = + { name: 'the-name', + version: '1.2.5', + description: 'description', + author: 'me <em@i.l> (http://url)', + scripts: { test: 'make test' }, + main: 'main.js', + config: { foo: 'bar' }, + package: {} } + t.same(data, expect) + t.end() + }) + setTimeout(function () { + process.stdin.emit('data', 'the-name\n') + }, 50) + setTimeout(function () { + process.stdin.emit('data', 'description\n') + }, 100) + setTimeout(function () { + process.stdin.emit('data', 'yes\n') + }, 150) +}) + +tap.test('teardown', function (t) { + rimraf(__dirname + '/package.json', t.end.bind(t)) +}) diff --git a/deps/npm/node_modules/lockfile/test/basic.js b/deps/npm/node_modules/lockfile/test/basic.js new file mode 100644 index 0000000000..77308cdc94 --- /dev/null +++ b/deps/npm/node_modules/lockfile/test/basic.js @@ -0,0 +1,226 @@ +var test = require('tap').test +var lockFile = require('../lockfile.js') +var path = require('path') +var fs = require('fs') + +test('setup', function (t) { + try { lockFile.unlockSync('basic-lock') } catch (er) {} + try { lockFile.unlockSync('sync-lock') } catch (er) {} + try { lockFile.unlockSync('never-forget') } catch (er) {} + try { lockFile.unlockSync('stale-lock') } catch (er) {} + try { lockFile.unlockSync('watch-lock') } catch (er) {} + try { lockFile.unlockSync('retry-lock') } catch (er) {} + t.end() +}) + +test('basic test', function (t) { + lockFile.check('basic-lock', function (er, locked) { + if (er) throw er + t.notOk(locked) + lockFile.lock('basic-lock', function (er) { + if (er) throw er + lockFile.lock('basic-lock', function (er) { + t.ok(er) + lockFile.check('basic-lock', function (er, locked) { + if (er) throw er + t.ok(locked) + lockFile.unlock('basic-lock', function (er) { + if (er) throw er + lockFile.check('basic-lock', function (er, locked) { + if (er) throw er + t.notOk(locked) + t.end() + }) + }) + }) + }) + }) + }) +}) + +test('sync test', function (t) { + var locked + locked = lockFile.checkSync('sync-lock') + t.notOk(locked) + lockFile.lockSync('sync-lock') + locked = lockFile.checkSync('sync-lock') + t.ok(locked) + lockFile.unlockSync('sync-lock') + locked = lockFile.checkSync('sync-lock') + t.notOk(locked) + t.end() +}) + +test('exit cleanup test', function (t) { + var child = require.resolve('./fixtures/child.js') + var node = process.execPath + var spawn = require('child_process').spawn + spawn(node, [child]).on('exit', function () { + setTimeout(function () { + var locked = lockFile.checkSync('never-forget') + t.notOk(locked) + t.end() + }, 100) + }) +}) + +test('error exit cleanup test', function (t) { + var child = require.resolve('./fixtures/bad-child.js') + var node = process.execPath + var spawn = require('child_process').spawn + spawn(node, [child]).on('exit', function () { + setTimeout(function () { + var locked = lockFile.checkSync('never-forget') + t.notOk(locked) + t.end() + }, 100) + }) +}) + + +test('staleness test', function (t) { + lockFile.lock('stale-lock', function (er) { + if (er) throw er + + var opts = { stale: 1 } + setTimeout(next, 10) + function next () { + lockFile.check('stale-lock', opts, function (er, locked) { + if (er) throw er + t.notOk(locked) + lockFile.lock('stale-lock', opts, function (er) { + if (er) throw er + lockFile.unlock('stale-lock', function (er) { + if (er) throw er + t.end() + }) + }) + }) + } + }) +}) + +test('staleness sync test', function (t) { + var opts = { stale: 1 } + lockFile.lockSync('stale-lock') + setTimeout(next, 10) + function next () { + var locked + locked = lockFile.checkSync('stale-lock', opts) + t.notOk(locked) + lockFile.lockSync('stale-lock', opts) + lockFile.unlockSync('stale-lock') + t.end() + } +}) + +test('watch test', function (t) { + var opts = { wait: 100 } + var fdx + lockFile.lock('watch-lock', function (er, fd1) { + if (er) throw er + setTimeout(unlock, 10) + function unlock () { + console.error('unlocking it') + lockFile.unlockSync('watch-lock') + // open another file, so the fd gets reused + // so we can know that it actually re-opened it fresh, + // rather than just getting the same lock as before. + fdx = fs.openSync('x', 'w') + fdy = fs.openSync('x', 'w') + } + + // should have gotten a new fd + lockFile.lock('watch-lock', opts, function (er, fd2) { + if (er) throw er + t.notEqual(fd1, fd2) + fs.closeSync(fdx) + fs.closeSync(fdy) + fs.unlinkSync('x') + lockFile.unlockSync('watch-lock') + t.end() + }) + }) +}) + +test('retries', function (t) { + // next 5 opens will fail. + var opens = 5 + fs._open = fs.open + fs.open = function (path, mode, cb) { + if (--opens === 0) { + fs.open = fs._open + return fs.open(path, mode, cb) + } + var er = new Error('bogus') + // to be, or not to be, that is the question. + er.code = opens % 2 ? 'EEXIST' : 'ENOENT' + process.nextTick(cb.bind(null, er)) + } + + lockFile.lock('retry-lock', { retries: opens }, function (er, fd) { + if (er) throw er + t.equal(opens, 0) + t.ok(fd) + lockFile.unlockSync('retry-lock') + t.end() + }) +}) + +test('retryWait', function (t) { + // next 5 opens will fail. + var opens = 5 + fs._open = fs.open + fs.open = function (path, mode, cb) { + if (--opens === 0) { + fs.open = fs._open + return fs.open(path, mode, cb) + } + var er = new Error('bogus') + // to be, or not to be, that is the question. + er.code = opens % 2 ? 'EEXIST' : 'ENOENT' + process.nextTick(cb.bind(null, er)) + } + + var opts = { retries: opens, retryWait: 100 } + lockFile.lock('retry-lock', opts, function (er, fd) { + if (er) throw er + t.equal(opens, 0) + t.ok(fd) + lockFile.unlockSync('retry-lock') + t.end() + }) +}) + +test('retry sync', function (t) { + // next 5 opens will fail. + var opens = 5 + fs._openSync = fs.openSync + fs.openSync = function (path, mode) { + if (--opens === 0) { + fs.openSync = fs._openSync + return fs.openSync(path, mode) + } + var er = new Error('bogus') + // to be, or not to be, that is the question. + er.code = opens % 2 ? 'EEXIST' : 'ENOENT' + throw er + } + + var opts = { retries: opens } + lockFile.lockSync('retry-lock', opts) + t.equal(opens, 0) + lockFile.unlockSync('retry-lock') + t.end() +}) + +test('cleanup', function (t) { + try { lockFile.unlockSync('basic-lock') } catch (er) {} + try { lockFile.unlockSync('sync-lock') } catch (er) {} + try { lockFile.unlockSync('never-forget') } catch (er) {} + try { lockFile.unlockSync('stale-lock') } catch (er) {} + try { lockFile.unlockSync('watch-lock') } catch (er) {} + try { lockFile.unlockSync('retry-lock') } catch (er) {} + t.end() +}) + diff --git a/deps/npm/node_modules/lockfile/test/fixtures/bad-child.js b/deps/npm/node_modules/lockfile/test/fixtures/bad-child.js new file mode 100644 index 0000000000..e65304542f --- /dev/null +++ b/deps/npm/node_modules/lockfile/test/fixtures/bad-child.js @@ -0,0 +1,5 @@ +var lockFile = require('../../lockfile.js') + +lockFile.lockSync('never-forget') + +throw new Error('waaaaaaaaa') diff --git a/deps/npm/node_modules/lockfile/test/fixtures/child.js b/deps/npm/node_modules/lockfile/test/fixtures/child.js new file mode 100644 index 0000000000..5b61d6c911 --- /dev/null +++ b/deps/npm/node_modules/lockfile/test/fixtures/child.js @@ -0,0 +1,3 @@ +var lockFile = require('../../lockfile.js') + +lockFile.lock('never-forget', function () {}) diff --git a/deps/npm/node_modules/lru-cache/test/basic.js b/deps/npm/node_modules/lru-cache/test/basic.js new file mode 100644 index 0000000000..6af0edf6c7 --- /dev/null +++ b/deps/npm/node_modules/lru-cache/test/basic.js @@ -0,0 +1,171 @@ +var test = require("tap").test + , LRU = require("../") + +test("basic", function (t) { + var cache = new LRU(10) + cache.set("key", "value") + t.equal(cache.get("key"), "value") + t.equal(cache.get("nada"), undefined) + t.equal(cache.length, 1) + t.equal(cache.maxLength, 10) + t.end() +}) + +test("least recently set", function (t) { + var cache = new LRU(2) + cache.set("a", "A") + cache.set("b", "B") + cache.set("c", "C") + t.equal(cache.get("c"), "C") + t.equal(cache.get("b"), "B") + t.equal(cache.get("a"), undefined) + t.end() +}) + +test("lru recently gotten", function (t) { + var cache = new LRU(2) + cache.set("a", "A") + cache.set("b", "B") + cache.get("a") + cache.set("c", "C") + t.equal(cache.get("c"), "C") + t.equal(cache.get("b"), undefined) + t.equal(cache.get("a"), "A") + t.end() +}) + +test("del", function (t) { + var cache = new LRU(2) + cache.set("a", "A") + cache.del("a") + t.equal(cache.get("a"), undefined) + t.end() +}) + +test("maxLength", function (t) { + var cache = new LRU(3) + + // test changing the maxLength, verify that the LRU items get dropped. + cache.maxLength = 100 + for (var i = 0; i < 100; i ++) cache.set(i, i) + t.equal(cache.length, 100) + for (var i = 0; i < 100; i ++) { + t.equal(cache.get(i), i) + } + cache.maxLength = 3 + t.equal(cache.length, 3) + for (var i = 0; i < 97; i ++) { + t.equal(cache.get(i), undefined) + } + for (var i = 98; i < 100; i ++) { + t.equal(cache.get(i), i) + } + + // now remove the maxLength restriction, and try again. + cache.maxLength = "hello" + for (var i = 0; i < 100; i ++) cache.set(i, i) + t.equal(cache.length, 100) + for (var i = 0; i < 100; i ++) { + t.equal(cache.get(i), i) + } + // should trigger an immediate resize + cache.maxLength = 3 + t.equal(cache.length, 3) + for (var i = 0; i < 97; i ++) { + t.equal(cache.get(i), undefined) + } + for (var i = 98; i < 100; i ++) { + t.equal(cache.get(i), i) + } + t.end() +}) + +test("reset", function (t) { + var cache = new LRU(10) + cache.set("a", "A") + cache.set("b", "B") + cache.reset() + t.equal(cache.length, 0) + t.equal(cache.maxLength, 10) + t.equal(cache.get("a"), undefined) + t.equal(cache.get("b"), undefined) + t.end() +}) + + +// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made +// about the format/layout of the response. +test("dump", function (t) { + var cache = new LRU(10) + var d = cache.dump(); + t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache") + cache.set("a", "A") + var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } } + t.ok(d.a) + t.equal(d.a.key, "a") + t.equal(d.a.value, "A") + t.equal(d.a.lu, 0) + + cache.set("b", "B") + cache.get("b") + d = cache.dump() + t.ok(d.b) + t.equal(d.b.key, "b") + t.equal(d.b.value, "B") + t.equal(d.b.lu, 2) + + t.end() +}) + + +test("basic with weighed length", function (t) { + var cache = new LRU(100, function (item) { return item.size } ) + cache.set("key", {val: "value", size: 50}) + t.equal(cache.get("key").val, "value") + t.equal(cache.get("nada"), undefined) + t.equal(cache.lengthCalculator(cache.get("key")), 50) + t.equal(cache.length, 50) + t.equal(cache.maxLength, 100) + t.end() +}) + + +test("weighed length item too large", function (t) { + var cache = new LRU(10, function (item) { return item.size } ) + t.equal(cache.maxLength, 10) + + // should fall out immediately + cache.set("key", {val: "value", size: 50}) + + t.equal(cache.length, 0) + t.equal(cache.get("key"), undefined) + t.end() +}) + +test("least recently set with weighed length", function (t) { + var cache = new LRU(8, function (item) { return item.length }) + cache.set("a", "A") + cache.set("b", "BB") + cache.set("c", "CCC") + cache.set("d", "DDDD") + t.equal(cache.get("d"), "DDDD") + t.equal(cache.get("c"), "CCC") + t.equal(cache.get("b"), undefined) + t.equal(cache.get("a"), undefined) + t.end() +}) + +test("lru recently gotten with weighed length", function (t) { + var cache = new LRU(8, function (item) { return item.length }) + cache.set("a", "A") + cache.set("b", "BB") + cache.set("c", "CCC") + cache.get("a") + cache.get("b") + cache.set("d", "DDDD") + t.equal(cache.get("c"), undefined) + t.equal(cache.get("d"), "DDDD") + t.equal(cache.get("b"), "BB") + t.equal(cache.get("a"), "A") + t.end() +}) diff --git a/deps/npm/node_modules/minimatch/test/basic.js b/deps/npm/node_modules/minimatch/test/basic.js new file mode 100644 index 0000000000..cf1778a575 --- /dev/null +++ b/deps/npm/node_modules/minimatch/test/basic.js @@ -0,0 +1,273 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + ; [ "http://www.bashcookbook.com/bashinfo" + + "/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + ].forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] || {} + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var m = new mm.Minimatch(pattern, options) + var r = m.makeRe() + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/deps/npm/node_modules/minimatch/test/brace-expand.js b/deps/npm/node_modules/minimatch/test/brace-expand.js new file mode 100644 index 0000000000..7ee278a274 --- /dev/null +++ b/deps/npm/node_modules/minimatch/test/brace-expand.js @@ -0,0 +1,33 @@ +var tap = require("tap") + , minimatch = require("../") + +tap.test("brace expansion", function (t) { + // [ pattern, [expanded] ] + ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" + , [ "abxy" + , "abxz" + , "acdxy" + , "acdxz" + , "acexy" + , "acexz" + , "afhxy" + , "afhxz" + , "aghxy" + , "aghxz" ] ] + , [ "a{1..5}b" + , [ "a1b" + , "a2b" + , "a3b" + , "a4b" + , "a5b" ] ] + , [ "a{b}c", ["a{b}c"] ] + ].forEach(function (tc) { + var p = tc[0] + , expect = tc[1] + t.equivalent(minimatch.braceExpand(p), expect, p) + }) + console.error("ending") + t.end() +}) + + diff --git a/deps/npm/node_modules/minimatch/test/caching.js b/deps/npm/node_modules/minimatch/test/caching.js new file mode 100644 index 0000000000..0fec4b0fad --- /dev/null +++ b/deps/npm/node_modules/minimatch/test/caching.js @@ -0,0 +1,14 @@ +var Minimatch = require("../minimatch.js").Minimatch +var tap = require("tap") +tap.test("cache test", function (t) { + var mm1 = new Minimatch("a?b") + var mm2 = new Minimatch("a?b") + t.equal(mm1, mm2, "should get the same object") + // the lru should drop it after 100 entries + for (var i = 0; i < 100; i ++) { + new Minimatch("a"+i) + } + mm2 = new Minimatch("a?b") + t.notEqual(mm1, mm2, "cache should have dropped") + t.end() +}) diff --git a/deps/npm/node_modules/minimatch/test/defaults.js b/deps/npm/node_modules/minimatch/test/defaults.js new file mode 100644 index 0000000000..25f1f601cd --- /dev/null +++ b/deps/npm/node_modules/minimatch/test/defaults.js @@ -0,0 +1,274 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + ; [ "http://www.bashcookbook.com/bashinfo" + + "/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + ].forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] || {} + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var Class = mm.defaults(options).Minimatch + var m = new Class(pattern, {}) + var r = m.makeRe() + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js b/deps/npm/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000000..e6924212e6 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js.orig b/deps/npm/node_modules/mkdirp/examples/pow.js.orig new file mode 100644 index 0000000000..7741462212 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/examples/pow.js.orig @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/deps/npm/node_modules/mkdirp/examples/pow.js.rej b/deps/npm/node_modules/mkdirp/examples/pow.js.rej new file mode 100644 index 0000000000..81e7f43115 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/examples/pow.js.rej @@ -0,0 +1,19 @@ +--- examples/pow.js ++++ examples/pow.js +@@ -1,6 +1,15 @@ +-var mkdirp = require('mkdirp').mkdirp; ++var mkdirp = require('../').mkdirp, ++ mkdirpSync = require('../').mkdirpSync; + + mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') + }); ++ ++try { ++ mkdirpSync('/tmp/bar/foo/baz', 0755); ++ console.log('double pow!'); ++} ++catch (ex) { ++ console.log(ex); ++}
\ No newline at end of file diff --git a/deps/npm/node_modules/mkdirp/test/chmod.js b/deps/npm/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000000..520dcb8e9b --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/clobber.js b/deps/npm/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000000..0eb7099870 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/mkdirp.js b/deps/npm/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000000..b07cd70c10 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/perm.js b/deps/npm/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000000..23a7abbd23 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/perm.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/deps/npm/node_modules/mkdirp/test/perm_sync.js b/deps/npm/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000000..f685f60906 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,39 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + +test('sync root perm', function (t) { + t.plan(1); + + var file = '/tmp'; + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/race.js b/deps/npm/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000000..96a0447636 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/race.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('race', function (t) { + t.plan(4); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + } + }) + }) + }); + } +}); diff --git a/deps/npm/node_modules/mkdirp/test/rel.js b/deps/npm/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000000..79858243ab --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/return.js b/deps/npm/node_modules/mkdirp/test/return.js new file mode 100644 index 0000000000..bce68e5613 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/return.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, '/tmp/' + x); + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, null); + }); + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/return_sync.js b/deps/npm/node_modules/mkdirp/test/return_sync.js new file mode 100644 index 0000000000..7c222d3558 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/return_sync.js @@ -0,0 +1,24 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + // Note that this will throw on failure, which will fail the test. + var made = mkdirp.sync(file); + t.equal(made, '/tmp/' + x); + + // making the same file again should have no effect. + made = mkdirp.sync(file); + t.equal(made, null); +}); diff --git a/deps/npm/node_modules/mkdirp/test/root.js b/deps/npm/node_modules/mkdirp/test/root.js new file mode 100644 index 0000000000..97ad7a2f35 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/root.js @@ -0,0 +1,18 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkdirp(file, 0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/sync.js b/deps/npm/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000000..7530cada84 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file, 0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/umask.js b/deps/npm/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000000..64ccafe22b --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/umask.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/deps/npm/node_modules/mkdirp/test/umask_sync.js b/deps/npm/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000000..35bd5cbbf4 --- /dev/null +++ b/deps/npm/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/deps/npm/node_modules/node-gyp/bin/node-gyp.js b/deps/npm/node_modules/node-gyp/bin/node-gyp.js index 7b7d621501..1f0f2c0447 100755 --- a/deps/npm/node_modules/node-gyp/bin/node-gyp.js +++ b/deps/npm/node_modules/node-gyp/bin/node-gyp.js @@ -25,8 +25,9 @@ if (prog.todo.length === 0) { } log.info('it worked if it ends with', 'ok') +log.verbose('cli', process.argv) log.info('using', 'node-gyp@%s', prog.version) -log.info('using', 'node@%s', process.versions.node) +log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, process.arch) /** @@ -61,7 +62,7 @@ function run () { if (prog.todo.length === 0) { // done! completed = true - log.info('done', 'ok') + log.info('ok') return } var command = prog.todo.shift() diff --git a/deps/npm/node_modules/node-gyp/lib/build.js b/deps/npm/node_modules/node-gyp/lib/build.js index c29b97e63c..f38ec993a4 100644 --- a/deps/npm/node_modules/node-gyp/lib/build.js +++ b/deps/npm/node_modules/node-gyp/lib/build.js @@ -6,19 +6,20 @@ module.exports = exports = build */ var fs = require('graceful-fs') + , rm = require('rimraf') , path = require('path') , glob = require('glob') , log = require('npmlog') , which = require('which') , mkdirp = require('mkdirp') , win = process.platform == 'win32' - , openbsd = process.platform == 'openbsd' exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' function build (gyp, argv, callback) { - var makeCommand = openbsd ? 'gmake' : 'make' + var makeCommand = gyp.opts.make || process.env.MAKE + || (process.platform.indexOf('bsd') != -1 ? 'gmake' : 'make') var command = win ? 'msbuild' : makeCommand , buildDir = path.resolve('build') , configPath = path.resolve(buildDir, 'config.gypi') @@ -216,7 +217,47 @@ function build (gyp, argv, callback) { if (signal) { return callback(new Error('`' + command + '` got signal: ' + signal)) } + //symlinkNodeBinding() callback() } + function symlinkNodeBinding () { + var buildDir = path.join('build', buildType, '*.node') + log.verbose('globbing for files', buildDir) + glob(buildDir, function (err, nodeFiles) { + if (err) return callback(err) + function link () { + var file = nodeFiles.shift() + if (!file) { + // no more files to link... done! + return callback() + } + var dest = path.join('build', path.basename(file)) + log.info('symlink', 'creating link %j pointing to %j', file, dest) + var rel = path.relative('build', file) + log.verbose('symlink data', rel) + fs.symlink(rel, dest, 'file', function (err) { + if (err) { + if (err.code === 'EEXIST') { + log.verbose('destination already exists; deleting', dest) + rm(dest, function (err) { + if (err) return callback(err) + log.verbose('delete successful; trying symlink again') + nodeFiles.unshift(file) + link() + }) + } else { + callback(err) + } + return + } + // process the next file, if any + link() + }) + } + // start linking + link() + }) + } + } diff --git a/deps/npm/node_modules/node-gyp/lib/configure.js b/deps/npm/node_modules/node-gyp/lib/configure.js index 1cdd32037d..3dbd418794 100644 --- a/deps/npm/node_modules/node-gyp/lib/configure.js +++ b/deps/npm/node_modules/node-gyp/lib/configure.js @@ -47,7 +47,7 @@ function configure (gyp, argv, callback) { // We're gonna glob C:\python2* function guessPython () { log.verbose('could not find "' + python + '". guessing location') - var rootDir = process.env.HOMEDRIVE || process.env.SystemDrive || 'C:\\' + var rootDir = process.env.SystemDrive || 'C:\\' if (rootDir[rootDir.length - 1] !== '\\') { rootDir += '\\' } @@ -72,11 +72,21 @@ function configure (gyp, argv, callback) { if (err) { return callback(err) } + log.verbose('check python version', '`python --version` returned: %j', stderr) var version = stderr.trim().replace(/[^\d\.]+/g, '') - if (semver.lt(version, '3.0.0')) { + var numDots = 0 + version.replace(/\./g, function () { + numDots++ + }) + while (numDots < 2) { + version += '.0' + numDots++ + } + log.verbose('check python version', 'using version %j to check', version) + if (semver.gte(version, '2.5.0') && semver.lt(version, '3.0.0')) { getNodeDir() } else { - failPython3() + failPythonVersion(version) } }) } @@ -86,10 +96,10 @@ function configure (gyp, argv, callback) { + '", you can set the PYTHON env variable.')) } - function failPython3 () { + function failPythonVersion (badVersion) { callback(new Error('Python executable "' + python - + '" is Python 3, which is not supported.\n' - + 'You can set the PYTHON env variable to point to a Python 2 interpreter.')) + + '" is v' + badVersion + ', which is not supported by gyp.\n' + + 'You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.')) } function getNodeDir () { diff --git a/deps/npm/node_modules/node-gyp/lib/install.js b/deps/npm/node_modules/node-gyp/lib/install.js index 4932b8f3bf..2bcc72bf8b 100644 --- a/deps/npm/node_modules/node-gyp/lib/install.js +++ b/deps/npm/node_modules/node-gyp/lib/install.js @@ -8,6 +8,7 @@ exports.usage = 'Install node development files for the specified node version.' */ var fs = require('graceful-fs') + , osenv = require('osenv') , tar = require('tar') , rm = require('rimraf') , path = require('path') @@ -41,7 +42,7 @@ function install (gyp, argv, callback) { // Determine which node dev files version we are installing var versionStr = argv[0] || gyp.opts.target || process.version - log.verbose('install', 'input version string', versionStr) + log.verbose('install', 'input version string %j', versionStr) // parse the version to normalize and ensure it's valid var version = semver.parse(versionStr) @@ -57,11 +58,16 @@ function install (gyp, argv, callback) { return callback(new Error('Minimum target version is `0.6.0` or greater. Got: ' + versionStr)) } - // 0.x.y-pre versions are not published yet. Use previous release. + // 0.x.y-pre versions are not published yet and cannot be installed. Bail. if (version[5] === '-pre') { - version[3] = +version[3] - 1 - version[5] = null - log.verbose('-pre version detected, adjusting patch version') + log.verbose('detected "pre" node version', versionStr) + if (gyp.opts.nodedir) { + log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir) + callback() + } else { + callback(new Error('"pre" versions of node cannot be installed, use the --nodedir flag instead')) + } + return } // flatten version into String @@ -107,12 +113,11 @@ function install (gyp, argv, callback) { go() } - function download (url, onError) { + function download (url) { log.http('GET', url) var requestOpts = { uri: url - , onResponse: true } // basic support for a proxy server @@ -124,7 +129,7 @@ function install (gyp, argv, callback) { log.verbose('proxy', proxyUrl) requestOpts.proxy = proxyUrl } - var req = request(requestOpts, onError) + var req = request(requestOpts) req.on('response', function (res) { log.http(res.statusCode, url) }) @@ -133,181 +138,210 @@ function install (gyp, argv, callback) { function go () { - log.verbose('ensuring nodedir is created', devDir) + log.verbose('ensuring nodedir is created', devDir) - // first create the dir for the node dev files - mkdir(devDir, function (err, created) { - if (err) return cb(err) - - if (created) { - log.verbose('created nodedir', created) - } + // first create the dir for the node dev files + mkdir(devDir, function (err, created) { + if (err) { + if (err.code == 'EACCES') { + // this EACCES fallback is a workaround for npm's `sudo` behavior, where + // it drops the permissions before invoking any child processes (like + // node-gyp). So what happens is the "nobody" user doesn't have + // permission to create the dev dir. As a fallback, make the tmpdir() be + // the dev dir for this installation. This is not ideal, but at least + // the compilation will succeed... + gyp.devDir = path.resolve(osenv.tmpdir(), '.node-gyp') + log.warn(err.code, 'user "%s" does not have permission to create dev dir "%s"', osenv.user(), devDir) + log.warn(err.code, 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir) + gyp.commands.install(argv, cb) + } else { + cb(err) + } + return + } - // now download the node tarball - var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz' - , badDownload = false - , extractCount = 0 - , gunzip = zlib.createGunzip() - , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid }) - - // checks if a file to be extracted from the tarball is valid. - // only .h header files and the gyp files get extracted - function isValid () { - var name = this.path.substring(devDir.length + 1) - var isValid = valid(name) - if (name === '' && this.type === 'Directory') { - // the first directory entry is ok - return true + if (created) { + log.verbose('created nodedir', created) } - if (isValid) { - log.verbose('extracted file from tarball', name) - extractCount++ - } else { - // invalid - log.silly('ignoring from tarball', name) + + // now download the node tarball + var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz' + , badDownload = false + , extractCount = 0 + , gunzip = zlib.createGunzip() + , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid }) + + // checks if a file to be extracted from the tarball is valid. + // only .h header files and the gyp files get extracted + function isValid () { + var name = this.path.substring(devDir.length + 1) + var isValid = valid(name) + if (name === '' && this.type === 'Directory') { + // the first directory entry is ok + return true + } + if (isValid) { + log.verbose('extracted file from tarball', name) + extractCount++ + } else { + // invalid + log.silly('ignoring from tarball', name) + } + return isValid } - return isValid - } - gunzip.on('error', cb) - extracter.on('error', cb) - extracter.on('end', afterTarball) + gunzip.on('error', cb) + extracter.on('error', cb) + extracter.on('end', afterTarball) - // download the tarball, gunzip and extract! - var req = download(tarballUrl, downloadError) - .pipe(gunzip) - .pipe(extracter) + // download the tarball, gunzip and extract! + var req = download(tarballUrl) - // something went wrong downloading the tarball? - function downloadError (err, res) { - if (err || res.statusCode != 200) { + // something went wrong downloading the tarball? + req.on('error', function (err) { badDownload = true - cb(err || new Error(res.statusCode + ' status code downloading tarball')) - } - } + cb(err) + }) - // invoked after the tarball has finished being extracted - function afterTarball () { - if (badDownload) return - if (extractCount === 0) { - return cb(new Error('There was a fatal problem while downloading/extracting the tarball')) - } - log.verbose('tarball', 'done parsing tarball') - var async = 0 + req.on('close', function () { + if (extractCount === 0) { + cb(new Error('Connection closed while downloading tarball file')) + } + }) - if (isLegacy) { - // copy over the files from the `legacy` dir - async++ - copyLegacy(deref) - } + req.on('response', function (res) { + if (res.statusCode !== 200) { + badDownload = true + cb(new Error(res.statusCode + ' status code downloading tarball')) + return + } + // start unzipping and untaring + req.pipe(gunzip).pipe(extracter) + }) - if (win) { - // need to download node.lib - async++ - downloadNodeLib(deref) - } + // invoked after the tarball has finished being extracted + function afterTarball () { + if (badDownload) return + if (extractCount === 0) { + return cb(new Error('There was a fatal problem while downloading/extracting the tarball')) + } + log.verbose('tarball', 'done parsing tarball') + var async = 0 - // write the "installVersion" file - async++ - var installVersionPath = path.resolve(devDir, 'installVersion') - fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref) + if (isLegacy) { + // copy over the files from the `legacy` dir + async++ + copyLegacy(deref) + } - if (async === 0) { - // no async tasks required - cb() - } + if (win) { + // need to download node.lib + async++ + downloadNodeLib(deref) + } - function deref (err) { - if (err) return cb(err) - --async || cb() - } - } + // write the "installVersion" file + async++ + var installVersionPath = path.resolve(devDir, 'installVersion') + fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref) - function copyLegacy (done) { - // legacy versions of node (< 0.8) require the legacy files to be copied - // over since they contain many bugfixes from the current node build system - log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version) + if (async === 0) { + // no async tasks required + cb() + } - var legacyDir = path.resolve(__dirname, '..', 'legacy') - log.verbose('legacy', 'using "legacy" dir', legacyDir) - log.verbose('legacy', 'copying to "dev" dir', devDir) + function deref (err) { + if (err) return cb(err) + --async || cb() + } + } - var reader = fstream.Reader({ path: legacyDir, type: 'Directory' }) - var writer = fstream.Writer({ path: devDir, type: 'Directory' }) + function copyLegacy (done) { + // legacy versions of node (< 0.8) require the legacy files to be copied + // over since they contain many bugfixes from the current node build system + log.verbose('legacy', 'copying "legacy" gyp configuration files for version', version) - reader.on('entry', function onEntry (entry) { - log.verbose('legacy', 'reading entry:', entry.path) - entry.on('entry', onEntry) - }) + var legacyDir = path.resolve(__dirname, '..', 'legacy') + log.verbose('legacy', 'using "legacy" dir', legacyDir) + log.verbose('legacy', 'copying to "dev" dir', devDir) - reader.on('error', done) - writer.on('error', done) + var reader = fstream.Reader({ path: legacyDir, type: 'Directory' }) + var writer = fstream.Writer({ path: devDir, type: 'Directory' }) - // Like `cp -rpf` - reader.pipe(writer) + reader.on('entry', function onEntry (entry) { + log.verbose('legacy', 'reading entry:', entry.path) + entry.on('entry', onEntry) + }) - reader.on('end', done) - } + reader.on('error', done) + writer.on('error', done) - function downloadNodeLib (done) { - log.verbose('on Windows; need to download `node.lib`...') - var dir32 = path.resolve(devDir, 'ia32') - , dir64 = path.resolve(devDir, 'x64') - , nodeLibPath32 = path.resolve(dir32, 'node.lib') - , nodeLibPath64 = path.resolve(dir64, 'node.lib') - , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib' - , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib' - - log.verbose('32-bit node.lib dir', dir32) - log.verbose('64-bit node.lib dir', dir64) - log.verbose('`node.lib` 32-bit url', nodeLibUrl32) - log.verbose('`node.lib` 64-bit url', nodeLibUrl64) - - var async = 2 - mkdir(dir32, function (err) { - if (err) return done(err) - log.verbose('streaming 32-bit node.lib to:', nodeLibPath32) - - var req = download(nodeLibUrl32) - req.on('error', done) - req.on('response', function (res) { - if (res.statusCode !== 200) { - done(new Error(res.statusCode + ' status code downloading 32-bit node.lib')) - } - }) - req.on('end', function () { - --async || done() - }) + // Like `cp -rpf` + reader.pipe(writer) - var ws = fs.createWriteStream(nodeLibPath32) - ws.on('error', cb) - req.pipe(ws) - }) - mkdir(dir64, function (err) { - if (err) return done(err) - log.verbose('streaming 64-bit node.lib to:', nodeLibPath64) - - var req = download(nodeLibUrl64) - req.on('error', done) - req.on('response', function (res) { - if (res.statusCode !== 200) { - done(new Error(res.statusCode + ' status code downloading 64-bit node.lib')) - } + reader.on('end', done) + } + + function downloadNodeLib (done) { + log.verbose('on Windows; need to download `node.lib`...') + var dir32 = path.resolve(devDir, 'ia32') + , dir64 = path.resolve(devDir, 'x64') + , nodeLibPath32 = path.resolve(dir32, 'node.lib') + , nodeLibPath64 = path.resolve(dir64, 'node.lib') + , nodeLibUrl32 = distUrl + '/v' + version + '/node.lib' + , nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib' + + log.verbose('32-bit node.lib dir', dir32) + log.verbose('64-bit node.lib dir', dir64) + log.verbose('`node.lib` 32-bit url', nodeLibUrl32) + log.verbose('`node.lib` 64-bit url', nodeLibUrl64) + + var async = 2 + mkdir(dir32, function (err) { + if (err) return done(err) + log.verbose('streaming 32-bit node.lib to:', nodeLibPath32) + + var req = download(nodeLibUrl32) + req.on('error', done) + req.on('response', function (res) { + if (res.statusCode !== 200) { + done(new Error(res.statusCode + ' status code downloading 32-bit node.lib')) + return + } + + var ws = fs.createWriteStream(nodeLibPath32) + ws.on('error', cb) + req.pipe(ws) + }) + req.on('end', function () { + --async || done() + }) }) - req.on('end', function () { - --async || done() + mkdir(dir64, function (err) { + if (err) return done(err) + log.verbose('streaming 64-bit node.lib to:', nodeLibPath64) + + var req = download(nodeLibUrl64) + req.on('error', done) + req.on('response', function (res) { + if (res.statusCode !== 200) { + done(new Error(res.statusCode + ' status code downloading 64-bit node.lib')) + return + } + + var ws = fs.createWriteStream(nodeLibPath64) + ws.on('error', cb) + req.pipe(ws) + }) + req.on('end', function () { + --async || done() + }) }) + } // downloadNodeLib() - var ws = fs.createWriteStream(nodeLibPath64) - ws.on('error', cb) - req.pipe(ws) - }) - } - - - }) + }) // mkdir() - } + } // go() /** * Checks if a given filename is "valid" for this installation. diff --git a/deps/npm/node_modules/node-gyp/lib/node-gyp.js b/deps/npm/node_modules/node-gyp/lib/node-gyp.js index 61e9dd1d76..9b2282520d 100644 --- a/deps/npm/node_modules/node-gyp/lib/node-gyp.js +++ b/deps/npm/node_modules/node-gyp/lib/node-gyp.js @@ -72,16 +72,17 @@ proto.package = require('../package') */ proto.configDefs = { - help: Boolean // everywhere - , arch: String // 'configure' - , debug: Boolean // 'build' + help: Boolean // everywhere + , arch: String // 'configure' + , debug: Boolean // 'build' , directory: String // bin + , make: String // 'build' , msvs_version: String // 'configure' - , ensure: Boolean // 'install' - , solution: String // 'build' (windows only) - , proxy: String // 'install' - , nodedir: String // 'configure' - , loglevel: String // everywhere + , ensure: Boolean // 'install' + , solution: String // 'build' (windows only) + , proxy: String // 'install' + , nodedir: String // 'configure' + , loglevel: String // everywhere } /** diff --git a/deps/npm/node_modules/node-gyp/package.json b/deps/npm/node_modules/node-gyp/package.json index f3fc686293..07c9178041 100644 --- a/deps/npm/node_modules/node-gyp/package.json +++ b/deps/npm/node_modules/node-gyp/package.json @@ -1,6 +1,6 @@ { "name": "node-gyp", - "description": "`node-gyp` is a cross-platform command-line tool written in Node.js for compiling", + "description": "Node.js native addon build tool", "keywords": [ "native", "addon", @@ -10,7 +10,7 @@ "bindings", "gyp" ], - "version": "0.5.2", + "version": "0.5.8", "installVersion": 9, "author": { "name": "Nathan Rajlich", @@ -34,6 +34,7 @@ "mkdirp": "0.3", "nopt": "1", "npmlog": "0", + "osenv": "0", "request": "2.9", "rimraf": "2", "semver": "1", @@ -44,9 +45,9 @@ "node": ">= 0.6.0" }, "readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n * On Unix:\n * `python`\n * `make`\n * A proper C/C++ compiler toolchain, like GCC\n * On Windows:\n * [Python][windows-python] ([`v2.7.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n * Microsoft Visual C++ ([Express][msvc] version works well)\n * For 64-bit builds of node and native modules you will _also_ need the [Windows 7 64-bit SDK][win7sdk]\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n \"targets\": [\n {\n \"target_name\": \"binding\",\n \"sources\": [ \"src/binding.cc\" ]\n }\n ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * ['\"binding.gyp\" files out in the wild' wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n * `build` - Invokes `make`/`msbuild.exe` and builds the native addon\n * `clean` - Removes any generated project files and the `out` dir\n * `configure` - Generates project build files for the current platform\n * `rebuild` - Runs \"clean\", \"configure\" and \"build\" all at once\n * `install` - Installs node development files for the given version.\n * `list` - Lists the currently installed node development file versions\n * `remove` - Removes a node development files for a given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n", - "_id": "node-gyp@0.5.2", + "_id": "node-gyp@0.5.8", "dist": { - "shasum": "7410e3dd9d950592ee80d09c7e5ef22286f79c0f" + "shasum": "2e6cdb28159c9bdd3fe484c7db81f119ee17e594" }, - "_from": "node-gyp@0.5.2" + "_from": "node-gyp@~0.5" } diff --git a/deps/npm/node_modules/npm-registry-client/index.js b/deps/npm/node_modules/npm-registry-client/index.js index 673789f9b0..c7bc21efcb 100644 --- a/deps/npm/node_modules/npm-registry-client/index.js +++ b/deps/npm/node_modules/npm-registry-client/index.js @@ -6,24 +6,34 @@ module.exports = RegClient var fs = require('fs') , url = require('url') , path = require('path') +, CouchLogin = require('couch-login') , npmlog try { npmlog = require("npmlog") } catch (er) { npmlog = { error: noop, warn: noop, info: noop, - verbose: noop, silly: noop, http: silly, + verbose: noop, silly: noop, http: noop, pause: noop, resume: noop } } function noop () {} function RegClient (options) { - // a registry url must be provided. - var registry = url.parse(options.registry) - if (!registry.protocol) throw new Error( - 'Invalid registry: ' + registry.url) - this.registry = registry.href + // if provided, then the registry needs to be a url. + // if it's not provided, then we're just using the cache only. + var registry = options.registry + if (registry) { + registry = url.parse(registry) + if (!registry.protocol) throw new Error( + 'Invalid registry: ' + registry.url) + this.registry = registry.href + if (this.registry.slice(-1) !== '/') { + this.registry += '/' + } + } else { + this.registry = null + } this.retries = options.retries || 2 this.retryFactor = options.retryFactor || 10 @@ -41,7 +51,25 @@ function RegClient (options) { a = a.split(":") this.username = a.shift() this.password = a.join(":") + } else { + this.username = options.username + this.password = options.password + + // if username and password are set, but auth isn't, use them. + if (this.username && this.password) { + var a = this.username + ":" + this.password + this.auth = new Buffer(a, "utf8").toString("base64") + } + } + + if (this.auth && !this.alwaysAuth && this.registry) { + // if we're always authing, then we just send the + // user/pass on every thing. otherwise, create a + // session, and use that. + this.token = options.token + this.couchLogin = new CouchLogin(this.registry, this.token) } + this.email = options.email || null this.defaultTag = options.tag || "latest" diff --git a/deps/npm/node_modules/npm-registry-client/lib/get.js b/deps/npm/node_modules/npm-registry-client/lib/get.js index b56fefcc63..835eb4ce51 100644 --- a/deps/npm/node_modules/npm-registry-client/lib/get.js +++ b/deps/npm/node_modules/npm-registry-client/lib/get.js @@ -15,6 +15,8 @@ function get (uri, timeout, nofollow, staleOk, cb) { timeout = Math.min(timeout, this.cacheMax) timeout = Math.max(timeout, this.cacheMin) + if (!this.registry) timeout = Infinity + if ( process.env.COMP_CWORD !== undefined && process.env.COMP_LINE !== undefined && process.env.COMP_POINT !== undefined diff --git a/deps/npm/node_modules/npm-registry-client/lib/request.js b/deps/npm/node_modules/npm-registry-client/lib/request.js index 1c6eb35e11..384b0d89d5 100644 --- a/deps/npm/node_modules/npm-registry-client/lib/request.js +++ b/deps/npm/node_modules/npm-registry-client/lib/request.js @@ -13,6 +13,9 @@ function regRequest (method, where, what, etag, nofollow, cb_) { if (typeof cb_ !== "function") cb_ = etag, etag = null if (typeof cb_ !== "function") cb_ = what, what = null + if (!this.registry) return cb(new Error( + "No registry url provided: " + method + " " + where)) + // Since there are multiple places where an error could occur, // don't let the cb be called more than once. var errState = null @@ -29,11 +32,12 @@ function regRequest (method, where, what, etag, nofollow, cb_) { var registry = this.registry var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/ - , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/ - , authRequired = (what || this.alwaysAuth) - && !where.match(adduserNew) - || where.match(adduserChange) - || method === "DELETE" + , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/ + , nu = where.match(adduserNew) + , uc = where.match(adduserChange) + , isUpload = what || this.alwaysAuth + , isDel = method === "DELETE" + , authRequired = isUpload && !nu || uc || isDel // resolve to a full url on the registry if (!where.match(/^https?:\/\//)) { @@ -58,20 +62,39 @@ function regRequest (method, where, what, etag, nofollow, cb_) { } var remote = url.parse(where) - , auth = authRequired && this.auth - - if (authRequired && !auth && this.username && this.password) { - var a = this.username + ":" + this.password - a = new Buffer(a, "utf8").toString("base64") - auth = this.auth = a + , auth = this.auth + + if (authRequired && !this.alwaysAuth) { + var couch = this.couchLogin + , token = couch && (this.token || couch.token) + , validToken = token && couch.valid(token) + + if (!validToken) token = null + else this.token = token + + if (couch && !token) { + // login to get a valid token + var a = { name: this.username, password: this.password } + var args = arguments + return this.couchLogin.login(a, function (er, cr, data) { + if (er || !couch.valid(couch.token)) { + er = er || new Error('login error') + return cb(er, cr, data) + } + this.token = this.couchLogin.token + return regRequest.call(this, method, where, what, etag, nofollow, cb_) + }.bind(this)) + } } - if (authRequired && !auth) { + // now we either have a valid token, or an auth. + + if (authRequired && !auth && !token) { return cb(new Error( "Cannot insert data into the registry without auth")) } - if (auth) { + if (auth && !token) { remote.auth = new Buffer(auth, "base64").toString("utf8") } @@ -87,7 +110,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) { operation.attempt(function (currentAttempt) { self.log.info("retry", "registry request attempt " + currentAttempt + " at " + (new Date()).toLocaleTimeString()) - makeRequest.call(self, method, remote, where, what, etag, nofollow + makeRequest.call(self, method, remote, where, what, etag, nofollow, token , function (er, parsed, raw, response) { // Only retry on 408, 5xx or no `response`. var statusCode = response && response.statusCode @@ -101,7 +124,7 @@ function regRequest (method, where, what, etag, nofollow, cb_) { }) } -function makeRequest (method, remote, where, what, etag, nofollow, cb_) { +function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) { var cbCalled = false function cb () { if (cbCalled) return @@ -112,7 +135,6 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) { var opts = { url: remote , method: method , ca: this.ca - , follow: false , strictSSL: this.strictSSL } , headers = opts.headers = {} if (etag) { @@ -120,6 +142,10 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb_) { headers[method === "GET" ? "if-none-match" : "if-match"] = etag } + if (tok) { + headers.cookie = 'AuthSession=' + tok.AuthSession + } + headers.accept = "application/json" headers["user-agent"] = this.userAgent diff --git a/deps/npm/node_modules/npm-registry-client/package.json b/deps/npm/node_modules/npm-registry-client/package.json index 08ecd7ef96..47b6dc4b7f 100644 --- a/deps/npm/node_modules/npm-registry-client/package.json +++ b/deps/npm/node_modules/npm-registry-client/package.json @@ -6,7 +6,7 @@ }, "name": "npm-registry-client", "description": "Client for the npm registry", - "version": "0.0.8", + "version": "0.0.10", "repository": { "url": "git://github.com/isaacs/npm-registry-client" }, @@ -24,6 +24,7 @@ "mkdirp": "~0.3.3", "rimraf": "~2.0.1", "retry": "0.6.0", + "couch-login": "~0.1.6", "npmlog": "" }, "devDependencies": { @@ -34,6 +35,6 @@ }, "license": "BSD", "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `retries` {Number} Number of times to retry on GET failures.\n Default=2\n* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10\n* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.\n Default=10000 (10 seconds)\n* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default=60000 (60 seconds)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n", - "_id": "npm-registry-client@0.0.8", + "_id": "npm-registry-client@0.0.10", "_from": "npm-registry-client@0" } diff --git a/deps/npm/node_modules/npm-registry-client/test/00-setup.js b/deps/npm/node_modules/npm-registry-client/test/00-setup.js new file mode 100644 index 0000000000..747768fb85 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/00-setup.js @@ -0,0 +1,10 @@ +var tap = require('tap') +var rimraf = require('rimraf') + +tap.test('setup', function (t) { + rimraf(__dirname + '/fixtures/cache', function (er) { + if (er) throw er + t.pass('cache cleaned') + t.end() + }) +}) diff --git a/deps/npm/node_modules/npm-registry-client/test/adduser-new.js b/deps/npm/node_modules/npm-registry-client/test/adduser-new.js new file mode 100644 index 0000000000..a0fee04c30 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/adduser-new.js @@ -0,0 +1,51 @@ +var tap = require('tap') +var server = require('./fixtures/server.js') +var RC = require('../') +var client = new RC({ + cache: __dirname + '/fixtures/cache' + , registry: 'http://localhost:' + server.port }) + +var userdata = +{ name: 'username', + email: 'i@izs.me', + _id: 'org.couchdb.user:username', + type: 'user', + roles: [], + date: '2012-06-07T04:11:21.591Z' } +, password = "password" +, username = "username" +, crypto = require("crypto") +, SD = require('string_decoder').StringDecoder +, decoder = new SD + +function sha (s) { + return crypto.createHash("sha1").update(s).digest("hex") +} + +tap.test("create new user account", function (t) { + server.expect("/-/user/org.couchdb.user:username", function (req, res) { + t.equal(req.method, "PUT") + var b = "" + req.on("data", function (d) { + b += decoder.write(d) + }) + + req.on("end", function () { + var o = JSON.parse(b) + var salt = o.salt + userdata.salt = salt + userdata.password_sha = sha(password + salt) + userdata.date = o.date + t.deepEqual(o, userdata) + + res.statusCode = 201 + res.json({created:true}) + }) + }) + + client.adduser(username, password, "i@izs.me", function (er, data, raw, res) { + if (er) throw er + t.deepEqual(data, { created: true }) + t.end() + }) +}) diff --git a/deps/npm/node_modules/npm-registry-client/test/adduser-update.js b/deps/npm/node_modules/npm-registry-client/test/adduser-update.js new file mode 100644 index 0000000000..03a1edbb26 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/adduser-update.js @@ -0,0 +1,68 @@ +var tap = require('tap') +var server = require('./fixtures/server.js') +var RC = require('../') +var client = new RC({ + cache: __dirname + '/fixtures/cache' + , registry: 'http://localhost:' + server.port }) + +var userdata = +{ name: 'username', + email: 'i@izs.me', + _id: 'org.couchdb.user:username', + type: 'user', + roles: [], + _rev: "1-15aac515ac515aac515aac515aac5125" +} + +, password = "password" +, username = "username" +, crypto = require("crypto") +, SD = require('string_decoder').StringDecoder +, decoder = new SD + + +function sha (s) { + return crypto.createHash("sha1").update(s).digest("hex") +} + +tap.test("update a user acct", function (t) { + server.expect("PUT", "/-/user/org.couchdb.user:username", function (req, res) { + t.equal(req.method, "PUT") + res.statusCode = 409 + res.json({error: "conflict"}) + }) + + server.expect("GET", "/-/user/org.couchdb.user:username", function (req, res) { + t.equal(req.method, "GET") + res.json(userdata) + }) + + server.expect("PUT", "/-/user/org.couchdb.user:username/-rev/" + userdata._rev, function (req, res) { + t.equal(req.method, "PUT") + + var b = "" + req.on("data", function (d) { + b += decoder.write(d) + }) + + req.on("end", function () { + var o = JSON.parse(b) + var salt = o.salt + userdata.salt = salt + userdata.password_sha = sha(password + salt) + userdata.date = o.date + t.deepEqual(o, userdata) + + res.statusCode = 201 + res.json({created:true}) + }) + }) + + + + client.adduser(username, password, "i@izs.me", function (er, data, raw, res) { + if (er) throw er + t.deepEqual(data, { created: true }) + t.end() + }) +}) diff --git a/deps/npm/node_modules/npm-registry-client/test/basic.js b/deps/npm/node_modules/npm-registry-client/test/basic.js new file mode 100644 index 0000000000..022466aeea --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/basic.js @@ -0,0 +1,32 @@ +var tap = require('tap') +var server = require('./fixtures/server.js') +var RC = require('../') +var rimraf = require("rimraf") +var client = new RC({ + cache: __dirname + '/fixtures/cache' + , registry: 'http://localhost:' + server.port }) +var us = require('./fixtures/underscore/1.3.3/cache.json') +var usroot = require("./fixtures/underscore/cache.json") + +tap.test("basic request", function (t) { + server.expect("/underscore/1.3.3", function (req, res) { + console.error('got a request') + res.json(us) + }) + + server.expect("/underscore", function (req, res) { + console.error('got a request') + res.json(usroot) + }) + + t.plan(2) + client.get("/underscore/1.3.3", function (er, data, raw, res) { + console.error("got response") + t.deepEqual(data, us) + }) + + client.get("/underscore", function (er, data, raw, res) { + console.error("got response") + t.deepEqual(data, usroot) + }) +}) diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js b/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js new file mode 100644 index 0000000000..468a89e5bf --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js @@ -0,0 +1,56 @@ +// a fake registry server. + +var http = require('http') +var server = http.createServer(handler) +var port = server.port = process.env.PORT || 1337 +server.listen(port) + +module.exports = server + +server._expect = {} + +var expect = {} +function handler (req, res) { + req.connection.setTimeout(1000) + + var u = '* ' + req.url + , mu = req.method + ' ' + req.url + + var k = server._expect[mu] ? mu : server._expect[u] ? u : null + if (!k) throw Error('unexpected request', req.method, req.url) + + var fn = server._expect[k].shift() + if (!fn) throw Error('unexpected request', req.method, req.url) + + + var remain = (Object.keys(server._expect).reduce(function (s, k) { + return s + server._expect[k].length + }, 0)) + if (remain === 0) server.close() + else console.error("TEST SERVER: %d reqs remain", remain) + console.error(Object.keys(server._expect).map(function(k) { + return [k, server._expect[k].length] + }).reduce(function (acc, kv) { + acc[kv[0]] = kv[1] + return acc + }, {})) + + res.json = json + fn(req, res) +} + +function json (o) { + this.setHeader('content-type', 'application/json') + this.end(JSON.stringify(o)) +} + +server.expect = function (method, u, fn) { + if (typeof u === 'function') { + fn = u + u = method + method = '*' + } + u = method + ' ' + u + server._expect[u] = server._expect[u] || [] + server._expect[u].push(fn) +} diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json new file mode 100644 index 0000000000..01da300276 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json @@ -0,0 +1 @@ +{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}
\ No newline at end of file diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json new file mode 100644 index 0000000000..d899f11922 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json @@ -0,0 +1 @@ +{"_id":"underscore","_rev":"72-47f2986bfd8e8b55068b204588bbf484","name":"underscore","description":"JavaScript's functional programming helper library.","dist-tags":{"latest":"1.3.3","stable":"1.3.3"},"versions":{"1.0.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.3","_id":"underscore@1.0.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.0.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.4","_id":"underscore@1.0.4","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.4.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.0":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.0","_id":"underscore@1.1.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.0.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.1":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.1","_id":"underscore@1.1.1","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.1.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.2":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.2","_id":"underscore@1.1.2","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.2.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.3","_id":"underscore@1.1.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.8-1","_nodeVersion":"v0.2.5","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore.js","version":"1.1.4","_id":"underscore@1.1.4","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.9","_nodeVersion":"v0.5.0-pre","dist":{"shasum":"9e82274902865625b3a6d4c315a38ffd80047dae","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.4.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.1.5":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.5","_id":"underscore@1.1.5","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.16","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"23601d62c75619998b2f0db24938102793336a56","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.5.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.6":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.6","_id":"underscore@1.1.6","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.18","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"6868da1bdd72d75285be0b4e50f228e70d001a2c","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.6.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.7":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.7","devDependencies":{},"_id":"underscore@1.1.7","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.3","_nodeVersion":"v0.4.7","_defaultsLoaded":true,"dist":{"shasum":"40bab84bad19d230096e8d6ef628bff055d83db0","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz"},"scripts":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.0","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.0","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"b32ce32c8c118caa8031c10b54c7f65ab3b557fd","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.0.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.1","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.1","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"fc5c6b0765673d92a2d4ac8b4dc0aa88702e2bd4","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.1.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.2","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"74dd40e9face84e724eb2edae945b8aedc233ba3","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.2.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.3","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"11b874da70f4683d7d48bba2b44be1e600d2f6cf","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.3.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.4":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.4","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.4","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"e8da6241aa06f64df2473bb2590b8c17c84c3c7e","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.4.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.0","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.0","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"253b2d79b7bb67943ced0fc744eb18267963ede8","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.0.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.1","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.1","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"6cb8aad0e77eb5dbbfb54b22bcd8697309cf9641","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.2","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"1b4e455089ab1d1d38ab6794ffe6cf08f764394a","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.2.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"time":{"1.0.3":"2011-12-07T15:12:18.045Z","1.0.4":"2011-12-07T15:12:18.045Z","1.1.0":"2011-12-07T15:12:18.045Z","1.1.1":"2011-12-07T15:12:18.045Z","1.1.2":"2011-12-07T15:12:18.045Z","1.1.3":"2011-12-07T15:12:18.045Z","1.1.4":"2011-12-07T15:12:18.045Z","1.1.5":"2011-12-07T15:12:18.045Z","1.1.6":"2011-12-07T15:12:18.045Z","1.1.7":"2011-12-07T15:12:18.045Z","1.2.0":"2011-12-07T15:12:18.045Z","1.2.1":"2011-12-07T15:12:18.045Z","1.2.2":"2011-11-14T20:28:47.115Z","1.2.3":"2011-12-07T15:12:18.045Z","1.2.4":"2012-01-09T17:23:14.818Z","1.3.0":"2012-01-11T16:41:38.459Z","1.3.1":"2012-01-23T22:57:36.474Z","1.3.2":"2012-04-09T18:38:14.345Z","1.3.3":"2012-04-10T14:43:48.089Z"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"users":{"vesln":true,"mvolkmann":true,"lancehunt":true,"mikl":true,"linus":true,"vasc":true,"bat":true,"dmalam":true,"mbrevoort":true,"danielr":true,"rsimoes":true,"thlorenz":true}}
\ No newline at end of file diff --git a/deps/npm/node_modules/npm-registry-client/test/retries.js b/deps/npm/node_modules/npm-registry-client/test/retries.js new file mode 100644 index 0000000000..500abf29d9 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/retries.js @@ -0,0 +1,46 @@ +var tap = require('tap') +var server = require('./fixtures/server.js') +var RC = require('../') +var pkg = { _id: 'some-package@1.2.3', + name: 'some-package', + version: '1.2.3' } +var client = new RC({ + retries: 6 + , retryMinTimeout: 10 + , retryMaxTimeout: 100 + , cache: __dirname + '/fixtures/cache' + , registry: 'http://localhost:' + server.port }) + +tap.test('create new user account', function (t) { + // first time, return a 408 + server.expect('GET', '/some-package/1.2.3', function (req, res) { + res.statusCode = 408 + res.end('Timeout') + }) + // then, slam the door in their face + server.expect('GET', '/some-package/1.2.3', function (req, res) { + res.destroy() + }) + // then, blame someone else + server.expect('GET', '/some-package/1.2.3', function (req, res) { + res.statusCode = 502 + res.end('Gateway Timeout') + }) + // 'No one's home right now, come back later' + server.expect('GET', '/some-package/1.2.3', function (req, res) { + res.statusCode = 503 + res.setHeader('retry-after', '10') + res.end('Come back later') + }) + // finally, you may enter. + server.expect('GET', '/some-package/1.2.3', function (req, res) { + res.statusCode = 200 + res.json(pkg) + }) + + client.get('/some-package/1.2.3', function (er, data, raw, res) { + if (er) throw er + t.deepEqual(data, pkg) + t.end() + }) +}) diff --git a/deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js b/deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js new file mode 100644 index 0000000000..35253c7acd --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/zz-cleanup.js @@ -0,0 +1,10 @@ +var tap = require('tap') +var rimraf = require('rimraf') + +tap.test('teardown', function (t) { + rimraf(__dirname + '/fixtures/cache', function (er) { + if (er) throw er + t.pass('cache cleaned') + t.end() + }) +}) diff --git a/deps/npm/node_modules/npmlog/example.js b/deps/npm/node_modules/npmlog/example.js new file mode 100644 index 0000000000..c009fb1577 --- /dev/null +++ b/deps/npm/node_modules/npmlog/example.js @@ -0,0 +1,39 @@ +var log = require('./log.js') + +log.heading = 'npm' + +console.error('log.level=silly') +log.level = 'silly' +log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) +log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) +log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) +log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) +log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) +log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) +log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) + +console.error('log.level=silent') +log.level = 'silent' +log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) +log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) +log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) +log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) +log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) +log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) +log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) + +console.error('log.level=info') +log.level = 'info' +log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) +log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) +log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) +log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) +log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) +log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) +log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) +log.error('404', 'This is a longer\n'+ + 'message, with some details\n'+ + 'and maybe a stack.\n'+ + new Error('a 404 error').stack) +log.addLevel('noise', 10000, {beep: true}) +log.noise(false, 'LOUD NOISES') diff --git a/deps/npm/node_modules/npmlog/test/basic.js b/deps/npm/node_modules/npmlog/test/basic.js new file mode 100644 index 0000000000..8b5e7eb420 --- /dev/null +++ b/deps/npm/node_modules/npmlog/test/basic.js @@ -0,0 +1,461 @@ +var tap = require('tap') +var log = require('../') + +var result = [] +var logEvents = [] +var logInfoEvents = [] +var logPrefixEvents = [] + +var util = require('util') + +var resultExpect = +[ '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[7m', + 'sill', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'silly prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[34m', + '\u001b[40m', + 'verb', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'verbose prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[32m', + '\u001b[7m', + 'info', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'info prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[32m', + 'http', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'http prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[30m', + '\u001b[41m', + 'WARN', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'warn prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'error prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[32m', + '\u001b[7m', + 'info', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'info prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[32m', + 'http', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'http prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[30m', + '\u001b[41m', + 'WARN', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'warn prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + 'error prefix', + '\u001b[0m', + ' x = {"foo":{"bar":"baz"}}\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + '404', + '\u001b[0m', + ' This is a longer\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + '404', + '\u001b[0m', + ' message, with some details\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + '404', + '\u001b[0m', + ' and maybe a stack.\n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[31m', + '\u001b[40m', + 'ERR!', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u001b[35m', + '404', + '\u001b[0m', + ' \n', + '\u001b[0m', + '\u001b[37m', + '\u001b[40m', + 'npm', + '\u001b[0m', + ' ', + '\u001b[0m', + '\u0007', + 'noise', + '\u001b[0m', + '\u001b[35m', + '', + '\u001b[0m', + ' LOUD NOISES\n', + '\u001b[0m' ] + +var logPrefixEventsExpect = +[ { id: 2, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 9, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 16, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] } ] + +// should be the same. +var logInfoEventsExpect = logPrefixEventsExpect + +var logEventsExpect = +[ { id: 0, + level: 'silly', + prefix: 'silly prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 1, + level: 'verbose', + prefix: 'verbose prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 2, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 3, + level: 'http', + prefix: 'http prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 4, + level: 'warn', + prefix: 'warn prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 5, + level: 'error', + prefix: 'error prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 6, + level: 'silent', + prefix: 'silent prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 7, + level: 'silly', + prefix: 'silly prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 8, + level: 'verbose', + prefix: 'verbose prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 9, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 10, + level: 'http', + prefix: 'http prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 11, + level: 'warn', + prefix: 'warn prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 12, + level: 'error', + prefix: 'error prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 13, + level: 'silent', + prefix: 'silent prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 14, + level: 'silly', + prefix: 'silly prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 15, + level: 'verbose', + prefix: 'verbose prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 16, + level: 'info', + prefix: 'info prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 17, + level: 'http', + prefix: 'http prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 18, + level: 'warn', + prefix: 'warn prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 19, + level: 'error', + prefix: 'error prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 20, + level: 'silent', + prefix: 'silent prefix', + message: 'x = {"foo":{"bar":"baz"}}', + messageRaw: [ 'x = %j', { foo: { bar: 'baz' } } ] }, + { id: 21, + level: 'error', + prefix: '404', + message: 'This is a longer\nmessage, with some details\nand maybe a stack.\n', + messageRaw: [ 'This is a longer\nmessage, with some details\nand maybe a stack.\n' ] }, + { id: 22, + level: 'noise', + prefix: false, + message: 'LOUD NOISES', + messageRaw: [ 'LOUD NOISES' ] } ] + +var Stream = require('stream').Stream +var s = new Stream() +s.write = function (m) { + result.push(m) +} + +s.writable = true +s.isTTY = true +s.end = function () {} + +log.stream = s + +log.heading = 'npm' + + +tap.test('basic', function (t) { + log.on('log', logEvents.push.bind(logEvents)) + log.on('log.info', logInfoEvents.push.bind(logInfoEvents)) + log.on('info prefix', logPrefixEvents.push.bind(logPrefixEvents)) + + console.error('log.level=silly') + log.level = 'silly' + log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) + log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) + log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) + log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) + log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) + log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) + log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) + + console.error('log.level=silent') + log.level = 'silent' + log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) + log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) + log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) + log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) + log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) + log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) + log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) + + console.error('log.level=info') + log.level = 'info' + log.silly('silly prefix', 'x = %j', {foo:{bar:'baz'}}) + log.verbose('verbose prefix', 'x = %j', {foo:{bar:'baz'}}) + log.info('info prefix', 'x = %j', {foo:{bar:'baz'}}) + log.http('http prefix', 'x = %j', {foo:{bar:'baz'}}) + log.warn('warn prefix', 'x = %j', {foo:{bar:'baz'}}) + log.error('error prefix', 'x = %j', {foo:{bar:'baz'}}) + log.silent('silent prefix', 'x = %j', {foo:{bar:'baz'}}) + log.error('404', 'This is a longer\n'+ + 'message, with some details\n'+ + 'and maybe a stack.\n') + log.addLevel('noise', 10000, {beep: true}) + log.noise(false, 'LOUD NOISES') + + t.deepEqual(result, resultExpect, 'result') + t.deepEqual(log.record, logEventsExpect, 'record') + t.deepEqual(logEvents, logEventsExpect, 'logEvents') + t.deepEqual(logInfoEvents, logInfoEventsExpect, 'logInfoEvents') + t.deepEqual(logPrefixEvents, logPrefixEventsExpect, 'logPrefixEvents') + + t.end() +}) diff --git a/deps/npm/node_modules/osenv/test/unix.js b/deps/npm/node_modules/osenv/test/unix.js new file mode 100644 index 0000000000..b72eb0b3f5 --- /dev/null +++ b/deps/npm/node_modules/osenv/test/unix.js @@ -0,0 +1,76 @@ +// only run this test on windows +// pretending to be another platform is too hacky, since it breaks +// how the underlying system looks up module paths and runs +// child processes, and all that stuff is cached. +if (process.platform === 'win32') { + console.log('TAP Version 13\n' + + '1..0\n' + + '# Skip unix tests, this is not unix\n') + return +} +var tap = require('tap') + +// like unix, but funny +process.env.USER = 'sirUser' +process.env.HOME = '/home/sirUser' +process.env.HOSTNAME = 'my-machine' +process.env.TMPDIR = '/tmpdir' +process.env.TMP = '/tmp' +process.env.TEMP = '/temp' +process.env.PATH = '/opt/local/bin:/usr/local/bin:/usr/bin/:bin' +process.env.PS1 = '(o_o) $ ' +process.env.EDITOR = 'edit' +process.env.VISUAL = 'visualedit' +process.env.SHELL = 'zsh' + + +tap.test('basic unix sanity test', function (t) { + var osenv = require('../osenv.js') + + t.equal(osenv.user(), process.env.USER) + t.equal(osenv.home(), process.env.HOME) + t.equal(osenv.hostname(), process.env.HOSTNAME) + t.same(osenv.path(), process.env.PATH.split(':')) + t.equal(osenv.prompt(), process.env.PS1) + t.equal(osenv.tmpdir(), process.env.TMPDIR) + + // mildly evil, but it's for a test. + process.env.TMPDIR = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), process.env.TMP) + + process.env.TMP = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), process.env.TEMP) + + process.env.TEMP = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), '/home/sirUser/tmp') + + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + osenv.home = function () { return null } + t.equal(osenv.tmpdir(), '/tmp') + + t.equal(osenv.editor(), 'edit') + process.env.EDITOR = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.editor(), 'visualedit') + + process.env.VISUAL = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.editor(), 'vi') + + t.equal(osenv.shell(), 'zsh') + process.env.SHELL = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.shell(), 'bash') + + t.end() +}) diff --git a/deps/npm/node_modules/osenv/test/windows.js b/deps/npm/node_modules/osenv/test/windows.js new file mode 100644 index 0000000000..dd3fe80700 --- /dev/null +++ b/deps/npm/node_modules/osenv/test/windows.js @@ -0,0 +1,82 @@ +// only run this test on windows +// pretending to be another platform is too hacky, since it breaks +// how the underlying system looks up module paths and runs +// child processes, and all that stuff is cached. +if (process.platform !== 'win32') { + console.log('TAP Version 13\n' + + '1..0\n' + + '# Skip windows tests, this is not windows\n') + return +} + +// load this before clubbing the platform name. +var tap = require('tap') + +process.env.windir = 'C:\\windows' +process.env.USERDOMAIN = 'some-domain' +process.env.USERNAME = 'sirUser' +process.env.USERPROFILE = 'C:\\Users\\sirUser' +process.env.COMPUTERNAME = 'my-machine' +process.env.TMPDIR = 'C:\\tmpdir' +process.env.TMP = 'C:\\tmp' +process.env.TEMP = 'C:\\temp' +process.env.Path = 'C:\\Program Files\\;C:\\Binary Stuff\\bin' +process.env.PROMPT = '(o_o) $ ' +process.env.EDITOR = 'edit' +process.env.VISUAL = 'visualedit' +process.env.ComSpec = 'some-com' + +tap.test('basic windows sanity test', function (t) { + var osenv = require('../osenv.js') + + var osenv = require('../osenv.js') + + t.equal(osenv.user(), + process.env.USERDOMAIN + '\\' + process.env.USERNAME) + t.equal(osenv.home(), process.env.USERPROFILE) + t.equal(osenv.hostname(), process.env.COMPUTERNAME) + t.same(osenv.path(), process.env.Path.split(';')) + t.equal(osenv.prompt(), process.env.PROMPT) + t.equal(osenv.tmpdir(), process.env.TMPDIR) + + // mildly evil, but it's for a test. + process.env.TMPDIR = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), process.env.TMP) + + process.env.TMP = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), process.env.TEMP) + + process.env.TEMP = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.tmpdir(), 'C:\\Users\\sirUser\\temp') + + process.env.TEMP = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + osenv.home = function () { return null } + t.equal(osenv.tmpdir(), 'C:\\windows\\temp') + + t.equal(osenv.editor(), 'edit') + process.env.EDITOR = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.editor(), 'visualedit') + + process.env.VISUAL = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.editor(), 'notepad.exe') + + t.equal(osenv.shell(), 'some-com') + process.env.ComSpec = '' + delete require.cache[require.resolve('../osenv.js')] + var osenv = require('../osenv.js') + t.equal(osenv.shell(), 'cmd') + + t.end() +}) diff --git a/deps/npm/node_modules/read-installed/test/basic.js b/deps/npm/node_modules/read-installed/test/basic.js new file mode 100644 index 0000000000..0f833203f8 --- /dev/null +++ b/deps/npm/node_modules/read-installed/test/basic.js @@ -0,0 +1,34 @@ +var readInstalled = require("../read-installed.js") +var util = require("util") +console.error("testing") + +var called = 0 +readInstalled(process.cwd(), function (er, map) { + console.error(called ++) + if (er) return console.error(er.stack || er.message) + cleanup(map) + console.error(util.inspect(map, true, 10, true)) +}) + +var seen = [] +function cleanup (map) { + if (seen.indexOf(map) !== -1) return + seen.push(map) + for (var i in map) switch (i) { + case "_id": + case "path": + case "extraneous": case "invalid": + case "dependencies": case "name": + continue + default: delete map[i] + } + var dep = map.dependencies +// delete map.dependencies + if (dep) { +// map.dependencies = dep + for (var i in dep) if (typeof dep[i] === "object") { + cleanup(dep[i]) + } + } + return map +} diff --git a/deps/npm/node_modules/read-package-json/package.json b/deps/npm/node_modules/read-package-json/package.json index e147c242b9..c3b300038f 100644 --- a/deps/npm/node_modules/read-package-json/package.json +++ b/deps/npm/node_modules/read-package-json/package.json @@ -1,6 +1,6 @@ { "name": "read-package-json", - "version": "0.0.12", + "version": "0.1.1", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", @@ -31,6 +31,6 @@ "graceful-fs": "~1.1.8" }, "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\nreadJson('/path/to/package.json', 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, cb)\n\n* `file` {String} The path to the package.json file\n* `cb` {Function}\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", - "_id": "read-package-json@0.0.12", - "_from": "read-package-json@0" + "_id": "read-package-json@0.1.1", + "_from": "read-package-json@~0.1.0" } diff --git a/deps/npm/node_modules/read-package-json/read-json.js b/deps/npm/node_modules/read-package-json/read-json.js index ec3bf709b5..bb1c952628 100644 --- a/deps/npm/node_modules/read-package-json/read-json.js +++ b/deps/npm/node_modules/read-package-json/read-json.js @@ -223,7 +223,8 @@ function readmeDescription (file, data) { function readme (file, data, cb) { if (data.readme) return cb(null, data); var dir = path.dirname(file) - glob("README?(.*)", { cwd: dir }, function (er, files) { + var globOpts = { cwd: dir, nocase: true } + glob("README?(.*)", globOpts, function (er, files) { if (er) return cb(er); if (!files.length) return cb() var rm = path.resolve(dir, files[0]) @@ -340,6 +341,13 @@ function typoWarn (file, data) { }) bugsTypoWarn(file, data) scriptTypoWarn(file, data) + noreadmeWarn(file, data) +} + +function noreadmeWarn (file, data) { + if (data.readme) return; + warn(file, data, "No README.md file found!") + data.readme = "ERROR: No README.md file found!" } function checkTypo (file, data, d) { diff --git a/deps/npm/node_modules/read-package-json/test/basic.js b/deps/npm/node_modules/read-package-json/test/basic.js new file mode 100644 index 0000000000..72ba814246 --- /dev/null +++ b/deps/npm/node_modules/read-package-json/test/basic.js @@ -0,0 +1,34 @@ +var tap = require("tap") +var readJson = require("../") +var path = require("path") +var fs = require("fs") +var readme = fs.readFileSync(path.resolve(__dirname, "../README.md"), "utf8") +var package = require("../package.json") + +console.error("basic test") +tap.test("basic test", function (t) { + var p = path.resolve(__dirname, "../package.json") + readJson(p, function (er, data) { + if (er) throw er; + basic_(t, data) + }) +}) +function basic_ (t, data) { + t.ok(data) + t.equal(data.version, package.version) + t.equal(data._id, data.name + "@" + data.version) + t.equal(data.name, package.name) + t.type(data.author, "object") + t.equal(data.readme, readme) + t.deepEqual(data.scripts, package.scripts) + t.equal(data.main, package.main) + + // optional deps are folded in. + t.deepEqual(data.optionalDependencies, + package.optionalDependencies) + t.has(data.dependencies, package.optionalDependencies) + t.has(data.dependencies, package.dependencies) + + t.deepEqual(data.devDependencies, package.devDependencies) + t.end() +} diff --git a/deps/npm/node_modules/read/example/example.js b/deps/npm/node_modules/read/example/example.js new file mode 100644 index 0000000000..6800dff65e --- /dev/null +++ b/deps/npm/node_modules/read/example/example.js @@ -0,0 +1,18 @@ +var read = require("../lib/read.js") + +read({prompt: "Username: ", default: "test-user" }, function (er, user) { + read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) { + read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) { + read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) { + console.error({user: user, + pass: pass, + verify: pass2, + four:four, + passMatch: (pass === pass2)}) + console.error("If the program doesn't end right now,\n" + +"then you may be experiencing this bug:\n" + +"https://github.com/joyent/node/issues/2257") + }) + }) + }) +}) diff --git a/deps/npm/node_modules/read/test/basic.js b/deps/npm/node_modules/read/test/basic.js new file mode 100644 index 0000000000..7f195362af --- /dev/null +++ b/deps/npm/node_modules/read/test/basic.js @@ -0,0 +1,54 @@ +var tap = require('tap') +var read = require('../lib/read.js') + +if (process.argv[2] === 'child') { + return child() +} + +var spawn = require('child_process').spawn + +tap.test('basic', function (t) { + var child = spawn(process.execPath, [__filename, 'child']) + var output = '' + child.stdout.on('data', function (c) { + console.error('data %s', c) + output += c + if (output.match(/Username: \(test-user\) $/)) { + child.stdin.write('a user\n') + } else if (output.match(/Password: \(<default hidden>\) $/)) { + child.stdin.write('a password\n') + } else if (output.match(/characters: $/)) { + child.stdin.write('asdf\n') + } else if (output.match(/Password again: \(<default hidden>\) $/)) { + child.stdin.write('a password\n') + } + }) + + var result = '' + child.stderr.on('data', function (c) { + result += c + }) + + child.on('close', function () { + result = JSON.parse(result) + t.same(result, {"user":"a user","pass":"a password","verify":"a password","four":"asdf","passMatch":true}) + t.equal(output, 'Username: (test-user) Password: (<default hidden>) Enter 4 characters: Password again: (<default hidden>) ') + t.end() + }) +}) + +function child () { + read({prompt: "Username: ", default: "test-user" }, function (er, user) { + read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) { + read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) { + read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) { + console.error(JSON.stringify({user: user, + pass: pass, + verify: pass2, + four:four, + passMatch: (pass === pass2)})) + }) + }) + }) + }) +} diff --git a/deps/npm/node_modules/request/tests/googledoodle.png b/deps/npm/node_modules/request/tests/googledoodle.png Binary files differnew file mode 100644 index 0000000000..f80c9c52d3 --- /dev/null +++ b/deps/npm/node_modules/request/tests/googledoodle.png diff --git a/deps/npm/node_modules/request/tests/run.js b/deps/npm/node_modules/request/tests/run.js new file mode 100644 index 0000000000..f3a30d3541 --- /dev/null +++ b/deps/npm/node_modules/request/tests/run.js @@ -0,0 +1,39 @@ +var spawn = require('child_process').spawn + , exitCode = 0 + ; + +var tests = [ + 'test-body.js' + , 'test-cookie.js' + , 'test-cookiejar.js' + , 'test-defaults.js' + , 'test-errors.js' + , 'test-headers.js' + , 'test-httpModule.js' + , 'test-https.js' + , 'test-https-strict.js' + , 'test-oauth.js' + , 'test-pipes.js' + , 'test-pool.js' + , 'test-proxy.js' + , 'test-qs.js' + , 'test-redirect.js' + , 'test-timeout.js' + , 'test-toJSON.js' + , 'test-tunnel.js' +] + +var next = function () { + if (tests.length === 0) process.exit(exitCode); + + var file = tests.shift() + console.log(file) + var proc = spawn('node', [ 'tests/' + file ]) + proc.stdout.pipe(process.stdout) + proc.stderr.pipe(process.stderr) + proc.on('exit', function (code) { + exitCode += code || 0 + next() + }) +} +next() diff --git a/deps/npm/node_modules/request/tests/server.js b/deps/npm/node_modules/request/tests/server.js new file mode 100644 index 0000000000..921f512040 --- /dev/null +++ b/deps/npm/node_modules/request/tests/server.js @@ -0,0 +1,82 @@ +var fs = require('fs') + , http = require('http') + , path = require('path') + , https = require('https') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + ; + +exports.createServer = function (port) { + port = port || 6767 + var s = http.createServer(function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'http://localhost:'+port + return s; +} + +exports.createSSLServer = function(port, opts) { + port = port || 16767 + + var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') + , 'cert': path.join(__dirname, 'ssl', 'test.crt') + } + if (opts) { + for (var i in opts) options[i] = opts[i] + } + + for (var i in options) { + options[i] = fs.readFileSync(options[i]) + } + + var s = https.createServer(options, function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'https://localhost:'+port + return s; +} + +exports.createPostStream = function (text) { + var postStream = new stream.Stream(); + postStream.writeable = true; + postStream.readable = true; + setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0); + return postStream; +} +exports.createPostValidator = function (text) { + var l = function (req, resp) { + var r = ''; + req.on('data', function (chunk) {r += chunk}) + req.on('end', function () { + if (r !== text) console.log(r, text); + assert.equal(r, text) + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write('OK') + resp.end() + }) + } + return l; +} +exports.createGetResponse = function (text, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + resp.write(text) + resp.end() + } + return l; +} +exports.createChunkResponse = function (chunks, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + chunks.forEach(function (chunk) { + resp.write(chunk) + }) + resp.end() + } + return l; +} diff --git a/deps/npm/node_modules/request/tests/squid.conf b/deps/npm/node_modules/request/tests/squid.conf new file mode 100644 index 0000000000..0d4a3b6fe7 --- /dev/null +++ b/deps/npm/node_modules/request/tests/squid.conf @@ -0,0 +1,77 @@ +# +# Recommended minimum configuration: +# +acl manager proto cache_object +acl localhost src 127.0.0.1/32 ::1 +acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 + +# Example rule allowing access from your local networks. +# Adapt to list your (internal) IP networks from where browsing +# should be allowed +acl localnet src 10.0.0.0/8 # RFC1918 possible internal network +acl localnet src 172.16.0.0/12 # RFC1918 possible internal network +acl localnet src 192.168.0.0/16 # RFC1918 possible internal network +acl localnet src fc00::/7 # RFC 4193 local private network range +acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl CONNECT method CONNECT + +# +# Recommended minimum Access Permission configuration: +# +# Only allow cachemgr access from localhost +http_access allow manager localhost +http_access deny manager + +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +#http_access deny CONNECT !SSL_ports + +# We strongly recommend the following be uncommented to protect innocent +# web applications running on the proxy server who think the only +# one who can access services on "localhost" is a local user +#http_access deny to_localhost + +# +# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS +# + +# Example rule allowing access from your local networks. +# Adapt localnet in the ACL section to list your (internal) IP networks +# from where browsing should be allowed +http_access allow localnet +http_access allow localhost + +# And finally deny all other access to this proxy +http_access deny all + +# Squid normally listens to port 3128 +http_port 3128 + +# We recommend you to use at least the following line. +hierarchy_stoplist cgi-bin ? + +# Uncomment and adjust the following to add a disk cache directory. +#cache_dir ufs /usr/local/var/cache 100 16 256 + +# Leave coredumps in the first cache dir +coredump_dir /usr/local/var/cache + +# Add any of your own refresh_pattern entries above these. +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern . 0 20% 4320 diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.cnf b/deps/npm/node_modules/request/tests/ssl/ca/ca.cnf new file mode 100644 index 0000000000..425a889156 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.cnf @@ -0,0 +1,20 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +output_password = password + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = request Certificate Authority +CN = requestCA +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.crl b/deps/npm/node_modules/request/tests/ssl/ca/ca.crl new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.crl diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.crt b/deps/npm/node_modules/request/tests/ssl/ca/ca.crt new file mode 100644 index 0000000000..b4524e44ba --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl +YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4 +5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ +5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD +xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB +ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm +D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo +88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj +-----END CERTIFICATE----- diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.csr b/deps/npm/node_modules/request/tests/ssl/ca/ca.csr new file mode 100644 index 0000000000..e48c56eefe --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.csr @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG +SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0 +deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br +44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB +AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3 +DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj +bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia +SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X +-----END CERTIFICATE REQUEST----- diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.key b/deps/npm/node_modules/request/tests/ssl/ca/ca.key new file mode 100644 index 0000000000..a53e7f75d6 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C8B5887048377F02 + +nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q +nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+ +GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH +gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38 +VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3 +/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb +4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U +gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR +Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh +FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf +dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC +uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb +EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w== +-----END RSA PRIVATE KEY----- diff --git a/deps/npm/node_modules/request/tests/ssl/ca/ca.srl b/deps/npm/node_modules/request/tests/ssl/ca/ca.srl new file mode 100644 index 0000000000..17128db3ac --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/ca.srl @@ -0,0 +1 @@ +ADF62016AA40C9C3 diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.cnf b/deps/npm/node_modules/request/tests/ssl/ca/server.cnf new file mode 100644 index 0000000000..cd1fd1e396 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/server.cnf @@ -0,0 +1,19 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = testing +CN = testing.request.mikealrogers.com +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.crt b/deps/npm/node_modules/request/tests/ssl/ca/server.crt new file mode 100644 index 0000000000..efe96cefc3 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/server.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx +dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr +ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM +20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh +DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj +7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB +kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC +yapjN3RxZbInGhWR+jA= +-----END CERTIFICATE----- diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.csr b/deps/npm/node_modules/request/tests/ssl/ca/server.csr new file mode 100644 index 0000000000..a8e7595a56 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/server.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp +MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq +hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB +BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU +ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw +7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A +HidVJ/3u +-----END CERTIFICATE REQUEST----- diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.js b/deps/npm/node_modules/request/tests/ssl/ca/server.js new file mode 100644 index 0000000000..05e21c1162 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/server.js @@ -0,0 +1,28 @@ +var fs = require("fs") +var https = require("https") +var options = { key: fs.readFileSync("./server.key") + , cert: fs.readFileSync("./server.crt") } + +var server = https.createServer(options, function (req, res) { + res.writeHead(200) + res.end() + server.close() +}) +server.listen(1337) + +var ca = fs.readFileSync("./ca.crt") +var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca }) + +https.request({ host: "localhost" + , method: "HEAD" + , port: 1337 + , headers: { host: "testing.request.mikealrogers.com" } + , agent: agent + , ca: [ ca ] + , path: "/" }, function (res) { + if (res.client.authorized) { + console.log("node test: OK") + } else { + throw new Error(res.client.authorizationError) + } +}).end() diff --git a/deps/npm/node_modules/request/tests/ssl/ca/server.key b/deps/npm/node_modules/request/tests/ssl/ca/server.key new file mode 100644 index 0000000000..72d86984f1 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/ca/server.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB +iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW +gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0 +JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ +rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ +0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw== +-----END RSA PRIVATE KEY----- diff --git a/deps/npm/node_modules/request/tests/ssl/npm-ca.crt b/deps/npm/node_modules/request/tests/ssl/npm-ca.crt new file mode 100644 index 0000000000..fde2fe933d --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/npm-ca.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x +IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w +bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y +MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV +BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj +YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA +aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE +OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz +Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl +y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC +l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv +yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl +ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op +-----END CERTIFICATE----- diff --git a/deps/npm/node_modules/request/tests/ssl/test.crt b/deps/npm/node_modules/request/tests/ssl/test.crt new file mode 100644 index 0000000000..b357f8641f --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/test.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU +SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo +ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx +MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV +BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz +dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto +wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj +eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV +l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4 +L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE +c7U8F6MWLQ== +-----END CERTIFICATE----- diff --git a/deps/npm/node_modules/request/tests/ssl/test.key b/deps/npm/node_modules/request/tests/ssl/test.key new file mode 100644 index 0000000000..b85810dda8 --- /dev/null +++ b/deps/npm/node_modules/request/tests/ssl/test.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt +NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE +mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB +AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt +Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ +fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb +rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6 +V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF ++WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb +G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf +Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ +fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w +kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w== +-----END RSA PRIVATE KEY----- diff --git a/deps/npm/node_modules/request/tests/test-body.js b/deps/npm/node_modules/request/tests/test-body.js new file mode 100644 index 0000000000..e3fc75d970 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-body.js @@ -0,0 +1,80 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) + diff --git a/deps/npm/node_modules/request/tests/test-cookie.js b/deps/npm/node_modules/request/tests/test-cookie.js new file mode 100644 index 0000000000..6c6a7a7798 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-cookie.js @@ -0,0 +1,29 @@ +var Cookie = require('../vendor/cookie') + , assert = require('assert'); + +var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; +var cookie = new Cookie(str); + +// test .toString() +assert.equal(cookie.toString(), str); + +// test .path +assert.equal(cookie.path, '/'); + +// test .httpOnly +assert.equal(cookie.httpOnly, true); + +// test .name +assert.equal(cookie.name, 'Sid'); + +// test .value +assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); + +// test .expires +assert.equal(cookie.expires instanceof Date, true); + +// test .path default +var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); +assert.equal(cookie.path, '/bar'); + +console.log('All tests passed'); diff --git a/deps/npm/node_modules/request/tests/test-cookiejar.js b/deps/npm/node_modules/request/tests/test-cookiejar.js new file mode 100644 index 0000000000..76fcd71612 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-cookiejar.js @@ -0,0 +1,90 @@ +var Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , assert = require('assert'); + +function expires(ms) { + return new Date(Date.now() + ms).toUTCString(); +} + +// test .get() expiration +(function() { + var jar = new Jar; + var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); + jar.add(cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 0); + }, 1000); + }, 5); +})(); + +// test .get() path support +(function() { + var jar = new Jar; + var a = new Cookie('sid=1234; path=/'); + var b = new Cookie('sid=1111; path=/foo/bar'); + var c = new Cookie('sid=2222; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + + // should remove the duplicates + assert.equal(jar.cookies.length, 2); + + // same name, same path, latter prevails + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], c); + + // same name, diff path, path specifity prevails, latter prevails + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], a); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=3333; path=/foo/bar'); + var c = new Cookie('pid=3333; path=/foo/bar'); + var d = new Cookie('sid=2222; path=/foo/'); + var e = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + jar.add(d); + jar.add(e); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 2); + assert.equal(cookies[0], b); + assert.equal(cookies[1], c); + + var cookies = jar.get({ url: 'http://foo.com/foo/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], d); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], e); +})(); + +setTimeout(function() { + console.log('All tests passed'); +}, 1200); diff --git a/deps/npm/node_modules/request/tests/test-defaults.js b/deps/npm/node_modules/request/tests/test-defaults.js new file mode 100644 index 0000000000..6c8b58fa69 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-defaults.js @@ -0,0 +1,68 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +s.listen(s.port, function () { + var counter = 0; + s.on('/get', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'GET') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end('TESTING!'); + }); + + // test get(string, function) + request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){ + if (e) throw e; + assert.deepEqual("TESTING!", b); + counter += 1; + }); + + s.on('/post', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.headers['content-type'], 'application/json'); + assert.equal(req.method, 'POST') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test post(string, object, function) + request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/del', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'DELETE') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test .del(string, function) + request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/head', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'HEAD') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end(); + }); + + // test head.(object, function) + request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){ + if (e) throw e; + counter += 1; + console.log(counter.toString() + " tests passed.") + s.close() + }); + +}) diff --git a/deps/npm/node_modules/request/tests/test-errors.js b/deps/npm/node_modules/request/tests/test-errors.js new file mode 100644 index 0000000000..1986a59ee4 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-errors.js @@ -0,0 +1,37 @@ +var server = require('./server') + , events = require('events') + , assert = require('assert') + , request = require('../main.js') + ; + +var local = 'http://localhost:8888/asdf' + +try { + request({uri:local, body:{}}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.body.') +} + +try { + request({uri:local, multipart: 'foo'}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.multipart.') +} + +try { + request({uri:local, multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +try { + request(local, {multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +console.log("All tests passed.") diff --git a/deps/npm/node_modules/request/tests/test-headers.js b/deps/npm/node_modules/request/tests/test-headers.js new file mode 100644 index 0000000000..31fe3f4e8b --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-headers.js @@ -0,0 +1,52 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , s = server.createServer() + +s.listen(s.port, function () { + var serverUri = 'http://localhost:' + s.port + , numTests = 0 + , numOutstandingTests = 0 + + function createTest(requestObj, serverAssertFn) { + var testNumber = numTests; + numTests += 1; + numOutstandingTests += 1; + s.on('/' + testNumber, function (req, res) { + serverAssertFn(req, res); + res.writeHead(200); + res.end(); + }); + requestObj.url = serverUri + '/' + testNumber + request(requestObj, function (err, res, body) { + assert.ok(!err) + assert.equal(res.statusCode, 200) + numOutstandingTests -= 1 + if (numOutstandingTests === 0) { + console.log(numTests + ' tests passed.') + s.close() + } + }) + } + + // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified + createTest({headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar') + }) + + // Issue #125: headers.cookie + cookie jar + var jar = new Jar() + jar.add(new Cookie('quux=baz')); + createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar; quux=baz') + }) + + // There should be no cookie header when neither headers.cookie nor a cookie jar is specified + createTest({}, function (req, res) { + assert.ok(!req.headers.cookie) + }) +}) diff --git a/deps/npm/node_modules/request/tests/test-httpModule.js b/deps/npm/node_modules/request/tests/test-httpModule.js new file mode 100644 index 0000000000..1866de2fa6 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-httpModule.js @@ -0,0 +1,94 @@ +var http = require('http') + , https = require('https') + , server = require('./server') + , assert = require('assert') + , request = require('../main.js') + + +var faux_requests_made = {'http':0, 'https':0} +function wrap_request(name, module) { + // Just like the http or https module, but note when a request is made. + var wrapped = {} + Object.keys(module).forEach(function(key) { + var value = module[key]; + + if(key != 'request') + wrapped[key] = value; + else + wrapped[key] = function(options, callback) { + faux_requests_made[name] += 1 + return value.apply(this, arguments) + } + }) + + return wrapped; +} + + +var faux_http = wrap_request('http', http) + , faux_https = wrap_request('https', https) + , plain_server = server.createServer() + , https_server = server.createSSLServer() + + +plain_server.listen(plain_server.port, function() { + plain_server.on('/plain', function (req, res) { + res.writeHead(200) + res.end('plain') + }) + plain_server.on('/to_https', function (req, res) { + res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'}) + res.end() + }) + + https_server.listen(https_server.port, function() { + https_server.on('/https', function (req, res) { + res.writeHead(200) + res.end('https') + }) + https_server.on('/to_plain', function (req, res) { + res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'}) + res.end() + }) + + run_tests() + run_tests({}) + run_tests({'http:':faux_http}) + run_tests({'https:':faux_https}) + run_tests({'http:':faux_http, 'https:':faux_https}) + }) +}) + +function run_tests(httpModules) { + var to_https = 'http://localhost:'+plain_server.port+'/to_https' + var to_plain = 'https://localhost:'+https_server.port+'/to_plain' + + request(to_https, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to SSL worked') + assert.equal(body, 'https', 'Received HTTPS server body') + done() + }) + + request(to_plain, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to plaintext server worked') + assert.equal(body, 'plain', 'Received HTTPS server body') + done() + }) +} + + +var passed = 0; +function done() { + passed += 1 + var expected = 10 + + if(passed == expected) { + plain_server.close() + https_server.close() + + assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately') + assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately') + + console.log((expected+2) + ' tests passed.') + } +} diff --git a/deps/npm/node_modules/request/tests/test-https-strict.js b/deps/npm/node_modules/request/tests/test-https-strict.js new file mode 100644 index 0000000000..f53fc14a8d --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-https-strict.js @@ -0,0 +1,97 @@ +// a test where we validate the siguature of the keys +// otherwise exactly the same as the ssl test + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key') + , cert: path.resolve(__dirname, 'ssl/ca/server.crt') } + , s = server.createSSLServer(null, opts) + , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt') + , ca = fs.readFileSync(caFile) + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + '<html><body>Oh hi.</body></html>' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + test.strictSSL = true + test.ca = ca + test.headers = { host: 'testing.request.mikealrogers.com' } + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/deps/npm/node_modules/request/tests/test-https.js b/deps/npm/node_modules/request/tests/test-https.js new file mode 100644 index 0000000000..df7330b39d --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-https.js @@ -0,0 +1,86 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + +var s = server.createSSLServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + '<html><body>Oh hi.</body></html>' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/deps/npm/node_modules/request/tests/test-oauth.js b/deps/npm/node_modules/request/tests/test-oauth.js new file mode 100644 index 0000000000..72ca92333d --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-oauth.js @@ -0,0 +1,117 @@ +var hmacsign = require('../oauth').hmacsign + , assert = require('assert') + , qs = require('querystring') + , request = require('../main') + ; + +function getsignature (r) { + var sign + r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) { + if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1) + }) + return decodeURIComponent(sign) +} + +// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth + +var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', + { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_timestamp: '1272323042' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") + +console.log(reqsign) +console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') +assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') + +var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', + { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , oauth_timestamp: '1272323047' + , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") + +console.log(accsign) +console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') +assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') + +var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', + { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" + , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , oauth_signature_method: "HMAC-SHA1" + , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , oauth_timestamp: "1272325550" + , oauth_version: "1.0" + , status: 'setting up my twitter 私のさえずりを設定する' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") + +console.log(upsign) +console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') +assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') + + +var rsign = request.post( + { url: 'https://api.twitter.com/oauth/request_token' + , oauth: + { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , timestamp: '1272323042' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + } + }) + +setTimeout(function () { + console.log(getsignature(rsign)) + assert.equal(reqsign, getsignature(rsign)) +}) + +var raccsign = request.post( + { url: 'https://api.twitter.com/oauth/access_token' + , oauth: + { consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , signature_method: 'HMAC-SHA1' + , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , timestamp: '1272323047' + , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" + } + }) + +setTimeout(function () { + console.log(getsignature(raccsign)) + assert.equal(accsign, getsignature(raccsign)) +}, 1) + +var rupsign = request.post( + { url: 'http://api.twitter.com/1/statuses/update.json' + , oauth: + { consumer_key: "GDdmIQH6jhtmLUypg82g" + , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , signature_method: "HMAC-SHA1" + , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , timestamp: "1272325550" + , version: "1.0" + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA" + } + , form: {status: 'setting up my twitter 私のさえずりを設定する'} + }) +setTimeout(function () { + console.log(getsignature(rupsign)) + assert.equal(upsign, getsignature(rupsign)) +}, 1) + + + + diff --git a/deps/npm/node_modules/request/tests/test-params.js b/deps/npm/node_modules/request/tests/test-params.js new file mode 100644 index 0000000000..8354f6d8d2 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-params.js @@ -0,0 +1,92 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + '<html><body>Oh hi.</body></html>' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + //test.uri = s.url + '/' + i + request(s.url + '/' + i, test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/deps/npm/node_modules/request/tests/test-pipes.js b/deps/npm/node_modules/request/tests/test-pipes.js new file mode 100644 index 0000000000..1869874456 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-pipes.js @@ -0,0 +1,202 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var s = server.createServer(3453); + +function ValidationStream(str) { + this.str = str + this.buf = '' + this.on('data', function (data) { + this.buf += data + }) + this.on('end', function () { + assert.equal(this.str, this.buf) + }) + this.writable = true +} +util.inherits(ValidationStream, stream.Stream) +ValidationStream.prototype.write = function (chunk) { + this.emit('data', chunk) +} +ValidationStream.prototype.end = function (chunk) { + if (chunk) emit('data', chunk) + this.emit('end') +} + +s.listen(s.port, function () { + counter = 0; + + var check = function () { + counter = counter - 1 + if (counter === 0) { + console.log('All tests passed.') + setTimeout(function () { + process.exit(); + }, 500) + } + } + + // Test pipeing to a request object + s.once('/push', server.createPostValidator("mydata")); + + var mydata = new stream.Stream(); + mydata.readable = true + + counter++ + var r1 = request.put({url:'http://localhost:3453/push'}, function () { + check(); + }) + mydata.pipe(r1) + + mydata.emit('data', 'mydata'); + mydata.emit('end'); + + + // Test pipeing from a request object. + s.once('/pull', server.createGetResponse("mypulldata")); + + var mypulldata = new stream.Stream(); + mypulldata.writable = true + + counter++ + request({url:'http://localhost:3453/pull'}).pipe(mypulldata) + + var d = ''; + + mypulldata.write = function (chunk) { + d += chunk; + } + mypulldata.end = function () { + assert.equal(d, 'mypulldata'); + check(); + }; + + + s.on('/cat', function (req, resp) { + if (req.method === "GET") { + resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); + resp.end('asdf') + } else if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/plain-test'); + assert.equal(req.headers['content-length'], 4) + var validate = ''; + + req.on('data', function (chunk) {validate += chunk}) + req.on('end', function () { + resp.writeHead(201); + resp.end(); + assert.equal(validate, 'asdf'); + check(); + }) + } + }) + s.on('/pushjs', function (req, resp) { + if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/javascript'); + check(); + } + }) + s.on('/catresp', function (req, resp) { + request.get('http://localhost:3453/cat').pipe(resp) + }) + s.on('/doodle', function (req, resp) { + if (req.headers['x-oneline-proxy']) { + resp.setHeader('x-oneline-proxy', 'yup') + } + resp.writeHead('200', {'content-type':'image/png'}) + fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp) + }) + s.on('/onelineproxy', function (req, resp) { + var x = request('http://localhost:3453/doodle') + req.pipe(x) + x.pipe(resp) + }) + + counter++ + fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) + + counter++ + request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) + + counter++ + request.get('http://localhost:3453/catresp', function (e, resp, body) { + assert.equal(resp.headers['content-type'], 'text/plain-test'); + assert.equal(resp.headers['content-length'], 4) + check(); + }) + + var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png')) + + counter++ + request.get('http://localhost:3453/doodle').pipe(doodleWrite) + + doodleWrite.on('close', function () { + assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png'))) + check() + }) + + process.on('exit', function () { + fs.unlinkSync(path.join(__dirname, 'test.png')) + }) + + counter++ + request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { + assert.equal(resp.headers['x-oneline-proxy'], 'yup') + check() + }) + + s.on('/afterresponse', function (req, resp) { + resp.write('d') + resp.end() + }) + + counter++ + var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { + var v = new ValidationStream('d') + afterresp.pipe(v) + v.on('end', check) + }) + + s.on('/forward1', function (req, resp) { + resp.writeHead(302, {location:'/forward2'}) + resp.end() + }) + s.on('/forward2', function (req, resp) { + resp.writeHead('200', {'content-type':'image/png'}) + resp.write('d') + resp.end() + }) + + counter++ + var validateForward = new ValidationStream('d') + validateForward.on('end', check) + request.get('http://localhost:3453/forward1').pipe(validateForward) + + // Test pipe options + s.once('/opts', server.createGetResponse('opts response')); + + var optsStream = new stream.Stream(); + optsStream.writable = true + + var optsData = ''; + optsStream.write = function (buf) { + optsData += buf; + if (optsData === 'opts response') { + setTimeout(check, 10); + } + } + + optsStream.end = function () { + assert.fail('end called') + }; + + counter++ + request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false }) +}) diff --git a/deps/npm/node_modules/request/tests/test-pool.js b/deps/npm/node_modules/request/tests/test-pool.js new file mode 100644 index 0000000000..1e7d5786ad --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-pool.js @@ -0,0 +1,16 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200; + resp.end('asdf'); +}).listen(8080, function () { + request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) { + var agent = resp.request.agent; + assert.strictEqual(typeof agent, 'boolean'); + assert.strictEqual(agent, false); + s.close(); + }); +});
\ No newline at end of file diff --git a/deps/npm/node_modules/request/tests/test-proxy.js b/deps/npm/node_modules/request/tests/test-proxy.js new file mode 100644 index 0000000000..647157cae6 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-proxy.js @@ -0,0 +1,39 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var port = 6768 + , called = false + , proxiedHost = 'google.com' + ; + +var s = server.createServer(port) +s.listen(port, function () { + s.on('http://google.com/', function (req, res) { + called = true + assert.equal(req.headers.host, proxiedHost) + res.writeHeader(200) + res.end() + }) + request ({ + url: 'http://'+proxiedHost, + proxy: 'http://localhost:'+port + /* + //should behave as if these arguments where passed: + url: 'http://localhost:'+port, + headers: {host: proxiedHost} + //*/ + }, function (err, res, body) { + s.close() + }) +}) + +process.on('exit', function () { + assert.ok(called, 'the request must be made to the proxy server') +}) diff --git a/deps/npm/node_modules/request/tests/test-qs.js b/deps/npm/node_modules/request/tests/test-qs.js new file mode 100644 index 0000000000..1aac22bc96 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-qs.js @@ -0,0 +1,28 @@ +var request = request = require('../main.js') + , assert = require('assert') + ; + + +// Test adding a querystring +var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req1.path) +}, 1) + +// Test replacing a querystring value +var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req2.path) +}, 1) + +// Test appending a querystring value to the ones present in the uri +var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?x=y&q=search', req3.path) +}, 1) + +// Test leaving a querystring alone +var req4 = request.get({ uri: 'http://www.google.com?x=y'}) +setTimeout(function() { + assert.equal('/?x=y', req4.path) +}, 1) diff --git a/deps/npm/node_modules/request/tests/test-redirect.js b/deps/npm/node_modules/request/tests/test-redirect.js new file mode 100644 index 0000000000..b84844a796 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-redirect.js @@ -0,0 +1,154 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + +var s = server.createServer() + +s.listen(s.port, function () { + var server = 'http://localhost:' + s.port; + var hits = {} + var passed = 0; + + bouncer(301, 'temp') + bouncer(302, 'perm') + bouncer(302, 'nope') + + function bouncer(code, label) { + var landing = label+'_landing'; + + s.on('/'+label, function (req, res) { + hits[label] = true; + res.writeHead(code, { + 'location':server + '/'+landing, + 'set-cookie': 'ham=eggs' + }) + res.end() + }) + + s.on('/'+landing, function (req, res) { + if (req.method !== 'GET') { // We should only accept GET redirects + console.error("Got a non-GET request to the redirect destination URL"); + res.writeHead(400); + res.end(); + return; + } + // Make sure the cookie doesn't get included twice, see #139: + // Make sure cookies are set properly after redirect + assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs'); + hits[landing] = true; + res.writeHead(200) + res.end(landing) + }) + } + + // Permanent bounce + var jar = new Jar() + jar.add(new Cookie('quux=baz')) + request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.perm, 'Original request is to /perm') + assert.ok(hits.perm_landing, 'Forward to permanent landing URL') + assert.equal(body, 'perm_landing', 'Got permanent landing content') + passed += 1 + done() + }) + + // Temporary bounce + request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + // Prevent bouncing. + request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode) + assert.ok(hits.nope, 'Original request to /nope') + assert.ok(!hits.nope_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 302, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow post redirects by default + request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when post') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow post redirects when followAllRedirects true + request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects by default + request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode < 301) throw new Error('Status is not a redirect.') + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects even if followRedirect is set to true + request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow delete redirects when followAllRedirects true + request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + var reqs_done = 0; + function done() { + reqs_done += 1; + if(reqs_done == 9) { + console.log(passed + ' tests passed.') + s.close() + } + } +}) diff --git a/deps/npm/node_modules/request/tests/test-s3.js b/deps/npm/node_modules/request/tests/test-s3.js new file mode 100644 index 0000000000..5f59c4ad0a --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-s3.js @@ -0,0 +1,13 @@ +var request = require('../main') + +var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', + { aws: + { key: 'AKIAI6KIQRRVMGK3WK5Q' + , secret: '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' + , bucket: 'log.curlybracecast.com' + } + }, function (e, resp, body) { + console.log(r.headers) + console.log(body) + } +)
\ No newline at end of file diff --git a/deps/npm/node_modules/request/tests/test-timeout.js b/deps/npm/node_modules/request/tests/test-timeout.js new file mode 100644 index 0000000000..673f8ad86f --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-timeout.js @@ -0,0 +1,87 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); +var expectedBody = "waited"; +var remainingTests = 5; + +s.listen(s.port, function () { + // Request that waits for 200ms + s.on('/timeout', function (req, resp) { + setTimeout(function(){ + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write(expectedBody) + resp.end() + }, 200); + }); + + // Scenario that should timeout + var shouldTimeout = { + url: s.url + "/timeout", + timeout:100 + } + + + request(shouldTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + + // Scenario that shouldn't timeout + var shouldntTimeout = { + url: s.url + "/timeout", + timeout:300 + } + + request(shouldntTimeout, function (err, resp, body) { + assert.equal(err, null); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with no timeout set, so shouldn't timeout + var noTimeout = { + url: s.url + "/timeout" + } + + request(noTimeout, function (err, resp, body) { + assert.equal(err); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with a negative timeout value, should be treated a zero or the minimum delay + var negativeTimeout = { + url: s.url + "/timeout", + timeout:-1000 + } + + request(negativeTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + // Scenario with a float timeout value, should be rounded by setTimeout anyway + var floatTimeout = { + url: s.url + "/timeout", + timeout: 100.76 + } + + request(floatTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + function checkDone() { + if(--remainingTests == 0) { + s.close(); + console.log("All tests passed."); + } + } +}) + diff --git a/deps/npm/node_modules/request/tests/test-toJSON.js b/deps/npm/node_modules/request/tests/test-toJSON.js new file mode 100644 index 0000000000..b7c67effca --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-toJSON.js @@ -0,0 +1,14 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200 + resp.end('asdf') +}).listen(8080, function () { + var r = request('http://localhost:8080', function (e, resp) { + assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200) + s.close() + }) +})
\ No newline at end of file diff --git a/deps/npm/node_modules/request/tests/test-tunnel.js b/deps/npm/node_modules/request/tests/test-tunnel.js new file mode 100644 index 0000000000..58131b9bba --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-tunnel.js @@ -0,0 +1,61 @@ +// test that we can tunnel a https request over an http proxy +// keeping all the CA and whatnot intact. +// +// Note: this requires that squid is installed. +// If the proxy fails to start, we'll just log a warning and assume success. + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt') + , ca = fs.readFileSync(caFile) + , child_process = require('child_process') + , sqConf = path.resolve(__dirname, 'squid.conf') + , sqArgs = ['-f', sqConf, '-N', '-d', '5'] + , proxy = 'http://localhost:3128' + , hadError = null + +var squid = child_process.spawn('squid', sqArgs); +var ready = false + +squid.stderr.on('data', function (c) { + console.error('SQUIDERR ' + c.toString().trim().split('\n') + .join('\nSQUIDERR ')) + ready = c.toString().match(/ready to serve requests/i) +}) + +squid.stdout.on('data', function (c) { + console.error('SQUIDOUT ' + c.toString().trim().split('\n') + .join('\nSQUIDOUT ')) +}) + +squid.on('exit', function (c) { + console.error('exit '+c) + if (c && !ready) { + console.error('squid must be installed to run this test.') + c = null + hadError = null + process.exit(0) + return + } + + if (c) { + hadError = hadError || new Error('Squid exited with '+c) + } + if (hadError) throw hadError +}) + +setTimeout(function F () { + if (!ready) return setTimeout(F, 100) + request({ uri: 'https://registry.npmjs.org/request/' + , proxy: 'http://localhost:3128' + , ca: ca + , json: true }, function (er, body) { + hadError = er + console.log(er || typeof body) + if (!er) console.log("ok") + squid.kill('SIGKILL') + }) +}, 100) diff --git a/deps/npm/node_modules/retry/example/dns.js b/deps/npm/node_modules/retry/example/dns.js new file mode 100644 index 0000000000..e4082af729 --- /dev/null +++ b/deps/npm/node_modules/retry/example/dns.js @@ -0,0 +1,31 @@ +var dns = require('dns'); +var retry = require('../lib/retry'); + +function faultTolerantResolve(address, cb) { + var opts = { + times: 2, + factor: 2, + minTimeout: 1 * 1000, + maxTimeout: 2 * 1000, + randomize: true + }; + var operation = retry.operation(opts); + + operation.attempt(function(currentAttempt) { + dns.resolve(address, function(err, addresses) { + if (operation.retry(err)) { + return; + } + + cb(operation.mainError(), operation.errors(), addresses); + }); + }); +} + +faultTolerantResolve('nodejs.org', function(err, errors, addresses) { + console.warn('err:'); + console.log(err); + + console.warn('addresses:'); + console.log(addresses); +});
\ No newline at end of file diff --git a/deps/npm/node_modules/retry/test/common.js b/deps/npm/node_modules/retry/test/common.js new file mode 100644 index 0000000000..224720696e --- /dev/null +++ b/deps/npm/node_modules/retry/test/common.js @@ -0,0 +1,10 @@ +var common = module.exports; +var path = require('path'); + +var rootDir = path.join(__dirname, '..'); +common.dir = { + lib: rootDir + '/lib' +}; + +common.assert = require('assert'); +common.fake = require('fake');
\ No newline at end of file diff --git a/deps/npm/node_modules/retry/test/integration/test-retry-operation.js b/deps/npm/node_modules/retry/test/integration/test-retry-operation.js new file mode 100644 index 0000000000..d873d1fa88 --- /dev/null +++ b/deps/npm/node_modules/retry/test/integration/test-retry-operation.js @@ -0,0 +1,80 @@ +var common = require('../common'); +var assert = common.assert; +var fake = common.fake.create(); +var retry = require(common.dir.lib + '/retry'); + +(function testErrors() { + var operation = retry.operation(); + + var error = new Error('some error'); + var error2 = new Error('some other error'); + operation._errors.push(error); + operation._errors.push(error2); + + assert.deepEqual(operation.errors(), [error, error2]); +})(); + +(function testMainErrorReturnsMostFrequentError() { + var operation = retry.operation(); + var error = new Error('some error'); + var error2 = new Error('some other error'); + + operation._errors.push(error); + operation._errors.push(error2); + operation._errors.push(error); + + assert.strictEqual(operation.mainError(), error); +})(); + +(function testMainErrorReturnsLastErrorOnEqualCount() { + var operation = retry.operation(); + var error = new Error('some error'); + var error2 = new Error('some other error'); + + operation._errors.push(error); + operation._errors.push(error2); + + assert.strictEqual(operation.mainError(), error2); +})(); + +(function testAttempt() { + var operation = retry.operation(); + var fn = new Function(); + + var timeoutOpts = { + timeout: 1, + cb: function() {} + }; + operation.attempt(fn, timeoutOpts); + + assert.strictEqual(fn, operation._fn); + assert.strictEqual(timeoutOpts.timeout, operation._operationTimeout); + assert.strictEqual(timeoutOpts.cb, operation._operationTimeoutCb); +})(); + +(function testRetry() { + var times = 3; + var error = new Error('some error'); + var operation = retry.operation([1, 2, 3]); + var attempts = 0; + + var finalCallback = fake.callback('finalCallback'); + fake.expectAnytime(finalCallback); + + var fn = function() { + operation.attempt(function(currentAttempt) { + attempts++; + assert.equal(currentAttempt, attempts); + if (operation.retry(error)) { + return; + } + + assert.strictEqual(attempts, 4); + assert.strictEqual(operation.attempts(), attempts); + assert.strictEqual(operation.mainError(), error); + finalCallback(); + }); + }; + + fn(); +})();
\ No newline at end of file diff --git a/deps/npm/node_modules/retry/test/integration/test-timeouts.js b/deps/npm/node_modules/retry/test/integration/test-timeouts.js new file mode 100644 index 0000000000..7206b0fb0b --- /dev/null +++ b/deps/npm/node_modules/retry/test/integration/test-timeouts.js @@ -0,0 +1,69 @@ +var common = require('../common'); +var assert = common.assert; +var retry = require(common.dir.lib + '/retry'); + +(function testDefaultValues() { + var timeouts = retry.timeouts(); + + assert.equal(timeouts.length, 10); + assert.equal(timeouts[0], 1000); + assert.equal(timeouts[1], 2000); + assert.equal(timeouts[2], 4000); +})(); + +(function testDefaultValuesWithRandomize() { + var minTimeout = 5000; + var timeouts = retry.timeouts({ + minTimeout: minTimeout, + randomize: true + }); + + assert.equal(timeouts.length, 10); + assert.ok(timeouts[0] > minTimeout); + assert.ok(timeouts[1] > timeouts[0]); + assert.ok(timeouts[2] > timeouts[1]); +})(); + +(function testPassedTimeoutsAreUsed() { + var timeoutsArray = [1000, 2000, 3000]; + var timeouts = retry.timeouts(timeoutsArray); + assert.deepEqual(timeouts, timeoutsArray); + assert.notStrictEqual(timeouts, timeoutsArray); +})(); + +(function testTimeoutsAreWithinBoundaries() { + var minTimeout = 1000; + var maxTimeout = 10000; + var timeouts = retry.timeouts({ + minTimeout: minTimeout, + maxTimeout: maxTimeout + }); + for (var i = 0; i < timeouts; i++) { + assert.ok(timeouts[i] >= minTimeout); + assert.ok(timeouts[i] <= maxTimeout); + } +})(); + +(function testTimeoutsAreIncremental() { + var timeouts = retry.timeouts(); + var lastTimeout = timeouts[0]; + for (var i = 0; i < timeouts; i++) { + assert.ok(timeouts[i] > lastTimeout); + lastTimeout = timeouts[i]; + } +})(); + +(function testTimeoutsAreIncrementalForFactorsLessThanOne() { + var timeouts = retry.timeouts({ + retries: 3, + factor: 0.5 + }); + + var expected = [250, 500, 1000]; + assert.deepEqual(expected, timeouts); +})(); + +(function testRetries() { + var timeouts = retry.timeouts({retries: 2}); + assert.strictEqual(timeouts.length, 2); +})(); diff --git a/deps/npm/node_modules/retry/test/runner.js b/deps/npm/node_modules/retry/test/runner.js new file mode 100644 index 0000000000..e0ee2f570f --- /dev/null +++ b/deps/npm/node_modules/retry/test/runner.js @@ -0,0 +1,5 @@ +var far = require('far').create(); + +far.add(__dirname); +far.include(/\/test-.*\.js$/); +far.execute(); diff --git a/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf b/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf Binary files differnew file mode 100644 index 0000000000..ca12d60cb2 --- /dev/null +++ b/deps/npm/node_modules/slide/nodejs-controlling-flow.pdf |