UNPKG

@signalapp/mock-server

Version:
101 lines (100 loc) 3.86 kB
"use strict"; // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Router = void 0; const debug_1 = __importDefault(require("debug")); const url_1 = require("url"); const querystring_1 = require("querystring"); const url_pattern_1 = __importDefault(require("url-pattern")); const util_1 = require("../../util"); const assert_1 = __importDefault(require("assert")); const debug = (0, debug_1.default)('mock:ws:router'); class Router { options; routes = []; isAuthenticated = false; constructor(options) { this.options = options; } register(method, pattern, handler) { this.routes.push({ method, pattern: new url_pattern_1.default(pattern, { segmentValueCharset: ':a-zA-Z0-9-_~ %', }), handler, }); } get(pattern, handler) { this.register('GET', pattern, handler); } patch(pattern, handler) { this.register('PATCH', pattern, handler); } put(pattern, handler) { this.register('PUT', pattern, handler); } post(pattern, handler) { this.register('POST', pattern, handler); } del(pattern, handler) { this.register('DELETE', pattern, handler); } async run(request) { const headers = {}; for (const pair of request.headers ?? []) { const [field, value = ''] = pair.split(/\s*:\s*/, 2); (0, assert_1.default)(field != null, 'Missing field name for header'); headers[field.toLowerCase()] = value; } let response = [404, { error: 'Not found' }]; debug('got request %s %s %s', this.isAuthenticated ? '(auth)' : '(unauth)', request.verb, request.path); // eslint-disable-next-line @typescript-eslint/no-deprecated const { pathname, query } = (0, url_1.parse)(request.path ?? ''); await this.options.beforeRequest(request.verb ?? '', pathname ?? '', headers); for (const { method, pattern, handler } of this.routes) { if (method !== request.verb) { continue; } const params = pattern.match(pathname ?? ''); if (params == null) { continue; } const decodedParams = {}; for (const [key, value] of Object.entries(params)) { decodedParams[key] = decodeURIComponent(String(value)); } response = await handler(decodedParams, request.body ?? undefined, headers, query === null ? undefined : (0, querystring_1.parse)(query)); break; } const [status, json, responseHeaders = {}] = response; debug('response %s %s status=%d', request.verb, request.path, status); const timestampHeader = `X-Signal-Timestamp:${Date.now()}`; const replyHeaders = [timestampHeader].concat(Object.entries(responseHeaders).map(([name, value]) => `${name}:${value}`)); if (json instanceof Uint8Array) { return { id: request.id, status, message: null, headers: ['Content-Type:application/x-protobuf'].concat(replyHeaders), body: Buffer.from(json), }; } (0, util_1.assertJsonValue)(json); return { id: request.id, status, message: null, headers: replyHeaders.concat(['Content-Type:application/json']), body: Buffer.from(JSON.stringify(json)), }; } setIsAuthenticated(value) { this.isAuthenticated = value; } } exports.Router = Router;