Index: frontend/node_modules/http-proxy-middleware/LICENSE
===================================================================
--- frontend/node_modules/http-proxy-middleware/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Steven Chim
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
Index: frontend/node_modules/http-proxy-middleware/README.md
===================================================================
--- frontend/node_modules/http-proxy-middleware/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,598 @@
+# http-proxy-middleware
+
+[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/chimurai/http-proxy-middleware/CI/master?style=flat-square)](https://github.com/chimurai/http-proxy-middleware/actions?query=branch%3Amaster)
+[![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square)](https://coveralls.io/r/chimurai/http-proxy-middleware)
+[![dependency Status](https://snyk.io/test/npm/http-proxy-middleware/badge.svg?style=flat-square)](https://snyk.io/test/npm/http-proxy-middleware)
+[![npm](https://img.shields.io/npm/v/http-proxy-middleware?color=%23CC3534&style=flat-square)](https://www.npmjs.com/package/http-proxy-middleware)
+
+Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/strongloop/express), [browser-sync](https://github.com/BrowserSync/browser-sync) and [many more](#compatible-servers).
+
+Powered by the popular Nodejitsu [`http-proxy`](https://github.com/nodejitsu/node-http-proxy). [![GitHub stars](https://img.shields.io/github/stars/nodejitsu/node-http-proxy.svg?style=social&label=Star)](https://github.com/nodejitsu/node-http-proxy)
+
+## ⚠️ Note <!-- omit in toc -->
+
+This page is showing documentation for version v2.x.x ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
+
+If you're looking for v0.x documentation. Go to:
+https://github.com/chimurai/http-proxy-middleware/tree/v0.21.0#readme
+
+## TL;DR <!-- omit in toc -->
+
+Proxy `/api` requests to `http://www.example.org`
+
+```javascript
+// javascript
+
+const express = require('express');
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+const app = express();
+
+app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
+app.listen(3000);
+
+// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
+```
+
+```typescript
+// typescript
+
+import * as express from 'express';
+import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-proxy-middleware';
+
+const app = express();
+
+app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
+app.listen(3000);
+
+// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
+```
+
+_All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#options) can be used, along with some extra `http-proxy-middleware` [options](#options).
+
+:bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
+
+## Table of Contents <!-- omit in toc -->
+
+- [Install](#install)
+- [Core concept](#core-concept)
+- [Example](#example)
+- [Context matching](#context-matching)
+- [Options](#options)
+  - [http-proxy-middleware options](#http-proxy-middleware-options)
+  - [http-proxy events](#http-proxy-events)
+  - [http-proxy options](#http-proxy-options)
+- [Shorthand](#shorthand)
+  - [app.use(path, proxy)](#appusepath-proxy)
+- [WebSocket](#websocket)
+  - [External WebSocket upgrade](#external-websocket-upgrade)
+- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
+- [Intercept and manipulate responses](#intercept-and-manipulate-responses)
+- [Working examples](#working-examples)
+- [Recipes](#recipes)
+- [Compatible servers](#compatible-servers)
+- [Tests](#tests)
+- [Changelog](#changelog)
+- [License](#license)
+
+## Install
+
+```bash
+$ npm install --save-dev http-proxy-middleware
+```
+
+## Core concept
+
+Proxy middleware configuration.
+
+#### createProxyMiddleware([context,] config)
+
+```javascript
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org' });
+//                                    \____/   \_____________________________/
+//                                      |                    |
+//                                    context             options
+
+// 'apiProxy' is now ready to be used as middleware in a server.
+```
+
+- **context**: Determine which requests should be proxied to the target host.
+  (more on [context matching](#context-matching))
+- **options.target**: target host to proxy to. _(protocol + host)_
+
+(full list of [`http-proxy-middleware` configuration options](#options))
+
+#### createProxyMiddleware(uri [, config])
+
+```javascript
+// shorthand syntax for the example above:
+const apiProxy = createProxyMiddleware('http://www.example.org/api');
+```
+
+More about the [shorthand configuration](#shorthand).
+
+## Example
+
+An example with `express` server.
+
+```javascript
+// include dependencies
+const express = require('express');
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+// proxy middleware options
+/** @type {import('http-proxy-middleware/dist/types').Options} */
+const options = {
+  target: 'http://www.example.org', // target host
+  changeOrigin: true, // needed for virtual hosted sites
+  ws: true, // proxy websockets
+  pathRewrite: {
+    '^/api/old-path': '/api/new-path', // rewrite path
+    '^/api/remove/path': '/path', // remove base path
+  },
+  router: {
+    // when request.headers.host == 'dev.localhost:3000',
+    // override target 'http://www.example.org' to 'http://localhost:8000'
+    'dev.localhost:3000': 'http://localhost:8000',
+  },
+};
+
+// create the proxy (without context)
+const exampleProxy = createProxyMiddleware(options);
+
+// mount `exampleProxy` in web server
+const app = express();
+app.use('/api', exampleProxy);
+app.listen(3000);
+```
+
+## Context matching
+
+Providing an alternative way to decide which requests should be proxied; In case you are not able to use the server's [`path` parameter](http://expressjs.com/en/4x/api.html#app.use) to mount the proxy or when you need more flexibility.
+
+[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used for context matching.
+
+```ascii
+         foo://example.com:8042/over/there?name=ferret#nose
+         \_/   \______________/\_________/ \_________/ \__/
+          |           |            |            |        |
+       scheme     authority       path        query   fragment
+```
+
+- **path matching**
+
+  - `createProxyMiddleware({...})` - matches any path, all requests will be proxied.
+  - `createProxyMiddleware('/', {...})` - matches any path, all requests will be proxied.
+  - `createProxyMiddleware('/api', {...})` - matches paths starting with `/api`
+
+- **multiple path matching**
+
+  - `createProxyMiddleware(['/api', '/ajax', '/someotherpath'], {...})`
+
+- **wildcard path matching**
+
+  For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
+
+  - `createProxyMiddleware('**', {...})` matches any path, all requests will be proxied.
+  - `createProxyMiddleware('**/*.html', {...})` matches any path which ends with `.html`
+  - `createProxyMiddleware('/*.html', {...})` matches paths directly under path-absolute
+  - `createProxyMiddleware('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
+  - `createProxyMiddleware(['/api/**', '/ajax/**'], {...})` combine multiple patterns
+  - `createProxyMiddleware(['/api/**', '!**/bad.json'], {...})` exclusion
+
+  **Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
+
+- **custom matching**
+
+  For full control you can provide a custom function to determine which requests should be proxied or not.
+
+  ```javascript
+  /**
+   * @return {Boolean}
+   */
+  const filter = function (pathname, req) {
+    return pathname.match('^/api') && req.method === 'GET';
+  };
+
+  const apiProxy = createProxyMiddleware(filter, {
+    target: 'http://www.example.org',
+  });
+  ```
+
+## Options
+
+### http-proxy-middleware options
+
+- **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
+
+  ```javascript
+  // rewrite path
+  pathRewrite: {'^/old/api' : '/new/api'}
+
+  // remove path
+  pathRewrite: {'^/remove/api' : ''}
+
+  // add base path
+  pathRewrite: {'^/' : '/basepath/'}
+
+  // custom rewriting
+  pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
+
+  // custom rewriting, returning Promise
+  pathRewrite: async function (path, req) {
+    const should_add_something = await httpRequestToDecideSomething(path);
+    if (should_add_something) path += "something";
+    return path;
+  }
+  ```
+
+- **option.router**: object/function, re-target `option.target` for specific requests.
+
+  ```javascript
+  // Use `host` and/or `path` to match requests. First match will be used.
+  // The order of the configuration matters.
+  router: {
+      'integration.localhost:3000' : 'http://localhost:8001',  // host only
+      'staging.localhost:3000'     : 'http://localhost:8002',  // host only
+      'localhost:3000/api'         : 'http://localhost:8003',  // host + path
+      '/rest'                      : 'http://localhost:8004'   // path only
+  }
+
+  // Custom router function (string target)
+  router: function(req) {
+      return 'http://localhost:8004';
+  }
+
+  // Custom router function (target object)
+  router: function(req) {
+      return {
+          protocol: 'https:', // The : is required
+          host: 'localhost',
+          port: 8004
+      };
+  }
+
+  // Asynchronous router function which returns promise
+  router: async function(req) {
+      const url = await doSomeIO();
+      return url;
+  }
+  ```
+
+- **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
+
+- **option.logProvider**: function, modify or replace log provider. Default: `console`.
+
+  ```javascript
+  // simple replace
+  function logProvider(provider) {
+    // replace the default console log provider.
+    return require('winston');
+  }
+  ```
+
+  ```javascript
+  // verbose replacement
+  function logProvider(provider) {
+    const logger = new (require('winston').Logger)();
+
+    const myCustomProvider = {
+      log: logger.log,
+      debug: logger.debug,
+      info: logger.info,
+      warn: logger.warn,
+      error: logger.error,
+    };
+    return myCustomProvider;
+  }
+  ```
+
+### http-proxy events
+
+Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events):
+
+- **option.onError**: function, subscribe to http-proxy's `error` event for custom error handling.
+
+  ```javascript
+  function onError(err, req, res, target) {
+    res.writeHead(500, {
+      'Content-Type': 'text/plain',
+    });
+    res.end('Something went wrong. And we are reporting a custom error message.');
+  }
+  ```
+
+- **option.onProxyRes**: function, subscribe to http-proxy's `proxyRes` event.
+
+  ```javascript
+  function onProxyRes(proxyRes, req, res) {
+    proxyRes.headers['x-added'] = 'foobar'; // add new header to response
+    delete proxyRes.headers['x-removed']; // remove header from response
+  }
+  ```
+
+- **option.onProxyReq**: function, subscribe to http-proxy's `proxyReq` event.
+
+  ```javascript
+  function onProxyReq(proxyReq, req, res) {
+    // add custom header to request
+    proxyReq.setHeader('x-added', 'foobar');
+    // or log the req
+  }
+  ```
+
+- **option.onProxyReqWs**: function, subscribe to http-proxy's `proxyReqWs` event.
+
+  ```javascript
+  function onProxyReqWs(proxyReq, req, socket, options, head) {
+    // add custom header
+    proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
+  }
+  ```
+
+- **option.onOpen**: function, subscribe to http-proxy's `open` event.
+
+  ```javascript
+  function onOpen(proxySocket) {
+    // listen for messages coming FROM the target here
+    proxySocket.on('data', hybridParseAndLogMessage);
+  }
+  ```
+
+- **option.onClose**: function, subscribe to http-proxy's `close` event.
+
+  ```javascript
+  function onClose(res, socket, head) {
+    // view disconnected websocket connections
+    console.log('Client disconnected');
+  }
+  ```
+
+### http-proxy options
+
+The following options are provided by the underlying [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) library.
+
+- **option.target**: url string to be parsed with the url module
+- **option.forward**: url string to be parsed with the url module
+- **option.agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
+- **option.ssl**: object to be passed to https.createServer()
+- **option.ws**: true/false: if you want to proxy websockets
+- **option.xfwd**: true/false, adds x-forward headers
+- **option.secure**: true/false, if you want to verify the SSL Certs
+- **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
+- **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
+- **option.ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
+- **option.localAddress** : Local interface string to bind for outgoing connections
+- **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
+- **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
+- **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
+- **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
+- **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
+- **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
+- **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
+  - `false` (default): disable cookie rewriting
+  - String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
+  - Object: mapping of domains to new domains, use `"*"` to match all domains.  
+    For example keep one domain unchanged, rewrite one domain and remove other domains:
+    ```json
+    cookieDomainRewrite: {
+      "unchanged.domain": "unchanged.domain",
+      "old.domain": "new.domain",
+      "*": ""
+    }
+    ```
+- **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
+  - `false` (default): disable cookie rewriting
+  - String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
+  - Object: mapping of paths to new paths, use `"*"` to match all paths.
+    For example, to keep one path unchanged, rewrite one path and remove other paths:
+    ```json
+    cookiePathRewrite: {
+      "/unchanged.path/": "/unchanged.path/",
+      "/old.path/": "/new.path/",
+      "*": ""
+    }
+    ```
+- **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
+- **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
+- **option.timeout**: timeout (in millis) for incoming requests
+- **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
+- **option.selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event
+- **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
+
+  ```javascript
+  'use strict';
+
+  const streamify = require('stream-array');
+  const HttpProxy = require('http-proxy');
+  const proxy = new HttpProxy();
+
+  module.exports = (req, res, next) => {
+    proxy.web(
+      req,
+      res,
+      {
+        target: 'http://localhost:4003/',
+        buffer: streamify(req.rawBody),
+      },
+      next
+    );
+  };
+  ```
+
+## Shorthand
+
+Use the shorthand syntax when verbose configuration is not needed. The `context` and `option.target` will be automatically configured when shorthand is used. Options can still be used if needed.
+
+```javascript
+createProxyMiddleware('http://www.example.org:8000/api');
+// createProxyMiddleware('/api', {target: 'http://www.example.org:8000'});
+
+createProxyMiddleware('http://www.example.org:8000/api/books/*/**.json');
+// createProxyMiddleware('/api/books/*/**.json', {target: 'http://www.example.org:8000'});
+
+createProxyMiddleware('http://www.example.org:8000/api', { changeOrigin: true });
+// createProxyMiddleware('/api', {target: 'http://www.example.org:8000', changeOrigin: true});
+```
+
+### app.use(path, proxy)
+
+If you want to use the server's `app.use` `path` parameter to match requests;
+Create and mount the proxy without the http-proxy-middleware `context` parameter:
+
+```javascript
+app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
+```
+
+`app.use` documentation:
+
+- express: http://expressjs.com/en/4x/api.html#app.use
+- connect: https://github.com/senchalabs/connect#mount-middleware
+- polka: https://github.com/lukeed/polka#usebase-fn
+
+## WebSocket
+
+```javascript
+// verbose api
+createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });
+
+// shorthand
+createProxyMiddleware('http://echo.websocket.org', { ws: true });
+
+// shorter shorthand
+createProxyMiddleware('ws://echo.websocket.org');
+```
+
+### External WebSocket upgrade
+
+In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the http `upgrade` event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's http `upgrade` event manually.
+
+```javascript
+const wsProxy = createProxyMiddleware('ws://echo.websocket.org', { changeOrigin: true });
+
+const app = express();
+app.use(wsProxy);
+
+const server = app.listen(3000);
+server.on('upgrade', wsProxy.upgrade); // <-- subscribe to http 'upgrade'
+```
+
+## Intercept and manipulate requests
+
+Intercept requests from downstream by defining `onProxyReq` in `createProxyMiddleware`.
+
+Currently the only pre-provided request interceptor is `fixRequestBody`, which is used to fix proxied POST requests when `bodyParser` is applied before this middleware.
+
+Example:
+
+```javascript
+const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');
+
+const proxy = createProxyMiddleware({
+  /**
+   * Fix bodyParser
+   **/
+  onProxyReq: fixRequestBody,
+});
+```
+
+## Intercept and manipulate responses
+
+Intercept responses from upstream with `responseInterceptor`. (Make sure to set `selfHandleResponse: true`)
+
+Responses which are compressed with `brotli`, `gzip` and `deflate` will be decompressed automatically. The response will be returned as `buffer` ([docs](https://nodejs.org/api/buffer.html)) which you can manipulate.
+
+With `buffer`, response manipulation is not limited to text responses (html/css/js, etc...); image manipulation will be possible too. ([example](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md#manipulate-image-response))
+
+NOTE: `responseInterceptor` disables streaming of target's response.
+
+Example:
+
+```javascript
+const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
+
+const proxy = createProxyMiddleware({
+  /**
+   * IMPORTANT: avoid res.end being called automatically
+   **/
+  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()
+
+  /**
+   * Intercept response and replace 'Hello' with 'Goodbye'
+   **/
+  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
+    const response = responseBuffer.toString('utf8'); // convert buffer to string
+    return response.replace('Hello', 'Goodbye'); // manipulate response and return the result
+  }),
+});
+```
+
+Check out [interception recipes](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md#readme) for more examples.
+
+## Working examples
+
+View and play around with [working examples](https://github.com/chimurai/http-proxy-middleware/tree/master/examples).
+
+- Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
+- express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
+- connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
+- WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))
+- Response Manipulation ([example source](https://github.com/chimurai/http-proxy-middleware/blob/master/examples/response-interceptor/index.js))
+
+## Recipes
+
+View the [recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes) for common use cases.
+
+## Compatible servers
+
+`http-proxy-middleware` is compatible with the following servers:
+
+- [connect](https://www.npmjs.com/package/connect)
+- [express](https://www.npmjs.com/package/express)
+- [fastify](https://www.npmjs.com/package/fastify)
+- [browser-sync](https://www.npmjs.com/package/browser-sync)
+- [lite-server](https://www.npmjs.com/package/lite-server)
+- [polka](https://github.com/lukeed/polka)
+- [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
+- [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
+- [gulp-connect](https://www.npmjs.com/package/gulp-connect)
+- [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
+
+Sample implementations can be found in the [server recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes/servers.md).
+
+## Tests
+
+Run the test suite:
+
+```bash
+# install dependencies
+$ yarn
+
+# linting
+$ yarn lint
+$ yarn lint:fix
+
+# building (compile typescript to js)
+$ yarn build
+
+# unit tests
+$ yarn test
+
+# code coverage
+$ yarn cover
+
+# check spelling mistakes
+$ yarn spellcheck
+```
+
+## Changelog
+
+- [View changelog](https://github.com/chimurai/http-proxy-middleware/blob/master/CHANGELOG.md)
+
+## License
+
+The MIT License (MIT)
+
+Copyright (c) 2015-2025 Steven Chim
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 });
Index: frontend/node_modules/http-proxy-middleware/package.json
===================================================================
--- frontend/node_modules/http-proxy-middleware/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/http-proxy-middleware/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,109 @@
+{
+  "name": "http-proxy-middleware",
+  "version": "2.0.9",
+  "description": "The one-liner node.js proxy middleware for connect, express and browser-sync",
+  "main": "dist/index.js",
+  "types": "dist/index.d.ts",
+  "files": [
+    "dist"
+  ],
+  "scripts": {
+    "clean": "rm -rf dist && rm -rf coverage",
+    "lint": "yarn prettier && yarn eslint",
+    "lint:fix": "yarn prettier:fix && yarn eslint:fix",
+    "eslint": "eslint '{src,test}/**/*.ts'",
+    "eslint:fix": "yarn eslint --fix",
+    "prettier": "prettier --list-different \"**/*.{js,ts,md,yml,json,html}\"",
+    "prettier:fix": "prettier --write \"**/*.{js,ts,md,yml,json,html}\"",
+    "prebuild": "yarn clean",
+    "build": "tsc",
+    "pretest": "yarn build",
+    "test": "jest",
+    "precoverage": "yarn build",
+    "coverage": "jest --coverage --coverageReporters=lcov",
+    "prepare": "husky install",
+    "prepack": "yarn build && rm dist/tsconfig.tsbuildinfo",
+    "spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/chimurai/http-proxy-middleware.git"
+  },
+  "keywords": [
+    "reverse",
+    "proxy",
+    "middleware",
+    "http",
+    "https",
+    "connect",
+    "express",
+    "fastify",
+    "polka",
+    "browser-sync",
+    "gulp",
+    "grunt-contrib-connect",
+    "websocket",
+    "ws",
+    "cors"
+  ],
+  "author": "Steven Chim",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/chimurai/http-proxy-middleware/issues"
+  },
+  "homepage": "https://github.com/chimurai/http-proxy-middleware#readme",
+  "devDependencies": {
+    "@commitlint/cli": "16.2.1",
+    "@commitlint/config-conventional": "16.2.1",
+    "@types/express": "4.17.13",
+    "@types/is-glob": "4.0.2",
+    "@types/jest": "27.4.0",
+    "@types/micromatch": "4.0.2",
+    "@types/node": "17.0.18",
+    "@types/supertest": "2.0.11",
+    "@types/ws": "8.2.2",
+    "@typescript-eslint/eslint-plugin": "5.12.0",
+    "@typescript-eslint/parser": "5.12.0",
+    "body-parser": "1.19.2",
+    "browser-sync": "2.27.7",
+    "connect": "3.7.0",
+    "eslint": "8.9.0",
+    "eslint-config-prettier": "8.3.0",
+    "eslint-plugin-prettier": "4.0.0",
+    "express": "4.17.3",
+    "get-port": "5.1.1",
+    "husky": "7.0.4",
+    "jest": "27.5.1",
+    "lint-staged": "12.3.4",
+    "mockttp": "2.6.0",
+    "open": "8.4.0",
+    "prettier": "2.5.1",
+    "supertest": "6.2.2",
+    "ts-jest": "27.1.3",
+    "typescript": "4.5.5",
+    "ws": "8.5.0"
+  },
+  "dependencies": {
+    "@types/http-proxy": "^1.17.8",
+    "http-proxy": "^1.18.1",
+    "is-glob": "^4.0.1",
+    "is-plain-obj": "^3.0.0",
+    "micromatch": "^4.0.2"
+  },
+  "peerDependencies": {
+    "@types/express": "^4.17.13"
+  },
+  "peerDependenciesMeta": {
+    "@types/express": {
+      "optional": true
+    }
+  },
+  "engines": {
+    "node": ">=12.0.0"
+  },
+  "commitlint": {
+    "extends": [
+      "@commitlint/config-conventional"
+    ]
+  }
+}
