@connected-home/serverless
Version:
The Serverless Application Framework - Powered By Amazon Web Services - http://www.serverless.com
299 lines (243 loc) • 7.9 kB
JavaScript
const SError = require('./Error'),
BbPromise = require('bluebird'),
path = require('path'),
_ = require('lodash'),
fs = require('fs'),
os = require('os');
module.exports = function(S) {
class Project extends S.classes.Serializer {
constructor(data) {
super();
this._class = 'Project';
// Default properties
this.name = null;
this.custom = {};
this.plugins = [];
this.functions = {};
this.stages = {};
this.resources = {
defaultResources: new S.classes.Resources({}, this.getRootPath('s-resources-cf.json'))
}; // This is an object because in the near future, we will introduce multiple resources stacks within a project
this.variables = new S.classes.Variables({}, this.getRootPath('_meta', 'variables', 's-variables-common.json'));
this.templates = new S.classes.Templates({}, this.getRootPath('s-templates.json'));
if (data) this.fromObject(data);
}
load() {
return this.deserialize(this);
}
save() {
return this.serialize(this);
}
toObject() {
return S.utils.exportObject(_.cloneDeep(this));
}
toObjectPopulated(options) {
options = options || {};
// Validate: Check project path is set
if (!S.hasProject()) throw new SError('Function could not be populated because no project path has been set on Serverless instance');
let obj = this.toObject();
// Populate Sub-Assets Separately
let functions, resources;
if (this.functions) {
functions = _.mapValues(this.functions, (f) => f.toObjectPopulated(options));
delete obj.functions;
}
if (this.resources) {
resources = _.mapValues(this.resources, (r) => r.toObjectPopulated(options));
delete obj.resources;
}
// Populate
let populated = S.utils.populate(this, this.getTemplates().toObject(), obj, options.stage, options.region);
if (functions) populated.functions = functions;
if (resources) populated.resources = resources;
return populated;
}
fromObject(data) {
let _this = this;
if (data.functions) {
let temp = {};
for (let f of Object.keys(data.functions)) {
if (this.functions[f]) {
temp[f] = this.functions[f].fromObject(data.functions[f]);
} else {
temp[f] = new S.classes.Function(_this, data.functions[f]);
}
}
delete data.functions;
this.functions = temp;
}
if (data.stages) {
let temp = {};
for (let s of Object.keys(data.stages)) {
if (this.stages[s]) {
temp[s] = this.stages[s].fromObject(data.stages[s]);
} else {
temp[s] = new S.classes.Stage(data.stages[s]);
}
}
delete data.stages;
this.stages = temp;
}
if (data.variables) {
this.variables.fromObject(data.variables);
delete data.variables;
}
if (data.templates) {
this.templates.fromObject(data.templates);
delete data.templates;
}
if (data.resources) {
let temp = {};
for (let r of Object.keys(data.resources)) {
if (this.resources[r]) {
temp[r] = this.resources[r].fromObject(data.resources[r]);
} else {
temp[r] = new S.classes.Resources(data.resources[r]);
}
}
delete data.resources;
this.resources = temp;
}
_.assign(_this, data);
return _this;
}
getFilePath() {
return path.join(S.config.projectPath, 's-project.json');
}
getRootPath() {
let args = _.toArray(arguments);
args.unshift(path.dirname(this.getFilePath()));
return path.join.apply(path, args);
}
getTempPath() {
return this.getRootPath('_meta', '_tmp');
}
getName() {
return this.name;
}
getAllFunctions() {
return _.values(this.functions);
}
getFunction(functionName) {
return _.find(_.values(this.functions), f => {
return f.getName() === functionName;
});
}
setFunction(func) {
this.functions[func.name] = func;
}
getAllEndpoints() {
return _.flatten(_.map(this.getAllFunctions(), f => f.getAllEndpoints()));
}
getEndpoint(endpointName) {
return _.find(_.values(this.getAllEndpoints()), e =>
e.getName() === endpointName
)
}
getEndpointsByNames(names) {
let _this = this;
let endpoints = [];
names.forEach(function (name) {
let endpoint = _this.getEndpoint(name);
if (!endpoint) throw new SError(`Endpoint "${name}" doesn't exist in your project`);
endpoints.push(endpoint);
});
return endpoints;
}
getAllEvents() {
return _.flatten(_.map(this.getAllFunctions(), f => f.getAllEvents()));
}
getEvent(eventName) {
return _.find(_.values(this.getAllEvents()), e =>
e.name === eventName
)
}
getResources() {
return this.resources.defaultResources;
}
setResources(resources) {
this.resources[resources.getName()] = resources;
}
getAllResources(resourcesName) {
if (this.resources[resourcesName]) return this.resources[resourcesName];
else return this.resources[Object.keys(this.resources)[0]]; // This temporarily defaults to a single resource stack for backward compatibility
}
getAllStages() {
let stages = [];
for (let i = 0; i < Object.keys(this.stages).length; i++) {
stages.push(this.stages[Object.keys(this.stages)[i]]);
}
return stages;
}
getStage(name) {
return this.stages[name];
}
setStage(stage) {
this.stages[stage.getName()] = stage;
}
removeStage(name) {
let stage = this.stages[name];
delete this.stages[name];
}
validateStageExists(name) {
return this.stages[name] != undefined;
}
getRegion(stageName, regionName) {
if (this.getStage(stageName)) {
let stage = this.getStage(stageName);
if (stage.hasRegion(regionName)) {
return stage.getRegion(regionName);
} else {
throw new SError(`Region ${regionName} doesnt exist in stage ${stageName}!`);
}
} else {
throw new SError(`Stage ${stageName} doesnt exist in this project!`);
}
}
getAllRegions(stageName) {
return this.getStage(stageName).getAllRegions();
}
getAllRegionNames(stageName) {
return _.map(this.getAllRegions(stageName), 'name');
}
setRegion(stageName, region) {
let stage = this.getStage(stageName);
stage.setRegion(region);
}
validateRegionExists(stageName, regionName) {
let stage = this.getStage(stageName);
if (stage) {
return stage.hasRegion(regionName);
} else {
return false;
}
}
setVariables(variables) {
this.variables = variables;
}
getVariables() {
return this.variables;
}
getVariablesObject(stage, region) {
let vars = this.getVariables().toObject();
if (stage) stage = this.getStage(stage);
if (stage && region) region = stage.getRegion(region);
vars = _.merge(vars, stage ? stage.getVariables().toObject() : {}, region ? region.getVariables().toObject() : {});
return vars;
}
addVariables(variablesObj) {
return this.getVariables().fromObject(variablesObj);
}
setTemplates(templates) {
this.templates = templates;
}
getTemplates() {
return this.templates;
}
addPlugin(pluginName) {
this.plugins.push(pluginName);
}
}
return Project;
};
;