From 815f41ccb611a578d3249b26301726b0220b5340 Mon Sep 17 00:00:00 2001 From: "Eslam A. Hefnawy" Date: Tue, 29 Dec 2015 15:24:55 +0200 Subject: [PATCH] added populate util function --- lib/ServerlessFunction.js | 4 +- lib/ServerlessModule.js | 7 +++- lib/ServerlessProject.js | 7 +++- lib/utils/index.js | 79 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index 994f0ae74..406527645 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -88,7 +88,9 @@ class ServerlessFunction { populate(stage, region) { this._populated = true; - // TODO: Implement via SUtils class which can be used in Project, Module & Function Classes + + // just to be sure, this.data is the function JSON right?! + this.data = SUtils.populate(this.data, this.S._projectRootPath, stage, region); } } diff --git a/lib/ServerlessModule.js b/lib/ServerlessModule.js index c9f0d8f8b..91bcb4efa 100644 --- a/lib/ServerlessModule.js +++ b/lib/ServerlessModule.js @@ -122,7 +122,12 @@ class ServerlessModule { populate(stage, region) { this._populated = true; - // TODO: Implement via SUtils class which can be used in Project, Module & Function Classes + + // this.data includes the already populated functions. + // So now we're gonna loop through them all again?! + // We should probably only pass in a module object without the functions. + // Eitherway, the populate util func. is ready to accept any obj, but it's a matter of efficiency. + this.data = SUtils.populate(this.data, this.S._projectRootPath, stage, region); } } diff --git a/lib/ServerlessProject.js b/lib/ServerlessProject.js index d7078773f..20a49c2db 100644 --- a/lib/ServerlessProject.js +++ b/lib/ServerlessProject.js @@ -164,7 +164,12 @@ class ServerlessProject { populate(stage, region) { this._populated = true; - // TODO: Implement via SUtils class which can be used in Project, Module & Function Classes + + // Am assuming this.data includes the already populated functions AND modules. + // So now we're gonna loop through them all again?! + // We should probably only pass in a project object without the functions and modules. + // Eitherway, the populate util func. is ready to accept any obj, but it's a matter of efficiency. + this.data = SUtils.populate(this.data, this.S._projectRootPath, stage, region); } } diff --git a/lib/utils/index.js b/lib/utils/index.js index 1082eb852..0e195b83d 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -801,6 +801,85 @@ exports.saveRegionalApi = function(projectJawsJson, regionName, restApiId, rootP fs.writeFileSync(path.join(rootPath, 's-project.json'), JSON.stringify(projectJawsJson, null, 2)); }; +exports.populate = function(obj, projectRootPath, stage, region) { + let _this = this, + meta = this.getMeta(projectRootPath); + + if (!stage) region = null; + + if (typeof stage != 'undefined' && !meta.private.stages[stage]) { + throw Error('Stage doesnt exist!'); + } + + if (typeof region != 'undefined' && !meta.private.stages[stage].regions[region]) { + throw Error('Region doesnt exist in the provided stage!'); + } + + // populate templates + traverse(obj).forEach(function(val) { + + // check if the current string is a template $${...} + if (typeof(val) === 'string' && val.match(/\$\${([^{}]*)}/g) != null) { + + let template = val.replace('$${', '').replace('}', ''); + let templateModule = template.slice(0, template.indexOf(".")); // assumes template path is valid format + let templateName = template.slice(template.indexOf(".") + 1, template.length - 1); // assumes template path is valid format + + let templateObj = _this.readAndParseJsonSync(path.join( + projectRootPath, + 'back', + 'modules', + templateModule, + 'templates', + 's-templates.json'))[templateName]; + + this.update(templateObj); + + } + }); + + // populate variables + traverse(obj).forEach(function(val) { + + // check if the current string is a variable ${...} + if (typeof(val) === 'string' && val.match(/\${([^{}]*)}/g) != null) { + + let newVal = val; + + // get all ${variable} in the string + val.match(/\${([^{}]*)}/g).forEach(function(variableSyntax) { + let variableName = variableSyntax.replace('${', '').replace('}', ''); + + let value; + if (stage && region) { + value = meta['private'].stages[stage].regions[region].variables[variableName]; + + } else if (stage) { + value = meta['private'].stages[stage].variables[variableName]; + + } else if (!stage && !region) { + value = meta['private'].variables[variableName]; + + } + + if (typeof value === 'undefined') { + throw Error('Variable Doesnt exist!'); + } else if (typeof value === 'string') { + newVal = newVal.replace(variableSyntax, value); + } else { + newVal = value; + } + }); + + this.update(newVal); + + } + }); + + return obj; +}; + + function pathToContext(path) { // Match files under lib, tests, or bin so we only report the // relevant part of the file name as the context