Saving all progress

This commit is contained in:
Luke Hagar
2025-03-19 22:47:50 -05:00
parent 5c6e8a1e4f
commit 00593b402b
14988 changed files with 2598505 additions and 1 deletions

22
node_modules/http-proxy-middleware/LICENSE generated vendored Normal file
View File

@@ -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.

648
node_modules/http-proxy-middleware/README.md generated vendored Normal file
View File

@@ -0,0 +1,648 @@
# http-proxy-middleware
[![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/chimurai/http-proxy-middleware/ci.yml?branch=master&logo=github-actions&logoColor=white&style=flat-square)](https://github.com/chimurai/http-proxy-middleware/actions/workflows/ci.yml?query=branch%3Amaster)
[![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square&logo=coveralls)](https://coveralls.io/r/chimurai/http-proxy-middleware)
[![Known Vulnerabilities](https://snyk.io/test/github/chimurai/http-proxy-middleware/badge.svg)](https://snyk.io/test/github/chimurai/http-proxy-middleware)
[![npm](https://img.shields.io/npm/v/http-proxy-middleware?color=%23CC3534&style=flat-square&logo=npm)](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/expressjs/express), [next.js](https://github.com/vercel/next.js) and [many more](#compatible-servers).
Powered by the popular Nodejitsu [`http-proxy`](https://github.com/http-party/node-http-proxy). [![GitHub stars](https://img.shields.io/github/stars/http-party/node-http-proxy.svg?style=social&label=Star)](https://github.com/http-party/node-http-proxy)
## ⚠️ Note <!-- omit in toc -->
This page is showing documentation for version v3.x.x ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
See [MIGRATION.md](https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md) for details on how to migrate from v2.x.x to v3.x.x
If you're looking for older documentation. Go to:
- <https://github.com/chimurai/http-proxy-middleware/tree/v2.0.4#readme>
- <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`
:bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
```typescript
// typescript
import * as express from 'express';
import type { Request, Response, NextFunction } from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import type { Filter, Options, RequestHandler } from 'http-proxy-middleware';
const app = express();
const proxyMiddleware = createProxyMiddleware<Request, Response>({
target: 'http://www.example.org/api',
changeOrigin: true,
}),
app.use('/api', proxyMiddleware);
app.listen(3000);
// proxy and keep the same base path "/api"
// http://127.0.0.1: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).
## Table of Contents <!-- omit in toc -->
<!-- // spell-checker:disable -->
- [Install](#install)
- [Basic usage](#basic-usage)
- [Express Server Example](#express-server-example)
- [app.use(path, proxy)](#appusepath-proxy)
- [Options](#options)
- [`pathFilter` (string, \[\]string, glob, \[\]glob, function)](#pathfilter-string-string-glob-glob-function)
- [`pathRewrite` (object/function)](#pathrewrite-objectfunction)
- [`router` (object/function)](#router-objectfunction)
- [`plugins` (Array)](#plugins-array)
- [`ejectPlugins` (boolean) default: `false`](#ejectplugins-boolean-default-false)
- [`logger` (Object)](#logger-object)
- [`http-proxy` events](#http-proxy-events)
- [`http-proxy` options](#http-proxy-options)
- [WebSocket](#websocket)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
- [Intercept and manipulate responses](#intercept-and-manipulate-responses)
- [Node.js 17+: ECONNREFUSED issue with IPv6 and localhost (#705)](#nodejs-17-econnrefused-issue-with-ipv6-and-localhost-705)
- [Debugging](#debugging)
- [Working examples](#working-examples)
- [Recipes](#recipes)
- [Compatible servers](#compatible-servers)
- [Tests](#tests)
- [Changelog](#changelog)
- [License](#license)
<!-- // spell-checker:enable -->
## Install
```shell
npm install --save-dev http-proxy-middleware
```
## Basic usage
Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
```javascript
const { createProxyMiddleware } = require('http-proxy-middleware');
const apiProxy = createProxyMiddleware({
target: 'http://www.example.org',
changeOrigin: true,
});
// 'apiProxy' is now ready to be used as middleware in a server.
```
- **options.target**: target host to proxy to. _(protocol + host)_
- **options.changeOrigin**: for virtual hosted sites
- see full list of [`http-proxy-middleware` configuration options](#options)
## Express Server Example
An example with `express` server.
```javascript
// include dependencies
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
// create the proxy
/** @type {import('http-proxy-middleware/dist/types').RequestHandler<express.Request, express.Response>} */
const exampleProxy = createProxyMiddleware({
target: 'http://www.example.org/api', // target host with the same base path
changeOrigin: true, // needed for virtual hosted sites
});
// mount `exampleProxy` in web server
app.use('/api', exampleProxy);
app.listen(3000);
```
### app.use(path, proxy)
If you want to use the server's `app.use` `path` parameter to match requests.
Use `pathFilter` option to further include/exclude requests which you want to proxy.
```javascript
app.use(
createProxyMiddleware({
target: 'http://www.example.org/api',
changeOrigin: true,
pathFilter: '/api/proxy-only-this-path',
}),
);
```
`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>
## Options
http-proxy-middleware options:
### `pathFilter` (string, []string, glob, []glob, function)
Narrow down which requests should be proxied. The `path` used for filtering is the `request.url` pathname. In Express, this is the `path` relative to the mount-point of the proxy.
- **path matching**
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied when `pathFilter` is not configured.
- `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
- **multiple path matching**
- `createProxyMiddleware({ pathFilter: ['/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({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
- `createProxyMiddleware({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
- `createProxyMiddleware({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
- `createProxyMiddleware({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
- `createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
- `createProxyMiddleware({ pathFilter: ['/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 pathFilter = function (path, req) {
return path.match('^/api') && req.method === 'GET';
};
const apiProxy = createProxyMiddleware({
target: 'http://www.example.org',
pathFilter: pathFilter,
});
```
### `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;
}
```
### `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://127.0.0.1:8001', // host only
'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
'/rest' : 'http://127.0.0.1:8004' // path only
}
// Custom router function (string target)
router: function(req) {
return 'http://127.0.0.1:8004';
}
// Custom router function (target object)
router: function(req) {
return {
protocol: 'https:', // The : is required
host: '127.0.0.1',
port: 8004
};
}
// Asynchronous router function which returns promise
router: async function(req) {
const url = await doSomeIO();
return url;
}
```
### `plugins` (Array)
```js
const simpleRequestLogger = (proxyServer, options) => {
proxyServer.on('proxyReq', (proxyReq, req, res) => {
console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
});
},
const config = {
target: `http://example.org`,
changeOrigin: true,
plugins: [simpleRequestLogger],
};
```
### `ejectPlugins` (boolean) default: `false`
If you're not satisfied with the pre-configured plugins, you can eject them by configuring `ejectPlugins: true`.
NOTE: register your own error handlers to prevent server from crashing.
```js
// eject default plugins and manually add them back
const {
debugProxyErrorsPlugin, // subscribe to proxy errors to prevent server from crashing
loggerPlugin, // log proxy events to a logger (ie. console)
errorResponsePlugin, // return 5xx response on proxy error
proxyEventsPlugin, // implements the "on:" option
} = require('http-proxy-middleware');
createProxyMiddleware({
target: `http://example.org`,
changeOrigin: true,
ejectPlugins: true,
plugins: [debugProxyErrorsPlugin, loggerPlugin, errorResponsePlugin, proxyEventsPlugin],
});
```
### `logger` (Object)
Configure a logger to output information from http-proxy-middleware: ie. `console`, `winston`, `pino`, `bunyan`, `log4js`, etc...
Only `info`, `warn`, `error` are used internally for compatibility across different loggers.
If you use `winston`, make sure to enable interpolation: <https://github.com/winstonjs/winston#string-interpolation>
See also logger recipes ([recipes/logger.md](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md)) for more details.
```javascript
createProxyMiddleware({
logger: console,
});
```
## `http-proxy` events
Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events) with the `on` option:
```js
createProxyMiddleware({
target: 'http://www.example.org',
on: {
proxyReq: (proxyReq, req, res) => {
/* handle proxyReq */
},
proxyRes: (proxyRes, req, res) => {
/* handle proxyRes */
},
error: (err, req, res) => {
/* handle error */
},
},
});
```
- **option.on.error**: 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.on.proxyRes**: 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.on.proxyReq**: 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.on.proxyReqWs**: 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.on.open**: 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.on.close**: 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://127.0.0.1:4003/',
buffer: streamify(req.rawBody),
},
next,
);
};
```
## WebSocket
```javascript
// verbose api
createProxyMiddleware({ pathFilter: '/', target: 'http://echo.websocket.org', ws: true });
```
### 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({ target: '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
**/
on: {
proxyReq: 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'
**/
on: {
proxyRes: 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.
## Node.js 17+: ECONNREFUSED issue with IPv6 and localhost ([#705](https://github.com/chimurai/http-proxy-middleware/issues/705))
Node.js 17+ no longer prefers IPv4 over IPv6 for DNS lookups.
E.g. It's **not** guaranteed that `localhost` will be resolved to `127.0.0.1` it might just as well be `::1` (or some other IP address).
If your target server only accepts IPv4 connections, trying to proxy to `localhost` will fail if resolved to `::1` (IPv6).
Ways to solve it:
- Change `target: "http://localhost"` to `target: "http://127.0.0.1"` (IPv4).
- Change the target server to (also) accept IPv6 connections.
- Add this flag when running `node`: `node index.js --dns-result-order=ipv4first`. (Not recommended.)
> Note: Theres a thing called [Happy Eyeballs](https://en.wikipedia.org/wiki/Happy_Eyeballs) which means connecting to both IPv4 and IPv6 in parallel, which Node.js doesnt have, but explains why for example `curl` can connect.
## Debugging
Configure the `DEBUG` environment variable enable debug logging.
See [`debug`](https://github.com/debug-js/debug#readme) project for more options.
```shell
DEBUG=http-proxy-middleware* node server.js
$ http-proxy-middleware proxy created +0ms
$ http-proxy-middleware proxying request to target: 'http://www.example.org' +359ms
```
## 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)
- [next.js](https://www.npmjs.com/package/next)
- [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-2024 Steven Chim

View File

@@ -0,0 +1,2 @@
import { Options } from './types';
export declare function verifyConfig<TReq, TRes>(options: Options<TReq, TRes>): void;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyConfig = verifyConfig;
const errors_1 = require("./errors");
function verifyConfig(options) {
if (!options.target && !options.router) {
throw new Error(errors_1.ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING);
}
}

5
node_modules/http-proxy-middleware/dist/debug.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import * as createDebug from 'debug';
/**
* Debug instance with the given namespace: http-proxy-middleware
*/
export declare const Debug: createDebug.Debugger;

8
node_modules/http-proxy-middleware/dist/debug.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Debug = void 0;
const createDebug = require("debug");
/**
* Debug instance with the given namespace: http-proxy-middleware
*/
exports.Debug = createDebug('http-proxy-middleware');

6
node_modules/http-proxy-middleware/dist/errors.d.ts generated vendored Normal file
View File

@@ -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 pathFilter. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]",
ERR_CONTEXT_MATCHER_INVALID_ARRAY = "[HPM] Invalid pathFilter. Plain paths (e.g. \"/api\") can not be mixed with globs (e.g. \"/api/**\"). 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"
}

10
node_modules/http-proxy-middleware/dist/errors.js generated vendored Normal file
View File

@@ -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 pathFilter. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]";
ERRORS["ERR_CONTEXT_MATCHER_INVALID_ARRAY"] = "[HPM] Invalid pathFilter. Plain paths (e.g. \"/api\") can not be mixed with globs (e.g. \"/api/**\"). 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 = ERRORS = {}));

3
node_modules/http-proxy-middleware/dist/factory.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import type { Options, RequestHandler, NextFunction } from './types';
import type * as http from 'http';
export declare function createProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction>(options: Options<TReq, TRes>): RequestHandler<TReq, TRes, TNext>;

8
node_modules/http-proxy-middleware/dist/factory.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProxyMiddleware = createProxyMiddleware;
const http_proxy_middleware_1 = require("./http-proxy-middleware");
function createProxyMiddleware(options) {
const { middleware } = new http_proxy_middleware_1.HttpProxyMiddleware(options);
return middleware;
}

View File

@@ -0,0 +1,2 @@
import type { Options, Plugin } from './types';
export declare function getPlugins<TReq, TRes>(options: Options<TReq, TRes>): Plugin<TReq, TRes>[];

13
node_modules/http-proxy-middleware/dist/get-plugins.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPlugins = getPlugins;
const default_1 = require("./plugins/default");
function getPlugins(options) {
// don't load default errorResponsePlugin if user has specified their own
const maybeErrorResponsePlugin = options.on?.error ? [] : [default_1.errorResponsePlugin];
const defaultPlugins = options.ejectPlugins
? [] // no default plugins when ejecting
: [default_1.debugProxyErrorsPlugin, default_1.proxyEventsPlugin, default_1.loggerPlugin, ...maybeErrorResponsePlugin];
const userPlugins = options.plugins ?? [];
return [...defaultPlugins, ...userPlugins];
}

View File

@@ -0,0 +1,8 @@
import type * as http from 'http';
export type BodyParserLikeRequest = http.IncomingMessage & {
body: any;
};
/**
* Fix proxied body if bodyParser is involved.
*/
export declare function fixRequestBody<TReq = http.IncomingMessage>(proxyReq: http.ClientRequest, req: TReq): void;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fixRequestBody = fixRequestBody;
const querystring = require("querystring");
/**
* Fix proxied body if bodyParser is involved.
*/
function fixRequestBody(proxyReq, req) {
const requestBody = req.body;
if (!requestBody) {
return;
}
const contentType = proxyReq.getHeader('Content-Type');
const writeBody = (bodyData) => {
// deepcode ignore ContentLengthInCode: bodyParser fix
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
};
if (contentType && (contentType.includes('application/json') || contentType.includes('+json'))) {
writeBody(JSON.stringify(requestBody));
}
if (contentType && contentType.includes('application/x-www-form-urlencoded')) {
writeBody(querystring.stringify(requestBody));
}
}

View File

@@ -0,0 +1 @@
export * from './public';

View File

@@ -0,0 +1,17 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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);

View File

@@ -0,0 +1,2 @@
export { responseInterceptor } from './response-interceptor';
export { fixRequestBody } from './fix-request-body';

View File

@@ -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; } });

View File

@@ -0,0 +1,11 @@
import type * as http from 'http';
type Interceptor<TReq = http.IncomingMessage, TRes = http.ServerResponse> = (buffer: Buffer, proxyRes: TReq, req: TReq, res: TRes) => 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<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(interceptor: Interceptor<TReq, TRes>): (proxyRes: TReq, req: TReq, res: TRes) => Promise<void>;
export {};

View File

@@ -0,0 +1,94 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.responseInterceptor = responseInterceptor;
const zlib = require("zlib");
const debug_1 = require("../debug");
const function_1 = require("../utils/function");
const debug = debug_1.Debug.extend('response-interceptor');
/**
* 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 proxyResResponseInterceptor(proxyRes, req, res) {
debug('intercept proxy response');
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)
debug('call interceptor function: %s', (0, function_1.getFunctionName)(interceptor));
const interceptedBuffer = Buffer.from(await interceptor(buffer, originalProxyRes, req, res));
// set correct content-length (with double byte character support)
debug('set content-length: %s', Buffer.byteLength(interceptedBuffer, 'utf8'));
res.setHeader('content-length', Buffer.byteLength(interceptedBuffer, 'utf8'));
debug('write intercepted response');
res.write(interceptedBuffer);
res.end();
});
_proxyRes.on('error', (error) => {
res.end(`Error fetching proxied request: ${error.message}`);
});
};
}
/**
* 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) {
debug(`decompress proxy response with 'content-encoding': %s`, contentEncoding);
_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) {
debug('copy original response headers');
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;
}
}

View File

@@ -0,0 +1,29 @@
import type { RequestHandler, Options } from './types';
export declare class HttpProxyMiddleware<TReq, TRes> {
private wsInternalSubscribed;
private serverOnCloseSubscribed;
private proxyOptions;
private proxy;
private pathRewriter;
private logger;
constructor(options: Options<TReq, TRes>);
middleware: RequestHandler;
private registerPlugins;
private catchUpgradeRequest;
private handleUpgrade;
/**
* Determine whether request should be proxied.
*/
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;
}

View File

@@ -0,0 +1,154 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpProxyMiddleware = void 0;
const httpProxy = require("http-proxy");
const configuration_1 = require("./configuration");
const get_plugins_1 = require("./get-plugins");
const path_filter_1 = require("./path-filter");
const PathRewriter = require("./path-rewriter");
const Router = require("./router");
const debug_1 = require("./debug");
const function_1 = require("./utils/function");
const logger_1 = require("./logger");
class HttpProxyMiddleware {
constructor(options) {
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) => {
if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
try {
const activeProxyOptions = await this.prepareProxyRequest(req);
(0, debug_1.Debug)(`proxy request to target: %O`, activeProxyOptions.target);
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 = (req.socket ?? req.connection)?.server;
if (server && !this.serverOnCloseSubscribed) {
server.on('close', () => {
(0, debug_1.Debug)('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) {
(0, debug_1.Debug)('subscribing to server upgrade event');
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.proxyOptions.pathFilter, req)) {
const activeProxyOptions = await this.prepareProxyRequest(req);
this.proxy.ws(req, socket, head, activeProxyOptions);
(0, debug_1.Debug)('server upgrade event received. Proxying WebSocket');
}
};
/**
* Determine whether request should be proxied.
*/
this.shouldProxy = (pathFilter, req) => {
try {
return (0, path_filter_1.matchPathFilter)(pathFilter, req.url, req);
}
catch (err) {
(0, debug_1.Debug)('Error: matchPathFilter() called with request url: ', `"${req.url}"`);
this.logger.error(err);
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) => {
/**
* Incorrect usage confirmed: https://github.com/expressjs/express/issues/4854#issuecomment-1066171160
* Temporary restore req.url patch for {@link src/legacy/create-proxy-middleware.ts legacyCreateProxyMiddleware()}
* FIXME: remove this patch in future release
*/
if (this.middleware.__LEGACY_HTTP_PROXY_MIDDLEWARE__) {
req.url = req.originalUrl || 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);
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) {
(0, debug_1.Debug)('router new target: "%s"', newTarget);
options.target = newTarget;
}
}
};
// rewrite path
this.applyPathRewrite = async (req, pathRewriter) => {
if (pathRewriter) {
const path = await pathRewriter(req.url, req);
if (typeof path === 'string') {
(0, debug_1.Debug)('pathRewrite new path: %s', req.url);
req.url = path;
}
else {
(0, debug_1.Debug)('pathRewrite: no rewritten path found: %s', req.url);
}
}
};
(0, configuration_1.verifyConfig)(options);
this.proxyOptions = options;
this.logger = (0, logger_1.getLogger)(options);
(0, debug_1.Debug)(`create proxy server`);
this.proxy = httpProxy.createProxyServer({});
this.registerPlugins(this.proxy, this.proxyOptions);
this.pathRewriter = PathRewriter.createPathRewriter(this.proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
// 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);
}
};
}
registerPlugins(proxy, options) {
const plugins = (0, get_plugins_1.getPlugins)(options);
plugins.forEach((plugin) => {
(0, debug_1.Debug)(`register plugin: "${(0, function_1.getFunctionName)(plugin)}"`);
plugin(proxy, options);
});
}
}
exports.HttpProxyMiddleware = HttpProxyMiddleware;

11
node_modules/http-proxy-middleware/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
export * from './factory';
export * from './handlers';
export type { Filter, Options, RequestHandler } from './types';
/**
* Default plugins
*/
export * from './plugins/default';
/**
* Legacy exports
*/
export * from './legacy';

26
node_modules/http-proxy-middleware/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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("./factory"), exports);
__exportStar(require("./handlers"), exports);
/**
* Default plugins
*/
__exportStar(require("./plugins/default"), exports);
/**
* Legacy exports
*/
__exportStar(require("./legacy"), exports);

View File

@@ -0,0 +1,12 @@
import { Filter, RequestHandler } from '../types';
import { LegacyOptions } from './types';
import type * as http from 'http';
/**
* @deprecated
* This function is deprecated and will be removed in a future version.
*
* Use {@link createProxyMiddleware} instead.
*/
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(shortHand: string): RequestHandler<TReq, TRes>;
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyContext: Filter<TReq>, legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.legacyCreateProxyMiddleware = legacyCreateProxyMiddleware;
const factory_1 = require("../factory");
const debug_1 = require("../debug");
const options_adapter_1 = require("./options-adapter");
const debug = debug_1.Debug.extend('legacy-create-proxy-middleware');
function legacyCreateProxyMiddleware(legacyContext, legacyOptions) {
debug('init');
const options = (0, options_adapter_1.legacyOptionsAdapter)(legacyContext, legacyOptions);
const proxyMiddleware = (0, factory_1.createProxyMiddleware)(options);
// https://github.com/chimurai/http-proxy-middleware/pull/731/files#diff-07e6ad10bda0df091b737caed42767657cd0bd74a01246a1a0b7ab59c0f6e977L118
debug('add marker for patching req.url (old behavior)');
proxyMiddleware.__LEGACY_HTTP_PROXY_MIDDLEWARE__ = true;
return proxyMiddleware;
}

View File

@@ -0,0 +1 @@
export * from './public';

View File

@@ -0,0 +1,17 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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);

View File

@@ -0,0 +1,6 @@
import { Filter, Options } from '../types';
import { LegacyOptions } from './types';
/**
* Convert {@link LegacyOptions legacy Options} to new {@link Options}
*/
export declare function legacyOptionsAdapter<TReq, TRes>(legacyContext: Filter<TReq> | LegacyOptions<TReq, TRes>, legacyOptions: LegacyOptions<TReq, TRes>): Options<TReq, TRes>;

View File

@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.legacyOptionsAdapter = legacyOptionsAdapter;
const url = require("url");
const debug_1 = require("../debug");
const logger_1 = require("../logger");
const debug = debug_1.Debug.extend('legacy-options-adapter');
// https://github.com/chimurai/http-proxy-middleware/blob/7341704d0aa9d1606dfd37ebfdffddd34c894784/src/_handlers.ts#L20-L27
const proxyEventMap = {
onError: 'error',
onProxyReq: 'proxyReq',
onProxyRes: 'proxyRes',
onProxyReqWs: 'proxyReqWs',
onOpen: 'open',
onClose: 'close',
};
/**
* Convert {@link LegacyOptions legacy Options} to new {@link Options}
*/
function legacyOptionsAdapter(legacyContext, legacyOptions) {
let options = {};
let logger;
// https://github.com/chimurai/http-proxy-middleware/pull/716
if (typeof legacyContext === 'string' && !!url.parse(legacyContext).host) {
throw new Error(`Shorthand syntax is removed from legacyCreateProxyMiddleware().
Please use "legacyCreateProxyMiddleware({ target: 'http://www.example.org' })" instead.
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-shorthand-usage
`);
}
// detect old "context" argument and convert to "options.pathFilter"
// https://github.com/chimurai/http-proxy-middleware/pull/722/files#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80L4
if (legacyContext && legacyOptions) {
debug('map legacy context/filter to options.pathFilter');
options = { ...legacyOptions, pathFilter: legacyContext };
logger = getLegacyLogger(options);
logger.warn(`[http-proxy-middleware] Legacy "context" argument is deprecated. Migrate your "context" to "options.pathFilter":
const options = {
pathFilter: '${legacyContext}',
}
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-context-argument
`);
}
else if (legacyContext && !legacyOptions) {
options = { ...legacyContext };
logger = getLegacyLogger(options);
}
else {
logger = getLegacyLogger({});
}
// map old event names to new event names
// https://github.com/chimurai/http-proxy-middleware/pull/745/files#diff-c54113cf61ec99691748a3890bfbeb00e10efb3f0a76f03a0fd9ec49072e410aL48-L53
Object.entries(proxyEventMap).forEach(([legacyEventName, proxyEventName]) => {
if (options[legacyEventName]) {
options.on = { ...options.on };
options.on[proxyEventName] = options[legacyEventName];
debug('map legacy event "%s" to "on.%s"', legacyEventName, proxyEventName);
logger.warn(`[http-proxy-middleware] Legacy "${legacyEventName}" is deprecated. Migrate to "options.on.${proxyEventName}":
const options = {
on: {
${proxyEventName}: () => {},
},
}
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#refactored-proxy-events
`);
}
});
// map old logProvider to new logger
// https://github.com/chimurai/http-proxy-middleware/pull/749
const logProvider = options.logProvider && options.logProvider();
const logLevel = options.logLevel;
debug('legacy logLevel', logLevel);
debug('legacy logProvider: %O', logProvider);
if (typeof logLevel === 'string' && logLevel !== 'silent') {
debug('map "logProvider" to "logger"');
logger.warn(`[http-proxy-middleware] Legacy "logLevel" and "logProvider" are deprecated. Migrate to "options.logger":
const options = {
logger: console,
}
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-logprovider-and-loglevel-options
`);
}
return options;
}
function getLegacyLogger(options) {
const legacyLogger = options.logProvider && options.logProvider();
if (legacyLogger) {
options.logger = legacyLogger;
}
return (0, logger_1.getLogger)(options);
}

View File

@@ -0,0 +1,2 @@
export { legacyCreateProxyMiddleware } from './create-proxy-middleware';
export { LegacyOptions } from './types';

View File

@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.legacyCreateProxyMiddleware = void 0;
var create_proxy_middleware_1 = require("./create-proxy-middleware");
Object.defineProperty(exports, "legacyCreateProxyMiddleware", { enumerable: true, get: function () { return create_proxy_middleware_1.legacyCreateProxyMiddleware; } });

View File

@@ -0,0 +1,111 @@
import type * as http from 'http';
import { Options } from '../types';
/**
* @deprecated
*
* Will be removed in a future version.
*/
export interface LegacyOptions<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends Options<TReq, TRes> {
/**
* @deprecated
* Use `on.error` instead.
*
* @example
* ```js
* {
* on: {
* error: () => {}
* }
* ```
*/
onError?: (...args: any[]) => void;
/**
* @deprecated
* Use `on.proxyRes` instead.
*
* @example
* ```js
* {
* on: {
* proxyRes: () => {}
* }
* ```
*/
onProxyRes?: (...args: any[]) => void;
/**
* @deprecated
* Use `on.proxyReq` instead.
*
* @example
* ```js
* {
* on: {
* proxyReq: () => {}
* }
* ```
*/
onProxyReq?: (...args: any[]) => void;
/**
* @deprecated
* Use `on.proxyReqWs` instead.
*
* @example
* ```js
* {
* on: {
* proxyReqWs: () => {}
* }
* ```
*/
onProxyReqWs?: (...args: any[]) => void;
/**
* @deprecated
* Use `on.open` instead.
*
* @example
* ```js
* {
* on: {
* open: () => {}
* }
* ```
*/
onOpen?: (...args: any[]) => void;
/**
* @deprecated
* Use `on.close` instead.
*
* @example
* ```js
* {
* on: {
* close: () => {}
* }
* ```
*/
onClose?: (...args: any[]) => void;
/**
* @deprecated
* Use `logger` instead.
*
* @example
* ```js
* {
* logger: console
* }
* ```
*/
logProvider?: any;
/**
* @deprecated
* Use `logger` instead.
*
* @example
* ```js
* {
* logger: console
* }
* ```
*/
logLevel?: any;
}

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

2
node_modules/http-proxy-middleware/dist/logger.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import { Logger, Options } from './types';
export declare function getLogger(options: Options): Logger;

24
node_modules/http-proxy-middleware/dist/logger.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLogger = getLogger;
/**
* Compatibility matrix
*
| Library | log | info | warn | error | \<interpolation\> |
|----------|:------|:-------|:------|:--------|:------------------|
| console | ✅ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
| bunyan | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
| pino | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
| winston | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O)^1 |
| log4js | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
*
* ^1: https://github.com/winstonjs/winston#string-interpolation
*/
const noopLogger = {
info: () => { },
warn: () => { },
error: () => { },
};
function getLogger(options) {
return options.logger || noopLogger;
}

View File

@@ -0,0 +1,3 @@
import type { Filter } from './types';
import type * as http from 'http';
export declare function matchPathFilter<TReq = http.IncomingMessage>(pathFilter: Filter<TReq> | undefined, uri: string | undefined, req: http.IncomingMessage): boolean;

80
node_modules/http-proxy-middleware/dist/path-filter.js generated vendored Normal file
View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.matchPathFilter = matchPathFilter;
const isGlob = require("is-glob");
const micromatch = require("micromatch");
const url = require("url");
const errors_1 = require("./errors");
function matchPathFilter(pathFilter = '/', uri, req) {
// single path
if (isStringPath(pathFilter)) {
return matchSingleStringPath(pathFilter, uri);
}
// single glob path
if (isGlobPath(pathFilter)) {
return matchSingleGlobPath(pathFilter, uri);
}
// multi path
if (Array.isArray(pathFilter)) {
if (pathFilter.every(isStringPath)) {
return matchMultiPath(pathFilter, uri);
}
if (pathFilter.every(isGlobPath)) {
return matchMultiGlobPath(pathFilter, uri);
}
throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY);
}
// custom matching
if (typeof pathFilter === 'function') {
const pathname = getUrlPathName(uri);
return pathFilter(pathname, req);
}
throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_GENERIC);
}
/**
* @param {String} pathFilter '/api'
* @param {String} uri 'http://example.org/api/b/c/d.html'
* @return {Boolean}
*/
function matchSingleStringPath(pathFilter, uri) {
const pathname = getUrlPathName(uri);
return pathname?.indexOf(pathFilter) === 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} pathFilterList ['/api', '/ajax']
* @param {String} uri 'http://example.org/api/b/c/d.html'
* @return {Boolean}
*/
function matchMultiPath(pathFilterList, uri) {
let isMultiPath = false;
for (const context of pathFilterList) {
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(pathFilter) {
return typeof pathFilter === 'string' && !isGlob(pathFilter);
}
function isGlobPath(pathFilter) {
return isGlob(pathFilter);
}

View File

@@ -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;

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPathRewriter = createPathRewriter;
const is_plain_object_1 = require("is-plain-object");
const errors_1 = require("./errors");
const debug_1 = require("./debug");
const debug = debug_1.Debug.extend('path-rewriter');
/**
* 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);
debug('rewriting path from "%s" to "%s"', path, result);
break;
}
}
return result;
}
}
function isValidRewriteConfig(rewriteConfig) {
if (typeof rewriteConfig === 'function') {
return true;
}
else if ((0, is_plain_object_1.isPlainObject)(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 ((0, is_plain_object_1.isPlainObject)(rewriteConfig)) {
for (const [key, value] of Object.entries(rewriteConfig)) {
rules.push({
regex: new RegExp(key),
value: value,
});
debug('rewrite rule created: "%s" ~> "%s"', key, value);
}
}
return rules;
}

View File

@@ -0,0 +1,6 @@
import { Plugin } from '../../types';
/**
* Subscribe to {@link https://www.npmjs.com/package/http-proxy#listening-for-proxy-events http-proxy error events} to prevent server from crashing.
* Errors are logged with {@link https://www.npmjs.com/package/debug debug} library.
*/
export declare const debugProxyErrorsPlugin: Plugin;

View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.debugProxyErrorsPlugin = void 0;
const debug_1 = require("../../debug");
const debug = debug_1.Debug.extend('debug-proxy-errors-plugin');
/**
* Subscribe to {@link https://www.npmjs.com/package/http-proxy#listening-for-proxy-events http-proxy error events} to prevent server from crashing.
* Errors are logged with {@link https://www.npmjs.com/package/debug debug} library.
*/
const debugProxyErrorsPlugin = (proxyServer) => {
/**
* http-proxy doesn't handle any errors by default (https://github.com/http-party/node-http-proxy#listening-for-proxy-events)
* Prevent server from crashing when http-proxy errors (uncaught errors)
*/
proxyServer.on('error', (error, req, res, target) => {
debug(`http-proxy error event: \n%O`, error);
});
proxyServer.on('proxyReq', (proxyReq, req, socket) => {
socket.on('error', (error) => {
debug('Socket error in proxyReq event: \n%O', error);
});
});
/**
* Fix SSE close events
* @link https://github.com/chimurai/http-proxy-middleware/issues/678
* @link https://github.com/http-party/node-http-proxy/issues/1520#issue-877626125
*/
proxyServer.on('proxyRes', (proxyRes, req, res) => {
res.on('close', () => {
if (!res.writableEnded) {
debug('Destroying proxyRes in proxyRes close event');
proxyRes.destroy();
}
});
});
/**
* Fix crash when target server restarts
* https://github.com/chimurai/http-proxy-middleware/issues/476#issuecomment-746329030
* https://github.com/webpack/webpack-dev-server/issues/1642#issuecomment-790602225
*/
proxyServer.on('proxyReqWs', (proxyReq, req, socket) => {
socket.on('error', (error) => {
debug('Socket error in proxyReqWs event: \n%O', error);
});
});
proxyServer.on('open', (proxySocket) => {
proxySocket.on('error', (error) => {
debug('Socket error in open event: \n%O', error);
});
});
proxyServer.on('close', (req, socket, head) => {
socket.on('error', (error) => {
debug('Socket error in close event: \n%O', error);
});
});
// https://github.com/webpack/webpack-dev-server/issues/1642#issuecomment-1103136590
proxyServer.on('econnreset', (error, req, res, target) => {
debug(`http-proxy econnreset event: \n%O`, error);
});
};
exports.debugProxyErrorsPlugin = debugProxyErrorsPlugin;

View File

@@ -0,0 +1,2 @@
import { Plugin } from '../../types';
export declare const errorResponsePlugin: Plugin;

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorResponsePlugin = void 0;
const status_code_1 = require("../../status-code");
const errorResponsePlugin = (proxyServer, options) => {
proxyServer.on('error', (err, req, res, target) => {
// Re-throw error. Not recoverable since req & res are empty.
if (!req && !res) {
throw err; // "Error: Must provide a proper URL as target"
}
if ('writeHead' in res && !res.headersSent) {
const statusCode = (0, status_code_1.getStatusCode)(err.code);
res.writeHead(statusCode);
}
const host = req.headers && req.headers.host;
res.end(`Error occurred while trying to proxy: ${host}${req.url}`);
});
};
exports.errorResponsePlugin = errorResponsePlugin;

View File

@@ -0,0 +1,4 @@
export * from './debug-proxy-errors-plugin';
export * from './error-response-plugin';
export * from './logger-plugin';
export * from './proxy-events';

View File

@@ -0,0 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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("./debug-proxy-errors-plugin"), exports);
__exportStar(require("./error-response-plugin"), exports);
__exportStar(require("./logger-plugin"), exports);
__exportStar(require("./proxy-events"), exports);

View File

@@ -0,0 +1,2 @@
import { Plugin } from '../../types';
export declare const loggerPlugin: Plugin;

View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loggerPlugin = void 0;
const url_1 = require("url");
const logger_1 = require("../../logger");
const logger_plugin_1 = require("../../utils/logger-plugin");
const loggerPlugin = (proxyServer, options) => {
const logger = (0, logger_1.getLogger)(options);
proxyServer.on('error', (err, req, res, target) => {
const hostname = req?.headers?.host;
const requestHref = `${hostname}${req?.url}`;
const targetHref = `${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
logger.error(errorMessage, requestHref, targetHref, err.code || err, errReference);
});
/**
* Log request and response
* @example
* ```shell
* [HPM] GET /users/ -> http://jsonplaceholder.typicode.com/users/ [304]
* ```
*/
proxyServer.on('proxyRes', (proxyRes, req, res) => {
// BrowserSync uses req.originalUrl
// Next.js doesn't have req.baseUrl
const originalUrl = req.originalUrl ?? `${req.baseUrl || ''}${req.url}`;
// construct targetUrl
let target;
try {
const port = (0, logger_plugin_1.getPort)(proxyRes.req?.agent?.sockets);
const obj = {
protocol: proxyRes.req.protocol,
host: proxyRes.req.host,
pathname: proxyRes.req.path,
};
target = new url_1.URL(`${obj.protocol}//${obj.host}${obj.pathname}`);
if (port) {
target.port = port;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}
catch (err) {
// nock issue (https://github.com/chimurai/http-proxy-middleware/issues/1035)
// fallback to old implementation (less correct - without port)
target = new url_1.URL(options.target);
target.pathname = proxyRes.req.path;
}
const targetUrl = target.toString();
const exchange = `[HPM] ${req.method} ${originalUrl} -> ${targetUrl} [${proxyRes.statusCode}]`;
logger.info(exchange);
});
/**
* When client opens WebSocket connection
*/
proxyServer.on('open', (socket) => {
logger.info('[HPM] Client connected: %o', socket.address());
});
/**
* When client closes WebSocket connection
*/
proxyServer.on('close', (req, proxySocket, proxyHead) => {
logger.info('[HPM] Client disconnected: %o', proxySocket.address());
});
};
exports.loggerPlugin = loggerPlugin;

View File

@@ -0,0 +1,22 @@
import { Plugin } from '../../types';
/**
* Implements option.on object to subscribe to http-proxy events.
*
* @example
* ```js
* createProxyMiddleware({
* on: {
* error: (error, req, res, target) => {},
* proxyReq: (proxyReq, req, res, options) => {},
* proxyReqWs: (proxyReq, req, socket, options) => {},
* proxyRes: (proxyRes, req, res) => {},
* open: (proxySocket) => {},
* close: (proxyRes, proxySocket, proxyHead) => {},
* start: (req, res, target) => {},
* end: (req, res, proxyRes) => {},
* econnreset: (error, req, res, target) => {},
* }
* });
* ```
*/
export declare const proxyEventsPlugin: Plugin;

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.proxyEventsPlugin = void 0;
const debug_1 = require("../../debug");
const function_1 = require("../../utils/function");
const debug = debug_1.Debug.extend('proxy-events-plugin');
/**
* Implements option.on object to subscribe to http-proxy events.
*
* @example
* ```js
* createProxyMiddleware({
* on: {
* error: (error, req, res, target) => {},
* proxyReq: (proxyReq, req, res, options) => {},
* proxyReqWs: (proxyReq, req, socket, options) => {},
* proxyRes: (proxyRes, req, res) => {},
* open: (proxySocket) => {},
* close: (proxyRes, proxySocket, proxyHead) => {},
* start: (req, res, target) => {},
* end: (req, res, proxyRes) => {},
* econnreset: (error, req, res, target) => {},
* }
* });
* ```
*/
const proxyEventsPlugin = (proxyServer, options) => {
Object.entries(options.on || {}).forEach(([eventName, handler]) => {
debug(`register event handler: "${eventName}" -> "${(0, function_1.getFunctionName)(handler)}"`);
proxyServer.on(eventName, handler);
});
};
exports.proxyEventsPlugin = proxyEventsPlugin;

1
node_modules/http-proxy-middleware/dist/router.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare function getTarget(req: any, config: any): Promise<any>;

45
node_modules/http-proxy-middleware/dist/router.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTarget = getTarget;
const is_plain_object_1 = require("is-plain-object");
const debug_1 = require("./debug");
const debug = debug_1.Debug.extend('router');
async function getTarget(req, config) {
let newTarget;
const router = config.router;
if ((0, is_plain_object_1.isPlainObject)(router)) {
newTarget = getTargetFromProxyTable(req, router);
}
else if (typeof router === 'function') {
newTarget = await router(req);
}
return newTarget;
}
function getTargetFromProxyTable(req, table) {
let result;
const host = req.headers.host;
const path = req.url;
const hostAndPath = host + path;
for (const [key, value] of Object.entries(table)) {
if (containsPath(key)) {
if (hostAndPath.indexOf(key) > -1) {
// match 'localhost:3000/api'
result = value;
debug('match: "%s" -> "%s"', key, result);
break;
}
}
else {
if (key === host) {
// match 'localhost:3000'
result = value;
debug('match: "%s" -> "%s"', host, result);
break;
}
}
}
return result;
}
function containsPath(v) {
return v.indexOf('/') > -1;
}

View File

@@ -0,0 +1 @@
export declare function getStatusCode(errorCode: string): number;

23
node_modules/http-proxy-middleware/dist/status-code.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStatusCode = getStatusCode;
function getStatusCode(errorCode) {
let statusCode;
if (/HPE_INVALID/.test(errorCode)) {
statusCode = 502;
}
else {
switch (errorCode) {
case 'ECONNRESET':
case 'ENOTFOUND':
case 'ECONNREFUSED':
case 'ETIMEDOUT':
statusCode = 504;
break;
default:
statusCode = 500;
break;
}
}
return statusCode;
}

122
node_modules/http-proxy-middleware/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,122 @@
/**
* Based on definition by DefinitelyTyped:
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
*/
import type * as http from 'http';
import type * as httpProxy from 'http-proxy';
import type * as net from 'net';
export type NextFunction<T = (err?: any) => void> = T;
export interface RequestHandler<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction> {
(req: TReq, res: TRes, next?: TNext): Promise<void>;
upgrade: (req: http.IncomingMessage, socket: net.Socket, head: Buffer) => void;
}
export type Filter<TReq = http.IncomingMessage> = string | string[] | ((pathname: string, req: TReq) => boolean);
export interface Plugin<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
(proxyServer: httpProxy<TReq, TRes>, options: Options<TReq, TRes>): void;
}
export interface OnProxyEvent<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
error?: httpProxy.ErrorCallback<Error, TReq, TRes>;
proxyReq?: httpProxy.ProxyReqCallback<http.ClientRequest, TReq, TRes>;
proxyReqWs?: httpProxy.ProxyReqWsCallback<http.ClientRequest, TReq>;
proxyRes?: httpProxy.ProxyResCallback<TReq, TRes>;
open?: httpProxy.OpenCallback;
close?: httpProxy.CloseCallback<TReq>;
start?: httpProxy.StartCallback<TReq, TRes>;
end?: httpProxy.EndCallback<TReq, TRes>;
econnreset?: httpProxy.EconnresetCallback<Error, TReq, TRes>;
}
export type Logger = Pick<Console, 'info' | 'warn' | 'error'>;
export interface Options<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends httpProxy.ServerOptions {
/**
* Narrow down requests to proxy or not.
* Filter on {@link http.IncomingMessage.url `pathname`} which is relative to the proxy's "mounting" point in the server.
* Or use the {@link http.IncomingMessage `req`} object for more complex filtering.
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathFilter.md
* @since v3.0.0
*/
pathFilter?: Filter<TReq>;
/**
* Modify request paths before requests are send to the target.
* @example
* ```js
* createProxyMiddleware({
* pathRewrite: {
* '^/api/old-path': '/api/new-path', // rewrite path
* }
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathRewrite.md
*/
pathRewrite?: {
[regexp: string]: string;
} | ((path: string, req: TReq) => string | undefined) | ((path: string, req: TReq) => Promise<string>);
/**
* Access the internal http-proxy server instance to customize behavior
*
* @example
* ```js
* createProxyMiddleware({
* plugins: [(proxyServer, options) => {
* proxyServer.on('error', (error, req, res) => {
* console.error(error);
* });
* }]
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware#plugins-array
* @since v3.0.0
*/
plugins?: Plugin<TReq, TRes>[];
/**
* Eject pre-configured plugins.
* NOTE: register your own error handlers to prevent server from crashing.
*
* @link https://github.com/chimurai/http-proxy-middleware#ejectplugins-boolean-default-false
* @since v3.0.0
*/
ejectPlugins?: boolean;
/**
* Listen to http-proxy events
* @see {@link OnProxyEvent} for available events
* @example
* ```js
* createProxyMiddleware({
* on: {
* error: (error, req, res, target) => {
* console.error(error);
* }
* }
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md
* @since v3.0.0
*/
on?: OnProxyEvent<TReq, TRes>;
/**
* Dynamically set the {@link Options.target `options.target`}.
* @example
* ```js
* createProxyMiddleware({
* router: async (req) => {
* return 'http://127:0.0.1:3000';
* }
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/router.md
*/
router?: {
[hostOrPath: string]: httpProxy.ServerOptions['target'];
} | ((req: TReq) => httpProxy.ServerOptions['target']) | ((req: TReq) => Promise<httpProxy.ServerOptions['target']>);
/**
* Log information from http-proxy-middleware
* @example
* ```js
* createProxyMiddleware({
* logger: console
* });
* ```
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md
* @since v3.0.0
*/
logger?: Logger | any;
}

6
node_modules/http-proxy-middleware/dist/types.js generated vendored Normal file
View File

@@ -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 });

View File

@@ -0,0 +1 @@
export declare function getFunctionName(fn: Function): string;

View File

@@ -0,0 +1,7 @@
"use strict";
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFunctionName = getFunctionName;
function getFunctionName(fn) {
return fn.name || '[anonymous Function]';
}

View File

@@ -0,0 +1,7 @@
import type { Agent } from 'node:http';
export type Sockets = Pick<Agent, 'sockets'>;
/**
* Get port from target
* Using proxyRes.req.agent.sockets to determine the target port
*/
export declare function getPort(sockets?: Sockets): string | undefined;

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPort = getPort;
/**
* Get port from target
* Using proxyRes.req.agent.sockets to determine the target port
*/
function getPort(sockets) {
return Object.keys(sockets || {})?.[0]?.split(':')[1];
}

107
node_modules/http-proxy-middleware/package.json generated vendored Normal file
View File

@@ -0,0 +1,107 @@
{
"name": "http-proxy-middleware",
"type": "commonjs",
"version": "3.0.3",
"description": "The one-liner node.js proxy middleware for connect, express, next.js and more",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"clean": "rm -rf dist coverage tsconfig.tsbuildinfo .eslintcache",
"install:all": "yarn && (cd examples && yarn)",
"lint": "yarn prettier && yarn eslint",
"lint:fix": "yarn prettier:fix && yarn eslint:fix",
"eslint": "eslint '{src,test,examples}/**/*.{js,ts}' --cache",
"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}\"",
"build": "tsc --build",
"test": "jest",
"coverage": "jest --coverage",
"prepare": "husky",
"prepack": "yarn clean && yarn test && yarn build",
"spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"
},
"publishConfig": {
"provenance": true
},
"repository": {
"type": "git",
"url": "git+https://github.com/chimurai/http-proxy-middleware.git"
},
"keywords": [
"reverse",
"proxy",
"middleware",
"http",
"https",
"connect",
"express",
"fastify",
"polka",
"next.js",
"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": "19.4.1",
"@commitlint/config-conventional": "19.4.1",
"@eslint/js": "9.9.1",
"@types/debug": "4.1.12",
"@types/eslint": "9.6.1",
"@types/eslint__js": "8.42.3",
"@types/express": "4.17.21",
"@types/is-glob": "4.0.4",
"@types/jest": "29.5.12",
"@types/micromatch": "4.0.9",
"@types/node": "22.5.1",
"@types/supertest": "6.0.2",
"@types/ws": "8.5.12",
"body-parser": "1.20.2",
"eslint": "9.9.1",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.2.1",
"express": "4.19.2",
"get-port": "5.1.1",
"globals": "15.9.0",
"husky": "9.1.5",
"jest": "29.7.0",
"lint-staged": "15.2.9",
"mockttp": "3.15.2",
"open": "8.4.2",
"prettier": "3.3.3",
"supertest": "7.0.0",
"ts-jest": "29.2.5",
"typescript": "5.5.4",
"typescript-eslint": "8.3.0",
"ws": "8.18.0"
},
"dependencies": {
"@types/http-proxy": "^1.17.15",
"debug": "^4.3.6",
"http-proxy": "^1.18.1",
"is-glob": "^4.0.3",
"is-plain-object": "^5.0.0",
"micromatch": "^4.0.8"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
}