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

gofer

Package Overview
Dependencies
Maintainers
2
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gofer - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0

lib/promise.js

18

API.md

@@ -100,4 +100,20 @@

The return value is the same as the one of `request`.
The return value is generally the same as the one of `request`.
In addition to what `request` offers, it has the following methods:
* `asPromise()`: Converts the callback arguments to a promise.
The promise resolves to an array with `[ body, response, meta ]`.
* `getBody()`: A promise of the, potentially parsed, body.
* `getResponse()`: A promise of the response object.
* `then(onResolved, onRejected)`: This function exists for convenience only.
It makes it possible to use the result as a thenable
that can be passed into `Promise.resolve`, `Promise.all`, etc..
By default it will resolve to the parsed body, matching `getBody()`.
Please note that while it has a `then` method,
it's not a real, spec-compliant promise.
E.g. calling `then` on the next tick of the event loop might lead to unexpected results.
If it's not possible to pass it into one of the proper Promise methods
in the same tick the request was created,
it's safer to call `getBody()` explicitly.
If an HTTP status code outside of the accepted range is returned,

@@ -104,0 +120,0 @@ the error object will have the following properties:

@@ -0,1 +1,6 @@

2.3.0
-----
* Migrate to latest deps and rebuild - @jkrems #28
* Support using the result as a promise - @jkrems #27
2.2.1

@@ -2,0 +7,0 @@ -----

423

lib/gofer.js

@@ -0,1 +1,3 @@

// Generated by CoffeeScript 1.9.0
/*

@@ -31,215 +33,218 @@ Copyright (c) 2014, Groupon, Inc.

SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
var Gofer, Hub, applyBaseUrl, buildUserAgent, cleanObject, extend, merge, parseDefaults, resolveOptional, _ref,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
// Generated by CoffeeScript 2.0.0-beta7
void function () {
var applyBaseUrl, buildUserAgent, cache$, cache$1, cleanObject, extend, Gofer, Hub, isJsonResponse, merge, parseDefaults, resolveOptional, safeParseJSON;
Hub = require('./hub');
cache$ = require('./helpers');
resolveOptional = cache$.resolveOptional;
parseDefaults = cache$.parseDefaults;
applyBaseUrl = cache$.applyBaseUrl;
buildUserAgent = cache$.buildUserAgent;
merge = cache$.merge;
cleanObject = cache$.cleanObject;
cache$1 = require('./json');
safeParseJSON = cache$1.safeParseJSON;
isJsonResponse = cache$1.isJsonResponse;
extend = require('lodash').extend;
Gofer = function () {
function Gofer(config, param$) {
var cache$2, instance$;
instance$ = this;
this.request = function (a, b, c) {
return Gofer.prototype.request.apply(instance$, arguments);
Hub = require('./hub');
_ref = require('./helpers'), resolveOptional = _ref.resolveOptional, parseDefaults = _ref.parseDefaults, applyBaseUrl = _ref.applyBaseUrl, buildUserAgent = _ref.buildUserAgent, merge = _ref.merge, cleanObject = _ref.cleanObject;
extend = require('lodash').extend;
Gofer = (function() {
function Gofer(config, _at_hub) {
var _ref1;
this.hub = _at_hub;
this.request = __bind(this.request, this);
_ref1 = parseDefaults(config, this.serviceName), this.defaults = _ref1.defaults, this.endpointDefaults = _ref1.endpointDefaults;
if (this.hub == null) {
this.hub = Hub();
}
}
Gofer.prototype["with"] = function(overrides) {
var copy, endpointDefaults, endpointName, _ref1;
copy = new this.constructor({}, this.hub);
copy.defaults = merge(this.defaults, overrides);
copy.endpointDefaults = {};
_ref1 = this.endpointDefaults;
for (endpointName in _ref1) {
endpointDefaults = _ref1[endpointName];
copy.endpointDefaults[endpointName] = merge(endpointDefaults, overrides);
}
return copy;
};
Gofer.prototype.clone = function() {
return this["with"]({});
};
Gofer.prototype.request = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
return this._request(options, cb);
};
Gofer.prototype.put = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options.method = 'PUT';
return this._request(options, cb);
};
Gofer.prototype.del = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options.method = 'DELETE';
return this._request(options, cb);
};
Gofer.prototype.head = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options.method = 'HEAD';
return this._request(options, cb);
};
Gofer.prototype.post = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options.method = 'POST';
return this._request(options, cb);
};
Gofer.prototype.patch = function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options.method = 'PATCH';
return this._request(options, cb);
};
Gofer.prototype.registerEndpoint = function(endpointName, endpointFn) {
Object.defineProperty(this, endpointName, {
configurable: true,
get: function() {
var request, value;
request = this.requestWithDefaults({
endpointName: endpointName
});
value = endpointFn(request);
Object.defineProperty(this, endpointName, {
value: value
});
return value;
}
});
return this;
};
Gofer.prototype.registerEndpoints = function(endpointMap) {
var handler, name;
for (name in endpointMap) {
handler = endpointMap[name];
this.registerEndpoint(name, handler);
}
return this;
};
Gofer.prototype.addOptionMapper = function(mapper) {
this._mappers = this._mappers.concat([mapper]);
return this;
};
Gofer.prototype.clearOptionMappers = function() {
return this._mappers = [];
};
Gofer.prototype.requestWithDefaults = function(defaults) {
return (function(_this) {
return function(uri, options, cb) {
var _ref1;
_ref1 = resolveOptional(uri, options, cb), options = _ref1.options, cb = _ref1.cb;
options = merge(defaults, options);
return _this._request(options, cb);
};
this.hub = param$;
cache$2 = parseDefaults(config, this.serviceName);
this.defaults = cache$2.defaults;
this.endpointDefaults = cache$2.endpointDefaults;
if (null != this.hub)
this.hub;
else
this.hub = Hub();
})(this);
};
Gofer.prototype._getDefaults = function(defaults, options) {
var endpointName;
endpointName = options.endpointName;
if ((endpointName != null) && (this.endpointDefaults[endpointName] != null)) {
defaults = merge(defaults, this.endpointDefaults[endpointName]);
}
Gofer.prototype['with'] = function (overrides) {
var copy, endpointDefaults, endpointName;
copy = new this.constructor({}, this.hub);
copy.defaults = merge(this.defaults, overrides);
copy.endpointDefaults = {};
for (endpointName in this.endpointDefaults) {
endpointDefaults = this.endpointDefaults[endpointName];
copy.endpointDefaults[endpointName] = merge(endpointDefaults, overrides);
}
return copy;
};
Gofer.prototype.clone = function () {
return this['with']({});
};
Gofer.prototype.request = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
return this._request(options, cb);
};
Gofer.prototype.put = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options.method = 'PUT';
return this._request(options, cb);
};
Gofer.prototype.del = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options.method = 'DELETE';
return this._request(options, cb);
};
Gofer.prototype.head = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options.method = 'HEAD';
return this._request(options, cb);
};
Gofer.prototype.post = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options.method = 'POST';
return this._request(options, cb);
};
Gofer.prototype.patch = function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options.method = 'PATCH';
return this._request(options, cb);
};
Gofer.prototype.registerEndpoint = function (endpointName, endpointFn) {
Object.defineProperty(this, endpointName, {
configurable: true,
get: function () {
var request, value;
request = this.requestWithDefaults({ endpointName: endpointName });
value = endpointFn(request);
Object.defineProperty(this, endpointName, { value: value });
return value;
}
return defaults;
};
Gofer.prototype.applyBaseUrl = applyBaseUrl;
Gofer.prototype._applyMappers = function(originalOptions) {
return this._mappers.reduce((function(_this) {
return function(options, mapper) {
return mapper.call(_this, options);
};
})(this), originalOptions);
};
Gofer.prototype._request = function(options, cb) {
var defaults, err, _base, _ref1;
defaults = this._getDefaults(this.defaults, options);
if (options.methodName == null) {
options.methodName = ((_ref1 = options.method) != null ? _ref1 : 'get').toLowerCase();
}
if (this.serviceName != null) {
options.serviceName = this.serviceName;
}
if (this.serviceVersion != null) {
options.serviceVersion = this.serviceVersion;
}
try {
options = this._applyMappers(merge(defaults, options));
} catch (_error) {
err = _error;
return cb(err);
}
if (options.headers == null) {
options.headers = {};
}
if ((_base = options.headers)['User-Agent'] == null) {
_base['User-Agent'] = buildUserAgent(options);
}
if (options.qs != null) {
options.qs = cleanObject(options.qs);
}
if (options.headers != null) {
options.headers = cleanObject(options.headers);
}
if (options.logData == null) {
options.logData = {};
}
extend(options.logData, {
serviceName: options.serviceName,
endpointName: options.endpointName,
methodName: options.methodName,
pathParams: options.pathParams
});
if (typeof cb === 'function') {
return this.hub.fetch(options, function(err, body, response, responseData) {
return cb(err, body, responseData, response);
});
return this;
};
Gofer.prototype.registerEndpoints = function (endpointMap) {
var handler, name;
for (name in endpointMap) {
handler = endpointMap[name];
this.registerEndpoint(name, handler);
} else {
return this.hub.fetch(options);
}
};
Gofer.prototype._mappers = [
function(opts) {
var baseUrl;
baseUrl = opts.baseUrl;
if (baseUrl != null) {
delete opts.baseUrl;
return this.applyBaseUrl(baseUrl, opts);
} else {
return opts;
}
return this;
};
Gofer.prototype.addOptionMapper = function (mapper) {
this._mappers = this._mappers.concat([mapper]);
return this;
};
Gofer.prototype.clearOptionMappers = function () {
return this._mappers = [];
};
Gofer.prototype.requestWithDefaults = function (defaults) {
return function (this$) {
return function (uri, options, cb) {
var cache$2;
cache$2 = resolveOptional(uri, options, cb);
options = cache$2.options;
cb = cache$2.cb;
options = merge(defaults, options);
return this$._request(options, cb);
};
}(this);
};
Gofer.prototype._getDefaults = function (defaults, options) {
var endpointName;
endpointName = options.endpointName;
if (null != endpointName && null != this.endpointDefaults[endpointName])
defaults = merge(defaults, this.endpointDefaults[endpointName]);
return defaults;
};
Gofer.prototype.applyBaseUrl = applyBaseUrl;
Gofer.prototype._applyMappers = function (originalOptions) {
return this._mappers.reduce(function (this$) {
return function (options, mapper) {
return mapper.call(this$, options);
};
}(this), originalOptions);
};
Gofer.prototype._request = function (options, cb) {
var defaults, err;
defaults = this._getDefaults(this.defaults, options);
if (null != options.methodName)
options.methodName;
else
options.methodName = (null != options.method ? options.method : 'get').toLowerCase();
if (null != this.serviceName)
options.serviceName = this.serviceName;
if (null != this.serviceVersion)
options.serviceVersion = this.serviceVersion;
try {
options = this._applyMappers(merge(defaults, options));
} catch (e$) {
err = e$;
return cb(err);
}
if (null != options.headers)
options.headers;
else
options.headers = {};
if (null != options.headers['User-Agent'])
options.headers['User-Agent'];
else
options.headers['User-Agent'] = buildUserAgent(options);
if (null != options.qs)
options.qs = cleanObject(options.qs);
if (null != options.headers)
options.headers = cleanObject(options.headers);
if (null != options.logData)
options.logData;
else
options.logData = {};
extend(options.logData, {
serviceName: options.serviceName,
endpointName: options.endpointName,
methodName: options.methodName,
pathParams: options.pathParams
});
return this.hub.fetch(options, function (err, body, response, responseData) {
var data, parseJSON;
parseJSON = null != options.parseJSON ? options.parseJSON : isJsonResponse(response, body);
if (!parseJSON)
return cb(err, body, responseData, response);
data = safeParseJSON(body);
return cb(null != err ? err : data.error, data.result, responseData, response);
});
};
Gofer.prototype._mappers = [function (opts) {
var baseUrl;
baseUrl = opts.baseUrl;
if (null != baseUrl) {
delete opts.baseUrl;
return this.applyBaseUrl(baseUrl, opts);
} else {
return opts;
}
}];
return Gofer;
}();
Gofer.prototype.fetch = Gofer.prototype.request;
Gofer.prototype.get = Gofer.prototype.request;
module.exports = Gofer;
Gofer['default'] = Gofer;
}.call(this);
}
];
return Gofer;
})();
Gofer.prototype.fetch = Gofer.prototype.request;
Gofer.prototype.get = Gofer.prototype.request;
module.exports = Gofer;
Gofer['default'] = Gofer;

@@ -0,1 +1,3 @@

// Generated by CoffeeScript 1.9.0
/*

@@ -31,138 +33,128 @@ Copyright (c) 2014, Groupon, Inc.

SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
var Url, cleanProperty, isObject, merge, mergeSafe, reduce, replacePathParams, _ref;
// Generated by CoffeeScript 2.0.0-beta7
void function () {
var cache$, cleanProperty, isObject, merge, mergeSafe, reduce, replacePathParams, Url;
cache$ = require('lodash');
merge = cache$.merge;
isObject = cache$.isObject;
reduce = cache$.reduce;
Url = require('url');
cleanProperty = function (obj, value, key) {
if (null != value)
obj[key] = value;
_ref = require('lodash'), merge = _ref.merge, isObject = _ref.isObject, reduce = _ref.reduce;
Url = require('url');
cleanProperty = function(obj, value, key) {
if (value != null) {
obj[key] = value;
}
return obj;
};
this.cleanObject = function(obj) {
if (typeof obj !== 'object') {
return obj;
};
this.cleanObject = function (obj) {
if (!(typeof obj === 'object'))
return obj;
return reduce(obj, cleanProperty, {});
};
this.merge = mergeSafe = function (o1, o2) {
return merge({}, o1, o2);
};
this.resolveOptional = function (uri, options, cb) {
if ('function' === typeof options) {
cb = options;
options = null;
} else if ('function' !== typeof cb) {
cb = function () {
};
}
return reduce(obj, cleanProperty, {});
};
this.merge = mergeSafe = function(o1, o2) {
return merge({}, o1, o2);
};
this.resolveOptional = function(uri, options, cb) {
if ('function' === typeof options) {
cb = options;
options = null;
} else if ('function' !== typeof cb) {
cb = function() {};
}
if ('string' === typeof uri) {
if (options == null) {
options = {};
}
if ('string' === typeof uri) {
if (null != options)
options;
else
options = {};
options.uri = uri;
} else {
options = uri;
}
return {
options: options,
cb: cb
};
options.uri = uri;
} else {
options = uri;
}
return {
options: options,
cb: cb
};
this.parseDefaults = function (rawConfig, serviceName) {
var defaults, endpointDefaults, globalDefaults, serviceDefaults;
if (null != rawConfig)
rawConfig;
else
rawConfig = {};
globalDefaults = null != rawConfig.globalDefaults ? rawConfig.globalDefaults : {};
serviceDefaults = null != rawConfig[serviceName] ? rawConfig[serviceName] : {};
defaults = mergeSafe(globalDefaults, serviceDefaults);
endpointDefaults = null != defaults.endpointDefaults ? defaults.endpointDefaults : {};
delete defaults.endpointDefaults;
return {
defaults: defaults,
endpointDefaults: endpointDefaults
};
};
this.parseDefaults = function(rawConfig, serviceName) {
var defaults, endpointDefaults, globalDefaults, serviceDefaults, _ref1, _ref2, _ref3;
if (rawConfig == null) {
rawConfig = {};
}
globalDefaults = (_ref1 = rawConfig.globalDefaults) != null ? _ref1 : {};
serviceDefaults = (_ref2 = rawConfig[serviceName]) != null ? _ref2 : {};
defaults = mergeSafe(globalDefaults, serviceDefaults);
endpointDefaults = (_ref3 = defaults.endpointDefaults) != null ? _ref3 : {};
delete defaults.endpointDefaults;
return {
defaults: defaults,
endpointDefaults: endpointDefaults
};
this.applyBaseUrl = function (baseUrl, options) {
var basePath, cache$1, cache$2, hostname, pathname, port, protocol, query, search, uri;
uri = options.uri;
if ('string' === typeof uri)
uri = Url.parse(uri);
if ('string' === typeof baseUrl)
baseUrl = Url.parse(baseUrl);
basePath = baseUrl.pathname.substr(-1) === '/' ? baseUrl.pathname.substr(0, baseUrl.pathname.length - 1) : baseUrl.pathname;
pathname = '' + basePath + uri.pathname;
cache$1 = baseUrl;
protocol = cache$1.protocol;
hostname = cache$1.hostname;
port = cache$1.port;
cache$2 = uri;
query = cache$2.query;
search = cache$2.search;
uri = Url.format({
protocol: protocol,
hostname: hostname,
port: port,
pathname: pathname,
query: query,
search: search
});
options.uri = replacePathParams(uri, options.pathParams);
return options;
};
this.buildUserAgent = function (options) {
var appName, appSha, cache$1, fqdn, serviceName, serviceVersion;
cache$1 = options;
serviceVersion = cache$1.serviceVersion;
serviceName = cache$1.serviceName;
appSha = cache$1.appSha;
appName = cache$1.appName;
fqdn = cache$1.fqdn;
if (null != serviceVersion)
serviceVersion;
else
serviceVersion = '[no serviceVersion]';
if (null != serviceName)
serviceName;
else
serviceName = '[no serviceName]';
if (null != appName)
appName;
else
appName = '[no appName]';
if (null != appSha)
appSha;
else
appSha = '[no appSha]';
if (null != fqdn)
fqdn;
else
fqdn = '[no fqdn]';
return '' + serviceName + '/' + serviceVersion + '; ' + appName + '/' + appSha + '; ' + fqdn;
};
replacePathParams = function (uri, pathParams) {
var regex, wrappedPathParams, wrappedTags;
if (!isObject(pathParams))
return uri;
wrappedPathParams = reduce(pathParams, function (acc, value, tag) {
var encoded, encodedWrapped, wrappedTag;
encoded = encodeURIComponent(value);
wrappedTag = '{' + tag + '}';
encodedWrapped = '%7B' + tag + '%7D';
acc[wrappedTag] = acc[encodedWrapped] = encoded;
return acc;
}, {});
wrappedTags = Object.keys(wrappedPathParams);
regex = new RegExp(wrappedTags.join('|'), 'g');
return uri.replace(regex, function (match) {
return wrappedPathParams[match];
});
};
}.call(this);
};
this.applyBaseUrl = function(baseUrl, options) {
var basePath, hostname, pathname, port, protocol, query, search, uri;
uri = options.uri;
if ('string' === typeof uri) {
uri = Url.parse(uri);
}
if ('string' === typeof baseUrl) {
baseUrl = Url.parse(baseUrl);
}
basePath = baseUrl.pathname.substr(-1) === '/' ? baseUrl.pathname.substr(0, baseUrl.pathname.length - 1) : baseUrl.pathname;
pathname = "" + basePath + uri.pathname;
protocol = baseUrl.protocol, hostname = baseUrl.hostname, port = baseUrl.port;
query = uri.query, search = uri.search;
uri = Url.format({
protocol: protocol,
hostname: hostname,
port: port,
pathname: pathname,
query: query,
search: search
});
options.uri = replacePathParams(uri, options.pathParams);
return options;
};
this.buildUserAgent = function(options) {
var appName, appSha, fqdn, serviceName, serviceVersion;
serviceVersion = options.serviceVersion, serviceName = options.serviceName, appSha = options.appSha, appName = options.appName, fqdn = options.fqdn;
if (serviceVersion == null) {
serviceVersion = "[no serviceVersion]";
}
if (serviceName == null) {
serviceName = "[no serviceName]";
}
if (appName == null) {
appName = "[no appName]";
}
if (appSha == null) {
appSha = "[no appSha]";
}
if (fqdn == null) {
fqdn = "[no fqdn]";
}
return serviceName + "/" + serviceVersion + "; " + appName + "/" + appSha + "; " + fqdn;
};
replacePathParams = function(uri, pathParams) {
var regex, wrappedPathParams, wrappedTags;
if (!isObject(pathParams)) {
return uri;
}
wrappedPathParams = reduce(pathParams, (function(acc, value, tag) {
var encoded, encodedWrapped, wrappedTag;
encoded = encodeURIComponent(value);
wrappedTag = "{" + tag + "}";
encodedWrapped = "%7B" + tag + "%7D";
acc[wrappedTag] = acc[encodedWrapped] = encoded;
return acc;
}), {});
wrappedTags = Object.keys(wrappedPathParams);
regex = new RegExp(wrappedTags.join("|"), "g");
return uri.replace(regex, function(match) {
return wrappedPathParams[match];
});
};

@@ -0,1 +1,3 @@

// Generated by CoffeeScript 1.9.0
/*

@@ -31,192 +33,217 @@ Copyright (c) 2014, Groupon, Inc.

SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
var DefaultPromise, EventEmitter, HRDuration, Hub, debug, extend, formatUri, generateHeaders, generateUUID, http, https, isJsonResponse, map, promiseHelpers, request, safeParseJSON, uuid, _ref, _ref1, _ref2;
// Generated by CoffeeScript 2.0.0-beta7
void function () {
var cache$, debug, EventEmitter, extend, formatUri, generateHeaders, generateUUID, HRDuration, http, https, Hub, map, request, uuid;
EventEmitter = require('events').EventEmitter;
http = require('http');
https = require('https');
request = require('request');
HRDuration = require('hrduration');
uuid = require('node-uuid');
cache$ = require('lodash');
extend = cache$.extend;
map = cache$.map;
debug = require('debug')('gofer:hub');
module.exports = Hub = function () {
var hub, logPendingRequests, setupCompletionTimeout, setupTimeouts;
hub = new EventEmitter;
hub.fetch = function (options, cb) {
var baseLog, completionTimeoutInterval, connectTimeoutInterval, fetchId, getSeconds, hubHeaders, req, responseData;
getSeconds = HRDuration().getSeconds;
fetchId = generateUUID();
if (null != options.timeout)
options.timeout;
else
options.timeout = Hub.requestTimeout;
if (null != options.headers)
options.headers;
else
options.headers = {};
options.method = null != options.method ? options.method.toUpperCase() : 'GET';
hubHeaders = generateHeaders(options.requestId, fetchId);
extend(options.headers, hubHeaders);
logPendingRequests(http.globalAgent);
logPendingRequests(https.globalAgent);
responseData = {
requestOptions: options,
EventEmitter = require('events').EventEmitter;
http = require('http');
https = require('https');
request = require('request');
HRDuration = require('hrduration');
uuid = require('node-uuid');
_ref = require('lodash'), extend = _ref.extend, map = _ref.map;
debug = require('debug')('gofer:hub');
DefaultPromise = (_ref1 = global.Promise) != null ? _ref1 : require('bluebird');
_ref2 = require('./json'), safeParseJSON = _ref2.safeParseJSON, isJsonResponse = _ref2.isJsonResponse;
promiseHelpers = require('./promise');
module.exports = Hub = function() {
var hub, logPendingRequests, setupCompletionTimeout, setupTimeouts;
hub = new EventEmitter;
hub.Promise = DefaultPromise;
hub.fetch = function(options, done) {
var baseLog, completionTimeoutInterval, connectTimeoutInterval, fetchId, getSeconds, handleResult, hubHeaders, req, responseData, sendResult, _ref3;
getSeconds = HRDuration().getSeconds;
fetchId = generateUUID();
if (options.timeout == null) {
options.timeout = Hub.requestTimeout;
}
if (options.headers == null) {
options.headers = {};
}
options.method = options.method != null ? options.method.toUpperCase() : 'GET';
hubHeaders = generateHeaders(options.requestId, fetchId);
extend(options.headers, hubHeaders);
logPendingRequests(http.globalAgent);
logPendingRequests(https.globalAgent);
responseData = {
requestOptions: options,
requestId: options.requestId,
fetchId: fetchId
};
debug('-> %s', options.method, options.uri);
baseLog = extend({
uri: options.uri,
method: options.method
}, options.logData);
hub.emit('start', extend(baseLog, responseData));
handleResult = function(error, response, body) {
var apiError, logLine, maxStatusCode, minStatusCode, parseJSON, successfulRequest, uri, _ref3, _ref4, _ref5;
parseJSON = (_ref3 = options.parseJSON) != null ? _ref3 : isJsonResponse(response, body);
if (parseJSON) {
_ref4 = safeParseJSON(body), error = _ref4.error, body = _ref4.result;
}
responseData.fetchDuration = getSeconds();
responseData.requestOptions.uri = this.uri;
uri = formatUri(responseData.requestOptions.uri);
logLine = extend({
statusCode: response != null ? response.statusCode : void 0,
uri: uri,
method: options.method,
connectDuration: responseData.connectDuration,
fetchDuration: responseData.fetchDuration,
requestId: options.requestId,
fetchId: fetchId
};
debug('-> %s', options.method, options.uri);
baseLog = extend({
uri: options.uri,
method: options.method
}, options.logData);
hub.emit('start', extend(baseLog, responseData));
req = request(options, function (error, response, body) {
var apiError, logLine, maxStatusCode, minStatusCode, successfulRequest, uri;
responseData.fetchDuration = getSeconds();
responseData.requestOptions.uri = this.uri;
uri = formatUri(responseData.requestOptions.uri);
logLine = extend({
statusCode: null != response ? response.statusCode : void 0,
uri: uri,
method: options.method,
connectDuration: responseData.connectDuration,
fetchDuration: responseData.fetchDuration,
requestId: options.requestId,
fetchId: fetchId
}, options.logData);
if (null != error) {
logLine.syscall = error.syscall;
logLine.statusCode = error.code;
logLine.error = error;
debug('<- %s', error.code, uri);
hub.emit('fetchError', logLine);
return cb(error, body);
}
apiError = null;
minStatusCode = options.minStatusCode || 200;
maxStatusCode = options.maxStatusCode || 299;
successfulRequest = minStatusCode <= response.statusCode && response.statusCode <= maxStatusCode;
if (successfulRequest) {
debug('<- %s', response.statusCode, uri);
hub.emit('success', logLine);
} else {
apiError = new Error('API Request returned a response outside the status code range (code: ' + response.statusCode + ', range: [' + minStatusCode + ', ' + maxStatusCode + '])');
apiError.type = 'api_response_error';
apiError.httpHeaders = response.headers;
apiError.body = body;
apiError.statusCode = response.statusCode;
apiError.minStatusCode = logLine.minStatusCode = minStatusCode;
apiError.maxStatusCode = logLine.maxStatusCode = maxStatusCode;
debug('<- %s', response.statusCode, uri);
hub.emit('failure', logLine);
}
return cb(apiError, body, response, responseData);
});
connectTimeoutInterval = null != options.connectTimeout ? options.connectTimeout : Hub.connectTimeout;
completionTimeoutInterval = options.completionTimeout;
setupTimeouts(connectTimeoutInterval, completionTimeoutInterval, req, responseData, getSeconds);
return req;
};
logPendingRequests = function (param$) {
var cache$1, maxSockets, queueReport, requests;
{
cache$1 = param$;
requests = cache$1.requests;
maxSockets = cache$1.maxSockets;
if (error != null) {
logLine.syscall = error.syscall;
logLine.statusCode = error.code;
logLine.error = error;
debug('<- %s', error.code, uri);
hub.emit('fetchError', logLine);
return sendResult(error, body);
}
if (!(Object.keys(requests).length > 0))
return;
queueReport = function (accum$) {
var host, queue;
for (host in requests) {
queue = requests[host];
accum$.push('' + host + ': ' + queue.length);
}
return accum$;
}.call(this, []);
return hub.emit('socketQueueing', {
maxSockets: maxSockets,
queueReport: queueReport
});
apiError = null;
minStatusCode = options.minStatusCode || 200;
maxStatusCode = options.maxStatusCode || 299;
successfulRequest = (minStatusCode <= (_ref5 = response.statusCode) && _ref5 <= maxStatusCode);
if (successfulRequest) {
debug('<- %s', response.statusCode, uri);
hub.emit('success', logLine);
} else {
apiError = new Error("API Request returned a response outside the status code range (code: " + response.statusCode + ", range: [" + minStatusCode + ", " + maxStatusCode + "])");
apiError.type = 'api_response_error';
apiError.httpHeaders = response.headers;
apiError.body = body;
apiError.statusCode = response.statusCode;
apiError.minStatusCode = logLine.minStatusCode = minStatusCode;
apiError.maxStatusCode = logLine.maxStatusCode = maxStatusCode;
debug('<- %s', response.statusCode, uri);
hub.emit('failure', logLine);
}
return sendResult(apiError, body, response, responseData);
};
setupTimeouts = function (connectTimeoutInterval, completionTimeoutInterval, request, responseData, getSeconds) {
return request.on('request', function (req) {
return req.on('socket', function (socket) {
var connectingSocket, connectionSuccessful, connectionTimedOut, connectTimeout;
connectTimeout = void 0;
connectionTimedOut = function () {
var err;
req.abort();
responseData.connectDuration = getSeconds();
err = new Error('ECONNECTTIMEDOUT');
err.code = 'ECONNECTTIMEDOUT';
err.message = 'Connecting to ' + responseData.requestOptions.method + ' ' + ('' + responseData.requestOptions.uri + ' timed out after ' + connectTimeoutInterval + 'ms');
err.responseData = responseData;
return req.emit('error', err);
};
connectionSuccessful = function () {
responseData.connectDuration = getSeconds();
hub.emit('connect', responseData);
clearTimeout(connectTimeout);
connectTimeout = null;
return setupCompletionTimeout(completionTimeoutInterval, req, responseData, getSeconds);
};
connectingSocket = null != socket.socket ? socket.socket : socket;
connectingSocket.on('connect', connectionSuccessful);
return connectTimeout = setTimeout(connectionTimedOut, connectTimeoutInterval);
});
});
sendResult = function(error, data, response, responseData) {
return req.emit('goferResult', error, data, response, responseData);
};
setupCompletionTimeout = function (completionTimeoutInterval, req, responseData, getSeconds) {
var completionSuccessful, completionTimedOut, completionTimeout;
if (!completionTimeoutInterval)
return;
completionTimeout = void 0;
completionTimedOut = function () {
var err;
req.abort();
responseData.completionDuration = getSeconds() - responseData.connectDuration;
err = new Error('ETIMEDOUT');
err.code = 'ETIMEDOUT';
err.message = 'Response timed out after ' + completionTimeoutInterval + 'ms';
err.responseData = responseData;
return req.emit('error', err);
};
completionSuccessful = function () {
responseData.completionDuration = getSeconds() - responseData.connectDuration;
clearTimeout(completionTimeout);
return completionTimeout = null;
};
req.on('complete', completionSuccessful);
return completionTimeout = setTimeout(completionTimedOut, completionTimeoutInterval);
};
return hub;
req = request(options, handleResult);
connectTimeoutInterval = (_ref3 = options.connectTimeout) != null ? _ref3 : Hub.connectTimeout;
completionTimeoutInterval = options.completionTimeout;
setupTimeouts(connectTimeoutInterval, completionTimeoutInterval, req, responseData, getSeconds);
if (typeof done === 'function') {
req.on('goferResult', done);
}
req.Promise = hub.Promise;
return Object.defineProperties(req, promiseHelpers);
};
generateUUID = function () {
return uuid.v1().replace(/-/g, '');
logPendingRequests = function(_arg) {
var host, maxSockets, queue, queueReport, requests;
requests = _arg.requests, maxSockets = _arg.maxSockets;
if (!(Object.keys(requests).length > 0)) {
return;
}
queueReport = (function() {
var _results;
_results = [];
for (host in requests) {
queue = requests[host];
_results.push(host + ": " + queue.length);
}
return _results;
})();
return hub.emit('socketQueueing', {
maxSockets: maxSockets,
queueReport: queueReport
});
};
generateHeaders = function (requestId, fetchId) {
var headers;
headers = {
Connection: 'close',
'X-Fetch-ID': fetchId
};
if (null != requestId)
headers['X-Request-ID'] = requestId;
return headers;
setupTimeouts = function(connectTimeoutInterval, completionTimeoutInterval, request, responseData, getSeconds) {
return request.on('request', function(req) {
return req.on('socket', function(socket) {
var connectTimeout, connectingSocket, connectionSuccessful, connectionTimedOut, _ref3;
connectTimeout = void 0;
connectionTimedOut = function() {
var err;
req.abort();
responseData.connectDuration = getSeconds();
err = new Error('ECONNECTTIMEDOUT');
err.code = 'ECONNECTTIMEDOUT';
err.message = ("Connecting to " + responseData.requestOptions.method + " ") + (responseData.requestOptions.uri + " timed out after " + connectTimeoutInterval + "ms");
err.responseData = responseData;
return req.emit('error', err);
};
connectionSuccessful = function() {
responseData.connectDuration = getSeconds();
hub.emit('connect', responseData);
clearTimeout(connectTimeout);
connectTimeout = null;
return setupCompletionTimeout(completionTimeoutInterval, req, responseData, getSeconds);
};
connectingSocket = (_ref3 = socket.socket) != null ? _ref3 : socket;
connectingSocket.on('connect', connectionSuccessful);
return connectTimeout = setTimeout(connectionTimedOut, connectTimeoutInterval);
});
});
};
formatUri = function (uri) {
if (typeof uri === 'object') {
return uri.href;
} else {
return uri;
setupCompletionTimeout = function(completionTimeoutInterval, req, responseData, getSeconds) {
var completionSuccessful, completionTimedOut, completionTimeout;
if (!completionTimeoutInterval) {
return;
}
completionTimeout = void 0;
completionTimedOut = function() {
var err;
req.abort();
responseData.completionDuration = getSeconds() - responseData.connectDuration;
err = new Error('ETIMEDOUT');
err.code = 'ETIMEDOUT';
err.message = "Response timed out after " + completionTimeoutInterval + "ms";
err.responseData = responseData;
return req.emit('error', err);
};
completionSuccessful = function() {
responseData.completionDuration = getSeconds() - responseData.connectDuration;
clearTimeout(completionTimeout);
return completionTimeout = null;
};
req.on('complete', completionSuccessful);
return completionTimeout = setTimeout(completionTimedOut, completionTimeoutInterval);
};
Hub.connectTimeout = 1e3;
Hub.requestTimeout = 1e4;
}.call(this);
return hub;
};
generateUUID = function() {
return uuid.v1().replace(/-/g, '');
};
generateHeaders = function(requestId, fetchId) {
var headers;
headers = {
'Connection': 'close',
'X-Fetch-ID': fetchId
};
if (requestId != null) {
headers['X-Request-ID'] = requestId;
}
return headers;
};
formatUri = function(uri) {
if (typeof uri === 'object') {
return uri.href;
} else {
return uri;
}
};
Hub.connectTimeout = 1000;
Hub.requestTimeout = 10000;

@@ -0,1 +1,3 @@

// Generated by CoffeeScript 1.9.0
/*

@@ -31,32 +33,35 @@ Copyright (c) 2014, Groupon, Inc.

SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
var jsonHeader, nonEmpty;
// Generated by CoffeeScript 2.0.0-beta7
void function () {
var jsonHeader, nonEmpty;
this.safeParseJSON = function (str) {
var data, err;
data = { error: null };
try {
data.result = 'string' === typeof str ? JSON.parse(str) : null != str ? str : '';
} catch (e$) {
err = e$;
data.error = err;
data.result = str;
}
return data;
this.safeParseJSON = function(str) {
var data, err;
data = {
error: null
};
jsonHeader = function (res) {
var contentType;
contentType = null != res && null != res.headers ? res.headers['content-type'] : void 0;
if (!(null != contentType))
return false;
return contentType.indexOf('application/json') === 0;
};
nonEmpty = function (body) {
return (null != body ? body.length : void 0) > 0;
};
this.isJsonResponse = function (res, body) {
return jsonHeader(res) && nonEmpty(body);
};
}.call(this);
try {
data.result = 'string' === typeof str ? JSON.parse(str) : str != null ? str : '';
} catch (_error) {
err = _error;
data.error = err;
data.result = str;
}
return data;
};
jsonHeader = function(res) {
var contentType, _ref;
contentType = res != null ? (_ref = res.headers) != null ? _ref['content-type'] : void 0 : void 0;
if (contentType == null) {
return false;
}
return contentType.indexOf('application/json') === 0;
};
nonEmpty = function(body) {
return (body != null ? body.length : void 0) > 0;
};
this.isJsonResponse = function(res, body) {
return jsonHeader(res) && nonEmpty(body);
};

@@ -0,1 +1,3 @@

// Generated by CoffeeScript 1.9.0
/*

@@ -31,33 +33,33 @@ Copyright (c) 2014, Groupon, Inc.

SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
var Url, omit;
// Generated by CoffeeScript 2.0.0-beta7
void function () {
var omit, Url;
omit = require('lodash').omit;
Url = require('url');
module.exports = function (client, req, res, next) {
var cache$, options, pathname, properReturnValue, proxyReq, query;
cache$ = Url.parse(req.url, true);
pathname = cache$.pathname;
query = cache$.query;
options = {
method: req.method,
headers: omit(req.headers, ['host']),
uri: pathname,
qs: omit(query, ['callback']),
minStatusCode: 200,
maxStatusCode: 399
};
properReturnValue = false;
proxyReq = client.request(options, function (err) {
if (properReturnValue)
return;
if (null != err)
return next(err);
});
properReturnValue = null != proxyReq;
if (properReturnValue)
return req.pipe(proxyReq).pipe(res);
omit = require('lodash').omit;
Url = require('url');
module.exports = function(client, req, res, next) {
var options, pathname, properReturnValue, proxyReq, query, _ref;
_ref = Url.parse(req.url, true), pathname = _ref.pathname, query = _ref.query;
options = {
method: req.method,
headers: omit(req.headers, ['host']),
uri: pathname,
qs: omit(query, ['callback']),
minStatusCode: 200,
maxStatusCode: 399
};
}.call(this);
properReturnValue = false;
proxyReq = client.request(options, function(err) {
if (properReturnValue) {
return;
}
if (err != null) {
return next(err);
}
});
properReturnValue = proxyReq != null;
if (properReturnValue) {
return req.pipe(proxyReq).pipe(res);
}
};
{
"name": "gofer",
"version": "2.2.1",
"version": "2.3.0",
"description": "A general purpose service client library for node.js",
"main": "lib/gofer.js",
"scripts": {
"prepublish": "rm -rf lib && make build",
"pretest": "make build",
"build": "npub prep && coffee -cbo lib src",
"prepublish": "rm -rf lib && npm run build",
"pretest": "npm run build",
"test": "mocha",

@@ -21,2 +22,3 @@ "posttest": "npub verify"

],
"license": "BSD-2-Clause",
"author": {

@@ -44,2 +46,3 @@ "name": "Jan Krems",

"exclude": [
"lib",
"test"

@@ -50,18 +53,18 @@ ]

"dependencies": {
"debug": "~0.8.1",
"bluebird": "^2.9.13",
"debug": "^2.1.2",
"hrduration": "^1.0.0",
"lodash": "~2.4.1",
"node-uuid": "~1.4.1",
"lodash": "^3.0.0",
"node-uuid": "^1.4.1",
"request": "2.40.0"
},
"devDependencies": {
"assertive": "~1.4.0",
"bondjs": "~1.1.1",
"coffee-script-redux": "2.0.0-beta7",
"assertive": "^1.4.0",
"bondjs": "^1.1.1",
"coffee-script": "1.9.0",
"deepmerge": "^0.2.7",
"express": "~4.1.1",
"mocha": "~1.18.2",
"npub": "~0.5.1",
"semver": "~2.1.0"
"express": "^4.1.1",
"mocha": "^2.1.0",
"npub": "^2.0.0"
}
}

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