FunctionDeploy: Fix CLI support, ModuleCreate: Use 'serverless-helpers-js' and auto-nom-install on creation

This commit is contained in:
Austen Collins 2015-12-07 09:10:05 -08:00
parent 7703ac10d6
commit 2aa69719fd
24 changed files with 249 additions and 680 deletions

View File

@ -104,36 +104,24 @@ class Packager {
_validateAndPrepare(evt) {
let _this = this;
// Skip Function if it does not have a lambda
if (!evt.function.cloudFormation ||
!evt.function.cloudFormation.lambda ||
!evt.function.cloudFormation.lambda.Function) {
throw new SError(evt.function.name + 'does not have a lambda property');
}
// Get Function JSON
return SUtils.getFunctions(
path.join(_this.S._projectRootPath, 'back', 'modules'),
[evt.function])
.then(function(functionJsons) {
// Validate lambda attributes
let lambda = evt.function.cloudFormation.lambda;
if (!lambda.Function.Type
|| !lambda.Function
|| !lambda.Function.Properties
|| !lambda.Function.Properties.Runtime
|| !lambda.Function.Properties.Handler) {
throw new SError('Missing required lambda attributes');
}
// Attach to evt
evt.function = functionJsons[0];
// Skip Function if it does not have a lambda
if (!evt.function.cloudFormation ||
!evt.function.cloudFormation.lambda ||
!evt.function.cloudFormation.lambda.Function) {
throw new SError(evt.function.name + 'does not have a lambda property');
}
// Validate lambda attributes
let lambda = evt.function.cloudFormation.lambda;
if (!lambda.Function.Type
|| !lambda.Function
|| !lambda.Function.Properties
|| !lambda.Function.Properties.Runtime
|| !lambda.Function.Properties.Handler) {
throw new SError('Missing required lambda attributes');
}
return evt;
});
return BbPromise.resolve(evt);
}
/**
@ -250,8 +238,7 @@ class Packager {
_optimize(evt) {
let _this = this,
lambda = evt.function.cloudFormation.lambda;
let _this = this;
if (!evt.function.package.optimize
|| !evt.function.package.optimize.builder) {
@ -368,6 +355,7 @@ class Packager {
return new BbPromise(function(resolve, reject) {
b.bundle(function(err, bundledBuf) {
if (err) {
console.error('Error running browserify bundle');
reject(err);

View File

@ -69,53 +69,41 @@ class EndpointPackageApiGateway extends SPlugin {
_validateAndPrepare(evt) {
let _this = this;
// If endpoint properties are missing, skip
if (!evt.function.cloudFormation ||
!evt.function.cloudFormation.apiGateway ||
!evt.function.cloudFormation.apiGateway.Endpoint) {
throw new SError(evt.function.name + ' does not have required apiGateway properties');
}
// Get Function JSON and validate Endpoint(s)
return SUtils.getFunctions(
_this.S._projectRootPath,
[evt.function])
.then(function(functionJsons) {
evt.endpoints = evt.function.cloudFormation.apiGateway.Endpoint;
// Attach to evt
evt.function = functionJsons[0];
// Endpoint property can be an array to support multiple endpoints per function
// Convert endpointJson to array, if it's not already
if (!Array.isArray(evt.endpoints)) evt.endpoints = [evt.endpoints];
// If endpoint properties are missing, skip
if (!evt.function.cloudFormation ||
!evt.function.cloudFormation.apiGateway ||
!evt.function.cloudFormation.apiGateway.Endpoint) {
throw new SError(evt.function.name + ' does not have required apiGateway properties');
}
// Validate all evt.endpoints
for (let i = 0; i < evt.endpoints.length;i++) {
evt.endpoints = evt.function.cloudFormation.apiGateway.Endpoint;
let e = evt.endpoints[i];
// Endpoint property can be an array to support multiple endpoints per function
// Convert endpointJson to array, if it's not already
if (!Array.isArray(evt.endpoints)) evt.endpoints = [evt.endpoints];
// Validate and sanitize endpoint attributes
if (!e.Type
|| !e.Path
|| !e.Method
|| !e.AuthorizationType
|| typeof e.ApiKeyRequired === 'undefined') {
return BbPromise.reject(new SError('Missing one of many required endpoint attributes: Type, Path, Method, AuthorizationType, ApiKeyRequired'));
}
// Validate all evt.endpoints
for (let i = 0; i < evt.endpoints.length;i++) {
// Sanitize path
if (e.Path.charAt(0) === '/') e.Path = e.Path.substring(1);
let e = evt.endpoints[i];
// Sanitize method
e.Method = e.Method.toUpperCase();
}
// Validate and sanitize endpoint attributes
if (!e.Type
|| !e.Path
|| !e.Method
|| !e.AuthorizationType
|| typeof e.ApiKeyRequired === 'undefined') {
return BbPromise.reject(new SError('Missing one of many required endpoint attributes: Type, Path, Method, AuthorizationType, ApiKeyRequired'));
}
// Sanitize path
if (e.Path.charAt(0) === '/') e.Path = e.Path.substring(1);
// Sanitize method
e.Method = e.Method.toUpperCase();
}
return evt;
});
return BbPromise.resolve(evt);
}
/**

View File

@ -101,15 +101,37 @@ class FunctionDeploy extends SPlugin {
functionDeploy(event) {
let _this = this;
let evt = {};
evt.type = event.type ? event.type : null;
evt.stage = event.stage ? event.stage : null;
evt.regions = event.region ? [event.region] : [];
evt.paths = event.paths ? event.paths : [];
evt.all = event.all ? event.all : null;
evt.aliasEndpoint = event.aliasEndpoint ? event.aliasEndpoint : null;
evt.aliasFunction = event.aliasFunction ? event.aliasFunction : null;
let _this = this,
evt = {};
// If CLI, parse options
if (_this.S.cli) {
// Options
evt = this.S.cli.options;
// Option - Non-interactive
if (_this.S.cli.options.nonInteractive) _this.S._interactive = false
// Type - Should be first in array
if (_this.S.cli.params.length) evt.type = _this.S.cli.params[0];
// Function paths - They should be all other array items
_this.S.cli.params.splice(0,1);
evt.paths = _this.S.cli.params;
}
// If NO-CLI, add options
if (event) evt = event;
// Add defaults
evt.type = evt.type ? evt.type : 'code';
evt.stage = evt.stage ? evt.stage : null;
evt.regions = evt.region ? [evt.region] : [];
evt.paths = evt.paths ? evt.paths : [];
evt.all = evt.all ? true : false;
evt.aliasEndpoint = evt.aliasEndpoint ? evt.aliasEndpoint : null;
evt.aliasFunction = evt.aliasFunction ? evt.aliasFunction : null;
evt.functions = [];
evt.deployed = {};
evt.failed = {};
@ -118,6 +140,7 @@ class FunctionDeploy extends SPlugin {
return _this._validateAndPrepare(evt)
.bind(_this)
.then(_this._promptStage)
.then(_this._prepareRegions)
.then(_this._processDeployment)
.then(function(evt) {
return evt;
@ -133,27 +156,18 @@ class FunctionDeploy extends SPlugin {
let _this = this;
// If CLI, parse command line input and validate
if (_this.S.cli) {
// Add Options
evt = _this.S.cli.options;
// Add type. Should be first in array
evt.type = _this.S.cli.params[0];
// Add function paths. Should be all other array items
_this.S.cli.params.splice(0,1);
evt.paths = _this.S.cli.params;
}
// If NO-CLI, validate
// If NO-CLI, validate paths
if (!_this.S.cli) {
// Check if paths or all is not used
// Validate Paths
if (!evt.paths.length && !evt.all) {
throw new SError(`One or multiple paths are required`);
}
// Validate Stage
if (!evt.stage) {
throw new SError(`Stage is required`);
}
}
// Validate type
@ -164,46 +178,38 @@ class FunctionDeploy extends SPlugin {
throw new SError(`Invalid type. Must be "code", "endpoint", or "both" `);
}
// Validate stage
if (!evt.stage) {
throw new SError(`Stage is required`);
}
// Get Functions From Paths
// If no region specified, deploy to all regions in stage
if (!evt.regions.length) {
evt.regions = _this.S._projectJson.stages[evt.stage].map(rCfg => {
return rCfg.region;
});
}
SUtils.sDebug('Queued regions: ' + evt.regions);
// If CLI and paths are missing, get paths from CWD, and return
if (_this.S.cli) {
if (!evt.paths || !evt.paths.length) {
// If CLI and no paths, get full paths from CWD
return SUtils.getFunctions(
evt.all ? _this.S._projectRootPath : process.cwd(),
null)
.then(function(functions) {
// If CLI & paths, get functions
// If CLI & no paths, get full paths from CWD
if (!functions.length) throw new SError(`No functions found`);
return SUtils.getFunctions(
evt.all ? _this.S._projectRootPath : process.cwd(),
evt.paths && evt.paths.length ? evt.paths : null)
.then(function(functions) {
if (!functions.length) throw new SError(`No functions found`);
evt.functions = functions;
// Delete Paths
if (evt.paths) delete evt.paths;
return evt;
});
} else {
// If NO-CLI, resolve full paths from submitted paths
return SUtils.getFunctions(
_this.S._projectRootPath,
evt.all ? null : evt.paths)
.then(function(functions) {
evt.functions = functions;
// Delete Paths
if (evt.paths) delete evt.paths;
return evt;
});
evt.functions = functions;
return evt;
});
}
}
// Otherwise, resolve full paths
return SUtils.getFunctions(
_this.S._projectRootPath,
evt.all ? null : evt.paths)
.then(function(functions) {
evt.functions = functions;
return evt;
});
}
/**
@ -212,19 +218,17 @@ class FunctionDeploy extends SPlugin {
_promptStage(evt) {
let _this = this,
stages = [];
let _this = this;
if (!evt.stage) {
// If user provided stage, skip prompt
if (evt.stage) return BbPromise.resolve(evt);
stages = Object.keys(_this.S._projectJson.stage);
// Collect project stages
let stages = Object.keys(_this.S._projectJson.stages);
// If project only has 1 stage, skip prompt
if (stages.length === 1) evt.stage = stages[0];
} else {
// If user provided stage, skip prompt
// If project only has 1 stage, skip prompt
if (stages.length === 1) {
evt.stage = stages[0];
return BbPromise.resolve(evt);
}
@ -246,6 +250,22 @@ class FunctionDeploy extends SPlugin {
});
}
/**
* Prepare Regions
*/
_prepareRegions(evt) {
// If no region specified, deploy to all regions in stage
if (!evt.regions.length) {
evt.regions = this.S._projectJson.stages[evt.stage].map(rCfg => {
return rCfg.region;
});
}
return evt;
}
/**
* Process Deployment
*/
@ -254,6 +274,9 @@ class FunctionDeploy extends SPlugin {
let _this = this;
// Status
SCli.log('Deploying in "' + evt.stage + '" to the following regions: ' + evt.regions);
return BbPromise.try(function() {
return evt.regions;
})
@ -270,9 +293,11 @@ class FunctionDeploy extends SPlugin {
endpoints: [],
};
//Deploy Function Code in each region
// Deploy Function Code in each region
if (['code', 'both'].indexOf(evt.type) > -1) {
// Status
SCli.log('"' + evt.stage + ' - ' + region + '": Deploying function code...');
return _this._deployCodeByRegion(evt, region);
}
})
@ -281,11 +306,11 @@ class FunctionDeploy extends SPlugin {
})
.each(function(region) {
/**
* Deploy Function Endpoints in each region
*/
// Deploy Function Endpoints in each region
if (['endpoint', 'both'].indexOf(evt.type) > -1) {
// Status
SCli.log('"' + evt.stage + ' - ' + region + '" - Deploying function endpoints...');
return _this._deployEndpointsByRegion(evt, region)
}
})
@ -318,7 +343,7 @@ class FunctionDeploy extends SPlugin {
_this.S._projectJson,
evt.stage,
region),
function: func.path,
function: func,
};
// Process sub-Actions
@ -368,7 +393,7 @@ class FunctionDeploy extends SPlugin {
_this.S._projectJson,
evt.stage,
region),
function: func.path,
function: func,
aliasEndpoint: evt.aliasEndpoint,
};

View File

@ -125,8 +125,7 @@ usage: serverless module create`,
.then(_this._createModuleSkeleton)
.then(_this._installFunctionDependencies)
.then(function() {
SCli.log('Successfully created ' + _this.evt.module + '/' + _this.evt.function);
SCli.log('Successfully created new serverless module "' + _this.evt.module + '" with its first function "' + _this.evt.function + '"');
// Return Event
return _this.evt;
});
@ -243,29 +242,21 @@ usage: serverless module create`,
// Save Paths
_this.evt.modulePath = path.join(this.S._projectRootPath, 'back', 'modules', _this.evt.module);
_this.evt.functionPath = path.join(_this.evt.modulePath, _this.evt.function);
_this.evt.functionPath = path.join(_this.evt.modulePath, _this.evt.function);
// Prep package.json
packageJsonTemplate.name = _this.evt.module;
packageJsonTemplate.description = 'A serverless module';
packageJsonTemplate.dependencies = {};
packageJsonTemplate.description = 'Dependencies for a Serverless Module written in Node.js';
// Write base module structure
writeDeferred.push(
fs.mkdirSync(_this.evt.modulePath),
fs.mkdirSync(path.join(_this.evt.modulePath, 'lib')),
fs.mkdirSync(path.join(_this.evt.modulePath, 'package')),
fs.mkdirSync(path.join(_this.evt.modulePath, 'package', 'functions')),
fs.mkdirSync(path.join(_this.evt.modulePath, 'node_modules')),
SUtils.writeFile(path.join(_this.evt.modulePath, 'package.json'), JSON.stringify(packageJsonTemplate, null, 2)),
SUtils.writeFile(path.join(_this.evt.modulePath, 's-module.json'), JSON.stringify(moduleJsonTemplate, null, 2))
);
// Copy NPM Dependencies
wrench.copyDirSyncRecursive(
path.join(_this._templatesDir, 'nodejs', 'dotenv'),
path.join(_this.evt.modulePath, 'node_modules', 'dotenv')
);
// Write module/function structure
writeDeferred.push(
@ -295,6 +286,7 @@ usage: serverless module create`,
*/
_generateFunctionJson() {
let _this = this;
let functionJsonTemplate = SUtils.readAndParseJsonSync(path.join(this._templatesDir, 's-function.json'));
@ -330,7 +322,9 @@ usage: serverless module create`,
};
_installFunctionDependencies() {
return SUtils.npmInstall(this.evt.modulePath);
SCli.log('Installing "serverless-helpers" for this module via NPM...');
SUtils.npmInstall(this.evt.modulePath);
return BbPromise.resolve();
}
}

View File

@ -124,7 +124,11 @@ class Serverless {
command(argv) {
SUtils.sDebug('command argv', argv);
// Set Debug to True
if (argv && argv.d) process.env.DEBUG = true;
SUtils.sDebug('Command raw argv: ', argv);
// Handle version command
if (argv._[0] === 'version') {
console.log(this._version);
@ -134,7 +138,7 @@ class Serverless {
let cmdContext = argv._[0],
cmdContextAction = argv._[1];
this.cli = {}; //options and args that the command was called with on the CLI so plugins can leverage
this.cli = {}; // Options and args that the command was called with on the CLI so plugins can leverage
if (argv._.length === 0 || argv._[0] === 'help' || argv._[0] === 'h') {
if (!this.commands[cmdContext]) {

View File

@ -1,198 +0,0 @@
# dotenv
<img src="https://raw.githubusercontent.com/motdotla/dotenv/master/dotenv.png" alt="dotenv" align="right" />
Dotenv loads environment variables from `.env` into `ENV` (process.env).
[![BuildStatus](https://img.shields.io/travis/motdotla/dotenv/master.svg?style=flat-square)](https://travis-ci.org/motdotla/dotenv)
[![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
> "Storing [configuration in the environment](http://www.12factor.net/config)
> is one of the tenets of a [twelve-factor app](http://www.12factor.net/).
> Anything that is likely to change between deployment environmentssuch as
> resource handles for databases or credentials for external servicesshould be
> extracted from the code into environment variables.
>
> But it is not always practical to set environment variables on development
> machines or continuous integration servers where multiple projects are run.
> Dotenv loads variables from a `.env` file into ENV when the environment is
> bootstrapped."
>
> [Brandon Keepers' Dotenv in Ruby](https://github.com/bkeepers/dotenv)
## Install
```bash
npm install dotenv --save
```
## Usage
As early as possible in your application, require and load dotenv.
```javascript
require('dotenv').load();
```
Create a `.env` file in the root directory of your project. Add
environment-specific variables on new lines in the form of `NAME=VALUE`.
For example:
```
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
```
That's it.
`process.env` now has the keys and values you defined in your `.env` file.
```javascript
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
});
```
### Preload
If you are using iojs-v1.6.0 or later, you can use the `--require` (`-r`) command line option to preload dotenv. By doing this, you do not need to require and load dotenv in your application code.
```bash
$ node -r dotenv/config your_script.js
```
The configuration options below are supported as command line arguments in the format `dotenv_config_<option>=value`
```bash
$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/your/env/vars
```
## Config
`config` will read your .env file, parse the contents, and assign it to
`process.env` - just like `load` does. You can additionally, pass options to
`config`.
Note: `config` and `load` are synonyms. You can pass options to either.
### Options
#### Silent
Default: `false`
Dotenv outputs a warning to your console if missing a `.env` file. Suppress
this warning using silent.
```js
require('dotenv').config({silent: true});
```
#### Path
Default: `.env`
You can specify a custom path if your file containing environment variables is
named or located differently.
```js
require('dotenv').config({path: '/custom/path/to/your/env/vars'});
```
#### Encoding
Default: `utf8`
You may specify the encoding of your file containing environment variables
using this option.
```js
require('dotenv').config({encoding: 'base64'});
```
## Parse
The engine which parses the contents of your file containing environment
variables is available to use. It accepts a String or Buffer and will return
an Object with the parsed keys and values.
```js
var dotenv = require('dotenv');
var buf = new Buffer('BASIC=basic');
var config = dotenv.parse(buf); // will return an object
console.log(typeof config, config) // object { BASIC : 'basic' }
```
### Rules
The parsing engine currently supports the following rules:
- `BASIC=basic` becomes `{BASIC: 'basic'}`
- empty lines are skipped
- lines beginning with `#` are treated as comments
- empty values become empty strings (`EMPTY=` becomes `{EMPTY: ''}`)
- single and double quoted values are escaped (`SINGLE_QUOTE='quoted'` becomes `{SINGLE_QUOTE: "quoted"}`)
- new lines are expanded if in double quotes (`MULTILINE="new\nline"` becomes
```
{MULTILINE: 'new
line'}
```
- inner quotes are maintained (think JSON) (`JSON={"foo": "bar"}` becomes `{JSON:"{\"foo\": \"bar\"}"`)
#### Expanding Variables
Basic variable expansion is supported.
```
BASIC=basic
TEST=$BASIC
```
Parsing that would result in `{BASIC: 'basic', TEST: 'basic'}`. You can escape
variables by quoting or beginning with `\` (e.g. `TEST=\$BASIC`). If the
variable is not found in the file, `process.env` is checked. Missing variables
result in an empty string.
```
BASIC=basic
TEST=$TEST
DNE=$DNE
```
```bash
TEST=example node -e 'require("dotenv").config();'
```
- `process.env.BASIC` would equal `basic`
- `process.env.TEST` would equal `example`
- `process.env.DNE` would equal `""`
## FAQ
### Should I commit my .env file?
No. We **strongly** recommend against committing your .env file to version
control. It should only include environment-specific values such as database
passwords or API keys. Your production database should have a different
password than your development database.
## Contributing
See [Contributing Guide](Contributing.md)
## Who's using dotenv
Here's just a few of many repositories using dotenv:
* [npm](https://github.com/npm/newww)
* [sendgrid-nodejs](https://github.com/sendgrid/sendgrid-nodejs)
* [handshake.js](https://github.com/handshakejs/handshakejs-api)
* [google-oauth2-service-account](https://github.com/jacoblwe20/google-oauth2-service-account)
* [kibble](https://github.com/motdotla/kibble)
* [github-streaker](https://github.com/motdotla/github-streaker)

View File

@ -1,11 +0,0 @@
(function () {
var options = {}
process.argv.forEach(function (val, idx, arr) {
var matches = val.match(/^dotenv_config_(.+)=(.+)/)
if (matches) {
options[matches[1]] = matches[2]
}
})
require('./lib/main').config(options)
})()

View File

@ -1,92 +0,0 @@
'use strict';
var fs = require('fs');
module.exports = {
/*
* Main entry point into dotenv. Allows configuration before loading .env and .env.$NODE_ENV
* @param {Object} options - valid options: path ('.env'), encoding ('utf8')
* @returns {Boolean}
*/
config: function (options) {
var path = '.env';
var encoding = 'utf8';
var silent = false;
if (options) {
if (options.silent) {
silent = options.silent
}
if (options.path) {
path = options.path
}
if (options.encoding) {
encoding = options.encoding
}
}
try {
// specifying an encoding returns a string instead of a buffer
var parsedObj = this.parse(fs.readFileSync(path, { encoding: encoding }));
Object.keys(parsedObj).forEach(function (key) {
process.env[key] = process.env[key] || parsedObj[key]
});
return true
} catch(e) {
if (!silent) {
console.error(e)
}
return false
}
},
/*
* Parses a string or buffer into an object
* @param {String|Buffer} src - source to be parsed
* @returns {Object}
*/
parse: function (src) {
var obj = {};
// convert Buffers before splitting into lines and processing
src.toString().split('\n').forEach(function (line) {
// matching "KEY' and 'VAL' in 'KEY=VAL'
var keyValueArr = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/);
// matched?
if (keyValueArr != null) {
var key = keyValueArr[1];
// default undefined or missing values to empty string
var value = keyValueArr[2] ? keyValueArr[2] : '';
// expand newlines in quoted values
var len = value ? value.length : 0;
if (len > 0 && value.charAt(0) === '\"' && value.charAt(len - 1) === '\"') {
value = value.replace(/\\n/gm, '\n')
}
// remove any surrounding quotes and extra spaces
value = value.replace(/(^['"]|['"]$)/g, '').trim();
// is this value a variable?
if (value.charAt(0) === '$') {
var possibleVar = value.substring(1);
value = obj[possibleVar] || process.env[possibleVar] || ''
}
// varaible can be escaped with a \$
if (value.substring(0, 2) === '\\$') {
value = value.substring(1)
}
obj[key] = value
}
});
return obj
}
};
module.exports.load = module.exports.config;

View File

@ -1,70 +0,0 @@
{
"name": "dotenv",
"version": "1.2.0",
"description": "Loads environment variables from .env file",
"main": "lib/main.js",
"scripts": {
"test": "lab test/* --coverage && standard",
"lint": "standard"
},
"repository": {
"type": "git",
"url": "git://github.com/motdotla/dotenv.git"
},
"keywords": [
"dotenv",
"env",
".env",
"environment",
"variables",
"config",
"settings"
],
"author": {
"name": "scottmotte"
},
"license": "BSD-2-Clause",
"devDependencies": {
"lab": "^5.3.0",
"semver": "^4.3.6",
"should": "4.4.2",
"sinon": "1.12.2",
"standard": "^2.10.0"
},
"dependencies": {},
"gitHead": "940d101b4df66157cf752b611fd2292060878b44",
"bugs": {
"url": "https://github.com/motdotla/dotenv/issues"
},
"homepage": "https://github.com/motdotla/dotenv#readme",
"_id": "dotenv@1.2.0",
"_shasum": "7cd73e16e07f057c8072147a5bc3a8677f0ab5c6",
"_from": "dotenv@^1.2.0",
"_npmVersion": "2.10.1",
"_nodeVersion": "1.2.0",
"_npmUser": {
"name": "jcblw",
"email": "jacoblowe2.0@gmail.com"
},
"maintainers": [
{
"name": "scottmotte",
"email": "scott@scottmotte.com"
},
{
"name": "jcblw",
"email": "jacoblowe2.0@gmail.com"
},
{
"name": "motdotla",
"email": "mot@mot.la"
}
],
"dist": {
"shasum": "7cd73e16e07f057c8072147a5bc3a8677f0ab5c6",
"tarball": "http://registry.npmjs.org/dotenv/-/dotenv-1.2.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-1.2.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -8,10 +8,10 @@
*/
// Require Serverless ENV vars
require('dotenv');
require('serverless-helpers-js');
// Require Logic
let controller = require('./lib');
var controller = require('../lib');
// Lambda Handler
module.exports.handler = function(event, context) {

View File

@ -4,7 +4,7 @@
module.exports.handler = function(event, cb) {
let response = {
var response = {
message: "Your Serverless Function ran successfully!"
};

View File

@ -12,6 +12,6 @@
"keywords": [],
"devDependencies": {},
"dependencies": {
"dotenv": "^1.2.0"
"serverless-helpers-js": "~0.0.3"
}
}

View File

@ -32,7 +32,7 @@ exports.asciiGreeting = function() {
art = art + '|____ |_____|__| \\___/|_____|__| |__|_____|_____|_____|' + os.EOL;
art = art + '| | | The Serverless Application Framework' + os.EOL;
art = art + '| | serverless.com, v.' + ver + os.EOL;
art = art + '`-------\'' + os.EOL;
art = art + '`-------\'';
console.log(chalk.yellow(art));
};

View File

@ -292,9 +292,9 @@ exports.endsWith = function(str, suffix) {
*/
exports.npmInstall = function(dir) {
process.chdir(dir);
if (exec('npm install ', {silent: false}).code !== 0) {
if (exec('npm install ', { silent: false }).code !== 0) {
throw new SError(`Error executing NPM install on ${dir}`, SError.errorCodes.UNKNOWN);
}
@ -325,10 +325,7 @@ exports.generateResourcesCf = function(projRootPath, projName, projDomain, stage
/**
* Write to console.log if process.env.DEBUG is true
*
* If we ever want to get more complicated with log levels we should use winston
*
* @param str
* - If we ever want to get more complicated with log levels we should use winston
*/
let debuggerCache = {};
@ -361,8 +358,6 @@ exports.isStageNameValid = function(stageName) {
/**
* Find Regional API
* - Finds a project REST API ID that already exists
* @param projectJawsJson
* @param regionName
*/
exports.findRegionalApi = function(projectJawsJson, regionName) {
@ -379,8 +374,6 @@ exports.findRegionalApi = function(projectJawsJson, regionName) {
/**
* Save Regional API
* - Saves regional API to all stage that have this region
* @param projectJawsJson
* @param regionName
*/
exports.saveRegionalApi = function(projectJawsJson, regionName, restApiId, rootPath) {
@ -425,7 +418,7 @@ function getCaller() {
function getStack() {
// Save original Error.prepareStackTrace
let origPrepareStackTrace = Error.prepareStackTrace;
// Override with function that just returns `stack`
Error.prepareStackTrace = function(_, stack) {
return stack;
@ -435,7 +428,7 @@ function getStack() {
// Get `err.stack`, which calls our new `Error.prepareStackTrace`
let stack = err.stack;
// Restore original `Error.prepareStackTrace`
Error.prepareStackTrace = origPrepareStackTrace;

View File

@ -17,13 +17,13 @@ describe('All Tests', function() {
//require('./tests/actions/StageCreate');
//require('./tests/actions/RegionCreate');
//require('./tests/actions/ModuleInstall');
require('./tests/actions/ModuleCreate');
//require('./tests/actions/ModuleCreate');
//require('./tests/actions/FunctionCreate');
//require('./tests/actions/EnvList');
//require('./tests/actions/EnvGet');
//require('./tests/actions/EnvSetUnset');
//require('./tests/actions/ResourcesDeploy');
//require('./tests/actions/FunctionRun');
//require('./tests/actions/FunctionDeploy');
require('./tests/actions/FunctionDeploy');
});

View File

@ -1,6 +1,9 @@
'use strict';
require('dotenv');
// Load ENV
var ServerlessHelpers = require('serverless-helpers-js');
ServerlessHelpers.loadEnv();
console.log(process.env);
// Lambda Handler
module.exports.handler = function(event, context) {

View File

@ -19,6 +19,7 @@
"moment": "^2.10.6",
"node-uuid": "^1.4.2",
"request": "^2.61.0",
"serverless-helpers-js": "~0.0.3",
"shortid": "^2.2.2",
"through2": "^2.0.0",
"underscore": "^1.8.3"

View File

@ -1,6 +1,9 @@
'use strict';
require('dotenv');
// Load ENV
var ServerlessHelpers = require('serverless-helpers-js');
ServerlessHelpers.loadEnv();
console.log(process.env);
// Lambda Handler
module.exports.handler = function(event, context) {

View File

@ -1,6 +1,9 @@
'use strict';
require('dotenv');
// Load ENV
var ServerlessHelpers = require('serverless-helpers-js');
ServerlessHelpers.loadEnv();
console.log(process.env);
// Modularized Code
var moduleOne = require('../../moduleone/lib');

View File

@ -11,6 +11,6 @@
},
"keywords": [],
"dependencies": {
"dotenv": "^1.2.0"
"serverless-helpers-js": "~0.0.3"
}
}

View File

@ -1,6 +1,9 @@
'use strict';
require('dotenv');
// Load ENV
var ServerlessHelpers = require('serverless-helpers-js');
ServerlessHelpers.loadEnv();
console.log(process.env);
// Modularized Code
var moduleOne = require('../../moduleone/lib');

View File

@ -1,65 +0,0 @@
{
"name": "UsersShow",
"envVars": [],
"package": {
"optimize": {
"builder": "browserify",
"minify": true,
"ignore": [],
"exclude": [
"aws-sdk"
],
"includePaths": []
},
"excludePatterns": []
},
"plugins": [],
"cloudFormation": {
"lambda": {
"Function": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Runtime": "nodejs",
"Handler": "modules/users/show/index.handler",
"Role": {
"Ref": "aaLambdaRoleArn"
},
"Code": {
"S3Bucket": "",
"S3Key": ""
},
"Timeout": 6,
"MemorySize": 1024
}
}
},
"apiGateway": {
"Endpoint": {
"Type": "AWS::ApiGateway::Endpoint",
"Path": "users",
"Method": "GET",
"AuthorizationType": "none",
"ApiKeyRequired": false,
"RequestTemplates": {
"application/json": "{\"access_token\":\"$input.params('access_token')\",\"body\":\"$input.json('$')\"}"
},
"RequestParameters": {
"integration.request.querystring.integrationQueryParam": "method.request.querystring.access_token"
},
"Responses": {
"default": {
"statusCode": "200",
"responseParameters": {},
"responseModels": {},
"responseTemplates": {
"application/json": ""
}
},
"400": {
"statusCode": "400"
}
}
}
}
}
}

View File

@ -8,7 +8,7 @@ let fs = require('fs'),
Promise = require('bluebird'),
uuid = require('node-uuid'),
SError = require('../lib/ServerlessError'),
utils = require('../lib/utils');
SUtils = require('../lib/utils');
/**
* Create test project
@ -27,7 +27,7 @@ module.exports.createTestProject = function(config, npmInstallDirs) {
// Create Test Project
let tmpProjectPath = path.join(os.tmpdir(), projectName);
utils.sDebug('test_utils', 'Creating test project in ' + tmpProjectPath + '\n');
SUtils.sDebug('test_utils', 'Creating test project in ' + tmpProjectPath + '\n');
// Delete test folder if already exists
if (fs.existsSync(tmpProjectPath)) {
@ -40,9 +40,9 @@ module.exports.createTestProject = function(config, npmInstallDirs) {
forceDelete: true,
});
let lambdasCF = utils.readAndParseJsonSync(__dirname + '/../lib/templates/lambdas-cf.json'),
resourcesCF = utils.readAndParseJsonSync(__dirname + '/../lib/templates/resources-cf.json'),
projectJSON = utils.readAndParseJsonSync(path.join(tmpProjectPath, 's-project.json'));
let lambdasCF = SUtils.readAndParseJsonSync(__dirname + '/../lib/templates/lambdas-cf.json'),
resourcesCF = SUtils.readAndParseJsonSync(__dirname + '/../lib/templates/resources-cf.json'),
projectJSON = SUtils.readAndParseJsonSync(path.join(tmpProjectPath, 's-project.json'));
// Delete Lambda Template
delete lambdasCF.Resources.lTemplate;
@ -59,8 +59,8 @@ module.exports.createTestProject = function(config, npmInstallDirs) {
resourcesCF.Parameters.aaDataModelStage.AllowedValues.push(config.stage2);
return Promise.all([
utils.writeFile(path.join(tmpProjectPath, 'cloudformation', 'lambdas-cf.json'), JSON.stringify(lambdasCF, null, 2)),
utils.writeFile(path.join(tmpProjectPath, 'cloudformation', 'resources-cf.json'), JSON.stringify(resourcesCF, null, 2)),
SUtils.writeFile(path.join(tmpProjectPath, 'cloudformation', 'lambdas-cf.json'), JSON.stringify(lambdasCF, null, 2)),
SUtils.writeFile(path.join(tmpProjectPath, 'cloudformation', 'resources-cf.json'), JSON.stringify(resourcesCF, null, 2)),
])
.then(function() {
projectJSON.name = projectName;
@ -69,7 +69,7 @@ module.exports.createTestProject = function(config, npmInstallDirs) {
projectJSON.stages[projectStage] = [{
region: projectRegion,
iamRoleArnLambda: projectLambdaIAMRole,
regionBucket: utils.generateRegionBucketName(projectRegion, projectDomain)
regionBucket: SUtils.generateRegionBucketName(projectRegion, projectDomain)
},];
fs.writeFileSync(path.join(tmpProjectPath, 's-project.json'), JSON.stringify(projectJSON, null, 2));
@ -87,8 +87,8 @@ module.exports.createTestProject = function(config, npmInstallDirs) {
npmInstallDirs.forEach(function(dir) {
let fullPath = path.join(tmpProjectPath, 'back', 'modules', dir);
utils.sDebug('test_utils', `Running NPM install on ${fullPath}`);
utils.npmInstall(fullPath);
SUtils.sDebug('test_utils', `Running NPM install on ${fullPath}`);
SUtils.npmInstall(fullPath);
});
}

View File

@ -143,56 +143,56 @@ describe('Test Action: Function Deploy', function() {
});
});
describe('Function Deploy Both', function() {
it('should deploy code', function(done) {
this.timeout(0);
let event = {
stage: config.stage,
region: config.region,
type: 'both',
paths: [
'moduletwo/browserify',
'moduletwo/nonoptimized',
'moduleone/simple',
'moduleone/multiendpoint'
]
};
serverless.actions.functionDeploy(event)
.then(function(evt) {
validateEvent(evt);
done();
})
.catch(e => {
done(e);
});
});
});
describe('Function Deploy Both with "all" option.', function() {
it('should deploy code', function(done) {
this.timeout(0);
let event = {
stage: config.stage,
region: config.region,
type: 'both',
all: true
};
serverless.actions.functionDeploy(event)
.then(function(evt) {
validateEvent(evt);
done();
})
.catch(e => {
done(e);
});
});
});
//describe('Function Deploy Both', function() {
// it('should deploy code', function(done) {
//
// this.timeout(0);
//
// let event = {
// stage: config.stage,
// region: config.region,
// type: 'both',
// paths: [
// 'moduletwo/browserify',
// 'moduletwo/nonoptimized',
// 'moduleone/simple',
// 'moduleone/multiendpoint'
// ]
// };
//
// serverless.actions.functionDeploy(event)
// .then(function(evt) {
// validateEvent(evt);
// done();
// })
// .catch(e => {
// done(e);
// });
// });
//});
//
//describe('Function Deploy Both with "all" option.', function() {
// it('should deploy code', function(done) {
//
// this.timeout(0);
//
// let event = {
// stage: config.stage,
// region: config.region,
// type: 'both',
// all: true
// };
//
// serverless.actions.functionDeploy(event)
// .then(function(evt) {
// validateEvent(evt);
// done();
// })
// .catch(e => {
// done(e);
// });
// });
//});
//describe('Function deploy "both", across multiple regions', function() {
//