diff --git a/packages/strapi-utils/lib/models.js b/packages/strapi-utils/lib/models.js index 0cfebd0248..f690a032b1 100644 --- a/packages/strapi-utils/lib/models.js +++ b/packages/strapi-utils/lib/models.js @@ -12,7 +12,7 @@ const _ = require('lodash'); // Following this discussion https://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric this function is the best implem to determine if a value is a valid number candidate const isNumeric = (value) => { - return !isNaN(parseFloat(value)) && isFinite(value); + return !_.isObject(value) && !isNaN(parseFloat(value)) && isFinite(value); }; /* eslint-disable prefer-template */ @@ -466,7 +466,7 @@ module.exports = { // Remove the filter keyword at the end let splitKey = key.split('_').slice(0,-1); splitKey = splitKey.join('_'); - + if (modelAttributes[splitKey]) { fieldType = modelAttributes[splitKey]['type']; } diff --git a/packages/strapi/lib/core/configurations.js b/packages/strapi/lib/core/configurations.js index 0e046de1bc..98bb8a5ef1 100755 --- a/packages/strapi/lib/core/configurations.js +++ b/packages/strapi/lib/core/configurations.js @@ -382,6 +382,31 @@ const enableHookNestedDependencies = function (name, flattenHooksConfig, force = } }; +/** + * Allow dynamic config values through + * the native ES6 template string function. + */ +const regex = /\$\{[^()]*\}/g; +const excludeConfigPaths = ['info.scripts']; +const templateConfigurations = function (obj, configPath = '') { + // Allow values which looks like such as + // an ES6 literal string without parenthesis inside (aka function call). + // Exclude config with conflicting syntax (e.g. npm scripts). + return Object.keys(obj).reduce((acc, key) => { + if (isPlainObject(obj[key]) && !isString(obj[key])) { + acc[key] = templateConfigurations(obj[key], `${configPath}.${key}`); + } else if (isString(obj[key]) + && !excludeConfigPaths.includes(configPath.substr(1)) + && obj[key].match(regex) !== null) { + acc[key] = eval('`' + obj[key] + '`'); // eslint-disable-line prefer-template + } else { + acc[key] = obj[key]; + } + + return acc; + }, {}); +}; + const isAdminInDevMode = function () { try { fs.accessSync(path.resolve(this.config.appPath, 'admin', 'admin', 'build', 'index.html'), fs.constants.R_OK | fs.constants.W_OK);