summaryrefslogtreecommitdiff
path: root/node_modules/superagent/lib
diff options
context:
space:
mode:
authorAlee14 <alee14498@gmail.com>2017-03-26 15:18:10 -0400
committerAlee14 <alee14498@gmail.com>2017-03-26 15:18:10 -0400
commit29433e2f7dbd0e4a73d3c78ffe1005b922fb5982 (patch)
treeaa0ad3fe59468cbe452ee597e914839b68c01436 /node_modules/superagent/lib
parent878fefb4c4e1f12b804ae5c0def433fa873f4c8b (diff)
downloadAleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.tar.gz
AleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.tar.bz2
AleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.zip
Don't mind me i'm adding the discord.js files
Diffstat (limited to 'node_modules/superagent/lib')
-rw-r--r--node_modules/superagent/lib/client.js933
-rw-r--r--node_modules/superagent/lib/is-function.js15
-rw-r--r--node_modules/superagent/lib/is-object.js13
-rw-r--r--node_modules/superagent/lib/node/agent.js90
-rw-r--r--node_modules/superagent/lib/node/index.js1053
-rw-r--r--node_modules/superagent/lib/node/parsers/image.js10
-rw-r--r--node_modules/superagent/lib/node/parsers/index.js8
-rw-r--r--node_modules/superagent/lib/node/parsers/json.js19
-rw-r--r--node_modules/superagent/lib/node/parsers/text.js7
-rw-r--r--node_modules/superagent/lib/node/parsers/urlencoded.js19
-rw-r--r--node_modules/superagent/lib/node/response.js123
-rw-r--r--node_modules/superagent/lib/node/unzip.js69
-rw-r--r--node_modules/superagent/lib/request-base.js591
-rw-r--r--node_modules/superagent/lib/response-base.js133
-rw-r--r--node_modules/superagent/lib/should-retry.js23
-rw-r--r--node_modules/superagent/lib/utils.js68
16 files changed, 3174 insertions, 0 deletions
diff --git a/node_modules/superagent/lib/client.js b/node_modules/superagent/lib/client.js
new file mode 100644
index 0000000..132542b
--- /dev/null
+++ b/node_modules/superagent/lib/client.js
@@ -0,0 +1,933 @@
+/**
+ * Root reference for iframes.
+ */
+
+var root;
+if (typeof window !== 'undefined') { // Browser window
+ root = window;
+} else if (typeof self !== 'undefined') { // Web Worker
+ root = self;
+} else { // Other environments
+ console.warn("Using browser-only version of superagent in non-browser environment");
+ root = this;
+}
+
+var Emitter = require('component-emitter');
+var RequestBase = require('./request-base');
+var isObject = require('./is-object');
+var isFunction = require('./is-function');
+var ResponseBase = require('./response-base');
+var shouldRetry = require('./should-retry');
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Expose `request`.
+ */
+
+var request = exports = module.exports = function(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new exports.Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new exports.Request('GET', method);
+ }
+
+ return new exports.Request(method, url);
+}
+
+exports.Request = Request;
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ throw Error("Browser-only verison of superagent could not find XHR");
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ pushEncodedKeyValuePair(pairs, key, obj[key]);
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Helps 'serialize' with serializing arrays.
+ * Mutates the pairs array.
+ *
+ * @param {Array} pairs
+ * @param {String} key
+ * @param {Mixed} val
+ */
+
+function pushEncodedKeyValuePair(pairs, key, val) {
+ if (val != null) {
+ if (Array.isArray(val)) {
+ val.forEach(function(v) {
+ pushEncodedKeyValuePair(pairs, key, v);
+ });
+ } else if (isObject(val)) {
+ for(var subkey in val) {
+ pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
+ }
+ } else {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(val));
+ }
+ } else if (val === null) {
+ pairs.push(encodeURIComponent(key));
+ }
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var pair;
+ var pos;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ pos = pair.indexOf('=');
+ if (pos == -1) {
+ obj[decodeURIComponent(pair)] = '';
+ } else {
+ obj[decodeURIComponent(pair.slice(0, pos))] =
+ decodeURIComponent(pair.slice(pos + 1));
+ }
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Check if `mime` is json or has +json structured syntax suffix.
+ *
+ * @param {String} mime
+ * @return {Boolean}
+ * @api private
+ */
+
+function isJSON(mime) {
+ return /[\/+]json\b/.test(mime);
+}
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req) {
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ var status = this.xhr.status;
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+ this._setStatusProperties(status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this._setHeaderProperties(this.header);
+
+ if (null === this.text && req._responseType) {
+ this.body = this.xhr.response;
+ } else {
+ this.body = this.req.method != 'HEAD'
+ ? this._parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+ }
+}
+
+ResponseBase(Response.prototype);
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype._parseBody = function(str){
+ var parse = request.parse[this.type];
+ if(this.req._parser) {
+ return this.req._parser(this, str);
+ }
+ if (!parse && isJSON(this.type)) {
+ parse = request.parse['application/json'];
+ }
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {}; // preserves header name case
+ this._header = {}; // coerces header names to lowercase
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ // issue #675: return the raw response if the response parsing fails
+ if (self.xhr) {
+ // ie9 doesn't have 'response' property
+ err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response;
+ // issue #876: return the http status code if the response parsing fails
+ err.status = self.xhr.status ? self.xhr.status : null;
+ err.statusCode = err.status; // backwards-compat only
+ } else {
+ err.rawResponse = null;
+ err.status = null;
+ }
+
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ var new_err;
+ try {
+ if (!self._isResponseOK(res)) {
+ new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+ }
+ } catch(e) {
+ new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android
+ }
+
+ // #1000 don't catch errors from the callback to avoid double calling it
+ if (new_err) {
+ self.callback(new_err, res);
+ } else {
+ self.callback(null, res);
+ }
+ });
+}
+
+/**
+ * Mixin `Emitter` and `RequestBase`.
+ */
+
+Emitter(Request.prototype);
+RequestBase(Request.prototype);
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} [pass] optional in case of using 'bearer' as type
+ * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass, options){
+ if (typeof pass === 'object' && pass !== null) { // pass is optional and can substitute for options
+ options = pass;
+ }
+ if (!options) {
+ options = {
+ type: 'function' === typeof btoa ? 'basic' : 'auto',
+ }
+ }
+
+ switch (options.type) {
+ case 'basic':
+ this.set('Authorization', 'Basic ' + btoa(user + ':' + pass));
+ break;
+
+ case 'auto':
+ this.username = user;
+ this.password = pass;
+ break;
+
+ case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
+ this.set('Authorization', 'Bearer ' + user);
+ break;
+ }
+ return this;
+};
+
+/**
+ * Add query-string `val`.
+ *
+ * Examples:
+ *
+ * request.get('/shoes')
+ * .query('size=10')
+ * .query({ color: 'blue' })
+ *
+ * @param {Object|String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `options` (or filename).
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String|Object} options
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, options){
+ if (file) {
+ if (this._data) {
+ throw Error("superagent can't mix .send() and .attach()");
+ }
+
+ this._getFormData().append(field, file, options || file.name);
+ }
+ return this;
+};
+
+Request.prototype._getFormData = function(){
+ if (!this._formData) {
+ this._formData = new root.FormData();
+ }
+ return this._formData;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ // console.log(this._retries, this._maxRetries)
+ if (this._maxRetries && this._retries++ < this._maxRetries && shouldRetry(err, res)) {
+ return this._retry();
+ }
+
+ var fn = this._callback;
+ this.clearTimeout();
+
+ if (err) {
+ if (this._maxRetries) err.retries = this._retries - 1;
+ this.emit('error', err);
+ }
+
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
+ err.crossDomain = true;
+
+ err.status = this.status;
+ err.method = this.method;
+ err.url = this.url;
+
+ this.callback(err);
+};
+
+// This only warns, because the request is still likely to work
+Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){
+ console.warn("This is not supported in browser version of superagent");
+ return this;
+};
+
+// This throws, because it can't send/receive data as expected
+Request.prototype.pipe = Request.prototype.write = function(){
+ throw Error("Streaming is not supported in browser version of superagent");
+};
+
+/**
+ * Compose querystring to append to req.url
+ *
+ * @api private
+ */
+
+Request.prototype._appendQueryString = function(){
+ var query = this._query.join('&');
+ if (query) {
+ this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
+ }
+
+ if (this._sort) {
+ var index = this.url.indexOf('?');
+ if (index >= 0) {
+ var queryArr = this.url.substring(index + 1).split('&');
+ if (isFunction(this._sort)) {
+ queryArr.sort(this._sort);
+ } else {
+ queryArr.sort();
+ }
+ this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
+ }
+ }
+};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+Request.prototype._isHost = function _isHost(obj) {
+ // Native objects stringify to [object File], [object Blob], [object FormData], etc.
+ return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]';
+}
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ if (this._endCalled) {
+ console.warn("Warning: .end() was called twice. This is not supported in superagent");
+ }
+ this._endCalled = true;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // querystring
+ this._appendQueryString();
+
+ return this._end();
+};
+
+Request.prototype._end = function() {
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var data = this._formData || this._data;
+
+ this._setTimeouts();
+
+ // state change
+ xhr.onreadystatechange = function(){
+ var readyState = xhr.readyState;
+ if (readyState >= 2 && self._responseTimeoutTimer) {
+ clearTimeout(self._responseTimeoutTimer);
+ }
+ if (4 != readyState) {
+ return;
+ }
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (!status) {
+ if (self.timedout || self._aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(direction, e) {
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ e.direction = direction;
+ self.emit('progress', e);
+ }
+ if (this.hasListeners('progress')) {
+ try {
+ xhr.onprogress = handleProgress.bind(null, 'download');
+ if (xhr.upload) {
+ xhr.upload.onprogress = handleProgress.bind(null, 'upload');
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+ }
+
+ // initiate request
+ try {
+ if (this.username && this.password) {
+ xhr.open(this.method, this.url, true, this.username, this.password);
+ } else {
+ xhr.open(this.method, this.url, true);
+ }
+ } catch (err) {
+ // see #1149
+ return this.callback(err);
+ }
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
+ // serialize stuff
+ var contentType = this._header['content-type'];
+ var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (!serialize && isJSON(contentType)) {
+ serialize = request.serialize['application/json'];
+ }
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+
+ if (this.header.hasOwnProperty(field))
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ if (this._responseType) {
+ xhr.responseType = this._responseType;
+ }
+
+ // send stuff
+ this.emit('request', this);
+
+ // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
+ // We need null here if data is undefined
+ xhr.send(typeof data !== 'undefined' ? data : null);
+ return this;
+};
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * OPTIONS query to `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.options = function(url, data, fn){
+ var req = request('OPTIONS', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} [data]
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+function del(url, data, fn){
+ var req = request('DELETE', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+request['del'] = del;
+request['delete'] = del;
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} [data]
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} [data]
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
diff --git a/node_modules/superagent/lib/is-function.js b/node_modules/superagent/lib/is-function.js
new file mode 100644
index 0000000..5fb118e
--- /dev/null
+++ b/node_modules/superagent/lib/is-function.js
@@ -0,0 +1,15 @@
+/**
+ * Check if `fn` is a function.
+ *
+ * @param {Function} fn
+ * @return {Boolean}
+ * @api private
+ */
+var isObject = require('./is-object');
+
+function isFunction(fn) {
+ var tag = isObject(fn) ? Object.prototype.toString.call(fn) : '';
+ return tag === '[object Function]';
+}
+
+module.exports = isFunction;
diff --git a/node_modules/superagent/lib/is-object.js b/node_modules/superagent/lib/is-object.js
new file mode 100644
index 0000000..dff357c
--- /dev/null
+++ b/node_modules/superagent/lib/is-object.js
@@ -0,0 +1,13 @@
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return null !== obj && 'object' === typeof obj;
+}
+
+module.exports = isObject;
diff --git a/node_modules/superagent/lib/node/agent.js b/node_modules/superagent/lib/node/agent.js
new file mode 100644
index 0000000..ad2a8f6
--- /dev/null
+++ b/node_modules/superagent/lib/node/agent.js
@@ -0,0 +1,90 @@
+
+/**
+ * Module dependencies.
+ */
+
+var CookieJar = require('cookiejar').CookieJar;
+var CookieAccess = require('cookiejar').CookieAccessInfo;
+var parse = require('url').parse;
+var request = require('../..');
+var methods = require('methods');
+
+/**
+ * Expose `Agent`.
+ */
+
+module.exports = Agent;
+
+/**
+ * Initialize a new `Agent`.
+ *
+ * @api public
+ */
+
+function Agent(options) {
+ if (!(this instanceof Agent)) return new Agent(options);
+ if (options) {
+ this._ca = options.ca;
+ this._key = options.key;
+ this._pfx = options.pfx;
+ this._cert = options.cert;
+ }
+ this.jar = new CookieJar;
+}
+
+/**
+ * Save the cookies in the given `res` to
+ * the agent's cookie jar for persistence.
+ *
+ * @param {Response} res
+ * @api private
+ */
+
+Agent.prototype._saveCookies = function(res){
+ var cookies = res.headers['set-cookie'];
+ if (cookies) this.jar.setCookies(cookies);
+};
+
+/**
+ * Attach cookies when available to the given `req`.
+ *
+ * @param {Request} req
+ * @api private
+ */
+
+Agent.prototype._attachCookies = function(req){
+ var url = parse(req.url);
+ var access = CookieAccess(url.hostname, url.pathname, 'https:' == url.protocol);
+ var cookies = this.jar.getCookies(access).toValueString();
+ req.cookies = cookies;
+};
+
+// generate HTTP verb methods
+if (methods.indexOf('del') == -1) {
+ // create a copy so we don't cause conflicts with
+ // other packages using the methods package and
+ // npm 3.x
+ methods = methods.slice(0);
+ methods.push('del');
+}
+methods.forEach(function(method){
+ var name = method;
+ method = 'del' == method ? 'delete' : method;
+
+ method = method.toUpperCase();
+ Agent.prototype[name] = function(url, fn){
+ var req = new request.Request(method, url);
+ req.ca(this._ca);
+ req.key(this._key);
+ req.pfx(this._pfx);
+ req.cert(this._cert);
+
+ req.on('response', this._saveCookies.bind(this));
+ req.on('redirect', this._saveCookies.bind(this));
+ req.on('redirect', this._attachCookies.bind(this, req));
+ this._attachCookies(req);
+
+ fn && req.end(fn);
+ return req;
+ };
+});
diff --git a/node_modules/superagent/lib/node/index.js b/node_modules/superagent/lib/node/index.js
new file mode 100644
index 0000000..ef06689
--- /dev/null
+++ b/node_modules/superagent/lib/node/index.js
@@ -0,0 +1,1053 @@
+
+/**
+ * Module dependencies.
+ */
+
+var debug = require('debug')('superagent');
+var formidable = require('formidable');
+var FormData = require('form-data');
+var Response = require('./response');
+var parse = require('url').parse;
+var format = require('url').format;
+var resolve = require('url').resolve;
+var methods = require('methods');
+var Stream = require('stream');
+var utils = require('../utils');
+var unzip = require('./unzip').unzip;
+var extend = require('extend');
+var mime = require('mime');
+var https = require('https');
+var http = require('http');
+var fs = require('fs');
+var qs = require('qs');
+var zlib = require('zlib');
+var util = require('util');
+var pkg = require('../../package.json');
+var RequestBase = require('../request-base');
+var isFunction = require('../is-function');
+var shouldRetry = require('../should-retry');
+
+var request = exports = module.exports = function(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new exports.Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new exports.Request('GET', method);
+ }
+
+ return new exports.Request(method, url);
+}
+
+/**
+ * Expose `Request`.
+ */
+
+exports.Request = Request;
+
+/**
+ * Expose the agent function
+ */
+
+exports.agent = require('./agent');
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Expose `Response`.
+ */
+
+exports.Response = Response;
+
+/**
+ * Define "form" mime type.
+ */
+
+mime.define({
+ 'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data']
+});
+
+/**
+ * Protocol map.
+ */
+
+exports.protocols = {
+ 'http:': http,
+ 'https:': https
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+exports.serialize = {
+ 'application/x-www-form-urlencoded': qs.stringify,
+ 'application/json': JSON.stringify
+};
+
+/**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(res, fn){
+ * fn(null, res);
+ * };
+ *
+ */
+
+exports.parse = require('./parsers');
+
+/**
+ * Initialize internal header tracking properties on a request instance.
+ *
+ * @param {Object} req the instance
+ * @api private
+ */
+function _initHeaders(req) {
+ var ua = 'node-superagent/' + pkg.version;
+ req._header = { // coerces header names to lowercase
+ 'user-agent': ua
+ };
+ req.header = { // preserves header name case
+ 'User-Agent': ua
+ };
+}
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String|Object} url
+ * @api public
+ */
+
+function Request(method, url) {
+ Stream.call(this);
+ if ('string' != typeof url) url = format(url);
+ this._agent = false;
+ this._formData = null;
+ this.method = method;
+ this.url = url;
+ _initHeaders(this);
+ this.writable = true;
+ this._redirects = 0;
+ this.redirects(method === 'HEAD' ? 0 : 5);
+ this.cookies = '';
+ this.qs = {};
+ this.qsRaw = [];
+ this._redirectList = [];
+ this._streamRequest = false;
+ this.once('end', this.clearTimeout.bind(this));
+}
+
+/**
+ * Inherit from `Stream` (which inherits from `EventEmitter`).
+ * Mixin `RequestBase`.
+ */
+util.inherits(Request, Stream);
+RequestBase(Request.prototype);
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `options` (or filename).
+ *
+ * ``` js
+ * request.post('http://localhost/upload')
+ * .attach(new Buffer('<b>Hello world</b>'), 'hello.html')
+ * .end(callback);
+ * ```
+ *
+ * A filename may also be used:
+ *
+ * ``` js
+ * request.post('http://localhost/upload')
+ * .attach('files', 'image.jpg')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {String|fs.ReadStream|Buffer} file
+ * @param {String|Object} options
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, options){
+ if (file) {
+ if (this._data) {
+ throw Error("superagent can't mix .send() and .attach()");
+ }
+
+ var o = options || {};
+ if ('string' == typeof options) {
+ o = { filename: options };
+ }
+
+ if ('string' == typeof file) {
+ if (!o.filename) o.filename = file;
+ debug('creating `fs.ReadStream` instance for file: %s', file);
+ file = fs.createReadStream(file);
+ } else if (!o.filename && file.path) {
+ o.filename = file.path;
+ }
+
+ this._getFormData().append(field, file, o);
+ }
+ return this;
+};
+
+Request.prototype._getFormData = function() {
+ if (!this._formData) {
+ this._formData = new FormData();
+ var that = this;
+ this._formData.on('error', function(err) {
+ that.emit('error', err);
+ that.abort();
+ });
+ }
+ return this._formData;
+};
+
+/**
+ * Gets/sets the `Agent` to use for this HTTP request. The default (if this
+ * function is not called) is to opt out of connection pooling (`agent: false`).
+ *
+ * @param {http.Agent} agent
+ * @return {http.Agent}
+ * @api public
+ */
+
+Request.prototype.agent = function(agent){
+ if (!arguments.length) return this._agent;
+ this._agent = agent;
+ return this;
+};
+
+/**
+ * Set _Content-Type_ response header passed through `mime.lookup()`.
+ *
+ * Examples:
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('json')
+ * .send(jsonstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/json')
+ * .send(jsonstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ return this.set('Content-Type', ~type.indexOf('/')
+ ? type
+ : mime.lookup(type));
+};
+
+/**
+ * Set _Accept_ response header passed through `mime.lookup()`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ return this.set('Accept', ~type.indexOf('/')
+ ? type
+ : mime.lookup(type));
+};
+
+/**
+ * Add query-string `val`.
+ *
+ * Examples:
+ *
+ * request.get('/shoes')
+ * .query('size=10')
+ * .query({ color: 'blue' })
+ *
+ * @param {Object|String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.query = function(val){
+ if ('string' == typeof val) {
+ this.qsRaw.push(val);
+ return this;
+ }
+
+ extend(this.qs, val);
+ return this;
+};
+
+/**
+ * Write raw `data` / `encoding` to the socket.
+ *
+ * @param {Buffer|String} data
+ * @param {String} encoding
+ * @return {Boolean}
+ * @api public
+ */
+
+Request.prototype.write = function(data, encoding){
+ var req = this.request();
+ if (!this._streamRequest) {
+ this._streamRequest = true;
+ }
+ return req.write(data, encoding);
+};
+
+/**
+ * Pipe the request body to `stream`.
+ *
+ * @param {Stream} stream
+ * @param {Object} options
+ * @return {Stream}
+ * @api public
+ */
+
+Request.prototype.pipe = function(stream, options){
+ this.piped = true; // HACK...
+ this.buffer(false);
+ this.end();
+ return this._pipeContinue(stream, options);
+};
+
+Request.prototype._pipeContinue = function(stream, options){
+ var self = this;
+ this.req.once('response', function(res){
+ // redirect
+ var redirect = isRedirect(res.statusCode);
+ if (redirect && self._redirects++ != self._maxRedirects) {
+ return self._redirect(res)._pipeContinue(stream, options);
+ }
+
+ self.res = res;
+ self._emitResponse();
+ if (self._aborted) return;
+
+ if (self._shouldUnzip(res)) {
+ res.pipe(zlib.createUnzip()).pipe(stream, options);
+ } else {
+ res.pipe(stream, options);
+ }
+ res.once('end', function(){
+ self.emit('end');
+ });
+ });
+ return stream;
+};
+
+/**
+ * Enable / disable buffering.
+ *
+ * @return {Boolean} [val]
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.buffer = function(val){
+ this._buffer = (false !== val);
+ return this;
+};
+
+/**
+ * Redirect to `url
+ *
+ * @param {IncomingMessage} res
+ * @return {Request} for chaining
+ * @api private
+ */
+
+Request.prototype._redirect = function(res){
+ var url = res.headers.location;
+ if (!url) {
+ return this.callback(new Error('No location header for redirect'), res);
+ }
+
+ debug('redirect %s -> %s', this.url, url);
+
+ // location
+ url = resolve(this.url, url);
+
+ // ensure the response is being consumed
+ // this is required for Node v0.10+
+ res.resume();
+
+ var headers = this.req._headers;
+
+ var shouldStripCookie = parse(url).host !== parse(this.url).host;
+
+ // implementation of 302 following defacto standard
+ if (res.statusCode == 301 || res.statusCode == 302){
+ // strip Content-* related fields
+ // in case of POST etc
+ headers = utils.cleanHeader(this.req._headers, shouldStripCookie);
+
+ // force GET
+ this.method = 'HEAD' == this.method
+ ? 'HEAD'
+ : 'GET';
+
+ // clear data
+ this._data = null;
+ }
+ // 303 is always GET
+ if (res.statusCode == 303) {
+ // strip Content-* related fields
+ // in case of POST etc
+ headers = utils.cleanHeader(this.req._headers, shouldStripCookie);
+
+ // force method
+ this.method = 'GET';
+
+ // clear data
+ this._data = null;
+ }
+ // 307 preserves method
+ // 308 preserves method
+ delete headers.host;
+
+ delete this.req;
+ delete this._formData;
+
+ // remove all add header except User-Agent
+ _initHeaders(this)
+
+ // redirect
+ this._endCalled = false;
+ this.url = url;
+ this.qs = {};
+ this.qsRaw = [];
+ this.set(headers);
+ this.emit('redirect', res);
+ this._redirectList.push(this.url);
+ this.end(this._callback);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * Examples:
+ *
+ * .auth('tobi', 'learnboost')
+ * .auth('tobi:learnboost')
+ * .auth('tobi')
+ * .auth(accessToken, { type: 'bearer' })
+ *
+ * @param {String} user
+ * @param {String} [pass]
+ * @param {Object} [options] options with authorization type 'basic' or 'bearer' ('basic' is default)
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass, options){
+ if (1 === arguments.length) pass = '';
+ if (2 === arguments.length && typeof pass === 'object') options = pass;
+ if (!options) {
+ options = { type: 'basic' };
+ }
+ switch (options.type) {
+ case 'bearer':
+ return this.set('Authorization', 'Bearer ' + user);
+
+ default: // 'basic'
+ if (!~user.indexOf(':')) user = user + ':';
+ var str = new Buffer(user + pass).toString('base64');
+ return this.set('Authorization', 'Basic ' + str);
+ }
+};
+
+/**
+ * Set the certificate authority option for https request.
+ *
+ * @param {Buffer | Array} cert
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.ca = function(cert){
+ this._ca = cert;
+ return this;
+};
+
+/**
+ * Set the client certificate key option for https request.
+ *
+ * @param {Buffer | String} cert
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.key = function(cert){
+ this._key = cert;
+ return this;
+};
+
+/**
+ * Set the key, certificate, and CA certs of the client in PFX or PKCS12 format.
+ *
+ * @param {Buffer | String} cert
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.pfx = function(cert){
+ this._pfx = cert;
+ return this;
+};
+
+/**
+ * Set the client certificate option for https request.
+ *
+ * @param {Buffer | String} cert
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.cert = function(cert){
+ this._cert = cert;
+ return this;
+};
+
+/**
+ * Return an http[s] request.
+ *
+ * @return {OutgoingMessage}
+ * @api private
+ */
+
+Request.prototype.request = function(){
+ if (this.req) return this.req;
+
+ var self = this;
+ var options = {};
+ var url = this.url;
+ var retries = this._retries;
+
+ // default to http://
+ if (0 != url.indexOf('http')) url = 'http://' + url;
+ url = parse(url);
+
+ // support unix sockets
+ if (/^https?\+unix:/.test(url.protocol) === true) {
+ // get the protocol
+ url.protocol = url.protocol.split('+')[0] + ':';
+
+ // get the socket, path
+ var unixParts = url.path.match(/^([^/]+)(.+)$/);
+ options.socketPath = unixParts[1].replace(/%2F/g, '/');
+ url.pathname = unixParts[2];
+ }
+
+ // options
+ options.method = this.method;
+ options.port = url.port;
+ options.path = url.pathname;
+ options.host = url.hostname;
+ options.ca = this._ca;
+ options.key = this._key;
+ options.pfx = this._pfx;
+ options.cert = this._cert;
+ options.agent = this._agent;
+
+ // initiate request
+ var mod = exports.protocols[url.protocol];
+
+ // request
+ var req = this.req = mod.request(options);
+ if ('HEAD' != options.method) {
+ req.setHeader('Accept-Encoding', 'gzip, deflate');
+ }
+ this.protocol = url.protocol;
+ this.host = url.host;
+
+ // expose events
+ req.once('drain', function(){ self.emit('drain'); });
+
+ req.once('error', function(err){
+ // flag abortion here for out timeouts
+ // because node will emit a faux-error "socket hang up"
+ // when request is aborted before a connection is made
+ if (self._aborted) return;
+ // if not the same, we are in the **old** (cancelled) request,
+ // so need to continue (same as for above)
+ if (self._retries !== retries) return;
+ // if we've received a response then we don't want to let
+ // an error in the request blow up the response
+ if (self.response) return;
+ self.callback(err);
+ });
+
+ // auth
+ if (url.auth) {
+ var auth = url.auth.split(':');
+ this.auth(auth[0], auth[1]);
+ }
+
+ // query
+ if (url.search)
+ this.query(url.search.substr(1));
+
+ // add cookies
+ if (this.cookies) req.setHeader('Cookie', this.cookies);
+
+ for (var key in this.header) {
+ if (this.header.hasOwnProperty(key))
+ req.setHeader(key, this.header[key]);
+ }
+
+ try {
+ this._appendQueryString(req);
+ } catch (e) {
+ return this.emit('error', e);
+ }
+
+ return req;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ // console.log(this._retries, this._maxRetries)
+ if (this._maxRetries && this._retries++ < this._maxRetries && shouldRetry(err, res)) {
+ return this._retry();
+ }
+
+ // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime.
+ var fn = this._callback || noop;
+ this.clearTimeout();
+ if (this.called) return console.warn('superagent: double callback bug');
+ this.called = true;
+
+ if (!err) {
+ if (this._isResponseOK(res)) {
+ return fn(err, res);
+ }
+
+ var msg = 'Unsuccessful HTTP response';
+ if (res) {
+ msg = http.STATUS_CODES[res.status] || msg;
+ }
+ err = new Error(msg);
+ err.status = res ? res.status : undefined;
+ }
+
+ err.response = res;
+ if (this._maxRetries) err.retries = this._retries - 1;
+
+ // only emit error event if there is a listener
+ // otherwise we assume the callback to `.end()` will get the error
+ if (err && this.listeners('error').length > 0) {
+ this.emit('error', err);
+ }
+
+ fn(err, res);
+};
+
+/**
+ * Compose querystring to append to req.path
+ *
+ * @return {String} querystring
+ * @api private
+ */
+
+Request.prototype._appendQueryString = function(req){
+ var query = qs.stringify(this.qs, { indices: false, strictNullHandling: true });
+ query += ((query.length && this.qsRaw.length) ? '&' : '') + this.qsRaw.join('&');
+ req.path += query.length ? (~req.path.indexOf('?') ? '&' : '?') + query : '';
+
+ if (this._sort) {
+ var index = req.path.indexOf('?');
+ if (index >= 0) {
+ var queryArr = req.path.substring(index + 1).split('&');
+ if (isFunction(this._sort)) {
+ queryArr.sort(this._sort);
+ } else {
+ queryArr.sort();
+ }
+ req.path = req.path.substring(0, index) + '?' + queryArr.join('&');
+ }
+ }
+};
+
+/**
+ * Check if `obj` is a host object,
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+Request.prototype._isHost = function _isHost(obj) {
+ return Buffer.isBuffer(obj) || obj instanceof Stream || obj instanceof FormData;
+}
+
+/**
+ * Initiate request, invoking callback `fn(err, res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype._emitResponse = function(body, files){
+ var response = new Response(this);
+ this.response = response;
+ response.redirects = this._redirectList;
+ if (undefined !== body) {
+ response.body = body;
+ }
+ response.files = files;
+ this.emit('response', response);
+ return response;
+};
+
+Request.prototype.end = function(fn){
+ this.request();
+ debug('%s %s', this.method, this.url);
+
+ if (this._endCalled) {
+ console.warn("Warning: .end() was called twice. This is not supported in superagent");
+ }
+ this._endCalled = true;
+
+ // store callback
+ this._callback = fn || noop;
+
+ return this._end();
+};
+
+Request.prototype._end = function() {
+ var self = this;
+ var data = this._data;
+ var req = this.req;
+ var buffer = this._buffer;
+ var method = this.method;
+
+ this._setTimeouts();
+
+ // body
+ if ('HEAD' != method && !req._headerSent) {
+ // serialize stuff
+ if ('string' != typeof data) {
+ var contentType = req.getHeader('Content-Type')
+ // Parse out just the content type from the header (ignore the charset)
+ if (contentType) contentType = contentType.split(';')[0]
+ var serialize = exports.serialize[contentType];
+ if (!serialize && isJSON(contentType)) {
+ serialize = exports.serialize['application/json'];
+ }
+ if (serialize) data = serialize(data);
+ }
+
+ // content-length
+ if (data && !req.getHeader('Content-Length')) {
+ req.setHeader('Content-Length', Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data));
+ }
+ }
+
+ // response
+ req.once('response', function(res){
+ debug('%s %s -> %s', self.method, self.url, res.statusCode);
+
+ if (self._responseTimeoutTimer) {
+ clearTimeout(self._responseTimeoutTimer);
+ }
+
+ if (self.piped) {
+ return;
+ }
+
+ var max = self._maxRedirects;
+ var mime = utils.type(res.headers['content-type'] || '') || 'text/plain';
+ var type = mime.split('/')[0];
+ var multipart = 'multipart' == type;
+ var redirect = isRedirect(res.statusCode);
+ var parser = self._parser;
+ var responseType = self._responseType;
+
+ self.res = res;
+
+ // redirect
+ if (redirect && self._redirects++ != max) {
+ return self._redirect(res);
+ }
+
+ if ('HEAD' == self.method) {
+ self.emit('end');
+ self.callback(null, self._emitResponse());
+ return;
+ }
+
+ // zlib support
+ if (self._shouldUnzip(res)) {
+ unzip(req, res);
+ }
+
+ if (!parser) {
+ if (responseType) {
+ parser = exports.parse.image; // It's actually a generic Buffer
+ buffer = true;
+ } else if (multipart) {
+ var form = new formidable.IncomingForm();
+ parser = form.parse.bind(form);
+ buffer = true;
+ } else if (isImageOrVideo(mime)) {
+ parser = exports.parse.image;
+ buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent
+ } else if (exports.parse[mime]) {
+ parser = exports.parse[mime];
+ } else if ('text' == type) {
+ parser = exports.parse.text;
+ buffer = (buffer !== false);
+
+ // everyone wants their own white-labeled json
+ } else if (isJSON(mime)) {
+ parser = exports.parse['application/json'];
+ buffer = (buffer !== false);
+ } else if (buffer) {
+ parser = exports.parse.text;
+ }
+ }
+
+ // by default only buffer text/*, json and messed up thing from hell
+ if (undefined === buffer && isText(mime) || isJSON(mime)) {
+ buffer = true;
+ }
+
+ var parserHandlesEnd = false;
+ if (parser) {
+ try {
+ // Unbuffered parsers are supposed to emit response early,
+ // which is weird BTW, because response.body won't be there.
+ parserHandlesEnd = buffer;
+
+ parser(res, function(err, obj, files) {
+ if (self.timedout) {
+ // Timeout has already handled all callbacks
+ return;
+ }
+
+ // Intentional (non-timeout) abort is supposed to preserve partial response,
+ // even if it doesn't parse.
+ if (err && !self._aborted) {
+ return self.callback(err);
+ }
+
+ if (parserHandlesEnd) {
+ self.emit('end');
+ self.callback(null, self._emitResponse(obj, files));
+ }
+ });
+ } catch (err) {
+ self.callback(err);
+ return;
+ }
+ }
+
+ self.res = res;
+
+ // unbuffered
+ if (!buffer) {
+ debug('unbuffered %s %s', self.method, self.url);
+ self.callback(null, self._emitResponse());
+ if (multipart) return // allow multipart to handle end event
+ res.once('end', function(){
+ debug('end %s %s', self.method, self.url);
+ self.emit('end');
+ })
+ return;
+ }
+
+ // terminating events
+ res.once('error', function(err){
+ self.callback(err, null);
+ });
+ if (!parserHandlesEnd) res.once('end', function(){
+ debug('end %s %s', self.method, self.url);
+ // TODO: unless buffering emit earlier to stream
+ self.emit('end');
+ self.callback(null, self._emitResponse());
+ });
+ });
+
+ this.emit('request', this);
+
+ // if a FormData instance got created, then we send that as the request body
+ var formData = this._formData;
+ if (formData) {
+
+ // set headers
+ var headers = formData.getHeaders();
+ for (var i in headers) {
+ debug('setting FormData header: "%s: %s"', i, headers[i]);
+ req.setHeader(i, headers[i]);
+ }
+
+ // attempt to get "Content-Length" header
+ formData.getLength(function(err, length) {
+ // TODO: Add chunked encoding when no length (if err)
+
+ debug('got FormData Content-Length: %s', length);
+ if ('number' == typeof length) {
+ req.setHeader('Content-Length', length);
+ }
+
+ var getProgressMonitor = function () {
+ var lengthComputable = true;
+ var total = req.getHeader('Content-Length');
+ var loaded = 0;
+
+ var progress = new Stream.Transform();
+ progress._transform = function (chunk, encoding, cb) {
+ loaded += chunk.length;
+ self.emit('progress', {
+ direction: 'upload',
+ lengthComputable: lengthComputable,
+ loaded: loaded,
+ total: total
+ });
+ cb(null, chunk);
+ };
+ return progress;
+ };
+ formData.pipe(getProgressMonitor()).pipe(req);
+ });
+ } else {
+ req.end(data);
+ }
+
+ return this;
+};
+
+/**
+ * Check whether response has a non-0-sized gzip-encoded body
+ */
+Request.prototype._shouldUnzip = function(res){
+ if (res.statusCode === 204 || res.statusCode === 304) {
+ // These aren't supposed to have any body
+ return false;
+ }
+
+ // header content is a string, and distinction between 0 and no information is crucial
+ if ('0' === res.headers['content-length']) {
+ // We know that the body is empty (unfortunately, this check does not cover chunked encoding)
+ return false;
+ }
+
+ // console.log(res);
+ return /^\s*(?:deflate|gzip)\s*$/.test(res.headers['content-encoding']);
+};
+
+// generate HTTP verb methods
+if (methods.indexOf('del') == -1) {
+ // create a copy so we don't cause conflicts with
+ // other packages using the methods package and
+ // npm 3.x
+ methods = methods.slice(0);
+ methods.push('del');
+}
+methods.forEach(function(method){
+ var name = method;
+ method = 'del' == method ? 'delete' : method;
+
+ method = method.toUpperCase();
+ request[name] = function(url, data, fn){
+ var req = request(method, url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ fn && req.end(fn);
+ return req;
+ };
+});
+
+/**
+ * Check if `mime` is text and should be buffered.
+ *
+ * @param {String} mime
+ * @return {Boolean}
+ * @api public
+ */
+
+function isText(mime) {
+ var parts = mime.split('/');
+ var type = parts[0];
+ var subtype = parts[1];
+
+ return 'text' == type
+ || 'x-www-form-urlencoded' == subtype;
+}
+
+function isImageOrVideo(mime) {
+ var type = mime.split('/')[0];
+
+ return 'image' == type || 'video' == type;
+}
+
+/**
+ * Check if `mime` is json or has +json structured syntax suffix.
+ *
+ * @param {String} mime
+ * @return {Boolean}
+ * @api private
+ */
+
+function isJSON(mime) {
+ return /[\/+]json\b/.test(mime);
+}
+
+/**
+ * Check if we should follow the redirect `code`.
+ *
+ * @param {Number} code
+ * @return {Boolean}
+ * @api private
+ */
+
+function isRedirect(code) {
+ return ~[301, 302, 303, 305, 307, 308].indexOf(code);
+}
diff --git a/node_modules/superagent/lib/node/parsers/image.js b/node_modules/superagent/lib/node/parsers/image.js
new file mode 100644
index 0000000..b3e0ebc
--- /dev/null
+++ b/node_modules/superagent/lib/node/parsers/image.js
@@ -0,0 +1,10 @@
+module.exports = function(res, fn){
+ var data = []; // Binary data needs binary storage
+
+ res.on('data', function(chunk){
+ data.push(chunk);
+ });
+ res.on('end', function () {
+ fn(null, Buffer.concat(data));
+ });
+}; \ No newline at end of file
diff --git a/node_modules/superagent/lib/node/parsers/index.js b/node_modules/superagent/lib/node/parsers/index.js
new file mode 100644
index 0000000..b6f4bf6
--- /dev/null
+++ b/node_modules/superagent/lib/node/parsers/index.js
@@ -0,0 +1,8 @@
+
+exports['application/x-www-form-urlencoded'] = require('./urlencoded');
+exports['application/json'] = require('./json');
+exports.text = require('./text');
+
+var binary = require('./image');
+exports['application/octet-stream'] = binary;
+exports.image = binary;
diff --git a/node_modules/superagent/lib/node/parsers/json.js b/node_modules/superagent/lib/node/parsers/json.js
new file mode 100644
index 0000000..b71662d
--- /dev/null
+++ b/node_modules/superagent/lib/node/parsers/json.js
@@ -0,0 +1,19 @@
+
+module.exports = function parseJSON(res, fn){
+ res.text = '';
+ res.setEncoding('utf8');
+ res.on('data', function(chunk){ res.text += chunk;});
+ res.on('end', function(){
+ try {
+ var body = res.text && JSON.parse(res.text);
+ } catch (e) {
+ var err = e;
+ // issue #675: return the raw response if the response parsing fails
+ err.rawResponse = res.text || null;
+ // issue #876: return the http status code if the response parsing fails
+ err.statusCode = res.statusCode;
+ } finally {
+ fn(err, body);
+ }
+ });
+};
diff --git a/node_modules/superagent/lib/node/parsers/text.js b/node_modules/superagent/lib/node/parsers/text.js
new file mode 100644
index 0000000..03575c6
--- /dev/null
+++ b/node_modules/superagent/lib/node/parsers/text.js
@@ -0,0 +1,7 @@
+
+module.exports = function(res, fn){
+ res.text = '';
+ res.setEncoding('utf8');
+ res.on('data', function(chunk){ res.text += chunk; });
+ res.on('end', fn);
+}; \ No newline at end of file
diff --git a/node_modules/superagent/lib/node/parsers/urlencoded.js b/node_modules/superagent/lib/node/parsers/urlencoded.js
new file mode 100644
index 0000000..245c665
--- /dev/null
+++ b/node_modules/superagent/lib/node/parsers/urlencoded.js
@@ -0,0 +1,19 @@
+
+/**
+ * Module dependencies.
+ */
+
+var qs = require('qs');
+
+module.exports = function(res, fn){
+ res.text = '';
+ res.setEncoding('ascii');
+ res.on('data', function(chunk){ res.text += chunk; });
+ res.on('end', function(){
+ try {
+ fn(null, qs.parse(res.text));
+ } catch (err) {
+ fn(err);
+ }
+ });
+}; \ No newline at end of file
diff --git a/node_modules/superagent/lib/node/response.js b/node_modules/superagent/lib/node/response.js
new file mode 100644
index 0000000..9a9ea15
--- /dev/null
+++ b/node_modules/superagent/lib/node/response.js
@@ -0,0 +1,123 @@
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('util');
+var Stream = require('stream');
+var ResponseBase = require('../response-base');
+
+/**
+ * Expose `Response`.
+ */
+
+module.exports = Response;
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * @param {Request} req
+ * @param {Object} options
+ * @constructor
+ * @extends {Stream}
+ * @implements {ReadableStream}
+ * @api private
+ */
+
+function Response(req) {
+ Stream.call(this);
+ var res = this.res = req.res;
+ this.request = req;
+ this.req = req.req;
+ this.text = res.text;
+ this.body = res.body !== undefined ? res.body : {};
+ this.files = res.files || {};
+ this.buffered = 'string' == typeof this.text;
+ this.header = this.headers = res.headers;
+ this._setStatusProperties(res.statusCode);
+ this._setHeaderProperties(this.header);
+ this.setEncoding = res.setEncoding.bind(res);
+ res.on('data', this.emit.bind(this, 'data'));
+ res.on('end', this.emit.bind(this, 'end'));
+ res.on('close', this.emit.bind(this, 'close'));
+ res.on('error', this.emit.bind(this, 'error'));
+}
+
+/**
+ * Inherit from `Stream`.
+ */
+
+util.inherits(Response, Stream);
+ResponseBase(Response.prototype);
+
+
+/**
+ * Implements methods of a `ReadableStream`
+ */
+
+Response.prototype.destroy = function(err){
+ this.res.destroy(err);
+};
+
+/**
+ * Pause.
+ */
+
+Response.prototype.pause = function(){
+ this.res.pause();
+};
+
+/**
+ * Resume.
+ */
+
+Response.prototype.resume = function(){
+ this.res.resume();
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var path = req.path;
+
+ var msg = 'cannot ' + method + ' ' + path + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.text = this.text;
+ err.method = method;
+ err.path = path;
+
+ return err;
+};
+
+
+Response.prototype.setStatusProperties = function(status){
+ console.warn("In superagent 2.x setStatusProperties is a private method");
+ return this._setStatusProperties(status);
+};
+
+/**
+ * To json.
+ *
+ * @return {Object}
+ * @api public
+ */
+
+Response.prototype.toJSON = function(){
+ return {
+ req: this.request.toJSON(),
+ header: this.header,
+ status: this.status,
+ text: this.text
+ };
+};
diff --git a/node_modules/superagent/lib/node/unzip.js b/node_modules/superagent/lib/node/unzip.js
new file mode 100644
index 0000000..2911fbc
--- /dev/null
+++ b/node_modules/superagent/lib/node/unzip.js
@@ -0,0 +1,69 @@
+
+/**
+ * Module dependencies.
+ */
+
+var StringDecoder = require('string_decoder').StringDecoder;
+var Stream = require('stream');
+var zlib = require('zlib');
+
+/**
+ * Buffers response data events and re-emits when they're unzipped.
+ *
+ * @param {Request} req
+ * @param {Response} res
+ * @api private
+ */
+
+exports.unzip = function(req, res){
+ var unzip = zlib.createUnzip();
+ var stream = new Stream;
+ var decoder;
+
+ // make node responseOnEnd() happy
+ stream.req = req;
+
+ unzip.on('error', function(err){
+ if (err && err.code === 'Z_BUF_ERROR') { // unexpected end of file is ignored by browsers and curl
+ stream.emit('end');
+ return;
+ }
+ stream.emit('error', err);
+ });
+
+ // pipe to unzip
+ res.pipe(unzip);
+
+ // override `setEncoding` to capture encoding
+ res.setEncoding = function(type){
+ decoder = new StringDecoder(type);
+ };
+
+ // decode upon decompressing with captured encoding
+ unzip.on('data', function(buf){
+ if (decoder) {
+ var str = decoder.write(buf);
+ if (str.length) stream.emit('data', str);
+ } else {
+ stream.emit('data', buf);
+ }
+ });
+
+ unzip.on('end', function(){
+ stream.emit('end');
+ });
+
+ // override `on` to capture data listeners
+ var _on = res.on;
+ res.on = function(type, fn){
+ if ('data' == type || 'end' == type) {
+ stream.on(type, fn);
+ } else if ('error' == type) {
+ stream.on(type, fn);
+ _on.call(res, type, fn);
+ } else {
+ _on.call(res, type, fn);
+ }
+ return this;
+ };
+}; \ No newline at end of file
diff --git a/node_modules/superagent/lib/request-base.js b/node_modules/superagent/lib/request-base.js
new file mode 100644
index 0000000..0fc62a4
--- /dev/null
+++ b/node_modules/superagent/lib/request-base.js
@@ -0,0 +1,591 @@
+/**
+ * Module of mixed-in functions shared between node and client code
+ */
+var isObject = require('./is-object');
+
+/**
+ * Expose `RequestBase`.
+ */
+
+module.exports = RequestBase;
+
+/**
+ * Initialize a new `RequestBase`.
+ *
+ * @api public
+ */
+
+function RequestBase(obj) {
+ if (obj) return mixin(obj);
+}
+
+/**
+ * Mixin the prototype properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in RequestBase.prototype) {
+ obj[key] = RequestBase.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.clearTimeout = function _clearTimeout(){
+ clearTimeout(this._timer);
+ clearTimeout(this._responseTimeoutTimer);
+ delete this._timer;
+ delete this._responseTimeoutTimer;
+ return this;
+};
+
+/**
+ * Override default response body parser
+ *
+ * This function will be called to convert incoming data into request.body
+ *
+ * @param {Function}
+ * @api public
+ */
+
+RequestBase.prototype.parse = function parse(fn){
+ this._parser = fn;
+ return this;
+};
+
+/**
+ * Set format of binary response body.
+ * In browser valid formats are 'blob' and 'arraybuffer',
+ * which return Blob and ArrayBuffer, respectively.
+ *
+ * In Node all values result in Buffer.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .responseType('blob')
+ * .end(callback);
+ *
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.responseType = function(val){
+ this._responseType = val;
+ return this;
+};
+
+/**
+ * Override default request body serializer
+ *
+ * This function will be called to convert data set via .send or .attach into payload to send
+ *
+ * @param {Function}
+ * @api public
+ */
+
+RequestBase.prototype.serialize = function serialize(fn){
+ this._serializer = fn;
+ return this;
+};
+
+/**
+ * Set timeouts.
+ *
+ * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
+ * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections.
+ *
+ * Value of 0 or false means no timeout.
+ *
+ * @param {Number|Object} ms or {response, read, deadline}
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.timeout = function timeout(options){
+ if (!options || 'object' !== typeof options) {
+ this._timeout = options;
+ this._responseTimeout = 0;
+ return this;
+ }
+
+ for(var option in options) {
+ switch(option) {
+ case 'deadline':
+ this._timeout = options.deadline;
+ break;
+ case 'response':
+ this._responseTimeout = options.response;
+ break;
+ default:
+ console.warn("Unknown timeout option", option);
+ }
+ }
+ return this;
+};
+
+/**
+ * Set number of retry attempts on error.
+ *
+ * Failed requests will be retried 'count' times if timeout or err.code >= 500.
+ *
+ * @param {Number} count
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.retry = function retry(count){
+ // Default to 1 if no count passed or true
+ if (arguments.length === 0 || count === true) count = 1;
+ if (count <= 0) count = 0;
+ this._maxRetries = count;
+ this._retries = 0;
+ return this;
+};
+
+/**
+ * Retry request
+ *
+ * @return {Request} for chaining
+ * @api private
+ */
+
+RequestBase.prototype._retry = function() {
+ this.clearTimeout();
+
+ // node
+ if (this.req) {
+ this.req = null;
+ this.req = this.request();
+ }
+
+ this._aborted = false;
+ this.timedout = false;
+
+ return this._end();
+};
+
+/**
+ * Promise support
+ *
+ * @param {Function} resolve
+ * @param {Function} [reject]
+ * @return {Request}
+ */
+
+RequestBase.prototype.then = function then(resolve, reject) {
+ if (!this._fullfilledPromise) {
+ var self = this;
+ if (this._endCalled) {
+ console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises");
+ }
+ this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
+ self.end(function(err, res){
+ if (err) innerReject(err); else innerResolve(res);
+ });
+ });
+ }
+ return this._fullfilledPromise.then(resolve, reject);
+}
+
+RequestBase.prototype.catch = function(cb) {
+ return this.then(undefined, cb);
+};
+
+/**
+ * Allow for extension
+ */
+
+RequestBase.prototype.use = function use(fn) {
+ fn(this);
+ return this;
+}
+
+RequestBase.prototype.ok = function(cb) {
+ if ('function' !== typeof cb) throw Error("Callback required");
+ this._okCallback = cb;
+ return this;
+};
+
+RequestBase.prototype._isResponseOK = function(res) {
+ if (!res) {
+ return false;
+ }
+
+ if (this._okCallback) {
+ return this._okCallback(res);
+ }
+
+ return res.status >= 200 && res.status < 300;
+};
+
+
+/**
+ * Get request header `field`.
+ * Case-insensitive.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+RequestBase.prototype.get = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ * This is a deprecated internal API. Use `.get(field)` instead.
+ *
+ * (getHeader is no longer used internally by the superagent code base)
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ * @deprecated
+ */
+
+RequestBase.prototype.getHeader = RequestBase.prototype.get;
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ * Case-insensitive.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ * Case-insensitive.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ */
+RequestBase.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Write the field `name` and `val`, or multiple fields with one object
+ * for "multipart/form-data" request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ *
+ * request.post('/upload')
+ * .field({ foo: 'bar', baz: 'qux' })
+ * .end(callback);
+ * ```
+ *
+ * @param {String|Object} name
+ * @param {String|Blob|File|Buffer|fs.ReadStream} val
+ * @return {Request} for chaining
+ * @api public
+ */
+RequestBase.prototype.field = function(name, val) {
+
+ // name should be either a string or an object.
+ if (null === name || undefined === name) {
+ throw new Error('.field(name, val) name can not be empty');
+ }
+
+ if (this._data) {
+ console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
+ }
+
+ if (isObject(name)) {
+ for (var key in name) {
+ this.field(key, name[key]);
+ }
+ return this;
+ }
+
+ if (Array.isArray(val)) {
+ for (var i in val) {
+ this.field(name, val[i]);
+ }
+ return this;
+ }
+
+ // val should be defined now
+ if (null === val || undefined === val) {
+ throw new Error('.field(name, val) val can not be empty');
+ }
+ if ('boolean' === typeof val) {
+ val = '' + val;
+ }
+ this._getFormData().append(name, val);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+RequestBase.prototype.abort = function(){
+ if (this._aborted) {
+ return this;
+ }
+ this._aborted = true;
+ this.xhr && this.xhr.abort(); // browser
+ this.req && this.req.abort(); // node
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+RequestBase.prototype.withCredentials = function(on){
+ // This is browser-only functionality. Node side is no-op.
+ if(on==undefined) on = true;
+ this._withCredentials = on;
+ return this;
+};
+
+/**
+ * Set the max redirects to `n`. Does noting in browser XHR implementation.
+ *
+ * @param {Number} n
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.redirects = function(n){
+ this._maxRedirects = n;
+ return this;
+};
+
+/**
+ * Convert to a plain javascript object (not JSON string) of scalar properties.
+ * Note as this method is designed to return a useful non-this value,
+ * it cannot be chained.
+ *
+ * @return {Object} describing method, url, and data of this request
+ * @api public
+ */
+
+RequestBase.prototype.toJSON = function(){
+ return {
+ method: this.method,
+ url: this.url,
+ data: this._data,
+ headers: this._header
+ };
+};
+
+
+/**
+ * Send `data` as the request body, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"}')
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.send = function(data){
+ var isObj = isObject(data);
+ var type = this._header['content-type'];
+
+ if (this._formData) {
+ console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
+ }
+
+ if (isObj && !this._data) {
+ if (Array.isArray(data)) {
+ this._data = [];
+ } else if (!this._isHost(data)) {
+ this._data = {};
+ }
+ } else if (data && this._data && this._isHost(this._data)) {
+ throw Error("Can't merge these send calls");
+ }
+
+ // merge
+ if (isObj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ // default to x-www-form-urlencoded
+ if (!type) this.type('form');
+ type = this._header['content-type'];
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!isObj || this._isHost(data)) {
+ return this;
+ }
+
+ // default to json
+ if (!type) this.type('json');
+ return this;
+};
+
+
+/**
+ * Sort `querystring` by the sort function
+ *
+ *
+ * Examples:
+ *
+ * // default order
+ * request.get('/user')
+ * .query('name=Nick')
+ * .query('search=Manny')
+ * .sortQuery()
+ * .end(callback)
+ *
+ * // customized sort function
+ * request.get('/user')
+ * .query('name=Nick')
+ * .query('search=Manny')
+ * .sortQuery(function(a, b){
+ * return a.length - b.length;
+ * })
+ * .end(callback)
+ *
+ *
+ * @param {Function} sort
+ * @return {Request} for chaining
+ * @api public
+ */
+
+RequestBase.prototype.sortQuery = function(sort) {
+ // _sort default to true but otherwise can be a function or boolean
+ this._sort = typeof sort === 'undefined' ? true : sort;
+ return this;
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+RequestBase.prototype._timeoutError = function(reason, timeout, errno){
+ if (this._aborted) {
+ return;
+ }
+ var err = new Error(reason + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ err.code = 'ECONNABORTED';
+ err.errno = errno;
+ this.timedout = true;
+ this.abort();
+ this.callback(err);
+};
+
+RequestBase.prototype._setTimeouts = function() {
+ var self = this;
+
+ // deadline
+ if (this._timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self._timeoutError('Timeout of ', self._timeout, 'ETIME');
+ }, this._timeout);
+ }
+ // response timeout
+ if (this._responseTimeout && !this._responseTimeoutTimer) {
+ this._responseTimeoutTimer = setTimeout(function(){
+ self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
+ }, this._responseTimeout);
+ }
+}
diff --git a/node_modules/superagent/lib/response-base.js b/node_modules/superagent/lib/response-base.js
new file mode 100644
index 0000000..e7fdde7
--- /dev/null
+++ b/node_modules/superagent/lib/response-base.js
@@ -0,0 +1,133 @@
+
+/**
+ * Module dependencies.
+ */
+
+var utils = require('./utils');
+
+/**
+ * Expose `ResponseBase`.
+ */
+
+module.exports = ResponseBase;
+
+/**
+ * Initialize a new `ResponseBase`.
+ *
+ * @api public
+ */
+
+function ResponseBase(obj) {
+ if (obj) return mixin(obj);
+}
+
+/**
+ * Mixin the prototype properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in ResponseBase.prototype) {
+ obj[key] = ResponseBase.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+ResponseBase.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+ResponseBase.prototype._setHeaderProperties = function(header){
+ // TODO: moar!
+ // TODO: make this a util
+
+ // content-type
+ var ct = header['content-type'] || '';
+ this.type = utils.type(ct);
+
+ // params
+ var params = utils.params(ct);
+ for (var key in params) this[key] = params[key];
+
+ this.links = {};
+
+ // links
+ try {
+ if (header.link) {
+ this.links = utils.parseLinks(header.link);
+ }
+ } catch (err) {
+ // ignore
+ }
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+ResponseBase.prototype._setStatusProperties = function(status){
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = this.statusCode = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.redirect = 3 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.forbidden = 403 == status;
+ this.notFound = 404 == status;
+};
diff --git a/node_modules/superagent/lib/should-retry.js b/node_modules/superagent/lib/should-retry.js
new file mode 100644
index 0000000..ce0af38
--- /dev/null
+++ b/node_modules/superagent/lib/should-retry.js
@@ -0,0 +1,23 @@
+var ERROR_CODES = [
+ 'ECONNRESET',
+ 'ETIMEDOUT',
+ 'EADDRINFO',
+ 'ESOCKETTIMEDOUT'
+];
+
+/**
+ * Determine if a request should be retried.
+ * (Borrowed from segmentio/superagent-retry)
+ *
+ * @param {Error} err
+ * @param {Response} [res]
+ * @returns {Boolean}
+ */
+module.exports = function shouldRetry(err, res) {
+ if (err && err.code && ~ERROR_CODES.indexOf(err.code)) return true;
+ if (res && res.status && res.status >= 500) return true;
+ // Superagent timeout
+ if (err && 'timeout' in err && err.code == 'ECONNABORTED') return true;
+ if (err && 'crossDomain' in err) return true;
+ return false;
+};
diff --git a/node_modules/superagent/lib/utils.js b/node_modules/superagent/lib/utils.js
new file mode 100644
index 0000000..9bf1285
--- /dev/null
+++ b/node_modules/superagent/lib/utils.js
@@ -0,0 +1,68 @@
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+exports.type = function(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+exports.params = function(str){
+ return str.split(/ *; */).reduce(function(obj, str){
+ var parts = str.split(/ *= */);
+ var key = parts.shift();
+ var val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Parse Link header fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+exports.parseLinks = function(str){
+ return str.split(/ *, */).reduce(function(obj, str){
+ var parts = str.split(/ *; */);
+ var url = parts[0].slice(1, -1);
+ var rel = parts[1].split(/ *= */)[1].slice(1, -1);
+ obj[rel] = url;
+ return obj;
+ }, {});
+};
+
+/**
+ * Strip content related fields from `header`.
+ *
+ * @param {Object} header
+ * @return {Object} header
+ * @api private
+ */
+
+exports.cleanHeader = function(header, shouldStripCookie){
+ delete header['content-type'];
+ delete header['content-length'];
+ delete header['transfer-encoding'];
+ delete header['host'];
+ if (shouldStripCookie) {
+ delete header['cookie'];
+ }
+ return header;
+}; \ No newline at end of file