UNPKG

serverless-cf-vars

Version:

Allows you to use Cloudformation pseudo parameters and substitute in other variables in your serverless.yml.

92 lines (85 loc) 2.51 kB
/*eslint no-template-curly-in-string: "off"*/ /*eslint no-cond-assign: "off"*/ var _ = require('lodash') var keyStem = 'serverlesscfvarsplugin' var searchRe = new RegExp(keyStem + '(\\d+)') /** * Some plugins try to clean up ${}-tags * This step finds our #{} and replace them with alpha numeric text. * This should allow our tags to slip past "helpful" cleanup attempts. */ function step0(dictionary, insideSub, ivars = {}) { const vars = Object.assign({}, ivars) const resources = _.transform(dictionary, function(acc, val, key) { insideSub = insideSub || key === 'Fn::Sub' if (_.isPlainObject(val) || _.isArray(val)) { const result = step0(val, insideSub, vars) Object.assign(vars, result.vars) acc[key] = result.resources return } if (typeof val === 'string') { var matches, cfkey while (matches = val.match(/#{([^}]+)}/)) { cfkey = keyStem + Object.keys(vars).length vars[cfkey] = matches[1] val = val.replace(/#{[^}]+}/, cfkey) } if (cfkey) { acc[key] = insideSub ? val : { 'Fn::Sub': val } return } } acc[key] = val }) return {resources, vars} } /** * Let's convert the strings that step0 produced into ${} */ function step1(dictionary, vars) { const resources = _.transform(dictionary, function(acc, val, key) { if (_.isPlainObject(val) || _.isArray(val)) { acc[key] = step1(val, vars) return } if (typeof val === 'string') { var matches, cfkey, cfvalue while (matches = val.match(searchRe)) { cfkey = keyStem + matches[1] cfvalue = vars[cfkey] val = val.replace(cfkey, '${'+cfvalue+'}') } if (cfkey) { acc[key] = val return } } acc[key] = val }) return resources } /** * Custom resources aren't available until now, so they haven't been replaced in step0. * Let's replace any #{} that exist at this point. */ function step2(dictionary, insideSub) { return _.transform(dictionary, function(acc, val, key) { insideSub = insideSub || key === 'Fn::Sub' if (_.isPlainObject(val) || _.isArray(val)) { acc[key] = step2(val, insideSub) return } if (typeof val === 'string' && val.search(/#{([^}]+)}/) !== -1) { const newValue = val.replace(/#{([^}]+)}/g, '${$1}') acc[key] = insideSub ? newValue : { 'Fn::Sub': newValue } return } acc[key] = val }) } module.exports = { step0, step1, step2 }