Socket
Socket
Sign inDemoInstall

hubkit

Package Overview
Dependencies
7
Maintainers
1
Versions
121
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.6 to 2.0.0

2

.eslintrc.js

@@ -8,3 +8,3 @@ module.exports = {

LRUCache: true,
superagent: true,
axios: true,
Promise: false,

@@ -11,0 +11,0 @@ setTimeout: false

{
"name": "hubkit",
"version": "1.0.6",
"version": "2.0.0",
"homepage": "https://github.com/pkaminski/hubkit",

@@ -24,4 +24,5 @@ "authors": [

"dependencies": {
"superagent": "5.x"
"axios": "^0.19.2",
"lru-cache": "^4.0.0"
}
}
if (typeof require !== 'undefined') {
/* global require */
if (typeof superagent === 'undefined') superagent = require('superagent');
if (typeof axios === 'undefined') axios = require('axios');
if (typeof LRUCache === 'undefined') LRUCache = require('lru-cache');

@@ -29,3 +29,2 @@ }

}
superagent.parse['text/plain'] = function(o) {return o;};
})(function(isNode) {

@@ -81,3 +80,3 @@ 'use strict';

Hubkit.defaults = {
method: 'get', host: 'https://api.github.com', perPage: 100, allPages: true, maxTries: 3,
method: 'GET', host: 'https://api.github.com', perPage: 100, allPages: true, maxTries: 3,
maxItemSizeRatio: 0.1, metadata: Hubkit, stats: new Hubkit.Stats(), agent: false,

@@ -98,3 +97,3 @@ corsSuccessFlags: {}

path = interpolatePath(path, options);
var req;
var cachedItem = null, cacheKey, cacheable = options.cache && options.method === 'GET';

@@ -130,5 +129,5 @@ if (cacheable) {

function handleError(error, res) {
error.request = {method: req.method, url: req.url, headers: res && res.req._headers};
error.request = {method: options.method, url: path, headers: res && res.config.headers};
if (error.request.headers) delete error.request.headers.authorization;
if (cacheable && error.status) {
if (cacheable && res && res.status) {
options.cache.del(cacheKey);

@@ -141,3 +140,3 @@ if (options.stats) options.stats.record(false);

if (cacheable &&
/Origin is not allowed by Access-Control-Allow-Origin/.test(error.originalMessage)) {
/Network Error/.test(error.originalMessage)) {
cacheable = false;

@@ -151,3 +150,3 @@ retry();

if (NETWORK_ERROR_CODES.indexOf(error.code) >= 0 ||
[500, 502, 503, 504].indexOf(error.status) >= 0 ||
[500, 502, 503, 504].indexOf(res && res.status) >= 0 ||
error.originalMessage === 'socket hang up' ||

@@ -158,6 +157,6 @@ error.originalMessage === 'Unexpected end of input'

options.agent = false;
} else if (error.status === 403 && res && res.header['retry-after']) {
} else if (res && res.status === 403 && res.headers['retry-after']) {
try {
error.retryDelay =
parseInt(res.header['retry-after'].replace(/[^\d]*$/, ''), 10) * 1000;
parseInt(res.headers['retry-after'].replace(/[^\d]*$/, ''), 10) * 1000;
if (!options.timeout || error.retryDelay < options.timeout) value = Hubkit.RETRY;

@@ -167,7 +166,7 @@ } catch (e) {

}
} else if (error.status === 403 && res && res.header['x-ratelimit-remaining'] === '0' &&
res.header['x-ratelimit-reset']) {
} else if (res && res.status === 403 && res.headers['x-ratelimit-remaining'] === '0' &&
res.headers['x-ratelimit-reset']) {
try {
error.retryDelay =
Math.max(0, parseInt(res.header['x-ratelimit-reset'], 10) * 1000 - Date.now());
Math.max(0, parseInt(res.headers['x-ratelimit-reset'], 10) * 1000 - Date.now());
if (!options.timeout || error.retryDelay < options.timeout) value = Hubkit.RETRY;

@@ -197,4 +196,17 @@ } catch (e) {

timeout = timeout || options.timeout;
req = superagent(options.method, path);
addHeaders(req, options, cachedItem);
var rawData;
var config = {
url: path,
method: options.method,
timeout: timeout || 0,
params: {},
headers: {},
transformResponse: [function(data) {
rawData = data;
return data;
}].concat(axios.defaults.transformResponse),
};
addHeaders(config, options, cachedItem);
// If we're paging through a query, the path contains the full query string already so we

@@ -204,6 +216,11 @@ // need to wipe out any additional query params inserted by addHeaders above. Also, if we

// well.
if (cause === 'page' || options._cause === 'page') req._query = [];
if (timeout) req.timeout(timeout);
if (body) req[options.method === 'GET' ? 'query' : 'send'](body);
req.end(onComplete);
if (cause === 'page' || options._cause === 'page') config.params = {};
if (body) {
if (options.method === 'GET') config.params = Object.assign(config.params, body);
else config.data = body;
}
axios(config).then(function(res) {
onComplete(res, rawData);
}).catch(onError);
}).catch(function(error) {

@@ -224,30 +241,34 @@ reject(error);

function onComplete(error, res) {
if (error && error.response) {
res = error.response;
error = null;
function onError(error) {
if (error.response) {
return onComplete(error.response);
}
if (/Network Error/.test(error.message) &&
(options.corsSuccessFlags[options.host] ||
!cacheable && (options.method === 'GET' || options.method === 'HEAD'))
) {
error.message = 'Request terminated abnormally, network may be offline';
}
error.originalMessage = error.message;
error.message = formatError('Hubkit', error.message);
error.fingerprint =
['Hubkit', options.method, options.pathPattern, error.originalMessage];
handleError(error);
}
function onComplete(res, rawData) {
extractMetadata(path, res, options.metadata);
if (!error && res.header['access-control-allow-origin']) {
if (res.headers['access-control-allow-origin']) {
options.corsSuccessFlags[options.host] = true;
}
try {
if (error) {
if (/Origin is not allowed by Access-Control-Allow-Origin/.test(error.message) &&
(options.corsSuccessFlags[options.host] ||
!cacheable && (options.method === 'GET' || options.method === 'HEAD'))
) {
error.message = 'Request terminated abnormally, network may be offline';
}
error.originalMessage = error.message;
error.message = formatError('Hubkit', error.message);
error.fingerprint =
['Hubkit', options.method, options.pathPattern, error.originalMessage];
handleError(error, res);
} else if (res.status === 304) {
if (res.status === 304) {
cachedItem.expiry = parseExpiry(res);
if (options.stats) options.stats.record(true, cachedItem.size);
resolve(cachedItem.value);
} else if (!(res.ok || options.boolean && res.notFound && res.body &&
res.body.message === 'Not Found') || res.body && !res.body.data && res.body.errors) {
} else if (!(res.status >= 200 && res.status < 300 || options.boolean &&
res.status === 404 && res.data && res.data.message === 'Not Found') ||
res.data && !res.data.data && res.data.errors) {
if (cacheable) {

@@ -263,6 +284,6 @@ options.cache.del(cacheKey);

var errors = '', rateLimited = false;
if (res.body && res.body.errors) {
if (res.data && res.data.errors) {
errors = [];
for (var i = 0; i < res.body.errors.length; i++) {
var errorItem = res.body.errors[i];
for (var i = 0; i < res.data.errors.length; i++) {
var errorItem = res.data.errors[i];
if (errorItem.message) {

@@ -278,6 +299,6 @@ errors.push(errorItem.message);

errors = errors.join('; ');
if (res.body.message) errors = ' (' + errors + ')';
if (res.data.message) errors = ' (' + errors + ')';
}
var statusError = new Error(
formatError('GitHub', res.status, (res.body && res.body.message || '') + errors)
formatError('GitHub', res.status, (res.data && res.data.message || '') + errors)
);

@@ -293,3 +314,3 @@ statusError.status = res.status;

}
} else if (options.media === 'raw' && res.type !== 'text/plain') {
} else if (options.media === 'raw' && /^text\/plain *;?/.test(res.headers['content-type'])) {
// retry if github disregards 'raw'

@@ -301,4 +322,4 @@ handleError(new Error(

var nextUrl;
if (res.header.link) {
var match = /<([^>]+?)>;\s*rel="next"/.exec(res.header.link);
if (res.headers.link) {
var match = /<([^>]+?)>;\s*rel="next"/.exec(res.headers.link);
nextUrl = match && match[1];

@@ -309,7 +330,7 @@ if (nextUrl && !(options.method === 'GET' || options.method === 'HEAD')) {

}
if (!res.body && res.text && /\bformat=json\b/.test(res.header['x-github-media-type'])) {
res.body = JSON.parse(res.text);
if (!res.data && rawData && /\bformat=json\b/.test(res.headers['x-github-media-type'])) {
res.data = JSON.parse(rawData);
}
if (/^https?:\/\/[^/]+\/graphql/.test(path)) {
var data = res.body.data;
var data = res.data.data;
var root = data, rootKeys = [];

@@ -344,3 +365,3 @@ while (true) {

if (!result) {
result = res.body;
result = res.data;
delete root.pageInfo;

@@ -392,16 +413,16 @@ } else {

} else {
result = res.body;
result = res.data;
}
} else if (res.body && (
Array.isArray(res.body) || Array.isArray(res.body.items) ||
Array.isArray(res.body.statuses)
} else if (res.data && (
Array.isArray(res.data) || Array.isArray(res.data.items) ||
Array.isArray(res.data.statuses)
)) {
if (!result) {
result = res.body;
} else if (Array.isArray(res.body) && Array.isArray(result)) {
result = result.concat(res.body);
} else if (Array.isArray(res.body.items) && Array.isArray(result.items)) {
result.items = result.items.concat(res.body.items);
} else if (Array.isArray(res.body.statuses) && Array.isArray(result.statuses)) {
result.statuses = result.statuses.concat(res.body.statuses);
result = res.data;
} else if (Array.isArray(res.data) && Array.isArray(result)) {
result = result.concat(res.data);
} else if (Array.isArray(res.data.items) && Array.isArray(result.items)) {
result.items = result.items.concat(res.data.items);
} else if (Array.isArray(res.data.statuses) && Array.isArray(result.statuses)) {
result.statuses = result.statuses.concat(res.data.statuses);
} else {

@@ -430,18 +451,18 @@ throw new Error(formatError('Hubkit', 'unable to concatenate paged results'));

if (options.boolean) {
result = !!res.noContent;
result = res.status === 204;
} else {
result =
(options.responseType ||
res.body && typeof res.body === 'object' && Object.keys(res.body).length) ?
res.body : res.text;
res.data && typeof res.data === 'object' && Object.keys(res.data).length) ?
res.data : rawData;
}
}
if (cacheable) {
var size = res.text ? res.text.length : (res.body ?
(res.body.size || res.body.byteLength) : 1);
var size = rawData ? rawData.length : (res.data ?
(res.data.size || res.data.byteLength) : 1);
if (options.stats) options.stats.record(false, size);
if (res.status === 200 && (res.header.etag || res.header['cache-control']) &&
if (res.status === 200 && (res.headers.etag || res.headers['cache-control']) &&
size <= options.cache.max * options.maxItemSizeRatio) {
options.cache.set(cacheKey, {
value: result, eTag: res.header.etag, status: res.status, size: size,
value: result, eTag: res.headers.etag, status: res.status, size: size,
expiry: parseExpiry(res)

@@ -463,3 +484,2 @@ });

return requestPromise;
};

@@ -534,22 +554,28 @@

function addHeaders(req, options, cachedItem) {
if (cachedItem && cachedItem.eTag) req.set('If-None-Match', cachedItem.eTag);
if (isNode && req.agent) req.agent(options.agent);
function addHeaders(config, options, cachedItem) {
if (cachedItem && cachedItem.eTag) config.headers['If-None-Match'] = cachedItem.eTag;
if (isNode && options.agent) {
config[/^https:/.test(options.host) ? 'httpsAgent' : 'httpAgent'] = options.agent;
}
if (options.token) {
if (!isNode && (options.method === 'GET' || options.method === 'HEAD')) {
req.query({'access_token': options.token});
config.params['access_token'] = options.token;
} else {
req.set('Authorization', 'token ' + options.token);
config.headers['Authorization'] = 'token ' + options.token;
}
} else if (options.username && options.password) {
req.auth(options.username, options.password);
config.auth = {
username: options.username,
password: options.password
};
} else if (options.clientId && options.clientSecret) {
req.query({'client_id': options.clientId, 'client_secret': options.clientSecret});
config.params['client_id'] = options.clientId;
config.params['client_secret'] = options.clientSecret;
}
if (options.userAgent) req.set('User-Agent', options.userAgent);
if (options.media) req.accept('application/vnd.github.' + options.media);
if (options.userAgent) config.headers['User-Agent'] = options.userAgent;
if (options.media) config.headers['Accept'] = 'application/vnd.github.' + options.media;
if (options.method === 'GET' || options.method === 'HEAD') {
req.query({per_page: options.perPage}); // eslint-disable-line camelcase
config.params['per_page'] = options.perPage;
}
if (!isNode && options.responseType) req.responseType(options.responseType);
if (!isNode && options.responseType) config.responseType = options.responseType;
// Work around Firefox bug that forces caching. We can't use Cache-Control because it's not

@@ -560,3 +586,3 @@ // allowed by Github's cross-domain request headers, and because we want to keep our requests

if (!isNode && (options.method === 'GET' || options.method === 'HEAD')) {
req.query({'_nocache': Math.round(Math.random() * 1000000)});
config.params['_nocache'] = Math.round(Math.random() * 1000000);
}

@@ -569,11 +595,11 @@ }

(/^https?:\/\/[^/]+\/graphql/.test(path) ? 'graphRateLimit' : 'rateLimit');
metadata[rateName] = res.header['x-ratelimit-limit'] &&
parseInt(res.header['x-ratelimit-limit'], 10);
metadata[rateName + 'Remaining'] = res.header['x-ratelimit-remaining'] &&
parseInt(res.header['x-ratelimit-remaining'], 10);
metadata[rateName] = res.headers['x-ratelimit-limit'] &&
parseInt(res.headers['x-ratelimit-limit'], 10);
metadata[rateName + 'Remaining'] = res.headers['x-ratelimit-remaining'] &&
parseInt(res.headers['x-ratelimit-remaining'], 10);
// Not every response includes an X-OAuth-Scopes header, so keep the last known set if
// missing.
if ('x-oauth-scopes' in res.header) {
if ('x-oauth-scopes' in res.headers) {
metadata.oAuthScopes = [];
var scopes = (res.header['x-oauth-scopes'] || '').split(/\s*,\s*/);
var scopes = (res.headers['x-oauth-scopes'] || '').split(/\s*,\s*/);
if (!(scopes.length === 1 && scopes[0] === '')) {

@@ -591,3 +617,3 @@ // GitHub will sometimes return duplicate scopes in the list, so uniquefy them.

function parseExpiry(res) {
var match = (res.header['cache-control'] || '').match(/(^|[,\s])max-age=(\d+)/);
var match = (res.headers['cache-control'] || '').match(/(^|[,\s])max-age=(\d+)/);
if (match) return Date.now() + 1000 * parseInt(match[2], 10);

@@ -594,0 +620,0 @@ }

{
"name": "hubkit",
"version": "1.0.6",
"version": "2.0.0",
"description": "GitHub API library for JavaScript, promise-based, for both NodeJS and the browser",

@@ -29,4 +29,4 @@ "main": "index.js",

"dependencies": {
"lru-cache": "^4.0.0",
"superagent": "^5.0.5"
"axios": "^0.19.2",
"lru-cache": "^4.0.0"
},

@@ -33,0 +33,0 @@ "devDependencies": {

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc