From 68c22bac1332f4128852e0c34c0576801bf03899 Mon Sep 17 00:00:00 2001 From: Pavel Denisjuk Date: Wed, 23 Oct 2019 12:32:34 +0200 Subject: [PATCH 1/3] fix: handle a case when "then" is called on a defaultObject thus breaking the execution. --- serverless.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/serverless.js b/serverless.js index 602edbe..baf6e49 100644 --- a/serverless.js +++ b/serverless.js @@ -18,6 +18,11 @@ class Template extends Component { return new Proxy(defaultFunction, { get: (obj, prop) => { + // This handles the weird case when `then` is called on the `defaultFunction` + if (prop === 'then') { + return obj[prop] + } + if (obj.hasOwnProperty(prop)) { return obj[prop] } From a82e9617989ddd8360f6be3dde30dd866969a9b7 Mon Sep 17 00:00:00 2001 From: Pavel Denisjuk Date: Wed, 23 Oct 2019 12:33:00 +0200 Subject: [PATCH 2/3] fix: ensure template is a proper object before fetching components. --- utils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utils.js b/utils.js index 8c37d2c..791399e 100644 --- a/utils.js +++ b/utils.js @@ -353,8 +353,12 @@ const createCustomMethodHandler = (instance, method) => { instance.context.debug( `Attempting to run method "${method}" on template aliases: ${components.join(', ')}` ) + + // Make sure the template is an object + const templateObject = await getTemplate({ template }) + // Load template components - const templateComponents = await getAllComponents(template) + const templateComponents = await getAllComponents(templateObject) // Get only the requested components ("component" input) const componentsToRun = Object.keys(templateComponents) From af70e317e70349f6d7c9254fc2565f20a813cd49 Mon Sep 17 00:00:00 2001 From: Pavel Denisjuk Date: Wed, 23 Oct 2019 12:33:19 +0200 Subject: [PATCH 3/3] doc: add a README file with a few examples. --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/README.md b/README.md index c296a5f..f9ee729 100644 --- a/README.md +++ b/README.md @@ -1 +1,90 @@ # Template + +This component is used behind the scenes to deploy your YAML templates. It is loaded by the serverless CLI and executed just as any other component. +However, there's a lot you can do with this component programmatically. See the sections below for some examples. + +### Programmatic usage and custom environments + +To deploy to multiple environments you must utilize the programmatic API, via `serverless.js` file. + +`serverless.js` + +```js +const { Component } = require('@serverless/core') + +class Deploy extends Component { + async default(inputs = {}) { + const { env } = inputs + + const template = await this.load('@serverless/template', env) + return await template({ template: __dirname + '/serverless.yml' }) + } + + async remove(inputs = {}) { + const { env } = inputs + + const template = await this.load('@serverless/template', env) + await template.remove(inputs) + } +} + +module.exports = Deploy +``` + +`serverless.yml` + +```yml +name: test + +lambda: + component: '@serverless/function' + inputs: + name: my-function + description: My Serverless Function + memory: 128 + timeout: 20 + code: './code' + hanlder": 'handler.handler' + region: us-east-1 + runtime: nodejs10.x +``` + +Invoking `sls --env=dev` will result in state files in `.serverless/` being prefixed with the value of your `env`: +`Deploy.dev.json`, etc. That way you can deploy unlimited environments, add pre/post processing, load whatever `.env` you need, etc. + +### Running custom methods on a template + +A template itself does not contain any methods so custom methods are executed on the specific template aliases. + +`sls install --component lambda` will load the `lambda` alias from your template, instantiate the corresponding component, and execute the `install` method passing in the inputs you specify via CLI parameters. +Inputs from the template itself are not passed as they can not be interpreted/resolved without running the entire template. + +You can pass as many `--component` parameters as you need. + +### Running custom methods programmatically + +`serverless.js` + +```js +const { Component } = require('@serverless/core') + +class Deploy extends Component { + /* ...skipped default method for brevity ... */ + + async install(inputs = {}) { + const template = await this.load('@serverless/template') + await template.install({ template: __dirname + '/serverless.yml', ...inputs }) + } +} + +module.exports = Deploy +``` + +When invoking methods on a `template` instance, you always need to pass in a path to the template file or a template object. + +Running `sls install --component lambda --debug` - this will load the template, find the `lambda` alias, and invoke the `install` method on the instance of the component. + +### Couldn't find what you were looking for? + +Visit our github and file an issue with as much info as possible about your problem. +If you think you've found a bug - please do post a complete reproduction repo. It will help us and our contributors to help you much faster.