@nuskin/configuration-sdk
Advanced tools
Comparing version 1.0.2 to 1.0.3-cx16-7895.1
{ | ||
"name": "@nuskin/configuration-sdk", | ||
"version": "1.0.2", | ||
"version": "1.0.3-cx16-7895.1", | ||
"description": "The configuration sdk gets market configuration from content stack. You can get the full configuration for a list of config maps or get partial configuration using graphql. The sdk caches the configurations for 2 minutes in memory. The sdk also allows for configuraitons to be overridden. Override configurations for runtime shopping context configurations. Or use the function for testing purposes to override configuration in the browser on the fly.", | ||
@@ -24,2 +24,3 @@ "main": "src/index.js", | ||
"devDependencies": { | ||
"@nuskin/ns-util": "3.107.1-cx16-7895.7", | ||
"@nuskin/docdash": "1.0.1", | ||
@@ -47,3 +48,6 @@ "axios-mock-adapter": "^1.21.2", | ||
"lodash": "^4.17.21" | ||
}, | ||
"peerDependencies": { | ||
"@nuskin/ns-util": "3.107.1-cx16-7895.7" | ||
} | ||
} |
@@ -51,9 +51,35 @@ # @nuskin/configuration-sdk | ||
// get full configuration for config maps | ||
// Get full configuration for config maps. | ||
// Each config will be stored in a cache which is where it will be retrieved in subsequent calls. | ||
const config = await getConfiguration({ | ||
configMapNames: ['Ordering', 'Cart'], | ||
country: 'US', | ||
environment: 'test', | ||
clientId: 'Your application client id' | ||
country: 'US' // optional - if not specified the country from the environment (runConfig) will be used | ||
// The environment and clientId are also retrieved from the runConfig and used in the call. | ||
}); | ||
// The following functions are designed to be used after configuration is originally | ||
// loaded git getConfiguration above. They only look for configuration that is in | ||
// local cache and these functions are synchronous and can be used in place of the | ||
// current ConfigService.getMarketConfig call. | ||
// This will return one or more configMaps from cache. | ||
// Will throw an exception if requested config has not already been loaded by getConfiguration. | ||
const configs = getCachedConfigurations( | ||
configNames = [], // List of configNames to be retrieved from local cache | ||
country = null // optional | ||
) | ||
// This function returns a single configMap from cache. | ||
// Will throw an exception if requested config has not already been loaded by getConfiguration. | ||
const config = getCachedConfiguration( | ||
configNames = [], // List of configNames to be retrieved from local cache | ||
country = null // optional | ||
) | ||
// This will return a single field from one of the configMaps previously loaded into | ||
// cache. All cached configMaps are searched so no cacheName is needed. Field names | ||
// are required to be unique across configMaps by contentStack | ||
const configFieldValue = getCachedConfigField( | ||
configField, | ||
country = null) | ||
``` | ||
@@ -60,0 +86,0 @@ |
145
src/index.js
'use strict' | ||
const { RunConfigService, ShoppingContext } = require('@nuskin/ns-util'); | ||
const assert = require('assert'); | ||
@@ -31,3 +32,3 @@ const axios = require('axios'); | ||
let configurationOverrides = {noCntxt: {}}; | ||
const configCache = {}; // cache for full config map requests | ||
let configCache = {}; // cache for full config map requests | ||
@@ -83,2 +84,19 @@ // If this module is used in a browser there is no need to call init | ||
/** | ||
* Gets the option values for querying contentStack | ||
* @param {string} country | ||
* @returns {object} | ||
*/ | ||
const getOptions = (country) => { | ||
const runConfig = RunConfigService.getRunConfig(); | ||
country = country || runConfig.country; | ||
configCache[country] = configCache[country] || {}; | ||
const environment = RunConfigService.getEnvironmentCode(); | ||
const clientId = runConfig.clientId; | ||
const context = ShoppingContext.getShoppingContext(); | ||
const shoppingContext = context && context.context ? context.context : undefined; | ||
return {country, environment, clientId, shoppingContext}; | ||
} | ||
/** | ||
* Function that allows for overriding of configuration properties | ||
@@ -90,5 +108,5 @@ * @param {Object} options | ||
* @param {string} options.value | ||
* @param {string} options.shoppingContext | ||
*/ | ||
const overrideConfigurationProperty = ({configMap, configMapProperty, country, value, shoppingContext = DEFAULT_CONTEXT}) => { | ||
const overrideConfigurationProperty = ({configMap, configMapProperty, country: _country, value}) => { | ||
const {country, shoppingContext} = getOptions(_country); | ||
const shopCntxt = { | ||
@@ -108,6 +126,6 @@ [country]: { | ||
* @param {Object} config | ||
* @param country | ||
* @param shoppingContext | ||
* @param _country | ||
*/ | ||
const overrideConfiguration = ({config, country, shoppingContext = DEFAULT_CONTEXT}) => { | ||
const overrideConfiguration = (config, _country) => { | ||
const {country, shoppingContext} = getOptions(_country); | ||
const shopCntxt = {}; | ||
@@ -121,5 +139,5 @@ shopCntxt[country] = config; | ||
* Clears configuration overrides | ||
* @param {string=} shoppingContext | ||
*/ | ||
const clearConfigurationOverrides = (shoppingContext = DEFAULT_CONTEXT) => { | ||
const clearConfigurationOverrides = () => { | ||
const {shoppingContext} = getOptions(); | ||
configurationOverrides[shoppingContext] = {}; | ||
@@ -131,15 +149,12 @@ storage.setItem(STORAGE_KEY, JSON.stringify(configurationOverrides)); | ||
* Gets configuration from content stack with graphql query through the contentstack configuration lambda | ||
* @param {Object} options | ||
* @param {Object} options.queryFields | ||
* @param {string} options.country | ||
* @param {string} options.environment | ||
* @param {string} options.clientId | ||
* @param {string=} options.shoppingContext | ||
* @param {Object} queryFields | ||
* @param {string} _country | ||
* @return {Promise<any>} configuration | ||
*/ | ||
const getPartialConfig = async ({queryFields, country, environment, clientId, shoppingContext = DEFAULT_CONTEXT}) => { | ||
const getPartialConfig = async (queryFields, _country) => { | ||
assert(queryFields, 'configMapNames is required'); | ||
assert(country, 'country is required'); | ||
assert(environment, 'environment is required'); | ||
assert(clientId, 'clientId is required'); | ||
// assert(country, 'country is required'); | ||
// assert(environment, 'environment is required'); | ||
// assert(clientId, 'clientId is required'); | ||
const {country, environment, clientId, shoppingContext} = getOptions(_country); | ||
@@ -173,30 +188,34 @@ _syncConfigurationOverrides(); | ||
* Gets the full configuration for given configMaps | ||
* @param {Object} options | ||
* @param {string[]} options.configMapNames - Ex: [Ordering] | ||
* @param {string} options.country - Ex: US | ||
* @param {string} options.environment - Ex: dev | ||
* @param {string} options.clientId | ||
* @param {string=} options.shoppingContext - Ex: personal_offer | ||
* @param {string[]} configMapNames - Ex: [Ordering] | ||
* @param {string} _country - Ex: US | ||
* @return {Promise<any>} Configuration | ||
*/ | ||
const getConfiguration = async ({configMapNames, country, environment, clientId, shoppingContext = DEFAULT_CONTEXT}) => { | ||
const getConfiguration = async (configMapNames, _country) => { | ||
assert(configMapNames, 'configMapNames is required'); | ||
assert(country, 'country is required'); | ||
assert(environment, 'environment is required'); | ||
assert(clientId, 'clientId is required'); | ||
// assert(country, 'country is required'); | ||
// assert(environment, 'environment is required'); | ||
// assert(clientId, 'clientId is required'); | ||
const {country, environment, clientId, shoppingContext} = getOptions(_country); | ||
_syncConfigurationOverrides(); | ||
const promises = configMapNames.map((configMap) => { | ||
const url = `${baseUrl[environment]}/contentstack-configuration/v1/${configMap}/${country}`; | ||
const fullUrl = shoppingContext === DEFAULT_CONTEXT ? url : `${url}/${shoppingContext}`; | ||
return api({ | ||
url: fullUrl, | ||
method: 'get', | ||
headers: { | ||
"client_id": clientId | ||
} | ||
}); | ||
const promises = []; | ||
const cachedConfigs = []; | ||
configMapNames.map((configMapName) => { | ||
try { | ||
cachedConfigs.push({[configMapName]: getCachedConfiguration(configMapName)}); | ||
} catch (err) { | ||
const url = `${baseUrl[environment]}/contentstack-configuration/v1/${configMapName}/${country}`; | ||
const fullUrl = shoppingContext ? `${url}/${shoppingContext}` : url; | ||
promises.push(api({ | ||
url: fullUrl, | ||
method: 'get', | ||
headers: { | ||
"client_id": clientId | ||
} | ||
})); | ||
} | ||
}); | ||
const results = await Promise.all(promises); | ||
const configs = results.map((result) => result.data); | ||
const configs = cachedConfigs.concat(results.map((result) => result.data)); | ||
// Apply overrides | ||
@@ -209,3 +228,3 @@ const retVal = _.merge( | ||
Object.keys(retVal).forEach((key) => { | ||
configCache[key] = retVal[key]; | ||
configCache[country][key] = retVal[key]; | ||
}); | ||
@@ -216,6 +235,7 @@ | ||
const checkConfigCache = (configNames = []) => { | ||
const checkConfigCache = (configNames = [], country) => { | ||
configNames.forEach((configName) => { | ||
if (!configCache[configName]) { | ||
console.error(`${configName} is not loaded in configuration cache!`); | ||
if (!configCache[country][configName]) { | ||
throw new Error(`${configName} configCache has not been loaded yet! | ||
This needs to be done prior to getting it from cache.`); | ||
} | ||
@@ -230,11 +250,12 @@ }); | ||
*/ | ||
const getCachedConfigurations = (configNames = []) => { | ||
const getCachedConfigurations = (configNames = [], country = null) => { | ||
const retVal = {}; | ||
if (!Array.isArray(configNames)) { | ||
console.error('configNames must be an array!'); | ||
return retVal; | ||
country = country || RunConfigService.getRunConfig().country; | ||
if (!Array.isArray(configNames) || configNames.some((name) => typeof name != 'string')) { | ||
throw new Error('getCachedConfigurations requires an array of strings'); | ||
} | ||
checkConfigCache(configNames); | ||
checkConfigCache(configNames, country); | ||
configNames.forEach((configName) => { | ||
retVal[configName] = configCache[configName] | ||
retVal[configName] = configCache[country][configName] | ||
}); | ||
@@ -248,11 +269,11 @@ | ||
* | ||
* @param {string[]} configNames | ||
* @param {string} configName | ||
*/ | ||
const getCachedConfiguration = (configName) => { | ||
const getCachedConfiguration = (configName, country = null) => { | ||
if (typeof configName != 'string') { | ||
console.error('configName must be a string!'); | ||
return {}; | ||
throw new Error('getCachedConfiguration requires a string'); | ||
} | ||
checkConfigCache([configName]); | ||
return configCache[configName]; | ||
country = country || RunConfigService.getRunConfig().country; | ||
checkConfigCache([configName], country); | ||
return configCache[country][configName]; | ||
}; | ||
@@ -266,7 +287,14 @@ | ||
*/ | ||
const getCachedConfigField = (configField) => { | ||
const result = Object.values(configCache).find((config) => config[configField]); | ||
return result && result[configField]; | ||
const getCachedConfigField = (configField, country = null) => { | ||
country = country || RunConfigService.getRunConfig().country; | ||
const result = Object.values(configCache[country]).find((config) => config[configField]); | ||
const value = result && result[configField]; | ||
return value; | ||
}; | ||
const clearConfigCache = () => { | ||
configCache = {}; | ||
}; | ||
module.exports = { | ||
@@ -281,3 +309,4 @@ getConfiguration, | ||
clearConfigurationOverrides, | ||
clearConfigCache, | ||
init | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15459
267
91
5
14
1