#!/usr/bin/env node 'use strict'; var JawsError = require('../lib/jaws-error'), Jaws = require('../lib/index.js'), JawsCLI = require('../lib/utils/cli.js'), program = require('commander'), utils = require('../lib/utils'), Promise = require('bluebird'), rawDebug = require('debug'), execute = utils.execute; Promise.onPossiblyUnhandledRejection(function(error) { throw error; }); var JAWS = new Jaws(); program .option('-v, --verbose') .version(JAWS._meta.version); /** * Project * - Create a new JAWS Project */ program .command('project ') .description(`Work with JAWS Project. Valid 's: create`) .option('-d, --dont-exe-cf', `Don't execute CloudFormation, just generate it`) .option('-s, --stage ', 'Name for the stage to create') .option('-r, --region ', 'Name of AWS region to use') .option('-u, --domain ', 'domain ex: myapp.com') .option('-n, --proj-name ', 'Name for the new project') .option('-e, --email ', 'Notification email to use in CloudFormation') .option('-p, --aws-profile ', 'Admin AWS profile as defined in ~/.aws/credentials to use') .action(function(cmd, options) { if (!JawsCLI.validateCmd(cmd, ['create'])) process.exit(1); switch (cmd) { case 'create': let theCmd = require('../lib/commands/ProjectCreate'); execute(theCmd.run( options.projName, options.stage ? options.stage.toLowerCase() : null, options.region, options.domain, options.email, options.awsProfile, options.dontExeCf )); break; default: console.error('Something went very wrong. :O'); process.exit(1); } }); /** * Region * - Create a new JAWS Region in the Current Project */ program .command('region ') .description(`Work with AWS Regions. Valid 's: create`) .option('-d, --dont-exe-cf', `Don't execute CloudFormation, just generate it`) .option('-s, --stage ', 'Name for the stage to be created in the region') .option('-r, --region ', 'Name of AWS region to use') .option('-p, --aws-profile ', 'Admin AWS profile as defined in ~/.aws/credentials to use') .action(function(cmd, options) { if (!JawsCLI.validateCmd(cmd, ['create'])) process.exit(1); switch (cmd) { case 'create': let theCmd = require('../lib/commands/StageRegion'); execute(theCmd.create( JAWS, 'region', options.stage, options.region, options.dontExeCf )); break; default: console.error('Something went very wrong. :O'); process.exit(1); } }); /** * Stage * - Create a new JAWS Stage in the Current Project */ program .command('stage ') .description(`Work with JAWS stages in a region. Valid 's: create`) .option('-d, --dont-exe-cf', `Don't execute CloudFormation, just generate it`) .option('-s, --stage ', 'Name for the stage create') .option('-r, --region ', 'Name of aws region to use') .option('-p, --aws-profile ', 'Admin AWS profile as defined in ~/.aws/credentials to use') .action(function(cmd, options) { if (!JawsCLI.validateCmd(cmd, ['create'])) process.exit(1); switch (cmd) { case 'create': let theCmd = require('../lib/commands/StageRegion'); execute(theCmd.create( JAWS, 'stage', options.stage, options.region, options.dontExeCf )); break; default: console.error('Something went very wrong. :O'); process.exit(1); } }); program .command('run') .description('Run the lambda in CWD locally') .action(function() { let runner = require('../lib/commands/LambdaRun'); execute(runner.run(JAWS)); }); program .command('module [params]') .description(`aws-module commands\n\nValid 's: create create: create aws-module action. Module will be created if DNE. create \t Ex: jaws module create users list` ) .option('-l, --lambda', '[create]: create lambda. Default is create lambda and endpoint.') .option('-e, --endpoint', '[create]: create API Gateway endpoint. Default is create lambda and endpoint.') .option('-r, --runtime', '[create]: lambda runtime. Valid: nodejs') .option('-p, --package-manager ', '[create]: Select package manager used when creating awsm for publishing. Valid options: npm') .action(function(cmd, params, options) { let theParams = process.argv.slice(3); if (!theParams) { throw new JawsError('Missing params', JawsError.errorCodes.UNKNOWN); } if (theParams[0][0] == '-') { //TODO: how do we get around this commander shortcoming? throw new JawsError('Specify options after cmd', JawsError.errorCodes.UNKNOWN); } if (cmd == 'create') { if (theParams.length < 3) { throw new JawsError('Please specify awsm resource and action name'); } let theCmd = require('../lib/commands/ModuleCreate'), name = theParams[1], action = theParams[2], runtime = options.runtime || 'nodejs', pkgMgr = options.packageManager || false, modType = 'both'; if (options.lambda) { modType = 'lambda'; } else if (options.endpoint) { modType = 'endpoint'; } execute(theCmd.run(JAWS, name, action, runtime, pkgMgr, modType)); } else { console.error(`Unsupported cmd ${cmd}. Must be install|update|create`); process.exit(1); } }); /** * Tag * - Tag a lambda or endpoint for deployment */ program .command('tag [type]') .description('Tag lambda function or api gateway resource (endpoint) for deployment ' + 'the next time deploy command is run. Type "lambda" is the default.') .option('-u, --untag', 'un-tag lambda|endpoint') .option('-a, --tag-all', 'tag all lambda|endpoint functions in project') .option('-l, --list-all', 'list all tagged lambda|endpoint functions in project') .option('-n, --untag-all', 'un-tag all lambda|endpoint functions in project') .action(function(type, options) { type = type || 'lambda'; type = type.toLowerCase(); if (-1 == ['endpoint', 'lambda'].indexOf(type)) { console.error(`Unsupported type ${type}. Must be endpoint|lambda`); process.exit(1); } let Tag = require('../lib/commands/Tag'), CmdTag = new Tag(JAWS, type); if (options.listAll) { execute(CmdTag.listAll().then(function(relPaths) { console.log(relPaths); })); } else if (options.tagAll || options.untagAll) { let untag = (options.untagAll) ? true : false; execute(CmdTag.tagAll(untag)); } else { // If not tagging all, you have to be tagging whats in your CWD (null 1st param) execute(Tag.tag(type, null, options.untag)); } }); /** * Deploy * - Deploy Lambda or Endpoint */ program .command('deploy [stage] [region]') .description('Deploy a lambda function (type lambda), a REST API (endpoint), or provision AWS resources (resources) for the specified stage.' + ' By default will tag and deploy type at cwd') .option('-t, --tags', 'Deploy all lambdas tagged as deployable in their jaws.json. Default is to just deploy cwd') .option('-d, --dont-exe-cf', `Don't execute the lambda cloudformation, just generate it. Zips will be uploaded to s3`) .action(function(type, stage, region, options) { let allTagged = (options.tags) ? true : false, theCmd; type = type.toLowerCase(); switch (type) { case 'endpoint': theCmd = require('../lib/commands/DeployEndpoint'); execute(theCmd.run(JAWS, stage, region, allTagged)); break; case 'lambda': theCmd = require('../lib/commands/DeployLambda'); execute(theCmd.run(JAWS, stage, region, allTagged, options.dontExeCf)); break; case 'resources': theCmd = require('../lib/commands/DeployResources'); execute(theCmd.run(JAWS, stage, region)); break; default: console.error(`Unsupported type ${type}. Must be endpoint|lambda|resources`); process.exit(1); break; } }); /** * Env * - Manage ENV variables for a stage */ program .command('env [key] [val]') .description(`Manage env vars for stage & region. can be "all" can be "local" Valid 's: list: vars for stage and region. jaws env list \t Ex: jaws env list prod all get: var value for stage and region. jaws env get \t Ex: jaws env get prod all JAWS_STAGE set: var value for stage and region. jaws set env \t Ex: jaws env set prod us-east-1 TABLE_NAME users unset: var value for stage and region. jaws env unset \t Ex: jaws unset prod us-east-1 TABLE_NAME` ) .action(function(cmd, stage, region, key, val) { let JawsEnv = require('../lib/commands/JawsEnv'), CmdEnv = new JawsEnv(JAWS, stage, region); cmd = cmd.toLowerCase(); switch (cmd) { case 'list': execute(CmdEnv.listEnv(true)); break; case 'get': if (!key) { console.error('Must specify key to set'); process.exit(1); } execute(CmdEnv.getEnvKey(key)); break; case 'set': if (!key || typeof val == 'undefined') { console.error('Must specify key and value'); process.exit(1); } execute(CmdEnv.setEnvKey(key, val)); break; case 'unset': if (!key) { console.error('Must specify key to unset'); process.exit(1); } if (val) { console.error('Do not specify val for unset'); process.exit(1); } execute(CmdEnv.setEnvKey(key)); break; default: console.error(`Unsupported cmd "${cmd}". Must be list|get|set|unset`); process.exit(1); break; } }); /** * Dash */ program .command('dash') .description('View a project summary and select resources to deploy.') .action(function() { let CmdDash = require('../lib/commands/dash'); execute(CmdDash.run(JAWS)); }); /** * Postinstall * - Kept separate from "module" commands because the options for this may likely grow */ program .command('postinstall ') .description('Performs automation when an aws-module is installed via a package manager') .action(function(moduleName, packageManager) { let CmdPostInstall = require('../lib/commands/Postinstall'); execute(CmdPostInstall.run(JAWS, moduleName, packageManager)); }); program .command('*') .action(function(cmd) { console.error('Unknown command:', cmd); }); program.parse(process.argv); if (process.argv.length == 2) { program.outputHelp(); } else { if (program.verbose) { rawDebug.enable('jaws:*'); } }