Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

superagent

Package Overview
Dependencies
Maintainers
10
Versions
174
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

superagent - npm Package Compare versions

Comparing version 0.21.0 to 1.0.0

Contributing.md

2

component.json

@@ -5,3 +5,3 @@ {

"description": "awesome http requests",
"version": "0.20.0",
"version": "1.0.0",
"keywords": [

@@ -8,0 +8,0 @@ "http",

@@ -0,2 +1,15 @@

1.0.0 / 2015-03-08
==================
* keep timeouts intact across redirects (hopkinsth)
* handle falsy json values (themaarten)
* fire response events in browser version (Schoonology)
* getXHR exported in client version (KidsKilla)
* remove arity check on `.end()` callbacks (defunctzombie)
* avoid setting content-type for host objects (rexxars)
* don't index array strings in querystring (travisjeffery)
* fix pipe() with redirects (cyrilis)
* add xhr2 file download (vstirbu)
* set default response type to text/plain if not specified (warrenseine)
0.21.0 / 2014-11-11

@@ -3,0 +16,0 @@ ==================

@@ -50,3 +50,3 @@ /**

function getXHR() {
request.getXHR = function () {
if (root.XMLHttpRequest

@@ -62,3 +62,3 @@ && ('file:' != root.location.protocol || !root.ActiveXObject)) {

return false;
}
};

@@ -299,5 +299,7 @@ /**

this.xhr = this.req.xhr;
this.text = this.req.method !='HEAD'
? this.xhr.responseText
// responseText is accessible only if responseType is '' or 'text'
this.text = (this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text'))
? this.xhr.responseText
: null;
this.statusText = this.req.xhr.statusText;
this.setStatusProperties(this.xhr.status);

@@ -311,3 +313,3 @@ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());

this.body = this.req.method != 'HEAD'
? this.parseBody(this.text)
? this.parseBody(this.text ? this.text : this.xhr.response)
: null;

@@ -363,3 +365,3 @@ }

var parse = request.parse[this.type];
return parse && str && str.length
return parse && str && (str.length || str instanceof Object)
? parse(str)

@@ -464,3 +466,3 @@ : null;

try {
res = new Response(self);
res = new Response(self);
} catch(e) {

@@ -472,3 +474,18 @@ err = new Error('Parser is unable to parse the response');

self.callback(err, res);
if (res) {
self.emit('response', res);
}
if (res && res.status >= 200 && res.status < 300) {
return self.callback(err, res);
}
var msg = 'Unsuccessful HTTP response';
if (res) {
msg = res.statusText || msg;
}
var new_err = new Error(msg);
new_err.original = err;
self.callback(err || new_err, res);
});

@@ -702,3 +719,3 @@ }

Request.prototype.field = function(name, val){
if (!this._formData) this._formData = new FormData();
if (!this._formData) this._formData = new root.FormData();
this._formData.append(name, val);

@@ -726,3 +743,3 @@ return this;

Request.prototype.attach = function(field, file, filename){
if (!this._formData) this._formData = new FormData();
if (!this._formData) this._formData = new root.FormData();
this._formData.append(field, file, filename);

@@ -806,3 +823,3 @@ return this;

if (!obj) return this;
if (!obj || isHost(data)) return this;
if (!type) this.type('json');

@@ -824,5 +841,3 @@ return this;

this.clearTimeout();
if (2 == fn.length) return fn(err, res);
if (err) return this.emit('error', err);
fn(res);
fn(err, res);
};

@@ -882,3 +897,3 @@

var self = this;
var xhr = this.xhr = getXHR();
var xhr = this.xhr = request.getXHR();
var query = this._query.join('&');

@@ -894,4 +909,11 @@ var timeout = this._timeout;

if (4 != xhr.readyState) return;
if (0 == xhr.status) {
if (self.aborted) return self.timeoutError();
// 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 (0 == status) {
if (self.timedout) return self.timeoutError();
if (self.aborted) return;
return self.crossDomainError();

@@ -903,7 +925,13 @@ }

// progress
if (xhr.upload) {
xhr.upload.onprogress = function(e){
e.percent = e.loaded / e.total * 100;
self.emit('progress', e);
};
try {
if (xhr.upload && this.hasListeners('progress')) {
xhr.upload.onprogress = function(e){
e.percent = e.loaded / e.total * 100;
self.emit('progress', e);
};
}
} 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
}

@@ -914,2 +942,3 @@

this._timer = setTimeout(function(){
self.timedout = true;
self.abort();

@@ -916,0 +945,0 @@ }, timeout);

@@ -12,2 +12,3 @@

var format = require('url').format;
var resolve = require('url').resolve;
var methods = require('methods');

@@ -133,2 +134,3 @@ var Stream = require('stream');

this.qs = {};
this.qsRaw = [];
this._redirectList = [];

@@ -198,7 +200,7 @@ this.on('end', this.clearTimeout.bind(this));

if ('string' == typeof file) {
filename = file;
debug('creating `fs.ReadStream` instance for file: %s', filename);
file = fs.createReadStream(filename);
if (!filename) filename = file;
debug('creating `fs.ReadStream` instance for file: %s', file);
file = fs.createReadStream(file);
}
this._formData.append(field, file, filename);
this._formData.append(field, file, { filename: filename });
return this;

@@ -386,11 +388,5 @@ };

Request.prototype.query = function(val){
var obj = {};
if ('string' == typeof val) {
var elements = val.split('&');
for (var i = 0; i < elements.length; i++) {
var parts = elements[i].split('=');
obj[parts[0]] = parts[1];
}
return this.query(obj);
this.qsRaw.push(val);
return this;
}

@@ -503,3 +499,10 @@

this.buffer(false);
var self = this;
this.end().req.on('response', function(res){
// redirect
var redirect = isRedirect(res.statusCode);
if (redirect && self._redirects++ != self._maxRedirects) {
return self.redirect(res).pipe(stream, options);
}
if (/^(deflate|gzip)$/.test(res.headers['content-encoding'])) {

@@ -510,2 +513,5 @@ res.pipe(zlib.createUnzip()).pipe(stream, options);

}
res.on('end', function(){
self.emit('end');
});
});

@@ -594,11 +600,10 @@ return stream;

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
if (!~url.indexOf('://')) {
if (0 != url.indexOf('//')) {
url = '//' + this.host + url;
}
url = this.protocol + url;
}
url = resolve(this.url, url);

@@ -609,19 +614,35 @@ // ensure the response is being consumed

// strip Content-* related fields
// in case of POST etc
var header = utils.cleanHeader(this.req._headers);
var headers = this.req._headers;
// 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);
// force GET
this.method = 'HEAD' == this.method
? 'HEAD'
: 'GET';
// clear data
this._data = null;
}
// 303 is always GET
if (res.statusCode == 303) {
// force method
this.method = 'GET';
// clear data
this._data = null;
}
// 307 preserves method
delete this.req;
// force GET
this.method = 'HEAD' == this.method
? 'HEAD'
: 'GET';
// redirect
this._data = null;
this.url = url;
this._redirectList.push(url);
this.clearTimeout();
this.emit('redirect', res);
this.set(header);
this.qs = {};
this.set(headers);
this.end(this._callback);

@@ -754,5 +775,18 @@ return this;

this.called = true;
if (2 == fn.length) return fn(err, res);
if (err) return this.emit('error', err);
fn(res);
// 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);
if (res && res.status >= 200 && res.status < 300) {
return fn(err, res);
}
var msg = 'Unsuccessful HTTP response';
if (res) {
msg = http.STATUS_CODES[res.status] || msg;
}
var new_err = new Error(msg);
new_err.original = err;
fn(err || new_err, res);
};

@@ -783,3 +817,4 @@

try {
var querystring = qs.stringify(this.qs);
var querystring = qs.stringify(this.qs, { indices: false });
querystring += ((querystring.length && this.qsRaw.length) ? '&' : '') + this.qsRaw.join('&');
req.path += querystring.length

@@ -798,2 +833,3 @@ ? (~req.path.indexOf('?') ? '&' : '?') + querystring

err.timeout = timeout;
err.code = 'ECONNABORTED';
self.abort();

@@ -825,3 +861,3 @@ self.callback(err);

var max = self._maxRedirects;
var mime = utils.type(res.headers['content-type'] || '');
var mime = utils.type(res.headers['content-type'] || '') || 'text/plain';
var len = res.headers['content-length'];

@@ -847,5 +883,2 @@ var type = mime.split('/');

if (self.piped) {
res.on('end', function(){
self.emit('end');
});
return;

@@ -898,6 +931,4 @@ }

// by default only buffer text/*, json
// and messed up thing from hell
var text = isText(mime);
if (null == buffer && text) buffer = true;
// by default only buffer text/*, json and messed up thing from hell
if (null == buffer && isText(mime) || isJSON(mime)) buffer = true;

@@ -909,2 +940,5 @@ // parser

// everyone wants their own white-labeled json
if (isJSON(mime)) parse = exports.parse['application/json'];
// buffered response

@@ -923,3 +957,3 @@ if (buffer) parse = parse || exports.parse.text;

});
} catch(err) {
} catch (err) {
self.callback(err);

@@ -1045,4 +1079,6 @@ return;

method = method.toUpperCase();
request[name] = function(url, fn){
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);

@@ -1067,3 +1103,2 @@ return req;

return 'text' == type
|| 'json' == subtype
|| 'x-www-form-urlencoded' == subtype;

@@ -1089,2 +1124,18 @@ }

/**
* Check if `mime` is json or has +json structured syntax suffix.
*
* @param {String} mime
* @return {Boolean}
* @api private
*/
function isJSON(mime) {
if (!mime) return false;
var parts = mime.split('/');
var type = parts[0];
var subtype = parts[1];
return subtype && subtype.match(/json/i);
}
/**
* Check if we should follow the redirect `code`.

@@ -1091,0 +1142,0 @@ *

module.exports = function(res, fn){
module.exports = function parseJSON(res, fn){
res.text = '';
res.setEncoding('utf8');
res.on('data', function(chunk){ res.text += chunk; });
res.on('data', function(chunk){ res.text += chunk;});
res.on('end', function(){

@@ -7,0 +7,0 @@ try {

@@ -38,3 +38,3 @@

this.text = res.text;
this.body = res.body || {};
this.body = res.body !== undefined ? res.body : {};
this.files = res.files || {};

@@ -41,0 +41,0 @@ this.buffered = 'string' == typeof this.text;

@@ -19,18 +19,2 @@

/**
* Generate a UID with the given `len`.
*
* @param {Number} len
* @return {String}
* @api private
*/
exports.uid = function(len){
var buf = '';
var chars = 'abcdefghijklmnopqrstuvwxyz123456789';
var nchars = chars.length;
while (len--) buf += chars[Math.random() * nchars | 0];
return buf;
};
/**
* Return the mime type for the given `str`.

@@ -37,0 +21,0 @@ *

{
"name": "superagent",
"version": "0.21.0",
"version": "1.0.0",
"description": "elegant & feature rich browser / node HTTP with a fluent API",

@@ -23,3 +23,3 @@ "scripts": {

"dependencies": {
"qs": "1.2.0",
"qs": "2.3.3",
"formidable": "1.0.14",

@@ -45,3 +45,5 @@ "mime": "1.2.11",

"should": "3.1.3",
"zuul": "~1.6.0"
"zuul": "~1.19.0",
"browserify": "~6.3.2",
"Base64": "0.3.0"
},

@@ -51,3 +53,4 @@ "browser": {

"emitter": "component-emitter",
"reduce": "reduce-component"
"reduce": "reduce-component",
"./test/support/server.js": "./test/support/blank.js"
},

@@ -54,0 +57,0 @@ "component": {

@@ -1,5 +0,7 @@

# SuperAgent
# SuperAgent [![Build Status](https://travis-ci.org/visionmedia/superagent.svg?branch=master)](https://travis-ci.org/visionmedia/superagent)
SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.com/superagent/).
[![Sauce Test Status](https://saucelabs.com/browser-matrix/shtylman-superagent.svg)](https://saucelabs.com/u/shtylman-superagent)
SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.com/superagent/).
![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png)

@@ -9,3 +11,3 @@

node:
node:

@@ -16,3 +18,3 @@ ```

component:
component:

@@ -23,44 +25,5 @@ ```

with script tags use ./superagent.js
Works with [browserify](https://github.com/substack/node-browserify) and should work with [webpack](https://github.com/visionmedia/superagent/wiki/Superagent-for-Webpack)
## Motivation
This library spawned from my frustration with jQuery's weak & inconsistent Ajax support. jQuery's API, while having recently added some promise-like support, is largely static, forcing you to build up big objects containing all the header fields and options, not to mention most of the options are awkwardly named "type" instead of "method", etc. Onto examples!
The following is what you might typically do for a simple __GET__ with jQuery:
```js
$.get('/user/1', function(data, textStatus, xhr){
});
```
Great, it's ok, but it's kinda lame having 3 arguments just to access something on the `xhr`. Our equivalent would be:
```js
request.get('/user/1', function(res){
});
```
The response object is an instanceof `request.Response`, encapsulating all of this information instead of throwing a bunch of arguments at you. For example, we can check `res.status`, `res.header` for header fields, `res.text`, `res.body` etc.
An example of a JSON POST with jQuery typically might use `$.post()`, however once you need to start defining header fields you have to then re-write it using `$.ajax()`... so that might look like:
```js
$.ajax({
url: '/api/pet',
type: 'POST',
data: { name: 'Manny', species: 'cat' },
headers: { 'X-API-Key': 'foobar' }
}).success(function(res){
}).error(function(){
});
```
Not only is it ugly, but it's pretty opinionated. jQuery likes to special-case {4,5}xx- for example, you cannot (easily at least) receive a parsed JSON response for say "400 Bad Request". This same request would look like this:
```js
request

@@ -71,3 +34,3 @@ .post('/api/pet')

.set('Accept', 'application/json')
.end(function(error, res){
.end(function(err, res){

@@ -77,13 +40,18 @@ });

Building on the existing API internally, we also provide something similar to `$.post()` for those times in life where your interactions are very basic:
## Supported browsers
```js
request.post('/api/pet', cat, function(error, res){
Tested browsers:
});
```
- Latest Android
- Latest Firefox
- Latest Chrome
- IE9 through latest
- Latest iPhone
- Latest Safari
Even though IE9 is supported, a polyfill `window.btoa` is needed to use basic auth.
# Plugins
Usage:
Superagent is easily extended via plugins.

@@ -109,3 +77,3 @@ ```js

Please prefix your plugin component with `superagent-*`
Please prefix your plugin with `superagent-*` so that it can easily be found by others.

@@ -116,34 +84,33 @@ For superagent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki).

Install dependencies:
Install dependencies:
$ npm install
```shell
$ npm install
```
Run em!
Run em!
```shell
$ make test
```
$ make test
## Running browser tests
Install the test server deps (nodejs / express):
Install dependencies:
$ npm install
```shell
$ npm install
```
Start the test server:
Start the test runner:
$ make test-server
```shell
$ make test-browser-local
```
Visit `localhost:4000/` in the browser.
Visit `http://localhost:4000/__zuul` in your browser.
## Browser build
Edit tests and refresh your browser. You do not have to restart the test runner.
The browser build of superagent is located in ./superagent.js
## Examples:
- [agency tests](https://github.com/visionmedia/superagent/blob/master/test/node/agency.js)
- [express demo app](https://github.com/hunterloftis/component-test/blob/master/lib/users/test/controller.test.js)
## License
MIT
MIT

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc