UNPKG

14.1 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 return new (P || (P = Promise))(function (resolve, reject) {
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 step((generator = generator.apply(thisArg, _arguments || [])).next());
9 });
10};
11var __generator = (this && this.__generator) || function (thisArg, body) {
12 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14 function verb(n) { return function (v) { return step([n, v]); }; }
15 function step(op) {
16 if (f) throw new TypeError("Generator is already executing.");
17 while (_) try {
18 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;
19 if (y = 0, t) op = [op[0] & 2, t.value];
20 switch (op[0]) {
21 case 0: case 1: t = op; break;
22 case 4: _.label++; return { value: op[1], done: false };
23 case 5: _.label++; y = op[1]; op = [0]; continue;
24 case 7: op = _.ops.pop(); _.trys.pop(); continue;
25 default:
26 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30 if (t[2]) _.ops.pop();
31 _.trys.pop(); continue;
32 }
33 op = body.call(thisArg, _);
34 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36 }
37};
38Object.defineProperty(exports, "__esModule", { value: true });
39var logger_1 = require("@bitblit/ratchet/dist/common/logger");
40var http = require("http");
41var web_handler_1 = require("./api-gateway/web-handler");
42var promise_ratchet_1 = require("@bitblit/ratchet/dist/common/promise-ratchet");
43var string_ratchet_1 = require("@bitblit/ratchet/dist/common/string-ratchet");
44var moment = require("moment-timezone");
45var qs = require("querystring");
46var simple_role_route_auth_1 = require("./api-gateway/auth/simple-role-route-auth");
47var router_util_1 = require("./api-gateway/route/router-util");
48var fs = require("fs");
49var path = require("path");
50var built_in_handlers_1 = require("./api-gateway/route/built-in-handlers");
51var epsilon_constants_1 = require("./epsilon-constants");
52/**
53 * A simplistic server for testing your lambdas locally
54 */
55var LocalServer = /** @class */ (function () {
56 function LocalServer(routerConfig, port) {
57 if (port === void 0) { port = 8888; }
58 this.routerConfig = routerConfig;
59 this.port = port;
60 this.aborted = false;
61 this.webHandler = new web_handler_1.WebHandler(routerConfig);
62 }
63 LocalServer.prototype.runServer = function () {
64 return __awaiter(this, void 0, void 0, function () {
65 var _this = this;
66 return __generator(this, function (_a) {
67 logger_1.Logger.info('Starting Epsilon server on port %d', this.port);
68 this.server = http.createServer(this.requestHandler.bind(this)).listen(this.port);
69 logger_1.Logger.info('Epsilon server is listening');
70 // Also listen for SIGINT
71 process.on('SIGINT', function () {
72 logger_1.Logger.info('Caught SIGINT - shutting down test server...');
73 _this.aborted = true;
74 });
75 return [2 /*return*/, this.checkFinished()];
76 });
77 });
78 };
79 LocalServer.prototype.checkFinished = function () {
80 return __awaiter(this, void 0, void 0, function () {
81 var wait;
82 return __generator(this, function (_a) {
83 switch (_a.label) {
84 case 0:
85 if (!this.aborted) return [3 /*break*/, 1];
86 return [2 /*return*/, true];
87 case 1: return [4 /*yield*/, promise_ratchet_1.PromiseRatchet.wait(1000)];
88 case 2:
89 wait = _a.sent();
90 return [2 /*return*/, this.checkFinished()];
91 }
92 });
93 });
94 };
95 LocalServer.prototype.requestHandler = function (request, response) {
96 return __awaiter(this, void 0, void 0, function () {
97 var evt, context, result, written;
98 return __generator(this, function (_a) {
99 switch (_a.label) {
100 case 0: return [4 /*yield*/, this.messageToApiGatewayEvent(request)];
101 case 1:
102 evt = _a.sent();
103 context = {};
104 logger_1.Logger.info('Processing event: %j', evt);
105 if (!(evt.path == '/epsilon-poison-pill')) return [3 /*break*/, 2];
106 this.aborted = true;
107 return [2 /*return*/, true];
108 case 2: return [4 /*yield*/, this.webHandler.lambdaHandler(evt, context)];
109 case 3:
110 result = _a.sent();
111 return [4 /*yield*/, this.writeProxyResultToServerResponse(result, response)];
112 case 4:
113 written = _a.sent();
114 return [2 /*return*/, written];
115 }
116 });
117 });
118 };
119 LocalServer.prototype.bodyAsBase64String = function (request) {
120 return __awaiter(this, void 0, void 0, function () {
121 return __generator(this, function (_a) {
122 return [2 /*return*/, new Promise(function (res, rej) {
123 var body = [];
124 request.on('data', function (chunk) {
125 body.push(chunk);
126 });
127 request.on('end', function () {
128 var rval = Buffer.concat(body).toString('base64');
129 res(rval);
130 });
131 })];
132 });
133 });
134 };
135 LocalServer.prototype.messageToApiGatewayEvent = function (request) {
136 return __awaiter(this, void 0, void 0, function () {
137 var bodyString, stageIdx, stage, path, reqTime, formattedTime, queryIdx, queryStringParams, headers, rval;
138 return __generator(this, function (_a) {
139 switch (_a.label) {
140 case 0: return [4 /*yield*/, this.bodyAsBase64String(request)];
141 case 1:
142 bodyString = _a.sent();
143 stageIdx = request.url.indexOf('/', 1);
144 stage = request.url.substring(1, stageIdx);
145 path = request.url.substring(stageIdx + 1);
146 reqTime = new Date().getTime();
147 formattedTime = moment.tz(reqTime, 'UTC').format('DD/MMM/YYYY:hh:mm:ss ZZ');
148 queryIdx = request.url.indexOf('?');
149 queryStringParams = (queryIdx > -1) ? qs.parse(request.url.substring(queryIdx + 1)) : {};
150 headers = Object.assign({}, request.headers);
151 headers['X-Forwarded-Proto'] = 'http'; // This server is always unencrypted
152 rval = {
153 body: bodyString,
154 multiValueHeaders: {},
155 multiValueQueryStringParameters: {},
156 resource: '/{proxy+}',
157 path: request.url,
158 httpMethod: request.method.toLowerCase(),
159 isBase64Encoded: true,
160 queryStringParameters: queryStringParams,
161 pathParameters: {
162 proxy: path
163 },
164 stageVariables: {
165 baz: 'qux'
166 },
167 headers: headers,
168 requestContext: {
169 accountId: '123456789012',
170 resourceId: '123456',
171 stage: stage,
172 requestId: string_ratchet_1.StringRatchet.createType4Guid(),
173 requestTime: formattedTime,
174 requestTimeEpoch: reqTime,
175 identity: null,
176 /*
177 identity: {
178 apiKey: null,
179 cognitoIdentityPoolId: null,
180 accountId: null,
181 cognitoIdentityId: null,
182 caller: null,
183 accessKey: null,
184 sourceIp: '127.0.0.1',
185 cognitoAuthenticationType: null,
186 cognitoAuthenticationProvider: null,
187 userArn: null,
188 userAgent: 'Custom User Agent String',
189 user: null
190 },
191 */
192 path: request.url,
193 domainName: request.headers['host'],
194 resourcePath: '/{proxy+}',
195 httpMethod: request.method.toLowerCase(),
196 apiId: '1234567890',
197 protocol: 'HTTP/1.1'
198 }
199 };
200 return [2 /*return*/, rval];
201 }
202 });
203 });
204 };
205 LocalServer.prototype.writeProxyResultToServerResponse = function (proxyResult, response) {
206 return __awaiter(this, void 0, void 0, function () {
207 var isGraphQLSchemaResponse, toWrite;
208 return __generator(this, function (_a) {
209 isGraphQLSchemaResponse = (!!proxyResult && !!proxyResult.body && proxyResult.body.indexOf('{\"data\":{\"__schema\"') > -1);
210 if (!isGraphQLSchemaResponse) {
211 logger_1.Logger.debug('Result: %j', proxyResult);
212 }
213 response.statusCode = proxyResult.statusCode;
214 if (proxyResult.headers) {
215 Object.keys(proxyResult.headers).forEach(function (hk) {
216 response.setHeader(hk, String(proxyResult.headers[hk]));
217 });
218 }
219 toWrite = (proxyResult.isBase64Encoded) ? Buffer.from(proxyResult.body, 'base64') : Buffer.from(proxyResult.body);
220 response.end(toWrite);
221 return [2 /*return*/, !!proxyResult.body];
222 });
223 });
224 };
225 return LocalServer;
226}());
227exports.LocalServer = LocalServer;
228// Functions below here are for using as samples
229function createSampleRouterConfig() {
230 var yamlString = loadSampleOpenApiYaml();
231 var authorizers = new Map();
232 var handlers = new Map();
233 var simpleRouteAuth = new simple_role_route_auth_1.SimpleRoleRouteAuth(['USER'], []);
234 authorizers.set('SampleAuthorizer', function (token, event, route) { return simpleRouteAuth.handler(token, event, route); });
235 handlers.set('get /', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
236 handlers.set('get /meta/server', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
237 handlers.set('get /meta/user', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
238 handlers.set('get /meta/item/{itemId}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
239 handlers.set('post /secure/access-token', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
240 handlers.set('get /multi/fixed', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'fixed'); });
241 handlers.set('get /multi/{v}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'variable'); });
242 handlers.set('get /err/{code}', function (event) { throw new Error('Fake err: ' + JSON.stringify(event)); });
243 var cfg = router_util_1.RouterUtil.openApiYamlToRouterConfig(yamlString, handlers, authorizers);
244 cfg.corsAllowedHeaders = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
245 cfg.corsAllowedOrigins = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
246 cfg.corsAllowedMethods = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
247 return cfg;
248}
249exports.createSampleRouterConfig = createSampleRouterConfig;
250function loadSampleOpenApiYaml() {
251 var yamlString = fs.readFileSync(path.join(__dirname, 'static', 'sample-open-api-doc.yaml')).toString();
252 return yamlString;
253}
254exports.loadSampleOpenApiYaml = loadSampleOpenApiYaml;
255//# sourceMappingURL=local-server.js.map
\No newline at end of file