serverless/lib/ServerlessState.js

440 lines
12 KiB
JavaScript

'use strict';
/**
* Serverless State Class
*/
const SError = require('./ServerlessError'),
SUtils = require('./utils/index'),
_ = require('lodash'),
path = require('path'),
fs = require('fs');
class ServerlessState {
/**
* Constructor
*/
constructor(Serverless) {
this._S = Serverless;
this.meta = new this._S.classes.Meta(this._S);
this.project = new this._S.classes.Project(this._S);
// If project path, load state
if (Serverless.config.projectPath) this.load();
}
/**
* Load
* - Load from source (i.e., file system);
* - Returns promise
*/
load() {
let _this = this;
return _this.project.load()
.then(function() {
return _this.meta.load();
});
}
/**
* Save
* - Load from source (i.e., file system);
*/
save() {
let _this = this;
return _this.project.save({ deep: true })
.then(function() {
return _this.meta.save({ deep: true });
});
}
/**
* Set
* - Set data
*/
set(data) {
this.meta = data.meta ? this.meta.set(data.meta) : this.meta;
this.project = data.project ? this.project.set(data.project, { deep: true }) : this.project;
return this;
}
/**
* Get
* - Returns clone of data
*/
get() {
return {
meta: this.meta.get(),
project: this.project.get()
}
}
/**
* Get Populated
* - Returns clone of data
*/
getPopulated(options) {
options = options || {};
// Validate: Check Stage & Region
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
let populatedData = {
meta: this.meta.get(),
project: {}
};
return this.project.getPopulated(options)
.then(function(data) {
populatedData.project = data;
return populatedData;
});
}
/**
* Get Meta
* - Returns meta data from state
*/
getMeta() {
return this.meta;
}
/**
* Get Project
* - Returns project data from state
*/
getProject() {
return this.project;
}
/**
* Get Resources
* - Get project resources
*/
getResources(options) {
options = options || {};
if (options.populate) {
return this.getPopulated(options)
.then(function(populatedData) {
return SUtils.getResources(populatedData.project);
});
} else {
return Promise.resolve(SUtils.getResources(this.project.get()));
}
}
/**
* Get Stages
* - Returns array of stages in project
*/
getStages() {
return this.meta.getStages();
}
/**
* Get Regions (in stage)
* - Returns array of regions in a stage
*/
getRegions(stage) {
return this.meta.getRegions(stage);
}
/**
* Get Components
* - Returns an array of this state's project component instances
* - Options: component
* - options.paths is an array of serverless paths like this: ['component', 'component']
*/
getComponents(options) {
let _this = this,
allComponents = [],
foundComponents = [];
// Get all
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
allComponents.push(_this.project.components[Object.keys(_this.project.components)[i]]);
}
// Return if no options specified
if (!options) return allComponents;
// If options specified, loop through and find the ones specified
for (let i = 0; i < allComponents.length; i++) {
let component = allComponents[i];
if (options.component) {
if (component._config.component == options.component) {
foundComponents.push(component);
}
continue;
}
if (options.paths && options.paths.indexOf(component._config.sPath) !== -1) {
foundComponents.push(component);
continue;
}
}
if (!foundComponents.length) {
throw new SError('No components found via the options you provided');
}
return foundComponents;
}
/**
* Get Modules
* - Returns an array of this state's modules instances
* - Options: component, module
* - options.paths is an array of serverless paths like this: ['component/moduleOne', 'component/moduleTwo']
*/
getModules(options) {
let _this = this,
allModules = [],
foundModules = [];
// Get all
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
let component = _this.project.components[Object.keys(_this.project.components)[i]];
if (!component.modules) continue;
for (let j = 0; j < Object.keys(component.modules).length; j++) {
allModules.push(component.modules[Object.keys(component.modules)[j]]);
}
}
// Return if no options specified
if (!options) return allModules;
// If options specified, loop through and find the ones specified
for (let i = 0; i < allModules.length; i++) {
let module = allModules[i];
if (options.component && options.module) {
if (module._config.component == options.component && module._config.module == options.module) {
foundModules.push(module);
}
continue;
}
if (options.component) {
if (module._config.component == options.component) {
foundModules.push(module);
}
continue;
}
if (options.paths && options.paths.indexOf(module._config.sPath) !== -1) {
foundModules.push(module);
continue;
}
}
if (!foundModules.length) {
throw new SError('No modules found via the options you provided');
}
return foundModules;
}
/**
* Get Functions
* - Returns an array of this state's function instances
* - Options: paths, component, module, function
* - options.paths is an array of Serverless paths like this: ['component/moduleOne/functionOne', 'component/moduleOne/functionOne']
*/
getFunctions(options) {
let _this = this,
allFunctions = [],
foundFunctions = [];
// Get all
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
let component = _this.project.components[Object.keys(_this.project.components)[i]];
if (!component.modules) continue;
for (let j = 0; j < Object.keys(component.modules).length; j++) {
let module = component.modules[Object.keys(component.modules)[j]];
if (!module.functions) continue;
for (let k = 0; k < Object.keys(module.functions).length; k++) {
allFunctions.push(module.functions[Object.keys(module.functions)[k]]);
}
}
}
// Return if no options specified
if (!options) return allFunctions;
// If options specified, loop through and find the ones specified
for (let i = 0; i < allFunctions.length; i++) {
let func = allFunctions[i];
if (options.component && options.module && options.function) {
if (func._config.component == options.component && func._config.module == options.module && func.name == options.function) {
foundFunctions.push(func);
}
continue;
}
if (options.component && options.module) {
if (func._config.component == options.component && func._config.module == options.module) {
foundFunctions.push(func);
}
continue;
}
if (options.component) {
if (func._config.component == options.component) {
foundFunctions.push(func);
}
continue;
}
if (options.paths && options.paths.indexOf(func._config.sPath) !== -1) {
foundFunctions.push(func);
continue;
}
}
if (!foundFunctions.length) {
throw new SError('No functions found via the options you provided');
}
return foundFunctions;
}
/**
* Get Endpoints
* - Returns an array of this state's function instances
* - Options: paths, component, module, function, endpointPath, endpointMethod
* - options.paths is an array of Serverless paths like this: ['component/moduleOne/functionOne@moduleOne/functionOne~GET']
*/
getEndpoints(options) {
let _this = this,
allEndpoints = [],
foundEndpoints = [];
// Get all functions
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
let component = _this.project.components[Object.keys(_this.project.components)[i]];
if (!component.modules) continue;
for (let j = 0; j < Object.keys(component.modules).length; j++) {
let module = component.modules[Object.keys(component.modules)[j]];
if (!module.functions) continue;
for (let k = 0; k < Object.keys(module.functions).length; k++) {
let func = module.functions[Object.keys(module.functions)[k]];
for (let l = 0; l < func.endpoints.length; l++) {
allEndpoints.push(func.endpoints[l]);
}
}
}
}
// Return if no options specified
if (!options) return allEndpoints;
// If options specified, loop through functions and find the ones specified
for (let i = 0; i < allEndpoints.length; i++) {
let endpoint = allEndpoints[i];
if (options.component && options.module && options.function && options.endpointPath && options.endpointMethod) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module && endpoint._config.function == options.function && endpoint.path == options.endpointPath && endpoint.method == options.endpointMethod) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.module && options.function && options.endpointPath && !options.endpointMethod) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module && endpoint._config.function == options.function && endpoint.path == options.endpointPath) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.module && options.function && options.endpointMethod && !options.endpointPath) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module && endpoint._config.function == options.function && endpoint.method == options.endpointMethod) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.module && options.function && !options.endpointPath && !options.endpointMethod) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module && endpoint._config.function == options.function) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.module && options.endpointMethod && !options.function && !options.endpointPath) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module && endpoint.method == options.endpointMethod) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.module && !options.function && !options.endpointPath && !options.endpointMethod) {
if (endpoint._config.component == options.component && endpoint._config.module == options.module) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && options.endpointMethod && !options.module && !options.function && !options.endpointPath) {
if (endpoint._config.component == options.component && endpoint.method == options.endpointMethod) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.component && !options.module && !options.function && !options.endpointPath && !options.endpointMethod) {
if (endpoint._config.component == options.component) {
foundEndpoints.push(endpoint);
}
continue;
}
if (options.paths && options.paths.indexOf(endpoint._config.sPath) !== -1) {
foundEndpoints.push(endpoint);
continue;
}
}
if (!foundEndpoints.length) {
throw new SError('No endpoints found via the options you provided');
}
return foundEndpoints;
}
/**
* Validate Stage Exists
* - Checks to see if a stage exists in your project
*/
validateStageExists(stage) {
return this.meta.validateStageExists(stage);
}
/**
* Validate Region Exists
* - Checks to see if a stage exists in your project
*/
validateRegionExists(stage, region) {
return this.meta.validateRegionExists(stage, region);
}
}
module.exports = ServerlessState;