@gis-ag/oniyi-http-plugin-cache-redis
Version:
Plugin responsible for caching responses into redis db
101 lines (84 loc) • 3.2 kB
JavaScript
;
// node core modules
// 3rd party modules
const debug = require('debug')('oniyi-http-plugin:cache:phase-lists:utils');
const _ = require('lodash');
// internal modules
const constants = {
PHASE_NAME: 'cache',
HOOK_STATE: 'hookState',
REQUEST_OPTIONS: 'options',
};
// it covers next use-cases:
// 1. https://host-name.com/other -> host-name.com
// 2. http://host-name.com/other -> host-name.com
// 3. https://www.host-name.com/other -> host-name.com
// 4. www.host-name.com/other -> host-name.com
// 5. https://user:pass@host-name.com/other -> host-name.com
const hostRegex = /^(?:https?:\/\/)?(?:[^@/]+@)?(?:www\.)?([^:/]+)/i;
const tryJsonParse = (options, raw) => {
if (!options.json) {
return raw;
}
try {
return JSON.parse(raw);
} catch (e) {
debug('JSON parsing error -> %o \nResponding with stringified raw data from the cache -> %o', e, raw);
return raw;
}
};
/**
* It omits the default request/response validators if required
*
* @param {Object} evaluator Evaluator object that needs to be updated, provided by oniyi-cache module
* @param {Object} validatorsToOmit Object that holds list of request/response validator names
* that should be omitted
*
* e.x.
* const validatorsToSkip = {
* requestValidators: ['disableCache', 'maxAgeZero'],
* responseValidators: ['maxAgeZero'].
* }
*/
const skipValidators = (evaluator, validatorsToOmit) =>
_.reduce(
validatorsToOmit,
(finalEvaluator, validatorIgnoreList, validatorName) =>
Object.assign(finalEvaluator, {
[validatorName]: evaluator[validatorName].filter(validator => !validatorIgnoreList.includes(validator.name)),
}),
evaluator
);
const getHostByUrl = url => (_.isString(url) ? hostRegex.exec(url)[1] : null);
const buildHashedIds = (cache, options) => {
const { user } = options;
const hashedId = cache.makeHash(options);
// if user is valid, build privateHashedId as well
if (user && (user.id || _.isFunction(user.getId))) {
const optionsWithUser = Object.assign({ authenticatedUser: user.getId() || user.id }, options);
const privateHashedId = cache.makeHash(optionsWithUser);
return { hashedId, privateHashedId };
}
return { hashedId };
};
const buildIdsAndEvaluator = (cache, pluginOptions, options) => {
const { plugins: { cache: { hostConfig, validatorsToSkip } = {} } = {}, baseUrl } = options;
const { hashedId, privateHashedId } = buildHashedIds(cache, options);
const host = getHostByUrl(baseUrl);
// init evaluator by merging host configuration from initial plugin setup
// with configuration provided by single http request options
const initEvaluator = cache.getEvaluator(host, _.merge({}, pluginOptions.hostConfig, hostConfig));
// build evaluator by skipping validators provided by initial plugin setup
// and validators provided by single http request options
const evaluator = skipValidators(initEvaluator, _.merge({}, pluginOptions.validatorsToSkip, validatorsToSkip));
return {
hashedId,
privateHashedId,
evaluator,
};
};
module.exports = {
constants,
tryJsonParse,
buildIdsAndEvaluator,
};