1 | "use strict";
|
2 | var __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 | };
|
11 | var __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 | };
|
38 | Object.defineProperty(exports, "__esModule", { value: true });
|
39 | var logger_1 = require("@bitblit/ratchet/dist/common/logger");
|
40 | var http = require("http");
|
41 | var web_handler_1 = require("./http/web-handler");
|
42 | var promise_ratchet_1 = require("@bitblit/ratchet/dist/common/promise-ratchet");
|
43 | var string_ratchet_1 = require("@bitblit/ratchet/dist/common/string-ratchet");
|
44 | var moment = require("moment-timezone");
|
45 | var qs = require("querystring");
|
46 | var simple_role_route_auth_1 = require("./http/auth/simple-role-route-auth");
|
47 | var router_util_1 = require("./http/route/router-util");
|
48 | var fs = require("fs");
|
49 | var path = require("path");
|
50 | var built_in_handlers_1 = require("./http/route/built-in-handlers");
|
51 | var epsilon_constants_1 = require("./epsilon-constants");
|
52 | var error_ratchet_1 = require("@bitblit/ratchet/dist/common/error-ratchet");
|
53 | var number_ratchet_1 = require("@bitblit/ratchet/dist/common/number-ratchet");
|
54 | var event_util_1 = require("./http/event-util");
|
55 |
|
56 |
|
57 |
|
58 | var LocalServer = (function () {
|
59 | function LocalServer(routerConfig, port) {
|
60 | if (port === void 0) { port = 8888; }
|
61 | this.routerConfig = routerConfig;
|
62 | this.port = port;
|
63 | this.aborted = false;
|
64 | this.webHandler = new web_handler_1.WebHandler(routerConfig);
|
65 | }
|
66 | LocalServer.prototype.runServer = function () {
|
67 | return __awaiter(this, void 0, void 0, function () {
|
68 | var _this = this;
|
69 | return __generator(this, function (_a) {
|
70 | logger_1.Logger.info('Starting Epsilon server on port %d', this.port);
|
71 | this.server = http.createServer(this.requestHandler.bind(this)).listen(this.port);
|
72 | logger_1.Logger.info('Epsilon server is listening');
|
73 |
|
74 | process.on('SIGINT', function () {
|
75 | logger_1.Logger.info('Caught SIGINT - shutting down test server...');
|
76 | _this.aborted = true;
|
77 | });
|
78 | return [2 , this.checkFinished()];
|
79 | });
|
80 | });
|
81 | };
|
82 | LocalServer.prototype.checkFinished = function () {
|
83 | return __awaiter(this, void 0, void 0, function () {
|
84 | var wait;
|
85 | return __generator(this, function (_a) {
|
86 | switch (_a.label) {
|
87 | case 0:
|
88 | if (!this.aborted) return [3 , 1];
|
89 | return [2 , true];
|
90 | case 1: return [4 , promise_ratchet_1.PromiseRatchet.wait(1000)];
|
91 | case 2:
|
92 | wait = _a.sent();
|
93 | return [2 , this.checkFinished()];
|
94 | }
|
95 | });
|
96 | });
|
97 | };
|
98 | LocalServer.prototype.requestHandler = function (request, response) {
|
99 | return __awaiter(this, void 0, void 0, function () {
|
100 | var evt, context, logEventLevel, result, written;
|
101 | return __generator(this, function (_a) {
|
102 | switch (_a.label) {
|
103 | case 0: return [4 , this.messageToApiGatewayEvent(request)];
|
104 | case 1:
|
105 | evt = _a.sent();
|
106 | context = {
|
107 | awsRequestId: 'LOCAL-' + string_ratchet_1.StringRatchet.createType4Guid()
|
108 | };
|
109 | logEventLevel = event_util_1.EventUtil.eventIsAGraphQLIntrospection(evt) ? 'silly' : 'info';
|
110 | logger_1.Logger.logByLevel(logEventLevel, 'Processing event: %j', evt);
|
111 | if (!(evt.path == '/epsilon-poison-pill')) return [3 , 2];
|
112 | this.aborted = true;
|
113 | return [2 , true];
|
114 | case 2: return [4 , this.webHandler.lambdaHandler(evt, context)];
|
115 | case 3:
|
116 | result = _a.sent();
|
117 | return [4 , this.writeProxyResultToServerResponse(result, response)];
|
118 | case 4:
|
119 | written = _a.sent();
|
120 | return [2 , written];
|
121 | }
|
122 | });
|
123 | });
|
124 | };
|
125 | LocalServer.prototype.bodyAsBase64String = function (request) {
|
126 | return __awaiter(this, void 0, void 0, function () {
|
127 | return __generator(this, function (_a) {
|
128 | return [2 , new Promise(function (res, rej) {
|
129 | var body = [];
|
130 | request.on('data', function (chunk) {
|
131 | body.push(chunk);
|
132 | });
|
133 | request.on('end', function () {
|
134 | var rval = Buffer.concat(body).toString('base64');
|
135 | res(rval);
|
136 | });
|
137 | })];
|
138 | });
|
139 | });
|
140 | };
|
141 | LocalServer.prototype.messageToApiGatewayEvent = function (request) {
|
142 | return __awaiter(this, void 0, void 0, function () {
|
143 | var bodyString, stageIdx, stage, path, reqTime, formattedTime, queryIdx, queryStringParams, headers, rval;
|
144 | return __generator(this, function (_a) {
|
145 | switch (_a.label) {
|
146 | case 0: return [4 , this.bodyAsBase64String(request)];
|
147 | case 1:
|
148 | bodyString = _a.sent();
|
149 | stageIdx = request.url.indexOf('/', 1);
|
150 | stage = request.url.substring(1, stageIdx);
|
151 | path = request.url.substring(stageIdx + 1);
|
152 | reqTime = new Date().getTime();
|
153 | formattedTime = moment.tz(reqTime, 'UTC').format('DD/MMM/YYYY:hh:mm:ss ZZ');
|
154 | queryIdx = request.url.indexOf('?');
|
155 | queryStringParams = queryIdx > -1 ? qs.parse(request.url.substring(queryIdx + 1)) : {};
|
156 | headers = Object.assign({}, request.headers);
|
157 | headers['X-Forwarded-Proto'] = 'http';
|
158 | rval = {
|
159 | body: bodyString,
|
160 | multiValueHeaders: {},
|
161 | multiValueQueryStringParameters: {},
|
162 | resource: '/{proxy+}',
|
163 | path: request.url,
|
164 | httpMethod: request.method.toLowerCase(),
|
165 | isBase64Encoded: true,
|
166 | queryStringParameters: queryStringParams,
|
167 | pathParameters: {
|
168 | proxy: path
|
169 | },
|
170 | stageVariables: {
|
171 | baz: 'qux'
|
172 | },
|
173 | headers: headers,
|
174 | requestContext: {
|
175 | accountId: '123456789012',
|
176 | resourceId: '123456',
|
177 | stage: stage,
|
178 | requestId: string_ratchet_1.StringRatchet.createType4Guid(),
|
179 | requestTime: formattedTime,
|
180 | requestTimeEpoch: reqTime,
|
181 | identity: null,
|
182 | |
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | path: request.url,
|
199 | domainName: request.headers['host'],
|
200 | resourcePath: '/{proxy+}',
|
201 | httpMethod: request.method.toLowerCase(),
|
202 | apiId: '1234567890',
|
203 | protocol: 'HTTP/1.1'
|
204 | }
|
205 | };
|
206 | return [2 , rval];
|
207 | }
|
208 | });
|
209 | });
|
210 | };
|
211 | LocalServer.prototype.writeProxyResultToServerResponse = function (proxyResult, response) {
|
212 | return __awaiter(this, void 0, void 0, function () {
|
213 | var isGraphQLSchemaResponse, toWrite;
|
214 | return __generator(this, function (_a) {
|
215 | isGraphQLSchemaResponse = !!proxyResult && !!proxyResult.body && proxyResult.body.indexOf('{"data":{"__schema"') > -1;
|
216 | if (!isGraphQLSchemaResponse) {
|
217 | logger_1.Logger.debug('Result: %j', proxyResult);
|
218 | }
|
219 | response.statusCode = proxyResult.statusCode;
|
220 | if (proxyResult.headers) {
|
221 | Object.keys(proxyResult.headers).forEach(function (hk) {
|
222 | response.setHeader(hk, String(proxyResult.headers[hk]));
|
223 | });
|
224 | }
|
225 | toWrite = proxyResult.isBase64Encoded ? Buffer.from(proxyResult.body, 'base64') : Buffer.from(proxyResult.body);
|
226 | response.end(toWrite);
|
227 | return [2 , !!proxyResult.body];
|
228 | });
|
229 | });
|
230 | };
|
231 | return LocalServer;
|
232 | }());
|
233 | exports.LocalServer = LocalServer;
|
234 |
|
235 | function createSampleRouterConfig() {
|
236 | var yamlString = loadSampleOpenApiYaml();
|
237 | var authorizers = new Map();
|
238 | var handlers = new Map();
|
239 | var simpleRouteAuth = new simple_role_route_auth_1.SimpleRoleRouteAuth(['USER'], []);
|
240 | authorizers.set('SampleAuthorizer', function (token, event, route) { return simpleRouteAuth.handler(token, event, route); });
|
241 | handlers.set('get /', function (event, context) { return built_in_handlers_1.BuiltInHandlers.sample(event, null, context); });
|
242 | handlers.set('get /meta/server', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
243 | handlers.set('get /meta/user', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
244 | handlers.set('get /meta/item/{itemId}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
245 | handlers.set('post /secure/access-token', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event); });
|
246 | handlers.set('get /multi/fixed', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'fixed'); });
|
247 | handlers.set('get /multi/{v}', function (event) { return built_in_handlers_1.BuiltInHandlers.sample(event, 'variable'); });
|
248 | handlers.set('get /err/{code}', function (event) {
|
249 | var err = error_ratchet_1.ErrorRatchet.fErr('Fake Err : %j', event);
|
250 | err['statusCode'] = number_ratchet_1.NumberRatchet.safeNumber(event.pathParameters['code']);
|
251 | throw err;
|
252 | });
|
253 | var cfg = router_util_1.RouterUtil.openApiYamlToRouterConfig(yamlString, handlers, authorizers);
|
254 | cfg.corsAllowedHeaders = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
255 | cfg.corsAllowedOrigins = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
256 | cfg.corsAllowedMethods = epsilon_constants_1.EpsilonConstants.CORS_MATCH_REQUEST_FLAG;
|
257 | cfg.defaultErrorMessage = 'Internal Server Error';
|
258 | return cfg;
|
259 | }
|
260 | exports.createSampleRouterConfig = createSampleRouterConfig;
|
261 | function loadSampleOpenApiYaml() {
|
262 | var yamlString = fs.readFileSync(path.join(__dirname, 'static', 'sample-open-api-doc.yaml')).toString();
|
263 | return yamlString;
|
264 | }
|
265 | exports.loadSampleOpenApiYaml = loadSampleOpenApiYaml;
|
266 |
|
\ | No newline at end of file |