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

superagent-cache

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

superagent-cache - npm Package Compare versions

Comparing version 1.0.3 to 1.0.4

2

package.json
{
"name": "superagent-cache",
"version": "1.0.3",
"version": "1.0.4",
"description": "Superagent with flexible built-in caching.",

@@ -5,0 +5,0 @@ "main": "superagentCache.js",

@@ -10,368 +10,371 @@ /**

var superagent = (agent) ? agent : require('superagent');
var Request = superagent.Request;
var props = {doQuery: true, cacheWhenEmpty: true};
var supportedMethods = ['GET', 'HEAD', 'PUT', 'DELETE'];
var cacheableMethods = ['GET', 'HEAD'];
if(!superagent.cache){
var Request = superagent.Request;
var props = {doQuery: true, cacheWhenEmpty: true};
var supportedMethods = ['GET', 'HEAD', 'PUT', 'DELETE'];
var cacheableMethods = ['GET', 'HEAD'];
if(cache){
superagent.cache = cache;
}
else{
var cModule = require('cache-service-cache-module');
superagent.cache = new cModule();
}
if(cache){
superagent.cache = cache;
}
else{
var cModule = require('cache-service-cache-module');
superagent.cache = new cModule();
}
/**
* Whether to execute an http query if the cache does not have the generated key
* @param {boolean} doQuery
*/
Request.prototype.doQuery = function(doQuery){
props.doQuery = doQuery;
return this;
}
/**
* Whether to execute an http query if the cache does not have the generated key
* @param {boolean} doQuery
*/
Request.prototype.doQuery = function(doQuery){
props.doQuery = doQuery;
return this;
}
/**
* Remove the given params from the query object after executing an http query and before generating a cache key
* @param {array of strings} pruneParams
*/
Request.prototype.pruneParams = function(pruneParams){
props.pruneParams = pruneParams;
return this;
}
/**
* Remove the given params from the query object after executing an http query and before generating a cache key
* @param {array of strings} pruneParams
*/
Request.prototype.pruneParams = function(pruneParams){
props.pruneParams = pruneParams;
return this;
}
/**
* Remove the given options from the headers object after executing an http query and before generating a cache key
* @param {boolean} pruneOptions
*/
Request.prototype.pruneOptions = function(pruneOptions){
props.pruneOptions = pruneOptions;
return this;
}
/**
* Remove the given options from the headers object after executing an http query and before generating a cache key
* @param {boolean} pruneOptions
*/
Request.prototype.pruneOptions = function(pruneOptions){
props.pruneOptions = pruneOptions;
return this;
}
/**
* Execute some logic on superagent's http response object before caching and returning it
* @param {function} prune
*/
Request.prototype.prune = function(prune){
props.prune = prune;
return this;
}
/**
* Execute some logic on superagent's http response object before caching and returning it
* @param {function} prune
*/
Request.prototype.prune = function(prune){
props.prune = prune;
return this;
}
/**
* Retrieve a top-level property from superagent's http response object before to cache and return
* @param {string} responseProp
*/
Request.prototype.responseProp = function(responseProp){
props.responseProp = responseProp;
return this;
}
/**
* Retrieve a top-level property from superagent's http response object before to cache and return
* @param {string} responseProp
*/
Request.prototype.responseProp = function(responseProp){
props.responseProp = responseProp;
return this;
}
/**
* Set an expiration for this key that will override the configured cache's default expiration
* @param {integer} expiration (seconds)
*/
Request.prototype.expiration = function(expiration){
props.expiration = expiration;
return this;
}
/**
* Set an expiration for this key that will override the configured cache's default expiration
* @param {integer} expiration (seconds)
*/
Request.prototype.expiration = function(expiration){
props.expiration = expiration;
return this;
}
/**
* Whether to cache superagent's http response object when it "empty"--especially useful with .prune and .pruneParams
* @param {string} responseProp
*/
Request.prototype.cacheWhenEmpty = function(cacheWhenEmpty){
props.cacheWhenEmpty = cacheWhenEmpty;
return this;
}
/**
* Whether to cache superagent's http response object when it "empty"--especially useful with .prune and .pruneParams
* @param {string} responseProp
*/
Request.prototype.cacheWhenEmpty = function(cacheWhenEmpty){
props.cacheWhenEmpty = cacheWhenEmpty;
return this;
}
/**
* Initialize a background refresh for the generated key and value
* @param {boolean | function} backgroundRefresh
*/
Request.prototype.backgroundRefresh = function(backgroundRefresh){
props.backgroundRefresh = (typeof backgroundRefresh !== 'undefined') ? backgroundRefresh : true;
return this;
}
/**
* Initialize a background refresh for the generated key and value
* @param {boolean | function} backgroundRefresh
*/
Request.prototype.backgroundRefresh = function(backgroundRefresh){
props.backgroundRefresh = (typeof backgroundRefresh !== 'undefined') ? backgroundRefresh : true;
return this;
}
/**
* An alias for the .end function because I use ._end and .end for other things
*/
Request.prototype.execute = Request.prototype.end;
/**
* An alias for the .end function because I use ._end and .end for other things
*/
Request.prototype.execute = Request.prototype.end;
/**
* Wraps the .end function so that .resetProps gets called--callable so that no caching logic takes place
*/
Request.prototype._end = function(cb){
resetProps();
this.execute(cb);
}
/**
* Wraps the .end function so that .resetProps gets called--callable so that no caching logic takes place
*/
Request.prototype._end = function(cb){
resetProps();
this.execute(cb);
}
/**
* Execute all caching and http logic
* @param {function} cb
*/
Request.prototype.end = function(cb){
var curProps = props;
resetProps();
if(~supportedMethods.indexOf(this.method)){
var _this = this;
var key = keygen(this, curProps);
if(~cacheableMethods.indexOf(this.method)){
superagent.cache.get(key, function (err, response){
if(!err && response){
callbackExecutor(cb, err, response, key);
}
else{
if(curProps.doQuery){
_this._end(function (err, response){
if(err) {
return callbackExecutor(cb, err, response, key);
}
else if(!err && response){
if(curProps.prune){
response = curProps.prune(response);
/**
* Execute all caching and http logic
* @param {function} cb
*/
Request.prototype.end = function(cb){
var curProps = props;
resetProps();
if(~supportedMethods.indexOf(this.method)){
var _this = this;
var key = keygen(this, curProps);
if(~cacheableMethods.indexOf(this.method)){
superagent.cache.get(key, function (err, response){
if(!err && response){
callbackExecutor(cb, err, response, key);
}
else{
if(curProps.doQuery){
_this._end(function (err, response){
if(err) {
return callbackExecutor(cb, err, response, key);
}
else if(curProps.responseProp){
response = response[curProps.responseProp] || null;
}
else{
response = gutResponse(response);
}
if(!isEmpty(response) || curProps.cacheWhenEmpty){
var refresh = curProps.backgroundRefresh || null;
if(typeof refresh == 'boolean'){
refresh = getBackgroundRefreshFunction(curProps);
else if(!err && response){
if(curProps.prune){
response = curProps.prune(response);
}
superagent.cache.set(key, response, curProps.expiration, refresh, function (){
else if(curProps.responseProp){
response = response[curProps.responseProp] || null;
}
else{
response = gutResponse(response);
}
if(!isEmpty(response) || curProps.cacheWhenEmpty){
var refresh = curProps.backgroundRefresh || null;
if(typeof refresh == 'boolean'){
refresh = getBackgroundRefreshFunction(curProps);
}
superagent.cache.set(key, response, curProps.expiration, refresh, function (){
callbackExecutor(cb, err, response, key);
});
}
else{
callbackExecutor(cb, err, response, key);
});
}
}
else{
callbackExecutor(cb, err, response, key);
}
}
});
}
else{
callbackExecutor(cb, null, null, key);
}
}
});
}
else{
this._end(function (err, response){
if (err) {
return callbackExecutor(cb, err, response, key);
}
if(!err && response){
superagent.cache.del(key, function (){
callbackExecutor(cb, err, response, key);
});
}
else{
callbackExecutor(cb, null, null, key);
}
}
});
});
}
}
else{
this._end(function (err, response){
if (err) {
return callbackExecutor(cb, err, response, key);
}
if(!err && response){
superagent.cache.del(key, function (){
callbackExecutor(cb, err, response, key);
});
}
callbackExecutor(cb, err, response, undefined);
});
}
}
else{
this._end(function (err, response){
callbackExecutor(cb, err, response, undefined);
/**
* Set this.req to null so that future http calls get a branc new req object
*/
Request.prototype.reset = function(){
this.req = null;
}
/**
* Generate a cache key unique to this query
* @param {object} reg
* @param {object} cProps
*/
function keygen(req, cProps){
var cleanParams = null;
var cleanOptions = null;
var params = !isEmpty(req.qs) ? req.qs : arrayToObj(req.qsRaw);
if(!params && req.req){
params = stringToObj(req.req.path);
}
var options = (req.req && req.req._headers) ? req.req._headers : null;
if(cProps.pruneParams || cProps.pruneOptions){
cleanParams = (cProps.pruneParams) ? pruneObj(cloneObject(params), cProps.pruneParams) : params;
cleanOptions = (cProps.pruneOptions) ? pruneObj(cloneObject(options), cProps.pruneOptions, true) : options;
}
return JSON.stringify({
nameSpace: superagent.cache.nameSpace,
method: req.method,
uri: req.url,
params: cleanParams || params || null,
options: cleanOptions || options || null
});
}
}
/**
* Set this.req to null so that future http calls get a branc new req object
*/
Request.prototype.reset = function(){
this.req = null;
}
/**
* Generate a cache key unique to this query
* @param {object} reg
* @param {object} cProps
*/
function keygen(req, cProps){
var cleanParams = null;
var cleanOptions = null;
var params = !isEmpty(req.qs) ? req.qs : arrayToObj(req.qsRaw);
if(!params && req.req){
params = stringToObj(req.req.path);
/**
* Convert an array to an object
* @param {array} arr
*/
function arrayToObj(arr){
if(arr && arr.length){
var obj = {};
for(var i = 0; i < arr.length; i++){
var str = arr[i];
var kvArray = str.split('&');
for(var j = 0; j < kvArray.length; j++){
var kvString = kvArray[j].split('=');
obj[kvString[0]] = kvString[1];
}
}
return obj;
}
return null;
}
var options = (req.req && req.req._headers) ? req.req._headers : null;
if(cProps.pruneParams || cProps.pruneOptions){
cleanParams = (cProps.pruneParams) ? pruneObj(cloneObject(params), cProps.pruneParams) : params;
cleanOptions = (cProps.pruneOptions) ? pruneObj(cloneObject(options), cProps.pruneOptions, true) : options;
}
return JSON.stringify({
nameSpace: superagent.cache.nameSpace,
method: req.method,
uri: req.url,
params: cleanParams || params || null,
options: cleanOptions || options || null
});
}
/**
* Convert an array to an object
* @param {array} arr
*/
function arrayToObj(arr){
if(arr && arr.length){
var obj = {};
for(var i = 0; i < arr.length; i++){
var str = arr[i];
/**
* Convert a string to an object
* @param {string} str
*/
function stringToObj(str){
if(str){
var obj = {};
if(~str.indexOf('?')){
var strs = str.split('?');
str = strs[1];
}
var kvArray = str.split('&');
for(var j = 0; j < kvArray.length; j++){
var kvString = kvArray[j].split('=');
for(var i = 0; i < kvArray.length; i++){
var kvString = kvArray[i].split('=');
obj[kvString[0]] = kvString[1];
}
return obj;
}
return obj;
return null;
}
return null;
}
/**
* Convert a string to an object
* @param {string} str
*/
function stringToObj(str){
if(str){
var obj = {};
if(~str.indexOf('?')){
var strs = str.split('?');
str = strs[1];
/**
* Remove properties from an object
* @param {object} obj
* @param {array} props
* @param {boolean} isOptions
*/
function pruneObj(obj, props, isOptions){
for(var i = 0; i < props.length; i++){
var prop = props[i];
if(isOptions){
prop = prop.toLowerCase();
}
delete obj[prop]
}
var kvArray = str.split('&');
for(var i = 0; i < kvArray.length; i++){
var kvString = kvArray[i].split('=');
obj[kvString[0]] = kvString[1];
}
return obj;
}
return null;
}
/**
* Remove properties from an object
* @param {object} obj
* @param {array} props
* @param {boolean} isOptions
*/
function pruneObj(obj, props, isOptions){
for(var i = 0; i < props.length; i++){
var prop = props[i];
if(isOptions){
prop = prop.toLowerCase();
}
delete obj[prop]
/**
* Simplify superagent's http response object
* @param {object} r
*/
function gutResponse(r){
var newResponse = {};
newResponse.body = r.body;
newResponse.text = r.text;
newResponse.headers = r.headers;
newResponse.statusCode = r.statusCode;
newResponse.status = r.status;
newResponse.ok = r.ok;
return newResponse;
}
return obj;
}
/**
* Simplify superagent's http response object
* @param {object} r
*/
function gutResponse(r){
var newResponse = {};
newResponse.body = r.body;
newResponse.text = r.text;
newResponse.headers = r.headers;
newResponse.statusCode = r.statusCode;
newResponse.status = r.status;
newResponse.ok = r.ok;
return newResponse;
}
/**
* Determine whether a value is considered empty
* @param {*} val
*/
function isEmpty(val){
return (val === false || val === null || (typeof val == 'object' && Object.keys(val).length == 0));
}
/**
* Determine whether a value is considered empty
* @param {*} val
*/
function isEmpty(val){
return (val === false || val === null || (typeof val == 'object' && Object.keys(val).length == 0));
}
/**
* Return a cloneof an object
* @param {object} obj
*/
function cloneObject(obj){
var newObj = {};
for(var attr in obj) {
if (obj.hasOwnProperty(attr)){
newObj[attr] = obj[attr];
/**
* Return a cloneof an object
* @param {object} obj
*/
function cloneObject(obj){
var newObj = {};
for(var attr in obj) {
if (obj.hasOwnProperty(attr)){
newObj[attr] = obj[attr];
}
}
return newObj;
}
return newObj;
}
/**
* Reset superagent-cache's default query properties
*/
function resetProps(){
props = {doQuery: true, cacheWhenEmpty: true};
}
/**
* Reset superagent-cache's default query properties
*/
function resetProps(){
props = {doQuery: true, cacheWhenEmpty: true};
}
/**
* Generate a background refresh query identical to the current query
* @param {object} curProps
*/
function getBackgroundRefreshFunction(curProps){
return function(key, cb){
key = JSON.parse(key);
var method = key.method.toLowerCase();
var request = superagent
[method](key.uri)
.doQuery(curProps.doQuery)
.pruneParams(curProps.pruneParams)
.pruneOptions(curProps.pruneOptions)
.prune(curProps.prune)
.responseProp(curProps.responseProp)
.expiration(curProps.expiration)
.cacheWhenEmpty(curProps.cacheWhenEmpty);
if(key.params){
request.query(key.params)
/**
* Generate a background refresh query identical to the current query
* @param {object} curProps
*/
function getBackgroundRefreshFunction(curProps){
return function(key, cb){
key = JSON.parse(key);
var method = key.method.toLowerCase();
var request = superagent
[method](key.uri)
.doQuery(curProps.doQuery)
.pruneParams(curProps.pruneParams)
.pruneOptions(curProps.pruneOptions)
.prune(curProps.prune)
.responseProp(curProps.responseProp)
.expiration(curProps.expiration)
.cacheWhenEmpty(curProps.cacheWhenEmpty);
if(key.params){
request.query(key.params)
}
if(key.options){
request.set(key.options);
}
request.end(cb);
}
if(key.options){
request.set(key.options);
}
/**
* Handle the varying number of callback output params
* @param {function} cb
* @param {object} err
* @param {object} response
* @param {string} key
*/
function callbackExecutor(cb, err, response, key){
if(cb.length === 1){
cb(response);
}
request.end(cb);
else if(cb.length === 2){
cb(err, response);
}
else if(cb.length === 3){
cb(err, response, key);
}
else{
throw new exception('UnsupportedCallbackException', 'You must have 1, 2, or 3 callback params in your .end() callback argument list.');
}
}
}
/**
* Handle the varying number of callback output params
* @param {function} cb
* @param {object} err
* @param {object} response
* @param {string} key
*/
function callbackExecutor(cb, err, response, key){
if(cb.length === 1){
cb(response);
/**
* Instantates an exception to be thrown
* @param {string} name
* @param {string} message
* @return {exception}
*/
function exception(name, message){
this.name = name;
this.message = message;
}
else if(cb.length === 2){
cb(err, response);
}
else if(cb.length === 3){
cb(err, response, key);
}
else{
throw new exception('UnsupportedCallbackException', 'You must have 1, 2, or 3 callback params in your .end() callback argument list.');
}
}
/**
* Instantates an exception to be thrown
* @param {string} name
* @param {string} message
* @return {exception}
*/
function exception(name, message){
this.name = name;
this.message = message;
}
if(!agent){

@@ -378,0 +381,0 @@ return superagent;

@@ -7,2 +7,3 @@ var expect = require('expect');

require('../../superagentCache')(superagent, cacheModule);
require('../../superagentCache')(superagent, cacheModule);

@@ -9,0 +10,0 @@ var app = express();

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