From e07c8a04aba095132a1f5f46faf3abf95980585f Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Fri, 27 Dec 2019 14:46:47 +0000 Subject: [PATCH] commit dist per https://github.com/softprops/serverless-localhost/issues/12 --- .gitignore | 3 +- dist/@types/localhost.d.ts | 17 ++ dist/@types/localhost.js | 3 + dist/@types/localhost.js.map | 1 + dist/@types/serverless.d.ts | 72 ++++++++ dist/@types/serverless.js | 3 + dist/@types/serverless.js.map | 1 + dist/docker.d.ts | 9 + dist/docker.js | 172 +++++++++++++++++++ dist/docker.js.map | 1 + dist/http.d.ts | 3 + dist/http.js | 17 ++ dist/http.js.map | 1 + dist/index.d.ts | 26 +++ dist/index.js | 314 ++++++++++++++++++++++++++++++++++ dist/index.js.map | 1 + dist/lambda.d.ts | 40 +++++ dist/lambda.js | 50 ++++++ dist/lambda.js.map | 1 + dist/signal.d.ts | 2 + dist/signal.js | 12 ++ dist/signal.js.map | 1 + 22 files changed, 748 insertions(+), 2 deletions(-) create mode 100644 dist/@types/localhost.d.ts create mode 100644 dist/@types/localhost.js create mode 100644 dist/@types/localhost.js.map create mode 100644 dist/@types/serverless.d.ts create mode 100644 dist/@types/serverless.js create mode 100644 dist/@types/serverless.js.map create mode 100644 dist/docker.d.ts create mode 100644 dist/docker.js create mode 100644 dist/docker.js.map create mode 100644 dist/http.d.ts create mode 100644 dist/http.js create mode 100644 dist/http.js.map create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/lambda.d.ts create mode 100644 dist/lambda.js create mode 100644 dist/lambda.js.map create mode 100644 dist/signal.d.ts create mode 100644 dist/signal.js create mode 100644 dist/signal.js.map diff --git a/.gitignore b/.gitignore index 597bbdf..d4b98be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ node_modules .DS_Store .serverless -dist *.log coverage .nyc_output -__pycache__ \ No newline at end of file +__pycache__ diff --git a/dist/@types/localhost.d.ts b/dist/@types/localhost.d.ts new file mode 100644 index 0000000..1b4d976 --- /dev/null +++ b/dist/@types/localhost.d.ts @@ -0,0 +1,17 @@ +import { Cors } from './serverless'; +export interface HttpFunc { + name: string; + qualifiedName: string; + handler: string; + runtime: string; + memorySize: number; + timeout: number; + events: { + method: string; + path: string; + cors?: Cors; + }[]; + environment: { + [key: string]: string; + }; +} diff --git a/dist/@types/localhost.js b/dist/@types/localhost.js new file mode 100644 index 0000000..d6cbddb --- /dev/null +++ b/dist/@types/localhost.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=localhost.js.map \ No newline at end of file diff --git a/dist/@types/localhost.js.map b/dist/@types/localhost.js.map new file mode 100644 index 0000000..8f963eb --- /dev/null +++ b/dist/@types/localhost.js.map @@ -0,0 +1 @@ +{"version":3,"file":"localhost.js","sourceRoot":"","sources":["../../src/@types/localhost.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/@types/serverless.d.ts b/dist/@types/serverless.d.ts new file mode 100644 index 0000000..7fd66b8 --- /dev/null +++ b/dist/@types/serverless.d.ts @@ -0,0 +1,72 @@ +export interface CommandOption { + usage: string; + shortcut: string; + required?: boolean; +} +export interface CommandDescription { + usage: string; + lifecycleEvents?: string[]; + commands?: { + [key: string]: CommandDescription; + }; + options?: { + [key: string]: CommandOption; + }; +} +export interface Serverless { + cli: { + log(args: any): any; + consoleLog(args: any): any; + }; + service: { + service: string; + provider: { + name: string; + runtime?: string; + memorySize?: number; + timeout?: number; + environment?: { + [key: string]: string; + }; + }; + package?: Package; + getAllFunctions: () => string[]; + functions: { + [key: string]: FunctionConfig; + }; + }; + getProvider(name: string): Provider; + pluginManager: { + spawn(cmd: string, options?: object): Promise; + }; +} +export declare type Cors = boolean | { + origin?: string; + headers?: string[]; + allowCredentials?: boolean; +}; +export interface FunctionConfig { + name: string; + handler: string; + runtime?: string; + events?: { + [key: string]: any; + }[]; + package?: Package; + memorySize?: number; + timeout?: number; + environment?: { + [key: string]: string; + }; +} +export interface Package { + artifact?: string; + disable?: boolean; +} +export interface Provider { + getStage(): string; +} +export interface Options { + port?: number; + debugPort?: number; +} diff --git a/dist/@types/serverless.js b/dist/@types/serverless.js new file mode 100644 index 0000000..a5b9d78 --- /dev/null +++ b/dist/@types/serverless.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=serverless.js.map \ No newline at end of file diff --git a/dist/@types/serverless.js.map b/dist/@types/serverless.js.map new file mode 100644 index 0000000..f78fc3f --- /dev/null +++ b/dist/@types/serverless.js.map @@ -0,0 +1 @@ +{"version":3,"file":"serverless.js","sourceRoot":"","sources":["../../src/@types/serverless.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/docker.d.ts b/dist/docker.d.ts new file mode 100644 index 0000000..7927026 --- /dev/null +++ b/dist/docker.d.ts @@ -0,0 +1,9 @@ +/// +import * as Dockerode from 'dockerode'; +import { ContainerCreateOptions } from 'dockerode'; +import { HttpFunc } from './@types/localhost'; +export declare function demux(logs: Buffer, stderr: (d: any) => void, stdout: (d: any) => void): void; +export declare function pull(docker: Dockerode, image: string): Promise; +export declare function runtimeImage(runtime: string): string; +export declare function debugSupported(runtime: string): boolean; +export declare function containerArgs(dockerImage: string, event: string, func: HttpFunc, region: string, debugPort?: number): ContainerCreateOptions; diff --git a/dist/docker.js b/dist/docker.js new file mode 100644 index 0000000..befbe44 --- /dev/null +++ b/dist/docker.js @@ -0,0 +1,172 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var readline = require("readline"); +var stream = require("stream"); +function demux(logs, stderr, stdout) { + // https://github.com/apocas/docker-modem/blob/7ec7abeb6b0cf7192d29667b397d292fe9f6e3ca/lib/modem.js#L296 + // when we're not `following` the logs we get a buffer. dockerode doesn't provide a helpful + // way do demux that hence the following... + var bufferStream = new stream.PassThrough(); + bufferStream.end(logs); + var header = bufferStream.read(8); + while (header !== null) { + var type = header.readUInt8(0); + var payload = bufferStream.read(header.readUInt32BE(4)); + if (payload === null) { + break; + } + if (type === 2) { + stderr(payload); + } + else { + stdout(payload); + } + header = bufferStream.read(8); + } +} +exports.demux = demux; +function pull(docker, image) { + return new Promise(function (resolve) { + docker.pull(image, {}, function (err, stream) { + docker.modem.followProgress(stream, function () { + process.stdout.write('\n'); + resolve(); + }, function (event) { + readline.clearLine(process.stdout, 0); + readline.cursorTo(process.stdout, 0); + process.stdout.write(event.status + " " + (event.id || '') + " " + (event.progress || '')); + }); + }); + }); +} +exports.pull = pull; +function runtimeImage(runtime) { + // https://hub.docker.com/r/lambci/lambda/tags + return "lambci/lambda:" + runtime; +} +exports.runtimeImage = runtimeImage; +function debugSupported(runtime) { + return debugEntrypoint(runtime, 0) !== undefined; +} +exports.debugSupported = debugSupported; +function debugEntrypoint(runtime, port) { + switch (runtime) { + case 'nodejs': + return [ + '/usr/bin/node', + "--debug-brk=" + port, + '--nolazy', + '--max-old-space-size=1229', + '--max-new-space-size=153', + '--max-executable-size=153', + '--expose-gc', + '/var/runtime/node_modules/awslambda/bin/awslambda' + ]; + case 'nodejs4.3': + return [ + '/usr/local/lib64/node-v4.3.x/bin/node', + "--debug-brk=" + port, + '--nolazy', + '--max-old-space-size=2547', + '--max-semi-space-size=150', + '--max-executable-size=160', + '--expose-gc', + '/var/runtime/node_modules/awslambda/index.js' + ]; + case 'nodejs6.10': + return [ + '/var/lang/bin/node', + "--debug-brk=" + port, + '--nolazy', + '--max-old-space-size=2547', + '--max-semi-space-size=150', + '--max-executable-size=160', + '--expose-gc', + '/var/runtime/node_modules/awslambda/index.js' + ]; + case 'nodejs8.10': + return [ + '/var/lang/bin/node', + "--inspect-brk=0.0.0.0:" + port, + '--nolazy', + '--expose-gc', + '--max-semi-space-size=150', + '--max-old-space-size=2707', + '/var/runtime/node_modules/awslambda/index.js' + ]; + case 'java8': + return [ + '/usr/bin/java', + "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=" + port, + '-XX:MaxHeapSize=2834432k', + '-XX:MaxMetaspaceSize=163840k', + '-XX:ReservedCodeCacheSize=81920k', + '-XX:+UseSerialGC', + '-XX:-TieredCompilation', + '-Djava.net.preferIPv4Stack=true', + '-jar', + '/var/runtime/lib/LambdaJavaRTEntry-1.0.jar' + ]; + case 'python2.7': + return ['/usr/bin/python2.7', '/var/runtime/awslambda/bootstrap.py']; + case 'python3.6': + return ['/var/lang/bin/python3.6', '/var/runtime/awslambda/bootstrap.py']; + case 'dotnetcore2.0': + case 'dotnetcore2.1': + return [ + '/var/lang/bin/dotnet', + '/var/runtime/MockBootstraps.dll', + '--debugger-spin-wait' + ]; + default: + return undefined; + } +} +function exposedPorts(port) { + var ports = {}; + ports["" + port] = {}; + return ports; +} +function portBindings(containerPort, hostPort) { + var bindings = {}; + bindings["" + containerPort] = [ + { + HostPort: "" + hostPort + } + ]; + return bindings; +} +function containerArgs(dockerImage, event, func, region, debugPort) { + var baseEnv = Object.keys(func.environment).reduce(function (res, key) { return res.concat([key + "=" + func.environment[key]]); }, []); + var entrypoint = debugPort !== undefined + ? debugEntrypoint(func.runtime, debugPort) + : undefined; + return { + Entrypoint: entrypoint, + ExposedPorts: debugPort !== undefined ? exposedPorts(debugPort) : undefined, + Image: dockerImage, + Volumes: { + '/var/task': {} + }, + // todo: what ever else lambci expects + HostConfig: { + Binds: [process.cwd() + ":/var/task:ro"], + PortBindings: debugPort !== undefined ? portBindings(debugPort, debugPort) : undefined + }, + // todo: what ever else lambci expects + // https://github.com/lambci/docker-lambda/blob/master/provided/run/init.go + Env: baseEnv.concat([ + "AWS_LAMBDA_FUNCTION_HANDLER=" + func.handler, + "AWS_LAMBDA_EVENT_BODY=" + event, + "AWS_LAMBDA_FUNCTION_NAME=" + func.qualifiedName, + "AWS_LAMBDA_FUNCTION_MEMORY_SIZE=" + func.memorySize, + "AWS_LAMBDA_FUNCTION_TIMEOUT=" + func.timeout, + "AWS_REGION=" + region, + "AWS_DEFAULT_REGION=" + region + // `AWS_LAMBDA_CLIENT_CONTEXT=??`, + // `AWS_LAMBDA_COGNITO_IDENTITY=??` + ]) + }; +} +exports.containerArgs = containerArgs; +//# sourceMappingURL=docker.js.map \ No newline at end of file diff --git a/dist/docker.js.map b/dist/docker.js.map new file mode 100644 index 0000000..3ad8f94 --- /dev/null +++ b/dist/docker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"docker.js","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/http.d.ts b/dist/http.d.ts new file mode 100644 index 0000000..f6c287f --- /dev/null +++ b/dist/http.d.ts @@ -0,0 +1,3 @@ +export declare function isHttpEvent(config: object): boolean; +export declare function translateMethod(method: string): string; +export declare function translatePath(apiGatewayPath: string): string; diff --git a/dist/http.js b/dist/http.js new file mode 100644 index 0000000..0463cf0 --- /dev/null +++ b/dist/http.js @@ -0,0 +1,17 @@ +"use strict"; +//type Method = "get" | "post" | "put" | "delete" | "patch" | "any"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isHttpEvent(config) { + return config['http'] !== undefined; +} +exports.isHttpEvent = isHttpEvent; +function translateMethod(method) { + var lowercased = method.toLowerCase(); + return 'any' === lowercased ? 'all' : lowercased; +} +exports.translateMethod = translateMethod; +function translatePath(apiGatewayPath) { + return apiGatewayPath.replace(/{proxy\+}/g, '*').replace(/{([^}]+)}/g, ':$1'); +} +exports.translatePath = translatePath; +//# sourceMappingURL=http.js.map \ No newline at end of file diff --git a/dist/http.js.map b/dist/http.js.map new file mode 100644 index 0000000..bccf6e0 --- /dev/null +++ b/dist/http.js.map @@ -0,0 +1 @@ +{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAAA,oEAAoE;;AAEpE,SAAgB,WAAW,CAAC,MAAc;IACxC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;AACtC,CAAC;AAFD,kCAEC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC5C,IAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;AACnD,CAAC;AAHD,0CAGC;AAED,SAAgB,aAAa,CAAC,cAAsB;IAClD,OAAO,cAAc,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAChF,CAAC;AAFD,sCAEC"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..4c1e035 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,26 @@ +import * as debug from 'debug'; +import * as Dockerode from 'dockerode'; +import * as express from 'express'; +import { HttpFunc } from './@types/localhost'; +import { CommandDescription, FunctionConfig, Options, Serverless } from './@types/serverless'; +declare const _default: { + new (serverless: Serverless, options: Options): { + readonly serverless: Serverless; + readonly options: Options; + readonly commands: { + [key: string]: CommandDescription; + }; + readonly hooks: { + [key: string]: any; + }; + readonly debug: debug.IDebugger; + httpFunc(name: string, runtime: string, env: { + [key: string]: string; + }, func: FunctionConfig): HttpFunc; + respond(funcResponse: string, response: express.Response): void; + httpFunctions(): HttpFunc[]; + bootstrap(docker: Dockerode, funcs: HttpFunc[]): Promise; + start(): Promise; + }; +}; +export = _default; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..591fe1c --- /dev/null +++ b/dist/index.js @@ -0,0 +1,314 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var cors = require("cors"); +var debug = require("debug"); +var Dockerode = require("dockerode"); +var express = require("express"); +var docker_1 = require("./docker"); +var http_1 = require("./http"); +var lambda_1 = require("./lambda"); +var signal_1 = require("./signal"); +var DEFAULT_PORT = 3000; +module.exports = /** @class */ (function () { + function Localhost(serverless, options) { + this.debug = debug('localhost'); + this.serverless = serverless; + this.options = options; + this.commands = { + localhost: { + usage: 'Runs a local http server simulating API Gateway, triggering your http functions on demand', + lifecycleEvents: ['start'], + options: { + port: { + usage: "Port to listen on. Default: " + DEFAULT_PORT, + shortcut: 'p' + }, + debugPort: { + usage: 'Debugger port to listen on. Only supported for a subset of runtimes. Default: none', + shortcut: 'd' + } + } + } + }; + this.hooks = { + 'localhost:start': this.start.bind(this) + }; + } + Localhost.prototype.httpFunc = function (name, runtime, env, func) { + return { + name: name, + qualifiedName: func.name, + handler: func.handler, + runtime: runtime, + memorySize: func.memorySize || this.serverless.service.provider.memorySize || 1536, + timeout: func.timeout || this.serverless.service.provider.timeout || 300, + events: (func.events || []).filter(http_1.isHttpEvent).map(function (event) { + var http = event['http']; + if (typeof http === 'string') { + var _a = http.split(' '), method = _a[0], path = _a[1]; + return { + method: http_1.translateMethod(method), + path: http_1.translatePath(path) + }; + } + return { + method: http_1.translateMethod(http.method), + path: http_1.translatePath(http.path), + cors: event.cors + }; + }), + environment: Object.assign(env, func.environment) + }; + }; + Localhost.prototype.respond = function (funcResponse, response) { + this.debug("raw function response '" + funcResponse + "'"); + // stdout stream may contain other data, response should be the last line + var lastLine = funcResponse.lastIndexOf('\n'); + if (lastLine >= 0) { + console.log(funcResponse.substring(lastLine).trim()); + funcResponse = funcResponse.substring(0, lastLine).trim(); + } + var json = JSON.parse(funcResponse); + if (lambda_1.errorLike(json)) { + this.debug('function invocation yieled unhandled error'); + response + .status(500) + .type('application/json') + .send(json); + } + else { + var status = json.statusCode || 200; + var contentType = (json.headers || {})['Content-Type'] || 'application/json'; + response + .status(status) + .type(contentType) + .send(json.isBase64Encoded ? Buffer.from(json.body, 'base64') : json.body); + } + }; + Localhost.prototype.httpFunctions = function () { + var _this = this; + var svc = this.serverless.service; + var env = Object.assign({}, svc.provider.environment); + return svc.getAllFunctions().reduce(function (httpFuncs, name) { + var func = svc.functions[name]; + var runtime = func.runtime || svc.provider.runtime; + if (!runtime) { + _this.serverless.cli.log("Warning: unable to infer a runtime for function " + name); + return httpFuncs; + } + if ((func.events || []).find(http_1.isHttpEvent)) { + httpFuncs.push(_this.httpFunc(name, runtime, env, func)); + } + return httpFuncs; + }, []); + }; + Localhost.prototype.bootstrap = function (docker, funcs) { + return __awaiter(this, void 0, void 0, function () { + var svc, app, _loop_1, _i, funcs_1, func; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + svc = this.serverless.service; + app = express().disable('x-powered-by'); + app.use(cors()); + _loop_1 = function (func) { + var _i, _a, event; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _i = 0, _a = func.events; + _b.label = 1; + case 1: + if (!(_i < _a.length)) return [3 /*break*/, 4]; + event = _a[_i]; + return [4 /*yield*/, app[event.method](event.path, function (request, response) { return __awaiter(_this, void 0, void 0, function () { + var dockerImage, provider, event, invokeArgs, create, container, logs, stdout; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + dockerImage = docker_1.runtimeImage(func.runtime); + provider = this.serverless + .getProvider(svc.provider.name) + .getStage(); + event = JSON.stringify(lambda_1.apigwEvent(request, provider)); + invokeArgs = docker_1.containerArgs(dockerImage, event, func, this.serverless.getProvider(svc.provider.name).getStage(), this.options.debugPort); + create = function () { + _this.debug('Creating docker container for ${func.handler}'); + return docker.createContainer(invokeArgs); + }; + return [4 /*yield*/, create().catch(function (e) { + if (e.statusCode === 404) { + _this.serverless.cli.log('Docker image not present'); + _this.serverless.cli.log("Pulling " + dockerImage + " image..."); + return docker_1.pull(docker, dockerImage).then(function () { + return create(); + }); + } + throw e; + })]; + case 1: + container = _a.sent(); + // invoke function + this.debug("Invoking " + func.handler + " function in " + container.id); + return [4 /*yield*/, container.start().then(function () { return container.wait(); })]; + case 2: + _a.sent(); + // get the logs + this.debug("Fetching container logs of " + container.id); + return [4 /*yield*/, container.logs({ + stdout: true, + stderr: true + })]; + case 3: + logs = _a.sent(); + stdout = []; + docker_1.demux(logs, function (data) { + process.stderr.write(data); + }, function (data) { + stdout.push(data); + }); + this.respond(Buffer.concat(stdout).toString('utf8'), response); + // sweep up + this.debug("Deleting container " + container.id); + return [4 /*yield*/, container.remove()]; + case 4: + _a.sent(); + return [2 /*return*/]; + } + }); + }); })]; + case 2: + _b.sent(); + _b.label = 3; + case 3: + _i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/]; + } + }); + }; + _i = 0, funcs_1 = funcs; + _a.label = 1; + case 1: + if (!(_i < funcs_1.length)) return [3 /*break*/, 4]; + func = funcs_1[_i]; + return [5 /*yield**/, _loop_1(func)]; + case 2: + _a.sent(); + _a.label = 3; + case 3: + _i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/, app]; + } + }); + }); + }; + Localhost.prototype.start = function () { + return __awaiter(this, void 0, void 0, function () { + var svc, providerName, funcs, docker, app; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + svc = this.serverless.service; + providerName = svc.provider.name; + if ('aws' !== providerName) { + throw Error("Provider " + providerName + " is not supported"); + } + funcs = this.httpFunctions(); + if (!funcs) { + throw Error('This serverless service has no http functions'); + } + docker = new Dockerode({ + socketPath: '/var/run/docker.sock' + }); + // make sure we can communicate with docker + this.debug('pinging docker daemon'); + return [4 /*yield*/, docker.ping().catch(function (e) { + throw new Error('Unable to communicate with docker. \n' + + (" Error: " + e.message + "\n") + + ' Follow https://docs.docker.com/get-started/ to make sure you have docker installed \n'); + })]; + case 1: + _a.sent(); + return [4 /*yield*/, this.bootstrap(docker, funcs)]; + case 2: + app = _a.sent(); + return [2 /*return*/, new Promise(function (resolve, reject) { + _this.serverless.cli.log('Starting server...'); + var port = _this.options.port || DEFAULT_PORT; + var debugPort = _this.options.debugPort; + app + .listen(port, function () { + _this.serverless.cli.log("Listening on port " + port + "..."); + if (debugPort) { + _this.serverless.cli.log("\u276F Debugging enabled on port " + debugPort); + } + _this.serverless.cli.log('❯ Function routes'); + for (var _i = 0, funcs_2 = funcs; _i < funcs_2.length; _i++) { + var func = funcs_2[_i]; + _this.serverless.cli.log("* " + func.name); + for (var _a = 0, _b = func.events; _a < _b.length; _a++) { + var event = _b[_a]; + _this.serverless.cli.log(" " + event.method + " http://localhost:" + port + event.path); + } + } + resolve(); + }) + .on('error', function (e) { + if (e.message.indexOf('listen EADDRINUSE') > -1) { + reject(new Error("Error starting server on localhost port " + port + ".\n" + + ' * Hint: You likely already have something listening on this port')); + return; + } + reject(new Error("Unexpected error while starting server " + e.message)); + }); + }).then(function () { + return signal_1.trapAll().then(function (sig) { + return _this.serverless.cli.log("Received " + sig + " signal. Stopping server..."); + }); + })]; + } + }); + }); + }; + return Localhost; +}()); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..c9095ef --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/lambda.d.ts b/dist/lambda.d.ts new file mode 100644 index 0000000..af35f0a --- /dev/null +++ b/dist/lambda.d.ts @@ -0,0 +1,40 @@ +/// +import * as express from 'express'; +export declare function errorLike(payload: object): boolean; +export declare function apigwEvent(request: express.Request, stage: string): { + httpMethod: string; + path: string; + body: any; + headers: import("http").IncomingHttpHeaders; + queryStringParameters: any; + multiValueQueryStringParameters: { + [key: string]: string[]; + }; + pathParameters: any; + stageVariables: null; + isBase64Encoded: boolean; + requestContext: { + path: string; + accountId: string; + resourceId: string; + stage: string; + requestId: string; + identity: { + cognitoIdentityPoolId: null; + accountId: null; + cognitoIdentityId: null; + caller: null; + apiKey: null; + sourceIp: string; + accessKey: null; + cognitoAuthenticationType: null; + cognitoAuthenticationProvider: null; + userArn: null; + userAgent: string; + user: null; + }; + resourcePath: string; + httpMethod: string; + apiId: string; + }; +}; diff --git a/dist/lambda.js b/dist/lambda.js new file mode 100644 index 0000000..674edf9 --- /dev/null +++ b/dist/lambda.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function errorLike(payload) { + // https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/ + var fields = ['errorMessage', 'errorType', 'stackTrace']; + return fields.every(function (f) { return f in payload; }) || 'errorMessage' in payload; +} +exports.errorLike = errorLike; +function apigwEvent(request, stage) { + request.headers['X-Forwarded-Proto'] = request.protocol; + return { + httpMethod: request.method, + path: request.path, + body: request.body, + headers: request.headers, + queryStringParameters: request.query, + multiValueQueryStringParameters: Object.keys(request.query).reduce(function (res, key) { return Object.assign(res, { key: [request.query[key]] }); }, {}), + pathParameters: request.params, + stageVariables: null, + isBase64Encoded: false, + requestContext: { + path: '/', + accountId: "" + Math.random() + .toString(10) + .slice(2), + resourceId: '123', + stage: stage, + requestId: '123', + identity: { + cognitoIdentityPoolId: null, + accountId: null, + cognitoIdentityId: null, + caller: null, + apiKey: null, + sourceIp: '127.0.0.1', + accessKey: null, + cognitoAuthenticationType: null, + cognitoAuthenticationProvider: null, + userArn: null, + userAgent: 'Serverless/xxx', + user: null + }, + resourcePath: '/', + httpMethod: request.method, + apiId: '123' + } + }; +} +exports.apigwEvent = apigwEvent; +//# sourceMappingURL=lambda.js.map \ No newline at end of file diff --git a/dist/lambda.js.map b/dist/lambda.js.map new file mode 100644 index 0000000..4757c37 --- /dev/null +++ b/dist/lambda.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lambda.js","sourceRoot":"","sources":["../src/lambda.ts"],"names":[],"mappings":";;AAEA,SAAgB,SAAS,CAAC,OAAe;IACvC,qGAAqG;IACrG,IAAM,MAAM,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC,KAAK,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,IAAI,OAAO,EAAZ,CAAY,CAAC,IAAI,cAAc,IAAI,OAAO,CAAC;AACtE,CAAC;AAJD,8BAIC;AAED,SAAgB,UAAU,CAAC,OAAwB,EAAE,KAAa;IAChE,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IACxD,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,qBAAqB,EAAE,OAAO,CAAC,KAAK;QACpC,+BAA+B,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAE/D,UAAC,GAAG,EAAE,GAAG,IAAK,OAAA,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAjD,CAAiD,EAAE,EAAE,CAAC;QACvE,cAAc,EAAE,OAAO,CAAC,MAAM;QAC9B,cAAc,EAAE,IAAI;QACpB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE;YACd,IAAI,EAAE,GAAG;YACT,SAAS,EAAE,KAAG,IAAI,CAAC,MAAM,EAAE;iBACxB,QAAQ,CAAC,EAAE,CAAC;iBACZ,KAAK,CAAC,CAAC,CAAG;YACb,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,KAAK;YACZ,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE;gBACR,qBAAqB,EAAE,IAAI;gBAC3B,SAAS,EAAE,IAAI;gBACf,iBAAiB,EAAE,IAAI;gBACvB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,WAAW;gBACrB,SAAS,EAAE,IAAI;gBACf,yBAAyB,EAAE,IAAI;gBAC/B,6BAA6B,EAAE,IAAI;gBACnC,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,gBAAgB;gBAC3B,IAAI,EAAE,IAAI;aACX;YACD,YAAY,EAAE,GAAG;YACjB,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,KAAK,EAAE,KAAK;SACb;KACF,CAAC;AACJ,CAAC;AAzCD,gCAyCC"} \ No newline at end of file diff --git a/dist/signal.d.ts b/dist/signal.d.ts new file mode 100644 index 0000000..e745ffd --- /dev/null +++ b/dist/signal.d.ts @@ -0,0 +1,2 @@ +/// +export declare function trapAll(): Promise; diff --git a/dist/signal.js b/dist/signal.js new file mode 100644 index 0000000..80703ad --- /dev/null +++ b/dist/signal.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function trap(sig) { + return new Promise(function (resolve) { + process.on(sig, function () { return resolve(sig); }); + }); +} +function trapAll() { + return Promise.race([trap('SIGINT'), trap('SIGTERM')]); +} +exports.trapAll = trapAll; +//# sourceMappingURL=signal.js.map \ No newline at end of file diff --git a/dist/signal.js.map b/dist/signal.js.map new file mode 100644 index 0000000..08319da --- /dev/null +++ b/dist/signal.js.map @@ -0,0 +1 @@ +{"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":";;AAAA,SAAS,IAAI,CAAC,GAAmB;IAC/B,OAAO,IAAI,OAAO,CAAC,UAAA,OAAO;QACxB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,cAAM,OAAA,OAAO,CAAC,GAAG,CAAC,EAAZ,CAAY,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,OAAO;IACrB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAFD,0BAEC"} \ No newline at end of file