diff --git a/lib/ServerlessComponent.js b/lib/ServerlessComponent.js index ab22a109c..cff022686 100644 --- a/lib/ServerlessComponent.js +++ b/lib/ServerlessComponent.js @@ -71,6 +71,22 @@ class ServerlessComponent { componentJson, componentContents; + // Helper to instantiate functions + let loadFn = function(cPath, fnName) { + let func = new _this._S.classes.Function(_this._S, { + component: _this._config.component, + cPath: cPath ? cPath : null, + function: fnName + }); + + return func.load() + .then(function(instance) { + componentJson.functions[m]= instance; + return componentJson.functions[m]; + }); + }; + + // Load component, then traverse component dirs to get all functions return BbPromise.try(function() { // Validate: Check project path is set @@ -87,22 +103,37 @@ class ServerlessComponent { return componentContents; }) - .each(function(m, i) { + .each(function(f, i) { + + // Skip node_modules and lib + if (['node_modules', 'lib'].indexOf(f.trim() == -1) return; + + // If s-function.json doesn't exist, look in 2 subfolders + if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, componentContents[i], 's-function.json'))) { + + let sfOne = fs.readdirSync(path.join(_this._config.fullPath, componentContents[i])); + + return BbPromise.resolve(sfOne) + .each(function(sf1, i) { + + if (!SUtils.fileExistsSync(path.join( + _this._config.fullPath, + componentContents[i], + sf1, + 's-function.json'))) return; + }); + + } + + + + + + + - if (!SUtils.fileExistsSync(path.join( - _this._config.fullPath, componentContents[i], - 's-function.json'))) return; - let func = new _this._S.classes.Function(_this._S, { - component: _this._config.component, - module: m - }); - return func.load() - .then(function(instance) { - componentJson.functions[m]= instance; - return componentJson.functions[m]; - }); }) .then(function() { diff --git a/lib/ServerlessEndpoint.js b/lib/ServerlessEndpoint.js index 5e75a7671..cb3b9fe5f 100644 --- a/lib/ServerlessEndpoint.js +++ b/lib/ServerlessEndpoint.js @@ -21,7 +21,7 @@ class ServerlessEndpoint { constructor(Serverless, config) { // Validate required attributes - if (!config.component || !config.function || !config.endpointPath || !config.endpointMethod) throw new SError('Missing required config.component, config.module, config.function, config.endpointMethod, config.endpointPath'); + if (!config.component || !config.function || !config.endpointPath || !config.endpointMethod) throw new SError('Missing required config.component, config.function, config.endpointMethod, config.endpointPath'); // Private properties let _this = this; @@ -63,15 +63,15 @@ class ServerlessEndpoint { // Set sPath if (config.component || config.function || config.endpointPath || config.endpointMethod) { this._config.component = config.component; - this._config.module = config.module; + this._config.cPath = config.cPath ? config.cPath : null; this._config.function = config.function; this._config.endpointPath = config.endpointPath; this._config.endpointMethod = config.endpointMethod; this._config.type = config.type ? config.type : 'AWS'; this._config.sPath = SUtils.buildSPath({ - component: config.component, - module: config.module, - function: config.function, + component: config.component, + cPath: config.cPath, + function: config.function, endpointPath: config.endpointPath, endpointMethod: config.endpointMethod }); @@ -80,7 +80,12 @@ class ServerlessEndpoint { // Make full path if (this._S.config.projectPath && this._config.sPath) { let parse = SUtils.parseSPath(this._config.sPath); - this._config.fullPath = path.join(this._S.config.projectPath, parse.component, parse.module, parse.function); + this._config.fullPath = path.join( + this._S.config.projectPath, + parse.component, + parse.cPath ? parse.cPath.split('/').join(path.sep) : null, + parse.function + ); } } @@ -129,7 +134,6 @@ class ServerlessEndpoint { */ set(data) { - // Merge _.assign(this, data); return this; @@ -258,7 +262,7 @@ class ServerlessEndpoint { let functions = this._S.state.getFunctions({ component: this._config.component, - module: this._config.module, + cPath: this._config.cPath, function: this._config.function }); diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index 83fbd51f9..13a0cfe2e 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -2,8 +2,10 @@ /** * Serverless Function Class - * - options.path format is: "componentPath/functionFolder - * - + * - options.path format is: "component/cPath/functionFolder" + * - cPath is for component path. You can nest functions in any amounts of subfolders (these subfolders are the cPath) + * - But you must use '/' to divide subfolders. E.g., restApi/data/users/show + * - In the example, data/users is the component path. The 'cPath' */ const SError = require('./ServerlessError'),