diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index f4de9b727..e9654f818 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -35,7 +35,6 @@ class ServerlessFunction { let _this = this; // Defaults - _this.moduleName = null; _this.data = {}; _this.data.name = _this.options.function || 'function' + SUtils.generateShortId(6); _this.data.handler = (_this.options.function && _this.options.module) ? path.join('modules', _this.options.module, 'functions', _this.options.function, 'handler.handler') : ""; diff --git a/lib/ServerlessProject.js b/lib/ServerlessProject.js index ca0658db7..10a7dde24 100644 --- a/lib/ServerlessProject.js +++ b/lib/ServerlessProject.js @@ -201,7 +201,7 @@ class ServerlessProject { /** * getFunctions - * - returns an array of module instances + * - returns an array of function instances * - paths is an array with this format: ['moduleOne/functionOne', 'moduleTwo/functionOne'] */ @@ -238,7 +238,6 @@ class ServerlessProject { module: module.name, function: func.name }); - funcInstance.data = func; functions.push(funcInstance); } } @@ -296,20 +295,22 @@ class ServerlessProject { // Loop - Endpoints for (let k = 0; k < func.endpoints.length; k++) { - let endpoint = func.endpoints[k]; + let endpoint = { + data: func.endpoints[k] + }; // If paths, and this endpoint is not included, skip if (options.paths && options.paths.length && (!pathsObj[module.name] || !pathsObj[module.name][func.name] || - !pathsObj[module.name][func.name][endpoint.path] || - !pathsObj[module.name][func.name][endpoint.path][endpoint.method]) + !pathsObj[module.name][func.name][endpoint.data.path] || + !pathsObj[module.name][func.name][endpoint.data.path][endpoint.data.method]) ) continue; - endpoint._module = module.name; - endpoint._function = func.name; - endpoint._sPath = module.name + '/' + func.name + '@' + endpoint.path + '~' + endpoint.method; + endpoint.module = module.name; + endpoint.function = func.name; + endpoint.sPath = module.name + '/' + func.name + '@' + endpoint.data.path + '~' + endpoint.data.method; endpoints.push(endpoint); } } diff --git a/lib/actions/CodePackageLambdaNodeJs.js b/lib/actions/CodePackageLambdaNodeJs.js index 036c58738..ab5858dee 100644 --- a/lib/actions/CodePackageLambdaNodeJs.js +++ b/lib/actions/CodePackageLambdaNodeJs.js @@ -119,7 +119,7 @@ module.exports = function(SPlugin, serverlessPath) { throw new SError('Function does not have a memorySize property'); } if (!_this.function.data.runtime) { - throw new SError('Function\'s parent module is missing a runtime property'); + throw new SError('Function does not have a runtime property'); } // Load AWS Service Instances diff --git a/lib/actions/EndpointBuildApiGateway.js b/lib/actions/EndpointBuildApiGateway.js index 72ff3a537..fdd16f442 100644 --- a/lib/actions/EndpointBuildApiGateway.js +++ b/lib/actions/EndpointBuildApiGateway.js @@ -93,7 +93,7 @@ module.exports = function(SPlugin, serverlessPath) { + _this.options.region + '.amazonaws.com/' + _this.options.stage - + _this.endpoint.path; + + _this.endpoint.data.path; SUtils.sDebug( '"' @@ -101,9 +101,9 @@ module.exports = function(SPlugin, serverlessPath) { + '" successfully built endpoint on API Gateway in the region "' + _this.options.region + '". Access it via ' - + _this.endpoint.method + + _this.endpoint.data.method + ' @ ' - + _this.endpoint.url); + + _this.url); /** * Return Action Data @@ -159,34 +159,34 @@ module.exports = function(SPlugin, serverlessPath) { _this.Lambda = require('../utils/aws/Lambda')(awsConfig); // Validate and sanitize endpoint attributes - if (!_this.endpoint.path) { + if (!_this.endpoint.data.path) { throw new SError('Endpoint does not have a "path" property'); } - if (!_this.endpoint.method) { + if (!_this.endpoint.data.method) { throw new SError('Endpoint does not have a "method" property'); } - if (!_this.endpoint.authorizationType) { + if (!_this.endpoint.data.authorizationType) { throw new SError('Endpoint does not have a "authorizationType" property'); } - if (typeof _this.endpoint.apiKeyRequired === 'undefined') { + if (typeof _this.endpoint.data.apiKeyRequired === 'undefined') { throw new SError('Endpoint does not have a "apiKeyRequired" property'); } - if (!_this.endpoint.requestTemplates) { + if (!_this.endpoint.data.requestTemplates) { throw new SError('Endpoint does not have a "requestTemplates" property'); } - if (!_this.endpoint.requestParameters) { + if (!_this.endpoint.data.requestParameters) { throw new SError('Endpoint does not have a "requestParameters" property'); } - if (!_this.endpoint.responses) { + if (!_this.endpoint.data.responses) { throw new SError('Endpoint does not have a "responses" property'); } // Sanitize path - Remove excessive forward slashes - if (_this.endpoint.path.charAt(0) !== '/') _this.endpoint.path = '/' + _this.endpoint.path; - if (_this.endpoint.path.charAt(_this.endpoint.path.length) === '/') _this.endpoint.path = _this.endpoint.path.slice(0, -1); + if (_this.endpoint.data.path.charAt(0) !== '/') _this.endpoint.data.path = '/' + _this.endpoint.data.path; + if (_this.endpoint.data.path.charAt(_this.endpoint.data.path.length) === '/') _this.endpoint.data.path = _this.endpoint.data.path.slice(0, -1); // Sanitize method - _this.endpoint.method = _this.endpoint.method.toUpperCase(); + _this.endpoint.data.method = _this.endpoint.data.method.toUpperCase(); return BbPromise.resolve(); } @@ -220,7 +220,7 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; let params = { - FunctionName: _this.Lambda.sGetLambdaName(_this.project.data.name, _this.endpoint._module, _this.endpoint._function), /* required */ + FunctionName: _this.Lambda.sGetLambdaName(_this.project.data.name, _this.endpoint.module, _this.endpoint.function), /* required */ Qualifier: _this.options.stage }; @@ -230,7 +230,7 @@ module.exports = function(SPlugin, serverlessPath) { _this.deployedLambda = data.Configuration; // Prepare StatementId - _this.lambdaPolicyStatementId = ('s_apig' + _this.endpoint.path + '_' + _this.endpoint.method).replace(/[\/{}]/g, '_'); + _this.lambdaPolicyStatementId = ('s_apig' + _this.endpoint.data.path + '_' + _this.endpoint.data.method).replace(/[\/{}]/g, '_'); SUtils.sDebug( '"' @@ -238,7 +238,7 @@ module.exports = function(SPlugin, serverlessPath) { + ' - ' + _this.options.region + ' - ' - + _this.endpoint.path + + _this.endpoint.data.path + '": found the target lambda with function name: ' + _this.deployedLambda.FunctionName); }) @@ -274,7 +274,7 @@ module.exports = function(SPlugin, serverlessPath) { + ' - ' + _this.options.region + ' - ' - + _this.endpoint.path + + _this.endpoint.data.path + '": found ' + _this.apiResources.length + ' existing Resources on API Gateway'); @@ -315,7 +315,7 @@ module.exports = function(SPlugin, serverlessPath) { // Check paths to see if resources need building for (let i = 0; i < _this.apiResources.length; i++) { - if (_this.apiResources[i].path === _this.endpoint.path) { + if (_this.apiResources[i].path === _this.endpoint.data.path) { _this.resource = _this.apiResources[i]; break; } @@ -331,14 +331,14 @@ module.exports = function(SPlugin, serverlessPath) { + ' - ' + _this.options.region + ' - ' - + _this.endpoint.path + + _this.endpoint.data.path + '": ' + '": no resources need to be created for this endpoint'); return BbPromise.resolve(); } - let eResources = _this.endpoint.path.split('/'); + let eResources = _this.endpoint.data.path.split('/'); eResources[0] = '/'; // Our split removes the initial '/' and leaves an empty string, replace it return new BbPromise(function(resolve, reject) { @@ -408,7 +408,7 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'created resource: ' + response.pathPart); @@ -431,17 +431,17 @@ module.exports = function(SPlugin, serverlessPath) { requestParameters = {}; // If Request Params, add them - if (_this.endpoint.requestParameters) { + if (_this.endpoint.data.requestParameters) { // Format them per APIG API's Expectations - for (let prop in _this.endpoint.requestParameters) { - let requestParam = _this.endpoint.requestParameters[prop]; + for (let prop in _this.endpoint.data.requestParameters) { + let requestParam = _this.endpoint.data.requestParameters[prop]; requestParameters[requestParam] = true; } } let params = { - httpMethod: _this.endpoint.method, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id /* required */ }; @@ -457,7 +457,7 @@ module.exports = function(SPlugin, serverlessPath) { } let params = { - httpMethod: _this.endpoint.method, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id /* required */ }; @@ -466,12 +466,12 @@ module.exports = function(SPlugin, serverlessPath) { .then(function(response) { let params = { - authorizationType: _this.endpoint.authorizationType, /* required */ - httpMethod: _this.endpoint.method, /* required */ + authorizationType: _this.endpoint.data.authorizationType, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id, /* required */ - apiKeyRequired: _this.endpoint.apiKeyRequired, - requestModels: _this.endpoint.requestModels, + apiKeyRequired: _this.endpoint.data.apiKeyRequired, + requestModels: _this.endpoint.data.requestModels, requestParameters: requestParameters }; return SUtils.persistantRequest( function(){ return _this.ApiGateway.putMethodPromised(params); } ) @@ -482,12 +482,12 @@ module.exports = function(SPlugin, serverlessPath) { // Method does not exist. Create it. let params = { - authorizationType: _this.endpoint.authorizationType, /* required */ - httpMethod: _this.endpoint.method, /* required */ + authorizationType: _this.endpoint.data.authorizationType, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id, /* required */ - apiKeyRequired: _this.endpoint.apiKeyRequired, - requestModels: _this.endpoint.requestModels, + apiKeyRequired: _this.endpoint.data.apiKeyRequired, + requestModels: _this.endpoint.data.requestModels, requestParameters: requestParameters }; @@ -499,18 +499,19 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'created method: ' - + _this.endpoint.method); + + _this.endpoint.data.method); }); } /* - Coerce the evnt.endpoint.requestTemplates[prop] values. Previously this was only validly a string. Often that + Coerce the _this.endpoint.data.requestTemplates[prop] values. Previously this was only validly a string. Often that string contained a stringified JSON object. For those cases, dealing with and modifying the string was painful. As such, this method enables the string to validly be of a different type. In this expansion, an object. */ - prepareRequestTemplates(requestTemplates) { + + _prepareRequestTemplates(requestTemplates) { let ret = {}; for (let property in requestTemplates) { if (requestTemplates.hasOwnProperty(property)) { @@ -537,12 +538,12 @@ module.exports = function(SPlugin, serverlessPath) { else alias = '${stageVariables.functionAlias}'; let params = { - httpMethod: _this.endpoint.method, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id, /* required */ type: 'AWS', /* required */ - cacheKeyParameters: _this.endpoint.cacheKeyParameters || [], - cacheNamespace: _this.endpoint.cacheNamespace || null, + cacheKeyParameters: _this.endpoint.data.cacheKeyParameters || [], + cacheNamespace: _this.endpoint.data.cacheNamespace || null, // Due to a bug in API Gateway reported here: https://github.com/awslabs/aws-apigateway-swagger-importer/issues/41 // Specifying credentials within API Gateway causes extra latency (~500ms) // Until API Gateway is fixed, we need to make a separate call to Lambda to add credentials to API Gateway @@ -550,8 +551,8 @@ module.exports = function(SPlugin, serverlessPath) { // _this._regionJson.iamRoleArnApiGateway credentials: null, integrationHttpMethod: 'POST', - requestParameters: _this.endpoint.requestParameters || {}, - requestTemplates: _this.prepareRequestTemplates(_this.endpoint.requestTemplates), + requestParameters: _this.endpoint.data.requestParameters || {}, + requestTemplates: _this._prepareRequestTemplates(_this.endpoint.requestTemplates), uri: 'arn:aws:apigateway:' // Make ARN for apigateway - lambda + _this.options.region + ':lambda:path/2015-03-31/functions/arn:aws:lambda:' @@ -576,7 +577,7 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'created integration with the type: AWS'); }) .catch(function(error) { @@ -597,7 +598,7 @@ module.exports = function(SPlugin, serverlessPath) { return BbPromise.try(function() { // Collect Response Keys - if (_this.endpoint.responses) return Object.keys(_this.endpoint.responses); + if (_this.endpoint.data.responses) return Object.keys(_this.endpoint.data.responses); else return []; }) @@ -605,7 +606,7 @@ module.exports = function(SPlugin, serverlessPath) { // Iterate through each response to be created - let thisResponse = _this.endpoint.responses[responseKey]; + let thisResponse = _this.endpoint.data.responses[responseKey]; let responseParameters = {}; let responseModels = {}; @@ -627,7 +628,7 @@ module.exports = function(SPlugin, serverlessPath) { } let params = { - httpMethod: _this.endpoint.method, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id, /* required */ statusCode: thisResponse.statusCode, /* required */ @@ -643,7 +644,7 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'created method response'); }) @@ -664,12 +665,12 @@ module.exports = function(SPlugin, serverlessPath) { return BbPromise.try(function() { // Collect Response Keys - if (_this.endpoint.responses) return Object.keys(_this.endpoint.responses); + if (_this.endpoint.data.responses) return Object.keys(_this.endpoint.data.responses); else return []; }) .each(function(responseKey) { - let thisResponse = _this.endpoint.responses[responseKey]; + let thisResponse = _this.endpoint.data.responses[responseKey]; // Add Response Parameters let responseParameters = thisResponse.responseParameters || {}; @@ -681,7 +682,7 @@ module.exports = function(SPlugin, serverlessPath) { let selectionPattern = thisResponse.selectionPattern || (responseKey === 'default' ? null : responseKey); let params = { - httpMethod: _this.endpoint.method, /* required */ + httpMethod: _this.endpoint.data.method, /* required */ resourceId: _this.resource.id, /* required */ restApiId: _this.restApi.id, /* required */ statusCode: thisResponse.statusCode, /* required */ @@ -698,7 +699,7 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'created method integration response'); }).catch(function(error) { @@ -781,7 +782,7 @@ module.exports = function(SPlugin, serverlessPath) { '"' + _this.options.stage + ' - ' + _this.options.region - + ' - ' + _this.endpoint.path + '": ' + + ' - ' + _this.endpoint.data.path + '": ' + 'removed existing lambda access policy statement'); }) .catch(function(error) {}); @@ -796,8 +797,8 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; // Sanitize Path - Remove first and last slashes, if any - _this.endpoint.path = _this.endpoint.path.split('/'); - _this.endpoint.path = _this.endpoint.path.join('/'); + _this.endpoint.data.path = _this.endpoint.data.path.split('/'); + _this.endpoint.data.path = _this.endpoint.data.path.join('/'); // Create new access policy statement let params = {}; @@ -812,8 +813,8 @@ module.exports = function(SPlugin, serverlessPath) { + ':' + _this.restApi.id + '/*/' - + _this.endpoint.method - + _this.endpoint.path; + + _this.endpoint.data.method + + _this.endpoint.data.path; return _this.Lambda.addPermissionPromised(params) .then(function() { @@ -824,7 +825,7 @@ module.exports = function(SPlugin, serverlessPath) { + ' - ' + _this.options.region + ' - ' - + _this.endpoint.path + + _this.endpoint.data.path + '": ' + 'added permission to Lambda'); }) diff --git a/lib/actions/EndpointDeploy.js b/lib/actions/EndpointDeploy.js index 145cad219..2ea33cb0c 100644 --- a/lib/actions/EndpointDeploy.js +++ b/lib/actions/EndpointDeploy.js @@ -271,7 +271,7 @@ module.exports = function(SPlugin, serverlessPath) { let options = { stage: _this.options.stage, region: region, - path: endpoint._sPath, + path: endpoint.sPath, aliasEndpoint: _this.options.aliasEndpoint, aliasRestApi: _this.options.aliasRestApi }; @@ -283,10 +283,11 @@ module.exports = function(SPlugin, serverlessPath) { if (!_this.deployed) _this.deployed = {}; if (!_this.deployed[region]) _this.deployed[region] = []; _this.deployed[region].push({ - endpointModule: endpoint._module, - endpointFunction: endpoint._function, - endpointPath: endpoint.path, - endpointMethod: endpoint.method, + module: endpoint.module, + function: endpoint.function, + endpointSPath: endpoint.sPath, + endpointPath: endpoint.data.path, + endpointMethod: endpoint.data.method, endpointUrl: result.data.url }); @@ -298,10 +299,11 @@ module.exports = function(SPlugin, serverlessPath) { if (!_this.failed) _this.failed = {}; if (!_this.failed[region]) _this.failed[region] = []; _this.failed[region].push({ - endpointModule: endpoint._module, - endpointFunction: endpoint._function, - endpointPath: endpoint.path, - endpointMethod: endpoint.method, + module: endpoint.module, + function: endpoint.function, + endpointSPath: endpoint.sPath, + endpointPath: endpoint.data.path, + endpointMethod: endpoint.data.method, message: e.message, stack: e.stack }); diff --git a/lib/actions/EndpointDeployApiGateway.js b/lib/actions/EndpointDeployApiGateway.js index 867d77da4..9d48bdc2a 100644 --- a/lib/actions/EndpointDeployApiGateway.js +++ b/lib/actions/EndpointDeployApiGateway.js @@ -77,10 +77,6 @@ module.exports = function(SPlugin, serverlessPath) { */ _validateAndPrepare() { - - let _this = this; - - return BbPromise.resolve(); } @@ -139,4 +135,4 @@ module.exports = function(SPlugin, serverlessPath) { } return( EndpointDeployApiGateway ); -}; +}; \ No newline at end of file diff --git a/lib/actions/FunctionDeploy.js b/lib/actions/FunctionDeploy.js index 8ea8176ef..be38460aa 100644 --- a/lib/actions/FunctionDeploy.js +++ b/lib/actions/FunctionDeploy.js @@ -115,15 +115,52 @@ module.exports = function(SPlugin, serverlessPath) { .then(_this._processDeployment) .then(function() { + // Display Failed Function Deployments + if (_this.failed) { + SCli.log('Failed to deploy the following functions in "' + + _this.options.stage + + '" to the following regions:'); + // Display Errors + for (let i = 0; i < Object.keys(_this.failed).length; i++) { + let region = _this.failed[Object.keys(_this.failed)[i]]; + SCli.log(Object.keys(_this.failed)[i] + ' ------------------------'); + for (let j = 0; j < region.length; j++) { + SCli.log(' ' + region[j].module + '/' + region[j].function + ': ' + region[j].message ); + SUtils.sDebug(region[j].stack); + } + } + } + + // Display Successful Function Deployments + if (_this.deployed) { + + // Status + SCli.log('Successfully deployed functions in "' + + _this.options.stage + + '" to the following regions: '); + + // Display Functions & ARNs + for (let i = 0; i < Object.keys(_this.deployed).length; i++) { + let region = _this.deployed[Object.keys(_this.deployed)[i]]; + SCli.log(Object.keys(_this.deployed)[i] + ' ------------------------'); + for (let j = 0; j < region.length; j++) { + SCli.log(' ' + region[j].module + '/' + region[j].function + ': ' + region[j].ARN ); + } + } + } + /** * Return Action Data * - WARNING: Adjusting these will break Plugins */ return { - options: _this.options + options: _this.options, + data: { + deployed: _this.deployed, + failed: _this.failed + } } - }); } @@ -137,18 +174,17 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; // Set Defaults - this.options.stage = this.options.stage ? this.options.stage : null; - this.options.paths = this.options.paths ? this.options.paths : []; - this.options.all = this.options.all ? true : false; - this.options.aliasFunction = this.options.aliasFunction ? this.options.aliasFunction : null; + _this.options.stage = _this.options.stage ? _this.options.stage : null; + _this.options.paths = _this.options.paths ? _this.options.paths : []; + _this.options.all = _this.options.all ? true : false; + _this.options.aliasFunction = _this.options.aliasFunction ? _this.options.aliasFunction : null; // Instantiate Classes - this.project = new this.S.classes.Project(this.S); - this.meta = new this.S.classes.Meta(this.S); + _this.project = new _this.S.classes.Project(_this.S); + _this.meta = new _this.S.classes.Meta(_this.S); // Set Deploy Regions - this.regions = this.options.region ? [this.options.region] : Object.keys(this.meta.data.private.stages[this.options.stage].regions); - this.deployed = {}; + _this.regions = _this.options.region ? [_this.options.region] : Object.keys(_this.meta.data.private.stages[_this.options.stage].regions); // Validate Paths if (!_this.options.paths.length && !_this.options.all) { @@ -176,6 +212,7 @@ module.exports = function(SPlugin, serverlessPath) { + _this.options.stage + '" to the following regions: ' + _this.regions.join(', ')); + SCli.log('------------------------'); _this._spinner = SCli.spinner(); _this._spinner.start(); @@ -195,39 +232,8 @@ module.exports = function(SPlugin, serverlessPath) { }) .then(function() { - // Status + // Stop Spinner _this._spinner.stop(true); - - if (_this.failed) { - - // Status - SCli.log('Failed to deploy the following functions in "' + _this.options.stage + '" to the following regions:'); - - // Display Methods & URLS - for (let i = 0; i < Object.keys(_this.failed).length; i++) { - let region = _this.failed[Object.keys(_this.failed)[i]]; - SCli.log(Object.keys(_this.failed)[i] + ' ------------------------'); - for (let j = 0; j < region.length; j++) { - SCli.log(' ' + region[j].function + ': ' + region[j].message ); - SUtils.sDebug(region[j].stack); - } - } - } else { - - // Status - SCli.log('Successfully deployed functions in "' - + _this.options.stage - + '" to the following regions: '); - - // Display Functions & ARNs - for (let i = 0; i < Object.keys(_this.deployed).length; i++) { - let region = _this.deployed[Object.keys(_this.deployed)[i]]; - SCli.log(Object.keys(_this.deployed)[i] + ' ------------------------'); - for (let j = 0; j < region.length; j++) { - SCli.log(' ' + region[j]); - } - } - } }); } @@ -248,7 +254,7 @@ module.exports = function(SPlugin, serverlessPath) { async.eachLimit(_this.functions, 5, function(func, cb) { - return new BbPromise(function(resolve) { + return BbPromise.try(function() { // Nodejs if (func.data.runtime = 'nodejs') { @@ -271,19 +277,21 @@ module.exports = function(SPlugin, serverlessPath) { function: result.options.function, pathDist: result.pathDist, pathsPackaged: result.pathsPackaged - }) - }) - .then(function(result) { - return resolve(result); + }); }); } + }) .then(function(result) { // Add Function and Region + if (!_this.deployed) _this.deployed = {}; if (!_this.deployed[region]) _this.deployed[region] = []; - let deployed = result.options.module + '-' + result.options.function + ': ' + result.lambdaAliasArn; - _this.deployed[region].push(deployed); + _this.deployed[region].push({ + module: func.module, + function: func.data.name, + ARN: result.lambdaAliasArn + }); return cb(); @@ -291,12 +299,13 @@ module.exports = function(SPlugin, serverlessPath) { .catch(function(e) { // Stash Failed Function Code - if (!_this.failed) _this.failed = {}; + if (!_this.failed) _this.failed = {}; if (!_this.failed[region]) _this.failed[region] = []; _this.failed[region].push({ + module: func.module, + function: func.data.name, message: e.message, - stack: e.stack, - function: func.module + '-' + func.data.name, + stack: e.stack }); return cb();