Index: frontend/node_modules/http-proxy-middleware/dist/_handlers.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/_handlers.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/_handlers.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,4 @@
+import type { Options } from './types';
+import type * as httpProxy from 'http-proxy';
+export declare function init(proxy: httpProxy, option: Options): void;
+export declare function getHandlers(options: Options): any;
Index: frontend/node_modules/http-proxy-middleware/dist/_handlers.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/_handlers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/_handlers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,84 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getHandlers = exports.init = void 0;
+const logger_1 = require("./logger");
+const logger = (0, logger_1.getInstance)();
+function init(proxy, option) {
+    const handlers = getHandlers(option);
+    for (const eventName of Object.keys(handlers)) {
+        proxy.on(eventName, handlers[eventName]);
+    }
+    // https://github.com/webpack/webpack-dev-server/issues/1642
+    proxy.on('econnreset', (error, req, res, target) => {
+        logger.error(`[HPM] ECONNRESET: %O`, error);
+    });
+    // https://github.com/webpack/webpack-dev-server/issues/1642#issuecomment-1104325120
+    proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
+        socket.on('error', (error) => {
+            logger.error(`[HPM] WebSocket error: %O`, error);
+        });
+    });
+    logger.debug('[HPM] Subscribed to http-proxy events:', Object.keys(handlers));
+}
+exports.init = init;
+function getHandlers(options) {
+    // https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events
+    const proxyEventsMap = {
+        error: 'onError',
+        proxyReq: 'onProxyReq',
+        proxyReqWs: 'onProxyReqWs',
+        proxyRes: 'onProxyRes',
+        open: 'onOpen',
+        close: 'onClose',
+    };
+    const handlers = {};
+    for (const [eventName, onEventName] of Object.entries(proxyEventsMap)) {
+        // all handlers for the http-proxy events are prefixed with 'on'.
+        // loop through options and try to find these handlers
+        // and add them to the handlers object for subscription in init().
+        const fnHandler = options ? options[onEventName] : null;
+        if (typeof fnHandler === 'function') {
+            handlers[eventName] = fnHandler;
+        }
+    }
+    // add default error handler in absence of error handler
+    if (typeof handlers.error !== 'function') {
+        handlers.error = defaultErrorHandler;
+    }
+    // add default close handler in absence of close handler
+    if (typeof handlers.close !== 'function') {
+        handlers.close = logClose;
+    }
+    return handlers;
+}
+exports.getHandlers = getHandlers;
+function defaultErrorHandler(err, req, res) {
+    // Re-throw error. Not recoverable since req & res are empty.
+    if (!req && !res) {
+        throw err; // "Error: Must provide a proper URL as target"
+    }
+    const host = req.headers && req.headers.host;
+    const code = err.code;
+    if (res.writeHead && !res.headersSent) {
+        if (/HPE_INVALID/.test(code)) {
+            res.writeHead(502);
+        }
+        else {
+            switch (code) {
+                case 'ECONNRESET':
+                case 'ENOTFOUND':
+                case 'ECONNREFUSED':
+                case 'ETIMEDOUT':
+                    res.writeHead(504);
+                    break;
+                default:
+                    res.writeHead(500);
+            }
+        }
+    }
+    res.end(`Error occurred while trying to proxy: ${host}${req.url}`);
+}
+function logClose(req, socket, head) {
+    // view disconnected websocket connections
+    logger.info('[HPM] Client disconnected');
+}
Index: frontend/node_modules/http-proxy-middleware/dist/config-factory.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/config-factory.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/config-factory.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+import { Filter, Options } from './types';
+export declare type Config = {
+    context: Filter;
+    options: Options;
+};
+export declare function createConfig(context: any, opts?: Options): Config;
Index: frontend/node_modules/http-proxy-middleware/dist/config-factory.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/config-factory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/config-factory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,80 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createConfig = void 0;
+const isPlainObj = require("is-plain-obj");
+const url = require("url");
+const errors_1 = require("./errors");
+const logger_1 = require("./logger");
+const logger = (0, logger_1.getInstance)();
+function createConfig(context, opts) {
+    // structure of config object to be returned
+    const config = {
+        context: undefined,
+        options: {},
+    };
+    // app.use('/api', proxy({target:'http://localhost:9000'}));
+    if (isContextless(context, opts)) {
+        config.context = '/';
+        config.options = Object.assign(config.options, context);
+        // app.use('/api', proxy('http://localhost:9000'));
+        // app.use(proxy('http://localhost:9000/api'));
+    }
+    else if (isStringShortHand(context)) {
+        const oUrl = url.parse(context);
+        const target = [oUrl.protocol, '//', oUrl.host].join('');
+        config.context = oUrl.pathname || '/';
+        config.options = Object.assign(config.options, { target }, opts);
+        if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
+            config.options.ws = true;
+        }
+        // app.use('/api', proxy({target:'http://localhost:9000'}));
+    }
+    else {
+        config.context = context;
+        config.options = Object.assign(config.options, opts);
+    }
+    configureLogger(config.options);
+    if (!config.options.target && !config.options.router) {
+        throw new Error(errors_1.ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING);
+    }
+    return config;
+}
+exports.createConfig = createConfig;
+/**
+ * Checks if a String only target/config is provided.
+ * This can be just the host or with the optional path.
+ *
+ * @example
+ *      app.use('/api', proxy('http://localhost:9000'));
+ *      app.use(proxy('http://localhost:9000/api'));
+ *
+ * @param  {String}  context [description]
+ * @return {Boolean}         [description]
+ */
+function isStringShortHand(context) {
+    if (typeof context === 'string') {
+        return !!url.parse(context).host;
+    }
+}
+/**
+ * Checks if a Object only config is provided, without a context.
+ * In this case the all paths will be proxied.
+ *
+ * @example
+ *     app.use('/api', proxy({target:'http://localhost:9000'}));
+ *
+ * @param  {Object}  context [description]
+ * @param  {*}       opts    [description]
+ * @return {Boolean}         [description]
+ */
+function isContextless(context, opts) {
+    return isPlainObj(context) && (opts == null || Object.keys(opts).length === 0);
+}
+function configureLogger(options) {
+    if (options.logLevel) {
+        logger.setLevel(options.logLevel);
+    }
+    if (options.logProvider) {
+        logger.setProvider(options.logProvider);
+    }
+}
Index: frontend/node_modules/http-proxy-middleware/dist/context-matcher.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/context-matcher.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/context-matcher.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2 @@
+import type { Filter, Request } from './types';
+export declare function match(context: Filter, uri: string, req: Request): boolean;
Index: frontend/node_modules/http-proxy-middleware/dist/context-matcher.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/context-matcher.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/context-matcher.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,81 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.match = void 0;
+const isGlob = require("is-glob");
+const micromatch = require("micromatch");
+const url = require("url");
+const errors_1 = require("./errors");
+function match(context, uri, req) {
+    // single path
+    if (isStringPath(context)) {
+        return matchSingleStringPath(context, uri);
+    }
+    // single glob path
+    if (isGlobPath(context)) {
+        return matchSingleGlobPath(context, uri);
+    }
+    // multi path
+    if (Array.isArray(context)) {
+        if (context.every(isStringPath)) {
+            return matchMultiPath(context, uri);
+        }
+        if (context.every(isGlobPath)) {
+            return matchMultiGlobPath(context, uri);
+        }
+        throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY);
+    }
+    // custom matching
+    if (typeof context === 'function') {
+        const pathname = getUrlPathName(uri);
+        return context(pathname, req);
+    }
+    throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_GENERIC);
+}
+exports.match = match;
+/**
+ * @param  {String} context '/api'
+ * @param  {String} uri     'http://example.org/api/b/c/d.html'
+ * @return {Boolean}
+ */
+function matchSingleStringPath(context, uri) {
+    const pathname = getUrlPathName(uri);
+    return pathname.indexOf(context) === 0;
+}
+function matchSingleGlobPath(pattern, uri) {
+    const pathname = getUrlPathName(uri);
+    const matches = micromatch([pathname], pattern);
+    return matches && matches.length > 0;
+}
+function matchMultiGlobPath(patternList, uri) {
+    return matchSingleGlobPath(patternList, uri);
+}
+/**
+ * @param  {String} contextList ['/api', '/ajax']
+ * @param  {String} uri     'http://example.org/api/b/c/d.html'
+ * @return {Boolean}
+ */
+function matchMultiPath(contextList, uri) {
+    let isMultiPath = false;
+    for (const context of contextList) {
+        if (matchSingleStringPath(context, uri)) {
+            isMultiPath = true;
+            break;
+        }
+    }
+    return isMultiPath;
+}
+/**
+ * Parses URI and returns RFC 3986 path
+ *
+ * @param  {String} uri from req.url
+ * @return {String}     RFC 3986 path
+ */
+function getUrlPathName(uri) {
+    return uri && url.parse(uri).pathname;
+}
+function isStringPath(context) {
+    return typeof context === 'string' && !isGlob(context);
+}
+function isGlobPath(context) {
+    return isGlob(context);
+}
Index: frontend/node_modules/http-proxy-middleware/dist/errors.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/errors.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/errors.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+export declare enum ERRORS {
+    ERR_CONFIG_FACTORY_TARGET_MISSING = "[HPM] Missing \"target\" option. Example: {target: \"http://www.example.org\"}",
+    ERR_CONTEXT_MATCHER_GENERIC = "[HPM] Invalid context. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]",
+    ERR_CONTEXT_MATCHER_INVALID_ARRAY = "[HPM] Invalid context. Expecting something like: [\"/api\", \"/ajax\"] or [\"/api/**\", \"!**.html\"]",
+    ERR_PATH_REWRITER_CONFIG = "[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function"
+}
Index: frontend/node_modules/http-proxy-middleware/dist/errors.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/errors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/errors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,10 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ERRORS = void 0;
+var ERRORS;
+(function (ERRORS) {
+    ERRORS["ERR_CONFIG_FACTORY_TARGET_MISSING"] = "[HPM] Missing \"target\" option. Example: {target: \"http://www.example.org\"}";
+    ERRORS["ERR_CONTEXT_MATCHER_GENERIC"] = "[HPM] Invalid context. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]";
+    ERRORS["ERR_CONTEXT_MATCHER_INVALID_ARRAY"] = "[HPM] Invalid context. Expecting something like: [\"/api\", \"/ajax\"] or [\"/api/**\", \"!**.html\"]";
+    ERRORS["ERR_PATH_REWRITER_CONFIG"] = "[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function";
+})(ERRORS = exports.ERRORS || (exports.ERRORS = {}));
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+/// <reference types="node" />
+import type * as http from 'http';
+/**
+ * Fix proxied body if bodyParser is involved.
+ */
+export declare function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingMessage): void;
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fixRequestBody = void 0;
+const querystring = require("querystring");
+/**
+ * Fix proxied body if bodyParser is involved.
+ */
+function fixRequestBody(proxyReq, req) {
+    // skip fixRequestBody() when req.readableLength not 0 (bodyParser failure)
+    if (req.readableLength !== 0) {
+        return;
+    }
+    const requestBody = req.body;
+    if (!requestBody) {
+        return;
+    }
+    const contentType = proxyReq.getHeader('Content-Type');
+    if (!contentType) {
+        return;
+    }
+    const writeBody = (bodyData) => {
+        // deepcode ignore ContentLengthInCode: bodyParser fix
+        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
+        proxyReq.write(bodyData);
+    };
+    if (contentType.includes('application/json')) {
+        writeBody(JSON.stringify(requestBody));
+    }
+    else if (contentType.includes('application/x-www-form-urlencoded')) {
+        writeBody(querystring.stringify(requestBody));
+    }
+}
+exports.fixRequestBody = fixRequestBody;
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/index.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './public';
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/index.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./public"), exports);
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/public.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/public.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/public.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2 @@
+export { responseInterceptor } from './response-interceptor';
+export { fixRequestBody } from './fix-request-body';
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/public.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/public.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/public.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fixRequestBody = exports.responseInterceptor = void 0;
+var response_interceptor_1 = require("./response-interceptor");
+Object.defineProperty(exports, "responseInterceptor", { enumerable: true, get: function () { return response_interceptor_1.responseInterceptor; } });
+var fix_request_body_1 = require("./fix-request-body");
+Object.defineProperty(exports, "fixRequestBody", { enumerable: true, get: function () { return fix_request_body_1.fixRequestBody; } });
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+/// <reference types="node" />
+import type * as http from 'http';
+declare type Interceptor = (buffer: Buffer, proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => Promise<Buffer | string>;
+/**
+ * Intercept responses from upstream.
+ * Automatically decompress (deflate, gzip, brotli).
+ * Give developer the opportunity to modify intercepted Buffer and http.ServerResponse
+ *
+ * NOTE: must set options.selfHandleResponse=true (prevent automatic call of res.end())
+ */
+export declare function responseInterceptor(interceptor: Interceptor): (proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
+export {};
Index: frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,86 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.responseInterceptor = void 0;
+const zlib = require("zlib");
+/**
+ * Intercept responses from upstream.
+ * Automatically decompress (deflate, gzip, brotli).
+ * Give developer the opportunity to modify intercepted Buffer and http.ServerResponse
+ *
+ * NOTE: must set options.selfHandleResponse=true (prevent automatic call of res.end())
+ */
+function responseInterceptor(interceptor) {
+    return async function proxyRes(proxyRes, req, res) {
+        const originalProxyRes = proxyRes;
+        let buffer = Buffer.from('', 'utf8');
+        // decompress proxy response
+        const _proxyRes = decompress(proxyRes, proxyRes.headers['content-encoding']);
+        // concat data stream
+        _proxyRes.on('data', (chunk) => (buffer = Buffer.concat([buffer, chunk])));
+        _proxyRes.on('end', async () => {
+            // copy original headers
+            copyHeaders(proxyRes, res);
+            // call interceptor with intercepted response (buffer)
+            const interceptedBuffer = Buffer.from(await interceptor(buffer, originalProxyRes, req, res));
+            // set correct content-length (with double byte character support)
+            res.setHeader('content-length', Buffer.byteLength(interceptedBuffer, 'utf8'));
+            res.write(interceptedBuffer);
+            res.end();
+        });
+        _proxyRes.on('error', (error) => {
+            res.end(`Error fetching proxied request: ${error.message}`);
+        });
+    };
+}
+exports.responseInterceptor = responseInterceptor;
+/**
+ * Streaming decompression of proxy response
+ * source: https://github.com/apache/superset/blob/9773aba522e957ed9423045ca153219638a85d2f/superset-frontend/webpack.proxy-config.js#L116
+ */
+function decompress(proxyRes, contentEncoding) {
+    let _proxyRes = proxyRes;
+    let decompress;
+    switch (contentEncoding) {
+        case 'gzip':
+            decompress = zlib.createGunzip();
+            break;
+        case 'br':
+            decompress = zlib.createBrotliDecompress();
+            break;
+        case 'deflate':
+            decompress = zlib.createInflate();
+            break;
+        default:
+            break;
+    }
+    if (decompress) {
+        _proxyRes.pipe(decompress);
+        _proxyRes = decompress;
+    }
+    return _proxyRes;
+}
+/**
+ * Copy original headers
+ * https://github.com/apache/superset/blob/9773aba522e957ed9423045ca153219638a85d2f/superset-frontend/webpack.proxy-config.js#L78
+ */
+function copyHeaders(originalResponse, response) {
+    response.statusCode = originalResponse.statusCode;
+    response.statusMessage = originalResponse.statusMessage;
+    if (response.setHeader) {
+        let keys = Object.keys(originalResponse.headers);
+        // ignore chunked, brotli, gzip, deflate headers
+        keys = keys.filter((key) => !['content-encoding', 'transfer-encoding'].includes(key));
+        keys.forEach((key) => {
+            let value = originalResponse.headers[key];
+            if (key === 'set-cookie') {
+                // remove cookie domain
+                value = Array.isArray(value) ? value : [value];
+                value = value.map((x) => x.replace(/Domain=[^;]+?/i, ''));
+            }
+            response.setHeader(key, value);
+        });
+    }
+    else {
+        response.headers = originalResponse.headers;
+    }
+}
Index: frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+import type { Filter, RequestHandler, Options } from './types';
+export declare class HttpProxyMiddleware {
+    private logger;
+    private config;
+    private wsInternalSubscribed;
+    private serverOnCloseSubscribed;
+    private proxyOptions;
+    private proxy;
+    private pathRewriter;
+    constructor(context: Filter | Options, opts?: Options);
+    middleware: RequestHandler;
+    private catchUpgradeRequest;
+    private handleUpgrade;
+    /**
+     * Determine whether request should be proxied.
+     *
+     * @private
+     * @param  {String} context [description]
+     * @param  {Object} req     [description]
+     * @return {Boolean}
+     */
+    private shouldProxy;
+    /**
+     * Apply option.router and option.pathRewrite
+     * Order matters:
+     *    Router uses original path for routing;
+     *    NOT the modified path, after it has been rewritten by pathRewrite
+     * @param {Object} req
+     * @return {Object} proxy options
+     */
+    private prepareProxyRequest;
+    private applyRouter;
+    private applyPathRewrite;
+    private logError;
+}
Index: frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/http-proxy-middleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,163 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HttpProxyMiddleware = void 0;
+const httpProxy = require("http-proxy");
+const config_factory_1 = require("./config-factory");
+const contextMatcher = require("./context-matcher");
+const handlers = require("./_handlers");
+const logger_1 = require("./logger");
+const PathRewriter = require("./path-rewriter");
+const Router = require("./router");
+class HttpProxyMiddleware {
+    constructor(context, opts) {
+        this.logger = (0, logger_1.getInstance)();
+        this.wsInternalSubscribed = false;
+        this.serverOnCloseSubscribed = false;
+        // https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
+        this.middleware = async (req, res, next) => {
+            var _a, _b;
+            if (this.shouldProxy(this.config.context, req)) {
+                try {
+                    const activeProxyOptions = await this.prepareProxyRequest(req);
+                    this.proxy.web(req, res, activeProxyOptions);
+                }
+                catch (err) {
+                    next(err);
+                }
+            }
+            else {
+                next();
+            }
+            /**
+             * Get the server object to subscribe to server events;
+             * 'upgrade' for websocket and 'close' for graceful shutdown
+             *
+             * NOTE:
+             * req.socket: node >= 13
+             * req.connection: node < 13 (Remove this when node 12/13 support is dropped)
+             */
+            const server = (_b = ((_a = req.socket) !== null && _a !== void 0 ? _a : req.connection)) === null || _b === void 0 ? void 0 : _b.server;
+            if (server && !this.serverOnCloseSubscribed) {
+                server.on('close', () => {
+                    this.logger.info('[HPM] server close signal received: closing proxy server');
+                    this.proxy.close();
+                });
+                this.serverOnCloseSubscribed = true;
+            }
+            if (this.proxyOptions.ws === true) {
+                // use initial request to access the server object to subscribe to http upgrade event
+                this.catchUpgradeRequest(server);
+            }
+        };
+        this.catchUpgradeRequest = (server) => {
+            if (!this.wsInternalSubscribed) {
+                server.on('upgrade', this.handleUpgrade);
+                // prevent duplicate upgrade handling;
+                // in case external upgrade is also configured
+                this.wsInternalSubscribed = true;
+            }
+        };
+        this.handleUpgrade = async (req, socket, head) => {
+            if (this.shouldProxy(this.config.context, req)) {
+                const activeProxyOptions = await this.prepareProxyRequest(req);
+                this.proxy.ws(req, socket, head, activeProxyOptions);
+                this.logger.info('[HPM] Upgrading to WebSocket');
+            }
+        };
+        /**
+         * Determine whether request should be proxied.
+         *
+         * @private
+         * @param  {String} context [description]
+         * @param  {Object} req     [description]
+         * @return {Boolean}
+         */
+        this.shouldProxy = (context, req) => {
+            try {
+                const path = req.originalUrl || req.url;
+                return contextMatcher.match(context, path, req);
+            }
+            catch (error) {
+                this.logger.error(error);
+                return false;
+            }
+        };
+        /**
+         * Apply option.router and option.pathRewrite
+         * Order matters:
+         *    Router uses original path for routing;
+         *    NOT the modified path, after it has been rewritten by pathRewrite
+         * @param {Object} req
+         * @return {Object} proxy options
+         */
+        this.prepareProxyRequest = async (req) => {
+            // https://github.com/chimurai/http-proxy-middleware/issues/17
+            // https://github.com/chimurai/http-proxy-middleware/issues/94
+            req.url = req.originalUrl || req.url;
+            // store uri before it gets rewritten for logging
+            const originalPath = req.url;
+            const newProxyOptions = Object.assign({}, this.proxyOptions);
+            // Apply in order:
+            // 1. option.router
+            // 2. option.pathRewrite
+            await this.applyRouter(req, newProxyOptions);
+            await this.applyPathRewrite(req, this.pathRewriter);
+            // debug logging for both http(s) and websockets
+            if (this.proxyOptions.logLevel === 'debug') {
+                const arrow = (0, logger_1.getArrow)(originalPath, req.url, this.proxyOptions.target, newProxyOptions.target);
+                this.logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target);
+            }
+            return newProxyOptions;
+        };
+        // Modify option.target when router present.
+        this.applyRouter = async (req, options) => {
+            let newTarget;
+            if (options.router) {
+                newTarget = await Router.getTarget(req, options);
+                if (newTarget) {
+                    this.logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget);
+                    options.target = newTarget;
+                }
+            }
+        };
+        // rewrite path
+        this.applyPathRewrite = async (req, pathRewriter) => {
+            if (pathRewriter) {
+                const path = await pathRewriter(req.url, req);
+                if (typeof path === 'string') {
+                    req.url = path;
+                }
+                else {
+                    this.logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url);
+                }
+            }
+        };
+        this.logError = (err, req, res, target) => {
+            var _a;
+            const hostname = ((_a = req.headers) === null || _a === void 0 ? void 0 : _a.host) || req.hostname || req.host; // (websocket) || (node0.10 || node 4/5)
+            const requestHref = `${hostname}${req.url}`;
+            const targetHref = `${target === null || target === void 0 ? void 0 : target.href}`; // target is undefined when websocket errors
+            const errorMessage = '[HPM] Error occurred while proxying request %s to %s [%s] (%s)';
+            const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
+            this.logger.error(errorMessage, requestHref, targetHref, err.code || err, errReference);
+        };
+        this.config = (0, config_factory_1.createConfig)(context, opts);
+        this.proxyOptions = this.config.options;
+        // create proxy
+        this.proxy = httpProxy.createProxyServer({});
+        this.logger.info(`[HPM] Proxy created: ${this.config.context}  -> ${this.proxyOptions.target}`);
+        this.pathRewriter = PathRewriter.createPathRewriter(this.proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
+        // attach handler to http-proxy events
+        handlers.init(this.proxy, this.proxyOptions);
+        // log errors for debug purpose
+        this.proxy.on('error', this.logError);
+        // https://github.com/chimurai/http-proxy-middleware/issues/19
+        // expose function to upgrade externally
+        this.middleware.upgrade = (req, socket, head) => {
+            if (!this.wsInternalSubscribed) {
+                this.handleUpgrade(req, socket, head);
+            }
+        };
+    }
+}
+exports.HttpProxyMiddleware = HttpProxyMiddleware;
Index: frontend/node_modules/http-proxy-middleware/dist/index.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,4 @@
+import { Filter, Options } from './types';
+export declare function createProxyMiddleware(context: Filter | Options, options?: Options): import("./types").RequestHandler;
+export * from './handlers';
+export { Filter, Options, RequestHandler } from './types';
Index: frontend/node_modules/http-proxy-middleware/dist/index.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createProxyMiddleware = void 0;
+const http_proxy_middleware_1 = require("./http-proxy-middleware");
+function createProxyMiddleware(context, options) {
+    const { middleware } = new http_proxy_middleware_1.HttpProxyMiddleware(context, options);
+    return middleware;
+}
+exports.createProxyMiddleware = createProxyMiddleware;
+__exportStar(require("./handlers"), exports);
Index: frontend/node_modules/http-proxy-middleware/dist/logger.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/logger.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/logger.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+export declare function getInstance(): any;
+/**
+ * -> normal proxy
+ * => router
+ * ~> pathRewrite
+ * ≈> router + pathRewrite
+ *
+ * @param  {String} originalPath
+ * @param  {String} newPath
+ * @param  {String} originalTarget
+ * @param  {String} newTarget
+ * @return {String}
+ */
+export declare function getArrow(originalPath: any, newPath: any, originalTarget: any, newTarget: any): string;
Index: frontend/node_modules/http-proxy-middleware/dist/logger.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/logger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/logger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,135 @@
+"use strict";
+/* eslint-disable prefer-rest-params */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getArrow = exports.getInstance = void 0;
+const util = require("util");
+let loggerInstance;
+const defaultProvider = {
+    // tslint:disable: no-console
+    log: console.log,
+    debug: console.log,
+    info: console.info,
+    warn: console.warn,
+    error: console.error,
+};
+// log level 'weight'
+var LEVELS;
+(function (LEVELS) {
+    LEVELS[LEVELS["debug"] = 10] = "debug";
+    LEVELS[LEVELS["info"] = 20] = "info";
+    LEVELS[LEVELS["warn"] = 30] = "warn";
+    LEVELS[LEVELS["error"] = 50] = "error";
+    LEVELS[LEVELS["silent"] = 80] = "silent";
+})(LEVELS || (LEVELS = {}));
+function getInstance() {
+    if (!loggerInstance) {
+        loggerInstance = new Logger();
+    }
+    return loggerInstance;
+}
+exports.getInstance = getInstance;
+class Logger {
+    constructor() {
+        this.setLevel('info');
+        this.setProvider(() => defaultProvider);
+    }
+    // log will log messages, regardless of logLevels
+    log() {
+        this.provider.log(this._interpolate.apply(null, arguments));
+    }
+    debug() {
+        if (this._showLevel('debug')) {
+            this.provider.debug(this._interpolate.apply(null, arguments));
+        }
+    }
+    info() {
+        if (this._showLevel('info')) {
+            this.provider.info(this._interpolate.apply(null, arguments));
+        }
+    }
+    warn() {
+        if (this._showLevel('warn')) {
+            this.provider.warn(this._interpolate.apply(null, arguments));
+        }
+    }
+    error() {
+        if (this._showLevel('error')) {
+            this.provider.error(this._interpolate.apply(null, arguments));
+        }
+    }
+    setLevel(v) {
+        if (this.isValidLevel(v)) {
+            this.logLevel = v;
+        }
+    }
+    setProvider(fn) {
+        if (fn && this.isValidProvider(fn)) {
+            this.provider = fn(defaultProvider);
+        }
+    }
+    isValidProvider(fnProvider) {
+        const result = true;
+        if (fnProvider && typeof fnProvider !== 'function') {
+            throw new Error('[HPM] Log provider config error. Expecting a function.');
+        }
+        return result;
+    }
+    isValidLevel(levelName) {
+        const validLevels = Object.keys(LEVELS);
+        const isValid = validLevels.includes(levelName);
+        if (!isValid) {
+            throw new Error('[HPM] Log level error. Invalid logLevel.');
+        }
+        return isValid;
+    }
+    /**
+     * Decide to log or not to log, based on the log levels 'weight'
+     * @param  {String}  showLevel [debug, info, warn, error, silent]
+     * @return {Boolean}
+     */
+    _showLevel(showLevel) {
+        let result = false;
+        const currentLogLevel = LEVELS[this.logLevel];
+        if (currentLogLevel && currentLogLevel <= LEVELS[showLevel]) {
+            result = true;
+        }
+        return result;
+    }
+    // make sure logged messages and its data are return interpolated
+    // make it possible for additional log data, such date/time or custom prefix.
+    _interpolate(format, ...args) {
+        const result = util.format(format, ...args);
+        return result;
+    }
+}
+/**
+ * -> normal proxy
+ * => router
+ * ~> pathRewrite
+ * ≈> router + pathRewrite
+ *
+ * @param  {String} originalPath
+ * @param  {String} newPath
+ * @param  {String} originalTarget
+ * @param  {String} newTarget
+ * @return {String}
+ */
+function getArrow(originalPath, newPath, originalTarget, newTarget) {
+    const arrow = ['>'];
+    const isNewTarget = originalTarget !== newTarget; // router
+    const isNewPath = originalPath !== newPath; // pathRewrite
+    if (isNewPath && !isNewTarget) {
+        arrow.unshift('~');
+    }
+    else if (!isNewPath && isNewTarget) {
+        arrow.unshift('=');
+    }
+    else if (isNewPath && isNewTarget) {
+        arrow.unshift('≈');
+    }
+    else {
+        arrow.unshift('-');
+    }
+    return arrow.join('');
+}
+exports.getArrow = getArrow;
Index: frontend/node_modules/http-proxy-middleware/dist/path-rewriter.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/path-rewriter.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/path-rewriter.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,7 @@
+/**
+ * Create rewrite function, to cache parsed rewrite rules.
+ *
+ * @param {Object} rewriteConfig
+ * @return {Function} Function to rewrite paths; This function should accept `path` (request.url) as parameter
+ */
+export declare function createPathRewriter(rewriteConfig: any): any;
Index: frontend/node_modules/http-proxy-middleware/dist/path-rewriter.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/path-rewriter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/path-rewriter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,66 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createPathRewriter = void 0;
+const isPlainObj = require("is-plain-obj");
+const errors_1 = require("./errors");
+const logger_1 = require("./logger");
+const logger = (0, logger_1.getInstance)();
+/**
+ * Create rewrite function, to cache parsed rewrite rules.
+ *
+ * @param {Object} rewriteConfig
+ * @return {Function} Function to rewrite paths; This function should accept `path` (request.url) as parameter
+ */
+function createPathRewriter(rewriteConfig) {
+    let rulesCache;
+    if (!isValidRewriteConfig(rewriteConfig)) {
+        return;
+    }
+    if (typeof rewriteConfig === 'function') {
+        const customRewriteFn = rewriteConfig;
+        return customRewriteFn;
+    }
+    else {
+        rulesCache = parsePathRewriteRules(rewriteConfig);
+        return rewritePath;
+    }
+    function rewritePath(path) {
+        let result = path;
+        for (const rule of rulesCache) {
+            if (rule.regex.test(path)) {
+                result = result.replace(rule.regex, rule.value);
+                logger.debug('[HPM] Rewriting path from "%s" to "%s"', path, result);
+                break;
+            }
+        }
+        return result;
+    }
+}
+exports.createPathRewriter = createPathRewriter;
+function isValidRewriteConfig(rewriteConfig) {
+    if (typeof rewriteConfig === 'function') {
+        return true;
+    }
+    else if (isPlainObj(rewriteConfig)) {
+        return Object.keys(rewriteConfig).length !== 0;
+    }
+    else if (rewriteConfig === undefined || rewriteConfig === null) {
+        return false;
+    }
+    else {
+        throw new Error(errors_1.ERRORS.ERR_PATH_REWRITER_CONFIG);
+    }
+}
+function parsePathRewriteRules(rewriteConfig) {
+    const rules = [];
+    if (isPlainObj(rewriteConfig)) {
+        for (const [key] of Object.entries(rewriteConfig)) {
+            rules.push({
+                regex: new RegExp(key),
+                value: rewriteConfig[key],
+            });
+            logger.info('[HPM] Proxy rewrite rule created: "%s" ~> "%s"', key, rewriteConfig[key]);
+        }
+    }
+    return rules;
+}
Index: frontend/node_modules/http-proxy-middleware/dist/router.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/router.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/router.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export declare function getTarget(req: any, config: any): Promise<any>;
Index: frontend/node_modules/http-proxy-middleware/dist/router.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/router.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/router.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,46 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getTarget = void 0;
+const isPlainObj = require("is-plain-obj");
+const logger_1 = require("./logger");
+const logger = (0, logger_1.getInstance)();
+async function getTarget(req, config) {
+    let newTarget;
+    const router = config.router;
+    if (isPlainObj(router)) {
+        newTarget = getTargetFromProxyTable(req, router);
+    }
+    else if (typeof router === 'function') {
+        newTarget = await router(req);
+    }
+    return newTarget;
+}
+exports.getTarget = getTarget;
+function getTargetFromProxyTable(req, table) {
+    let result;
+    const host = req.headers.host;
+    const path = req.url;
+    const hostAndPath = host + path;
+    for (const [key] of Object.entries(table)) {
+        if (containsPath(key)) {
+            if (hostAndPath.indexOf(key) > -1) {
+                // match 'localhost:3000/api'
+                result = table[key];
+                logger.debug('[HPM] Router table match: "%s"', key);
+                break;
+            }
+        }
+        else {
+            if (key === host) {
+                // match 'localhost:3000'
+                result = table[key];
+                logger.debug('[HPM] Router table match: "%s"', host);
+                break;
+            }
+        }
+    }
+    return result;
+}
+function containsPath(v) {
+    return v.indexOf('/') > -1;
+}
Index: frontend/node_modules/http-proxy-middleware/dist/types.d.ts
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,54 @@
+/**
+ * Based on definition by DefinitelyTyped:
+ * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
+ */
+/// <reference types="node" />
+import type * as express from 'express';
+import type * as http from 'http';
+import type * as httpProxy from 'http-proxy';
+import type * as net from 'net';
+import type * as url from 'url';
+export interface Request extends express.Request {
+}
+export interface Response extends express.Response {
+}
+export interface RequestHandler extends express.RequestHandler {
+    upgrade?: (req: Request, socket: net.Socket, head: any) => void;
+}
+export declare type Filter = string | string[] | ((pathname: string, req: Request) => boolean);
+export interface Options extends httpProxy.ServerOptions {
+    pathRewrite?: {
+        [regexp: string]: string;
+    } | ((path: string, req: Request) => string) | ((path: string, req: Request) => Promise<string>);
+    router?: {
+        [hostOrPath: string]: httpProxy.ServerOptions['target'];
+    } | ((req: Request) => httpProxy.ServerOptions['target']) | ((req: Request) => Promise<httpProxy.ServerOptions['target']>);
+    logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
+    logProvider?: LogProviderCallback;
+    onError?: OnErrorCallback;
+    onProxyRes?: OnProxyResCallback;
+    onProxyReq?: OnProxyReqCallback;
+    onProxyReqWs?: OnProxyReqWsCallback;
+    onOpen?: OnOpenCallback;
+    onClose?: OnCloseCallback;
+}
+interface LogProvider {
+    log: Logger;
+    debug?: Logger;
+    info?: Logger;
+    warn?: Logger;
+    error?: Logger;
+}
+declare type Logger = (...args: any[]) => void;
+export declare type LogProviderCallback = (provider: LogProvider) => LogProvider;
+/**
+ * Use types based on the events listeners from http-proxy
+ * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/51504fd999031b7f025220fab279f1b2155cbaff/types/http-proxy/index.d.ts
+ */
+export declare type OnErrorCallback = (err: Error, req: Request, res: Response, target?: string | Partial<url.Url>) => void;
+export declare type OnProxyResCallback = (proxyRes: http.IncomingMessage, req: Request, res: Response) => void;
+export declare type OnProxyReqCallback = (proxyReq: http.ClientRequest, req: Request, res: Response, options: httpProxy.ServerOptions) => void;
+export declare type OnProxyReqWsCallback = (proxyReq: http.ClientRequest, req: Request, socket: net.Socket, options: httpProxy.ServerOptions, head: any) => void;
+export declare type OnCloseCallback = (proxyRes: Response, proxySocket: net.Socket, proxyHead: any) => void;
+export declare type OnOpenCallback = (proxySocket: net.Socket) => void;
+export {};
Index: frontend/node_modules/http-proxy-middleware/dist/types.js
===================================================================
--- frontend/node_modules/http-proxy-middleware/dist/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/dist/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+"use strict";
+/**
+ * Based on definition by DefinitelyTyped:
+ * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
