diff --git a/lib/Actions.json b/lib/Actions.json index 954027a91..a86983d26 100644 --- a/lib/Actions.json +++ b/lib/Actions.json @@ -13,7 +13,6 @@ "./actions/CodeDeployLambda.js", "./actions/EndpointDeploy.js", "./actions/EndpointBuildApiGateway.js", - "./actions/EndpointRun.js", "./actions/EventDeploy.js", "./actions/EventLambdaStream.js", "./actions/EventLambdaS3.js", diff --git a/lib/Function.js b/lib/Function.js index dc5c81522..247ce2789 100644 --- a/lib/Function.js +++ b/lib/Function.js @@ -76,7 +76,7 @@ class Function extends SerializerFileSystem { fromObject(data) { // Merge - _.assign(this, data) + _.assign(this, data); data.endpoints = data.endpoints || []; data.events = data.events || []; diff --git a/lib/SerializerFileSystem.js b/lib/SerializerFileSystem.js index 1a6fdbe92..fc2ea7330 100644 --- a/lib/SerializerFileSystem.js +++ b/lib/SerializerFileSystem.js @@ -340,7 +340,7 @@ class SerializerFileSystem { return template.load() .then(function(template) { - let componentTemplates = func.getComponent().getTemplates() + let componentTemplates = func.getComponent().getTemplates(); let parents = getParentTemplates(func.getFilePath()); diff --git a/lib/actions/CodeDeployLambda.js b/lib/actions/CodeDeployLambda.js index facc4eec2..9dea9baa3 100644 --- a/lib/actions/CodeDeployLambda.js +++ b/lib/actions/CodeDeployLambda.js @@ -105,9 +105,9 @@ module.exports = function(SPlugin, serverlessPath) { // TODO: Validate Options // Instantiate Classes - _this.aws = _this.S.getProvider('aws'); + _this.aws = _this.S.getProvider(); _this.project = _this.S.getProject(); - _this.function = _this.S.getProject().getFunction( _this.evt.options.functionName ); + _this.function = _this.S.getProject().getFunction( _this.evt.options.name ); // Set default function name _this.functionName = _this.function.getDeployedName({ @@ -166,7 +166,7 @@ module.exports = function(SPlugin, serverlessPath) { let d = new Date(), s3Bucket = _this.project.getVariables().projectBucket, - s3Region = s3Bucket.split('.')[1], + projectBucketRegion = _this.project.getVariables().projectBucketRegion, key = ['serverless', _this.project.name, _this.evt.options.stage, 'lambdas', _this.functionName + '@' + d.getTime() + '.zip'].join('/'), params = { Bucket: s3Bucket, @@ -176,7 +176,7 @@ module.exports = function(SPlugin, serverlessPath) { Body: fs.createReadStream(_this.pathCompressed) }; - return _this.aws.request('S3', 'upload', params, _this.evt.options.stage, s3Region) + return _this.aws.request('S3', 'upload', params, _this.evt.options.stage, projectBucketRegion) .then(function (s3Key) { // Store S3 Data diff --git a/lib/actions/CodePackageLambda.js b/lib/actions/CodePackageLambda.js index 001e8b5a6..2c8f7502f 100644 --- a/lib/actions/CodePackageLambda.js +++ b/lib/actions/CodePackageLambda.js @@ -96,9 +96,9 @@ module.exports = function(SPlugin, serverlessPath) { // Instantiate classes _this.aws = _this.S.getProvider('aws'); _this.project = _this.S.getProject(); - _this.function = _this.S.getProject().getFunction( _this.evt.options.functionName ); + _this.function = _this.S.getProject().getFunction( _this.evt.options.name ); - if (!_this.function) BbPromise.reject(new SError(`Function could not be found: ${_this.evt.options.functionName}`)); + if (!_this.function) BbPromise.reject(new SError(`Function could not be found: ${_this.evt.options.name}`)); //TODO: Use Function.validate() @@ -134,7 +134,7 @@ module.exports = function(SPlugin, serverlessPath) { // Set Dist Dir let d = new Date(); - _this.pathDist = path.join(_this.S._projectPath, '_meta', '_tmp', _this.function.name + '@' + d.getTime()); + _this.pathDist = path.join(_this.S.getProject().getRootPath(), '_meta', '_tmp', _this.function.name + '@' + d.getTime()); // Status SUtils.sDebug(`"${_this.evt.options.stage} - ${_this.evt.options.region} - ${_this.function.name}": Copying in dist dir ${_this.pathDist}`); @@ -173,7 +173,6 @@ module.exports = function(SPlugin, serverlessPath) { ); let key = ['serverless', _this.project.name, _this.evt.options.stage, _this.evt.options.region, 'envVars', '.env'].join('/'), - s3Region = _this.project.getVariablesObject().projectBucket.split('.')[1], params = { Bucket: _this.project.getVariablesObject().projectBucket, Key: key @@ -183,7 +182,7 @@ module.exports = function(SPlugin, serverlessPath) { // Get ENV file from S3 let NoSuchKey = {code: 'NoSuchKey'}; - return _this.aws.request('S3', 'getObject', params, _this.evt.options.stage, s3Region) + return _this.aws.request('S3', 'getObject', params, _this.evt.options.stage, _this.S.getProject().getVariables().projectBucketRegion) .catch(NoSuchKey => ({Body: ''})) .then(function(s3ObjData) { diff --git a/lib/actions/DashSummary.js b/lib/actions/DashSummary.js index 5581003ae..26e3b1fb9 100644 --- a/lib/actions/DashSummary.js +++ b/lib/actions/DashSummary.js @@ -53,6 +53,7 @@ module.exports = function(SPlugin, serverlessPath) { // Show ASCII SCli.asciiGreeting(); + // Blank space for neatness in the CLI console.log(''); @@ -67,7 +68,7 @@ module.exports = function(SPlugin, serverlessPath) { // list regions for stage regions.forEach(function(region) { regionsNum++; - SCli.log(` |_ ${region}`); + SCli.log(` |_ ${region.name}`); }); }); @@ -90,13 +91,13 @@ module.exports = function(SPlugin, serverlessPath) { // list endpoints for function _.each( endpoints, function(endpoint){ endpointsNum++; - SCli.log(` |_ ${endpoint.path} - (${endpoint.method} endpoint)`); + SCli.log(` |_ ${endpoint.method} ${endpoint.path} (endpoint)`); }); // list events for function _.each( events, function(event){ eventsNum++; - SCli.log(` |_ ${event.name} - (${event.type} event)`); + SCli.log(` |_ ${event.name} (${event.type} event)`); }); }); }); diff --git a/lib/actions/EndpointBuildApiGateway.js b/lib/actions/EndpointBuildApiGateway.js index f9f674d0a..69e124b76 100644 --- a/lib/actions/EndpointBuildApiGateway.js +++ b/lib/actions/EndpointBuildApiGateway.js @@ -125,16 +125,16 @@ module.exports = function(SPlugin, serverlessPath) { // Instantiate Classes _this.project = _this.S.getProject(); - _this.aws = _this.S.getProvider('aws'); + _this.aws = _this.S.getProvider(); // If no iamRoleLambda, throw error - if (!_this.project.getVariablesObject(_this.evt.options.stage, _this.evt.options.region).iamRoleArnLambda) { + if (!_this.project.getRegion(_this.evt.options.stage, _this.evt.options.region).getVariables().iamRoleArnLambda) { throw new SError('No Lambda IAM Role found'); } // Define useful variables - _this.awsAccountNumber = _this.project.getVariablesObject(_this.evt.options.stage, _this.evt.options.region).iamRoleArnLambda.replace('arn:aws:iam::', '').split(':')[0]; - _this.restApiName = _this.project.getVariablesObject(_this.evt.options.stage, _this.evt.options.region).apiGatewayApi; + _this.awsAccountNumber = _this.project.getRegion(_this.evt.options.stage, _this.evt.options.region).getVariables().iamRoleArnLambda.replace('arn:aws:iam::', '').split(':')[0]; + _this.restApiName = _this.project.getRegion(_this.evt.options.stage, _this.evt.options.region).getVariables().apiGatewayApi; _this.resource = null; _this.resourceParent = null; _this.prevIntegration = null; @@ -143,13 +143,12 @@ module.exports = function(SPlugin, serverlessPath) { _this.apiResources = null; // Get populated endpoint - _this.endpointPath = _this.evt.options.endpointName.split('#')[0]; - _this.endpointMethod = _this.evt.options.endpointName.split('#')[1]; - _this.endpoint = _this.project.getEndpoint( _this.endpointPath, _this.endpointMethod ); + _this.endpoint = _this.project.getEndpoint( _this.evt.options.endpointPath, _this.evt.options.endpointMethod ); - if (!_this.endpoint) BbPromise.reject(new SError(`Endpoint could not be found: ${_this.evt.options.endpointName}`)); + if (!_this.endpoint) BbPromise.reject(new SError(`Endpoint could not be found: ${_this.evt.options.endpointPath}#${_this.evt.options.endpointMethod}`)); // Set function name + _this.functionName = _this.endpoint.getFunction().getDeployedName({ stage: _this.evt.options.stage, region: _this.evt.options.region diff --git a/lib/actions/EndpointDeploy.js b/lib/actions/EndpointDeploy.js index 691b308b9..6236848dd 100644 --- a/lib/actions/EndpointDeploy.js +++ b/lib/actions/EndpointDeploy.js @@ -77,7 +77,7 @@ module.exports = function(SPlugin, serverlessPath) { ], parameters: [ { - parameter: 'endpointNames', + parameter: 'names', description: 'The names/ids of the endpoints you want to deploy in this format: user/create#GET', position: '0->' } @@ -102,7 +102,7 @@ module.exports = function(SPlugin, serverlessPath) { // Prompt: Stage if (!_this.S.config.interactive || _this.evt.options.stage) return resolve(); - return _this.cliPromptSelectStage('Function Deployer - Choose a stage: ', _this.evt.options.stage, false) + return _this.cliPromptSelectStage('Endpoint Deployer - Choose a stage: ', _this.evt.options.stage, false) .then(stage => { _this.evt.options.stage = stage; return resolve(); @@ -163,22 +163,22 @@ module.exports = function(SPlugin, serverlessPath) { cwdType = SUtils.getCwdType(); _this.project = _this.S.getProject(); - _this.aws = _this.S.getProvider('aws'); + _this.aws = _this.S.getProvider(); _this.endpoints = []; // Set defaults - _this.evt.options.endpointNames = _this.evt.options.endpointNames ? _this.evt.options.endpointNames : []; - _this.regions = _this.evt.options.region ? [_this.evt.options.region] : _this.project.getAllRegions(_this.evt.options.stage); + _this.evt.options.names = _this.evt.options.names ? _this.evt.options.names : []; + _this.regions = _this.evt.options.region ? [_this.evt.options.region] : _this.project.getAllRegions(_this.evt.options.stage).map(r => {return r.name;}); - if (_this.evt.options.endpointNames.length) { - _this.evt.options.endpointNames.forEach(function(endpointName) { + if (_this.evt.options.names.length) { + _this.evt.options.names.forEach(function(endpointName) { _this.endpoints.push(_this.project.getEndpoint(endpointName.split('#')[0], endpointName.split('#')[1])); }); } // If CLI and no endpoint names targeted, deploy from CWD if Function if (_this.S.cli && - !_this.evt.options.endpointNames.length && + !_this.evt.options.names.length && !_this.evt.options.all) { if(cwdType.function) { @@ -247,8 +247,8 @@ module.exports = function(SPlugin, serverlessPath) { // Get or Create REST API for Region by name let restApi; - if (_this.project.getVariablesObject(_this.evt.options.stage, region)['apiGatewayApi']) { - restApi = _this.project.getVariablesObject(_this.evt.options.stage, region)['apiGatewayApi']; + if (_this.project.getRegion(_this.evt.options.stage, region).getVariables()['apiGatewayApi']) { + restApi = _this.project.getRegion(_this.evt.options.stage, region).getVariables()['apiGatewayApi']; } else { restApi = _this.project.name; } @@ -261,11 +261,12 @@ module.exports = function(SPlugin, serverlessPath) { _this.restApiData = restApiData; - // Persist API to meta - _this.project.getVariablesObject(_this.evt.options.stage, region)['apiGatewayApi'] = restApiData.name; + let regionInstance = _this.project.getRegion(_this.evt.options.stage, region); + regionInstance.addVariables({ + apiGatewayApi: restApiData.name + }); - // TODO: do not save all meta upon each endpoint deploy. `sls endpoint deploy -a` is awfully slow this way - return _this.project.save().then(function(){ + return regionInstance.save().then(function(){ return new BbPromise(function(resolve, reject) { // A function can have multiple endpoints. Process all endpoints for this Function diff --git a/lib/actions/EndpointDeployApiGateway.js b/lib/actions/EndpointDeployApiGateway.js index 665d600b8..d8d1ea643 100644 --- a/lib/actions/EndpointDeployApiGateway.js +++ b/lib/actions/EndpointDeployApiGateway.js @@ -43,14 +43,7 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt = evt; - // Load AWS Service Instances - let awsConfig = { - region: _this.evt.options.region, - accessKeyId: _this.S.config.awsAdminKeyId, - secretAccessKey: _this.S.config.awsAdminSecretKey - }; - - _this.aws = _this.S.getProvider('aws'); + _this.aws = _this.S.getProvider(); return _this._validateAndPrepare() .bind(_this) diff --git a/lib/actions/EndpointRun.js b/lib/actions/EndpointRun.js deleted file mode 100644 index 2cb82a443..000000000 --- a/lib/actions/EndpointRun.js +++ /dev/null @@ -1,156 +0,0 @@ -'use strict'; - -/** - * Action: EndpointRun - * - Tests your deployed endpoint by making an HTTP request according to your endpoint config - */ - -module.exports = function(SPlugin, serverlessPath) { - const path = require('path'), - SCli = require(path.join(serverlessPath, 'utils/cli')), - _ = require('lodash'), - BbPromise = require('bluebird'); - - /** - * EndpointRun Class - */ - - class EndpointRun extends SPlugin { - - constructor(S, config) { - super(S, config); - } - - static getName() { - return 'serverless.core.' + EndpointRun.name; - } - - registerActions() { - this.S.addAction(this.endpointRun.bind(this), { - handler: 'endpointRun', - description: `Tests your deployed endpoint by making an HTTP request according to your endpoint config`, - context: 'endpoint', - contextAction: 'run', - options: [ - { - option: 'region', - shortcut: 'r', - description: 'region you want to run your function in' - }, - { - option: 'stage', - shortcut: 's', - description: 'stage you want to run your function in' - } - ], - parameters: [ - { - parameter: 'path', - description: 'path to your endpoint', - position: '0->1' - } - ] - }); - return BbPromise.resolve(); - } - - /** - * Action - */ - - endpointRun() { - - let _this = this; - _this.evt = evt; - - // Instantiate Classes - _this.project = _this.S.getProject(); - _this.meta = _this.S.state.getMeta(); - - // Set defaults - _this.evt.options.path = _this.evt.options.paths ? _this.evt.options.paths[0] : null; - - return _this._prompt() - .bind(_this) - .then(_this._validateAndPrepare) - .then(_this._request) - .then(function() { - - /** - * Return EVT - */ - - return _this.evt; - - }); - } - - /** - * Prompt key, stage and region - */ - _prompt() { - - let _this = this; - _this.evt = evt; - - return _this.cliPromptSelectStage('Select the stage you want to run endpoint from: ', _this.evt.options.stage, false) - .then(stage => { - _this.evt.options.stage = stage; - BbPromise.resolve(); - }) - .then(function(){ - return _this.cliPromptSelectRegion('Select the region you want to run endpoint from: ', false, true, _this.evt.options.region, _this.evt.options.stage) - .then(region => { - _this.evt.options.region = region; - BbPromise.resolve(); - }); - }); - - } - - _validateAndPrepare(){ - let _this = this; - - // non interactive validation - if (!_this.S.config.interactive) { - // Check Params - if (!_this.evt.options.stage || !_this.evt.options.region) { - return BbPromise.reject(new SError('Missing stage and/or region')); - } - } - - // validate stage: make sure stage exists - if (!_this.S.state.meta.get().stages[_this.evt.options.stage]) { - return BbPromise.reject(new SError('Stage ' + _this.evt.options.stage + ' does not exist in your project', SError.errorCodes.UNKNOWN)); - } - - // validate region: make sure region exists in stage - if (!_this.S.state.meta.get().stages[_this.evt.options.stage].regions[_this.evt.options.region]) { - return BbPromise.reject(new SError('Region "' + _this.evt.options.region + '" does not exist in stage "' + _this.evt.options.stage + '"')); - } - - _this.Endpoint = null; - - } - - _request(){ - let _this = this; - - let options = { - url: BASE_URL + endpoint + '?' + qs.stringify(params), - method: Endpoint.method, - json: true - }; - - request(options, function(error, response, body) { - if (response.statusCode != 200) - throw new Error(body.error + ' | Error Code: ' + body.code + ' | HTTP Code: ' + response.statusCode); - else - callback(body); - }); - - } - } - - return( EndpointRun ); -}; \ No newline at end of file diff --git a/lib/actions/FunctionCreate.js b/lib/actions/FunctionCreate.js index f5b297b8d..942d7c73d 100644 --- a/lib/actions/FunctionCreate.js +++ b/lib/actions/FunctionCreate.js @@ -146,27 +146,6 @@ usage: serverless function create `, )); } - // If subfolders are missing, create them - //if (_this.evt.options.sPath.split('/').length > 1) { - // let dir = _this.evt.options.sPath.split(path.sep); - // dir.pop(); - // let c = dir.shift(); - // if (dir[0] && !SUtils.dirExistsSync(_this.S.getProject().getFilePath(c, dir[0]))) { - // fs.mkdirSync(_this.S.getProject().getFilePath(c, dir[0])); - // } - // if (dir[1] && !SUtils.dirExistsSync(_this.S.getProject().getFilePath(c, dir[0], dir[1]))) { - // fs.mkdirSync(_this.S.getProject().getFilePath(c, dir[0], dir[1])); - // } - //} - - // If function already exists in component, throw error - //if (_this.S.getProject().getFunction( _this.evt.options.sPath )) { - // return BbPromise.reject(new SError( - // 'Function ' + _this.evt.options.sPath + ' already exists in this component', - // SError.errorCodes.INVALID_PROJECT_SERVERLESS - // )); - //} - return BbPromise.resolve(); }; @@ -176,9 +155,8 @@ usage: serverless function create `, _createFunction() { this.function = new this.S.classes.Function(this.S, this.evt.options.component, { - name: this.functionName, - rootPath: path.join(this.S.getProject().getRootPath(), this.evt.options.path) - }); + name: this.functionName + }, path.join(this.S.getProject().getRootPath(), this.evt.options.path)); this.evt.options.component.setFunction( this.function ); this.evt.data.path = this.evt.options.path; return this.function.save(); diff --git a/lib/actions/FunctionDeploy.js b/lib/actions/FunctionDeploy.js index f8522171b..5a56d93eb 100644 --- a/lib/actions/FunctionDeploy.js +++ b/lib/actions/FunctionDeploy.js @@ -75,7 +75,7 @@ module.exports = function(SPlugin, serverlessPath) { ], parameters: [ { - parameter: 'functionNames', // Only accepting paths makes it easier for plugin developers. Otherwise, people should use dash deploy + parameter: 'names', // Only accepting paths makes it easier for plugin developers. Otherwise, people should use dash deploy description: 'One or multiple function names', position: '0->' } @@ -174,7 +174,7 @@ module.exports = function(SPlugin, serverlessPath) { // Set Defaults _this.functions = []; - _this.evt.options.functionNames = _this.evt.options.functionNames ? _this.evt.options.functionNames : []; + _this.evt.options.names = _this.evt.options.names ? _this.evt.options.names : []; _this.evt.options.stage = _this.evt.options.stage ? _this.evt.options.stage : null; _this.evt.options.aliasFunction = _this.evt.options.aliasFunction ? _this.evt.options.aliasFunction : null; @@ -182,12 +182,12 @@ module.exports = function(SPlugin, serverlessPath) { _this.project = _this.S.getProject(); // Set Deploy Regions - _this.regions = _this.evt.options.region ? [_this.evt.options.region] : _this.S.getProject().getAllRegions(_this.evt.options.stage); + _this.regions = _this.evt.options.region ? [_this.evt.options.region] : _this.S.getProject().getAllRegions(_this.evt.options.stage).map(r => {return r.name;}); - if (_this.evt.options.functionNames.length) { - _this.evt.options.functionNames.forEach(function(functionName) { - _this.functions.push(_this.project.getFunction(functionName)); + if (_this.evt.options.names.length) { + _this.evt.options.names.forEach(function(name) { + _this.functions.push(_this.project.getFunction(name)); }); } @@ -196,7 +196,7 @@ module.exports = function(SPlugin, serverlessPath) { // If CLI and no function names targeted, deploy from CWD if (_this.S.cli && - !_this.evt.options.functionNames.length && + !_this.evt.options.names.length && !_this.evt.options.all) { if(cwdType.function) { @@ -214,8 +214,8 @@ module.exports = function(SPlugin, serverlessPath) { } // Ensure tmp folder exists in _meta - if (!SUtils.dirExistsSync(path.join(_this.S._projectPath, '_meta', '_tmp'))) { - fse.mkdirSync(path.join(_this.S._projectPath, '_meta', '_tmp')); + if (!SUtils.dirExistsSync(path.join(_this.S.getProject().getRootPath(), '_meta', '_tmp'))) { + fse.mkdirSync(path.join(_this.S.getProject().getRootPath(), '_meta', '_tmp')); } return BbPromise.resolve(); @@ -269,7 +269,7 @@ module.exports = function(SPlugin, serverlessPath) { * - Package must be redone for each region because ENV vars and IAM Roles are set for each region */ - async.eachLimit(_this.evt.options.functions, 5, function(func, cb) { + async.eachLimit(_this.functions, 5, function(func, cb) { return BbPromise.try(function() { @@ -277,7 +277,7 @@ module.exports = function(SPlugin, serverlessPath) { options: { stage: _this.evt.options.stage, region: region, - functionName: func.name + name: func.name } }; @@ -289,7 +289,7 @@ module.exports = function(SPlugin, serverlessPath) { options: { stage: result.options.stage, region: result.options.region, - functionName: func.name, + name: func.name, pathDist: result.data.pathDist, pathsPackaged: result.data.pathsPackaged } @@ -336,7 +336,7 @@ module.exports = function(SPlugin, serverlessPath) { _removeTmpFolder() { if (!this.evt.options.dontRemoveTmp) { - return fse.removeAsync(path.join(_this.S._projectPath, '_meta', '_tmp')); + return fse.removeAsync(path.join(this.S.getProject().getRootPath(), '_meta', '_tmp')); } else { SCli.log('Skipping `_tmp` folder removal'); } diff --git a/lib/actions/FunctionLogs.js b/lib/actions/FunctionLogs.js index 7c755f36d..5abd72a09 100644 --- a/lib/actions/FunctionLogs.js +++ b/lib/actions/FunctionLogs.js @@ -74,8 +74,8 @@ module.exports = function(SPlugin, serverlessPath) { ], parameters: [ { - parameter: 'functionName', - description: 'Name of the function you want get logs from (componentName/functionName)', + parameter: 'name', + description: 'Name of the function you want get logs for', position: '0' } ] @@ -108,18 +108,18 @@ module.exports = function(SPlugin, serverlessPath) { if (!this.evt.options.pollInterval) this.evt.options.pollInterval = 1000; if (!this.evt.options.duration) this.evt.options.duration = '5m'; - if (this.S.cli && !this.evt.options.functionName) { + if (this.S.cli && !this.evt.options.name) { - if(cwdType.function) { - this.function = this.project.getFunction(cwdType.function); - } else { + if (!SUtils.fileExistsSync(path.join(process.cwd(), 's-function.json'))) { throw new SError(`You must be in a function folder to run this command`); } + + this.evt.options.name = process.cwd().split(path.sep)[process.cwd().split(path.sep).length - 1]; } - if (!this.S.cli && !this.evt.options.functionName) throw new SError(`Please provide a function name as a parameter`); - + if (!this.S.cli && !this.evt.options.name) throw new SError(`Please provide a function name as a parameter`); + this.function = this.S.getProject().getFunction(this.evt.options.name); this.spinner = SCli.spinner(); diff --git a/lib/actions/FunctionRun.js b/lib/actions/FunctionRun.js index 9a4dbafaa..34e3d1242 100644 --- a/lib/actions/FunctionRun.js +++ b/lib/actions/FunctionRun.js @@ -56,8 +56,8 @@ module.exports = function(SPlugin, serverlessPath) { ], parameters: [ { - parameter: 'path', - description: 'Path of the function you want to run (componentName/functionName)', + parameter: 'name', + description: 'The name of the function you want to run', position: '0' } ] @@ -97,26 +97,19 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; // If CLI and path is not specified, deploy from CWD if Function - if (_this.S.cli && !_this.evt.options.path) { + if (_this.S.cli && !_this.evt.options.name) { // Get all functions in CWD - let sPath = _this.getSPathFromCwd(_this.S.getProject().getFilePath()); - if (!sPath || sPath.split('/').length == 1) { - return BbPromise.reject(new SError(`You must be in a function folder to run it`)); + if (!SUtils.fileExistsSync(path.join(process.cwd(), 's-function.json'))) { + return BbPromise.reject(new SError('You must be in a function folder to run it')); } - _this.evt.options.path = sPath; + _this.evt.options.name = process.cwd().split(path.sep)[process.cwd().split(path.sep).length - 1]; } - // strip trailing slashes from path - _this.evt.options.path = _this.evt.options.path.replace(/\/$/, ""); - let funcs = _this.S.getProject().getAllFunctions({ paths: [ _this.evt.options.path ]}); - if (funcs.length > 1) { - return BbPromise.reject(new SError(`You must be in a function folder to run it`)); - } - _this.function = funcs[0]; + _this.function = _this.S.getProject().getFunction(_this.evt.options.name); // Missing function - if (!_this.function) return BbPromise.reject(new SError('Function could not be found at the path specified.')); + if (!_this.function) return BbPromise.reject(new SError(`Function ${_this.evt.options.name} does not exist in your project.`)); return BbPromise.resolve(); } @@ -132,7 +125,7 @@ module.exports = function(SPlugin, serverlessPath) { let newOptions = { options: { - path: _this.evt.options.path + name: _this.evt.options.name } }; @@ -152,7 +145,7 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt.options.invocationType = _this.evt.options.invocationType || 'RequestResponse'; - _this.evt.options.region = _this.evt.options.region || _this.S.getProject().getAllRegions(_this.evt.options.stage)[0]; + _this.evt.options.region = _this.evt.options.region || _this.S.getProject().getAllRegions(_this.evt.options.stage)[0].name; if (_this.evt.options.invocationType !== 'RequestResponse') { _this.evt.options.logType = 'None'; @@ -161,12 +154,12 @@ module.exports = function(SPlugin, serverlessPath) { } // validate stage: make sure stage exists - if (_this.S.getProject().getStages().indexOf(_this.evt.options.stage) == -1) { + if (!_this.S.getProject().validateStageExists(_this.evt.options.stage)) { return BbPromise.reject(new SError('Stage ' + _this.evt.options.stage + ' does not exist in your project', SError.errorCodes.UNKNOWN)); } // validate region: make sure region exists in stage - if (_this.evt.options.region && !_this.S.getProject().getAllRegions(_this.evt.options.stage).indexOf(_this.evt.options.region) == -1) { + if (!_this.S.getProject().validateRegionExists(_this.evt.options.stage, _this.evt.options.region)) { return BbPromise.reject(new SError('Region "' + _this.evt.options.region + '" does not exist in stage "' + _this.evt.options.stage + '"')); } @@ -177,7 +170,7 @@ module.exports = function(SPlugin, serverlessPath) { // ClientContext: new Buffer(JSON.stringify({x: 1, y: [3,4]})).toString('base64'), InvocationType: _this.evt.options.invocationType, LogType: _this.evt.options.logType, - Payload: new Buffer(JSON.stringify(require(path.join(_this.function.getFullPath(), 'event')))), + Payload: new Buffer(JSON.stringify(require(path.join(_this.function.getRootPath(), 'event')))), Qualifier: _this.evt.options.stage }; diff --git a/lib/actions/FunctionRunLambdaNodeJs.js b/lib/actions/FunctionRunLambdaNodeJs.js index 2f43959db..a825ae479 100644 --- a/lib/actions/FunctionRunLambdaNodeJs.js +++ b/lib/actions/FunctionRunLambdaNodeJs.js @@ -43,12 +43,12 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt = evt; - if (!_this.evt.options.path || _this.evt.options.path.split('/').length < 2) { - return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/function .')); + if (!_this.evt.options.name) { + return BbPromise.reject(new SError('Please provide a function name to run')); } - // Instantiate Classes - _this.function = _this.S.getProject().getFunction( _this.evt.options.path ); + + _this.function = _this.S.getProject().getFunction( _this.evt.options.name ); // Prepare result object _this.evt.data.result = { status: false }; @@ -56,18 +56,20 @@ module.exports = function(SPlugin, serverlessPath) { // Run Function return new BbPromise(function(resolve) { - SCli.log(`Running ${_this.function._config.sPath}...`); + SCli.log(`Running ${_this.evt.options.name}...`); try { // Load function file & handler let functionFile = _this.function.handler.split('/').pop().split('.')[0]; let functionHandler = _this.function.handler.split('/').pop().split('.')[1]; - functionFile = path.join(_this.function._config.fullPath, (functionFile + '.js')); + functionFile = path.join(process.cwd(), _this.function.getRootPath(), (functionFile + '.js')); functionHandler = require(functionFile)[functionHandler]; + + // Fire function - let functionEvent = SUtils.readAndParseJsonSync(path.join(_this.function._config.fullPath, 'event.json')); + let functionEvent = SUtils.readAndParseJsonSync(path.join(_this.function.getRootPath(), 'event.json')); functionHandler(functionEvent, context(_this.function.name, function (err, result) { SCli.log(`-----------------`); diff --git a/lib/actions/FunctionRunLambdaPython2.js b/lib/actions/FunctionRunLambdaPython2.js index 558bcaadb..cf790ec75 100644 --- a/lib/actions/FunctionRunLambdaPython2.js +++ b/lib/actions/FunctionRunLambdaPython2.js @@ -43,12 +43,12 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt = evt; - if (!_this.evt.options.path || _this.evt.options.path.split('/').length < 2) { - return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/function .')); + if (!_this.evt.options.name) { + return BbPromise.reject(new SError('Please provide a function name to run')); } // Instantiate Classes - _this.function = _this.S.getProject().getFunction( _this.evt.options.path ); + _this.function = _this.S.getProject().getFunction( _this.evt.options.name ); // Prepare result object _this.evt.data.result = { status: false }; @@ -56,7 +56,7 @@ module.exports = function(SPlugin, serverlessPath) { // Run Function return new BbPromise(function(resolve) { - SCli.log(`Running ${_this.function._config.sPath}...`); + SCli.log(`Running ${_this.evt.options.name}...`); try { @@ -64,8 +64,7 @@ module.exports = function(SPlugin, serverlessPath) { let functionFile = _this.function.handler.split('/').pop().split('.')[0]; let functionHandler = _this.function.handler.split('/').pop().split('.')[1]; let functionEvent = SUtils.readAndParseJsonSync(path.join(_this.function.getFullPath(), 'event.json')); - - functionFile = path.join(_this.function.getFullPath(), (functionFile + '.py')); + functionFile = path.join(process.cwd(), _this.function.getRootPath(), (functionFile + '.py')); var child = spawnSync( "serverless-run-python-handler",