serverless-docker
Version:
This is a proof of concept to see if we can replicate Amazon API Gateway using docker images to run lambda
168 lines (140 loc) • 4.42 kB
JavaScript
'use strict'
const BbPromise = require('bluebird')
const path = require('path')
const run = require('./lib/run')
const config = require('./lib/config')
const lambda = require('./lib/lambda')
const serve = require('./lib/serve')
const apiGatewayConfig = {
usage: 'Simulate the API Gateway and serves λ locally',
lifecycleEvents: [
'initialize',
'start',
],
options: {
port: {
usage: 'Port to listen on. Default: 3000',
shortcut: 'p',
},
'lambda-port': {
usage: 'Endpoint of a lambda simulation. Optional',
shortcut: 'l',
},
},
}
class Simulate {
constructor(serverless, options) {
this.serverless = serverless
this.options = options
Object.assign(
this,
run
)
this.commands = {
simulate: {
usage: 'Simulate λ locally',
lifecycleEvents: [
'invoke',
],
options: {
path: {
usage: 'Path to handlers directory',
shortcut: 'i',
},
},
commands: {
invoke: {
usage: 'Run a λ function locally',
lifecycleEvents: [
'invoke',
],
options: {
function: {
usage: 'Name of the function',
shortcut: 'f',
required: true,
},
path: {
usage: 'Path to JSON file holding input data',
shortcut: 'p',
},
},
},
serve: apiGatewayConfig,
apigateway: apiGatewayConfig,
lambda: {
usage: 'Simulate the λ API',
lifecycleEvents: [
'start',
],
options: {
port: {
usage: 'Port to listen on. Default: 4000',
shortcut: 'p',
},
'db-path': {
usage: 'Path to store the functions database. Default: ./.simulate-lambda-db',
shortcut: 'd',
},
},
},
register: {
usage: 'Register functions with the λ API',
lifecycleEvents: [
'register',
],
options: {
'lambda-port': {
usage: 'Endpoint of a lambda simulation. Optional',
shortcut: 'l',
required: true,
},
},
},
},
},
}
this.hooks = {
'simulate:invoke:invoke': () => BbPromise.bind(this)
.then(this.run)
.then(out => this.serverless.cli.consoleLog(out)),
'simulate:register:register': () => BbPromise.bind(this)
.then(this.register),
'simulate:lambda:start': () => BbPromise.bind(this)
.then(this.lambda),
'simulate:serve:initialize': () => BbPromise.bind(this)
.then(this.apigatewayInit),
'simulate:serve:start': () => BbPromise.bind(this)
.then(this.apigatewayStart),
'simulate:apigateway:initialize': () => BbPromise.bind(this)
.then(this.apigatewayInit),
'simulate:apigateway:start': () => BbPromise.bind(this)
.then(this.apigatewayStart),
}
}
apigatewayInit() {
const lambdaPort = this.options['lambda-port']
if (!lambdaPort) return BbPromise.resolve()
const functions = config.getFunctions(this.serverless)
return lambda.register(lambdaPort, functions, (msg) => this.serverless.cli.log(msg))
}
apigatewayStart() {
const lambdaPort = this.options['lambda-port']
const port = this.options.port || 3000
const endpoints = config.getEndpoints(this.serverless)
return serve.start(endpoints, port, lambdaPort, (msg) => this.serverless.cli.log(msg))
}
lambda() {
const defaultDbPath = path.join(this.serverless.config.servicePath, '.sls-simulate-registry')
const port = this.options.port || 4000
const dbPath = this.options['db-path'] || defaultDbPath
return lambda.start(port, dbPath, (msg) => this.serverless.cli.log(msg))
}
register() {
const functions = config.getFunctions(this.serverless)
const lambdaPort = this.options['lambda-port']
if (!lambdaPort) return BbPromise.reject(new Error('Lambda port is required'))
return lambda.register(lambdaPort, functions, (msg) => this.serverless.cli.log(msg))
}
}
module.exports = Simulate