├── .all-contributorsrc
├── .editorconfig
├── .gitignore
├── .templates
├── .editorconfig
├── .gitignore
├── template-sample-react-component
│ ├── index.jsx
│ └── index.scss
└── template-sample
│ └── index.js
├── README.md
├── build
├── index.d.ts
├── index.js
└── index.test.d.ts
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
├── index.test.ts
└── index.ts
├── template.config.js
└── tsconfig.json
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "README.md"
4 | ],
5 | "imageSize": 100,
6 | "commit": false,
7 | "contributors": [
8 | {
9 | "login": "iamdenny",
10 | "name": "Denny Lim",
11 | "avatar_url": "https://avatars.githubusercontent.com/u/1505166?v=4",
12 | "profile": "http://iamdenny.com",
13 | "contributions": [
14 | "bug",
15 | "code"
16 | ]
17 | },
18 | {
19 | "login": "larrifax",
20 | "name": "Kristian Tryggestad",
21 | "avatar_url": "https://avatars.githubusercontent.com/u/144189?v=4",
22 | "profile": "https://github.com/larrifax",
23 | "contributions": [
24 | "bug",
25 | "code"
26 | ]
27 | },
28 | {
29 | "login": "gthb",
30 | "name": "Gunnlaugur Thor Briem",
31 | "avatar_url": "https://avatars.githubusercontent.com/u/153580?v=4",
32 | "profile": "https://github.com/gthb",
33 | "contributions": [
34 | "code",
35 | "ideas"
36 | ]
37 | },
38 | {
39 | "login": "ottovw",
40 | "name": "Otto von Wesendonk",
41 | "avatar_url": "https://avatars.githubusercontent.com/u/1045946?v=4",
42 | "profile": "https://ottovw.com",
43 | "contributions": [
44 | "security"
45 | ]
46 | },
47 | {
48 | "login": "dsilvasc",
49 | "name": "Daniel Silva",
50 | "avatar_url": "https://avatars.githubusercontent.com/u/24484414?v=4",
51 | "profile": "https://github.com/dsilvasc",
52 | "contributions": [
53 | "ideas"
54 | ]
55 | },
56 | {
57 | "login": "Kerumen",
58 | "name": "Yann Pringault",
59 | "avatar_url": "https://avatars.githubusercontent.com/u/5436545?v=4",
60 | "profile": "https://lumenstudio.dev/",
61 | "contributions": [
62 | "code"
63 | ]
64 | },
65 | {
66 | "login": "lorenzodejong",
67 | "name": "Lorenzo",
68 | "avatar_url": "https://avatars.githubusercontent.com/u/30781484?v=4",
69 | "profile": "https://github.com/lorenzodejong",
70 | "contributions": [
71 | "doc"
72 | ]
73 | },
74 | {
75 | "login": "tgrassl",
76 | "name": "Timon Grassl",
77 | "avatar_url": "https://avatars.githubusercontent.com/u/34568407?v=4",
78 | "profile": "https://medium.com/@timon.grassl",
79 | "contributions": [
80 | "bug"
81 | ]
82 | },
83 | {
84 | "login": "abhinavkumar940",
85 | "name": "Abhinav Kumar",
86 | "avatar_url": "https://avatars.githubusercontent.com/u/1189133?v=4",
87 | "profile": "https://github.com/abhinavkumar940",
88 | "contributions": [
89 | "doc"
90 | ]
91 | },
92 | {
93 | "login": "JackCuthbert",
94 | "name": "Jack Cuthbert",
95 | "avatar_url": "https://avatars.githubusercontent.com/u/5564612?v=4",
96 | "profile": "https://jackcuthbert.dev/",
97 | "contributions": [
98 | "doc"
99 | ]
100 | },
101 | {
102 | "login": "FDiskas",
103 | "name": "Vytenis",
104 | "avatar_url": "https://avatars.githubusercontent.com/u/468006?v=4",
105 | "profile": "https://vytenis.kuciauskas.lt",
106 | "contributions": [
107 | "doc"
108 | ]
109 | },
110 | {
111 | "login": "dariosky",
112 | "name": "Dario Varotto",
113 | "avatar_url": "https://avatars.githubusercontent.com/u/705644?v=4",
114 | "profile": "https://dariosky.it",
115 | "contributions": [
116 | "doc"
117 | ]
118 | },
119 | {
120 | "login": "johannbrynjar",
121 | "name": "johannbrynjar",
122 | "avatar_url": "https://avatars.githubusercontent.com/u/2641440?v=4",
123 | "profile": "https://github.com/johannbrynjar",
124 | "contributions": [
125 | "bug",
126 | "code"
127 | ]
128 | },
129 | {
130 | "login": "bever1337",
131 | "name": "bever1337",
132 | "avatar_url": "https://avatars.githubusercontent.com/u/28774413?v=4",
133 | "profile": "https://github.com/bever1337",
134 | "contributions": [
135 | "doc"
136 | ]
137 | }
138 | ],
139 | "contributorsPerLine": 7,
140 | "projectName": "next-http-proxy-middleware",
141 | "projectOwner": "stegano",
142 | "repoType": "github",
143 | "repoHost": "https://github.com",
144 | "skipCi": true,
145 | "commitType": "docs",
146 | "commitConvention": "angular"
147 | }
148 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # @see https://editorconfig-specification.readthedocs.io/en/latest/
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 | charset = utf-8
13 |
14 | # 4 space indentation
15 | [*.py]
16 | indent_style = space
17 | indent_size = 4
18 |
19 | # Tab indentation (no size specified)
20 | [Makefile]
21 | indent_style = tab
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # @see https://git-scm.com/docs/gitignore
2 |
3 | # `.DS_Store` is a file that stores custom attributes of its containing folder
4 | .DS_Store
5 |
6 | # Logs
7 | logs
8 | *.log
9 |
10 | # Dependencies
11 | node_modules
12 | bower_components
13 | vendor
14 |
15 | # Caches
16 | .cache
17 | .npm
18 | .eslintcache
19 |
20 | # Temporaries
21 | .tmp
22 | .temp
23 |
24 | # Built
25 | dist
26 | target
27 | built
28 | output
29 | out
30 |
--------------------------------------------------------------------------------
/.templates/.editorconfig:
--------------------------------------------------------------------------------
1 | # @see https://editorconfig-specification.readthedocs.io/en/latest/
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 | charset = utf-8
13 |
14 | # 4 space indentation
15 | [*.py]
16 | indent_style = space
17 | indent_size = 4
18 |
19 | # Tab indentation (no size specified)
20 | [Makefile]
21 | indent_style = tab
22 |
--------------------------------------------------------------------------------
/.templates/.gitignore:
--------------------------------------------------------------------------------
1 | # @see https://git-scm.com/docs/gitignore
2 |
3 | # `.DS_Store` is a file that stores custom attributes of its containing folder
4 | .DS_Store
5 |
6 | # Logs
7 | logs
8 | *.log
9 |
10 | # Dependencies
11 | node_modules
12 | bower_components
13 | vendor
14 |
15 | # Caches
16 | .cache
17 | .npm
18 | .eslintcache
19 |
20 | # Temporaries
21 | .tmp
22 | .temp
23 |
24 | # Built
25 | dist
26 | target
27 | built
28 | output
29 | out
30 |
--------------------------------------------------------------------------------
/.templates/template-sample-react-component/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import classNames from "classnames/bind";
3 |
4 | import styles from "./index.scss";
5 |
6 | const cx = classNames.bind(styles);
7 |
8 | function __templateNameToPascalCase__() {
9 | return
Hello :)
;
10 | }
11 |
12 | export default __templateNameToPascalCase__;
13 |
--------------------------------------------------------------------------------
/.templates/template-sample-react-component/index.scss:
--------------------------------------------------------------------------------
1 | .__templateNameToParamCase__ {
2 | display: inline-block;
3 | }
4 |
--------------------------------------------------------------------------------
/.templates/template-sample/index.js:
--------------------------------------------------------------------------------
1 | export default function __templateNameToPascalCase__() {
2 | console.log("TemplateName -> __templateName__");
3 | console.log("TemplateName to ParamCase -> __templateNameToParamCase__");
4 | console.log("TemplateName to PascalCase -> __templateNameToPascalCase__");
5 | }
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Next.js HTTP Proxy Middleware
2 | 
3 | 
4 | [](#contributors-)
5 |
6 |
7 | HTTP Proxy middleware available in API Middleware provided by Next.js.
8 |
9 |
10 | ## ⭐️ Before using
11 | Please try the solutions below before using this library. 😀
12 |
13 | ### Try using `Next.js` Rewrites(recommended)
14 | * This function is supported by Next.js. No additional libraries need to be installed!
15 | * https://nextjs.org/docs/api-reference/next.config.js/rewrites
16 | ```ts
17 | // next.config.js
18 | async rewrites() {
19 | return [
20 | {
21 | source: "/api/:path*",
22 | destination: "http://example.com/api/:path*",
23 | },
24 | ];
25 | },
26 | ```
27 |
28 | ### Try using `Http-Proxy`
29 | * `next-http-proxy-middleware` is implemented using `http-proxy` internally. Since the implementation is not complicated, it is recommended to try `http-proxy` directly.
30 | ```ts
31 | // pages/api/[...all].ts
32 | import httpProxy from "http-proxy";
33 |
34 | export const config = {
35 | api: {
36 | // Enable `externalResolver` option in Next.js
37 | externalResolver: true,
38 | bodyParser: false,
39 | },
40 | };
41 |
42 | export default (req, res) =>
43 | new Promise((resolve, reject) => {
44 | const proxy: httpProxy = httpProxy.createProxy();
45 | proxy.once("proxyRes", resolve).once("error", reject).web(req, res, {
46 | changeOrigin: true,
47 | target: process.env.NEXT_PUBLIC_API_PROXY_URL,
48 | });
49 | });
50 | ```
51 |
52 | ## Installation
53 |
54 | The easiest way to install `next-http-proxy-middleware` is with [npm](https://www.npmjs.com/).
55 |
56 | ```bash
57 | npm install next-http-proxy-middleware
58 | ```
59 |
60 | Alternately, download the source.
61 |
62 | ```bash
63 | git clone https://github.com/stegano/next-http-proxy-middleware.git
64 | ```
65 |
66 | ## Features
67 |
68 | This middleware is implemented using the [`http-proxy`](https://www.npmjs.com/package/http-proxy) library. You can use the existing options provided by `http-proxy`. And you can rewrite the api path using `pathRewrite`, an additional option provided by this middleware.
69 |
70 | - [http-proxy options](https://www.npmjs.com/package/http-proxy#options)
71 |
72 | ### `pathRewrite` option
73 |
74 | - Replaces URL information matching the pattern with another string.
75 | - Priority is determined in the order entered in the array.
76 | - If the request URL matches the pattern `pathRewrite.patternStr` replace the URL string with the value `pathRewrite.replaceStr`.
77 |
78 | ### `onProxyInit` option
79 | - You can access the `http-proxy` instance using the `onProxyInit` option. See the example below.
80 |
81 | ```ts
82 | import type { NextApiRequest, NextApiResponse } from "next";
83 | import type { NextHttpProxyMiddlewareOptions } from "next-http-proxy-middleware";
84 | import httpProxyMiddleware from "next-http-proxy-middleware";
85 |
86 | const handleProxyInit: NextHttpProxyMiddlewareOptions["onProxyInit"] = (proxy) => {
87 | /**
88 | * Check the list of bindable events in the `http-proxy` specification.
89 | * @see https://www.npmjs.com/package/http-proxy#listening-for-proxy-events
90 | */
91 | proxy.on("proxyReq", (proxyReq, req, res) => {
92 | // ...
93 | });
94 | proxy.on("proxyRes", (proxyRes, req, res) => {
95 | // ...
96 | });
97 | };
98 |
99 | export default async (req: NextApiRequest, res: NextApiResponse) =>
100 | httpProxyMiddleware(req, res, {
101 | target: "http://example.com",
102 | onProxyInit: handleProxyInit,
103 | });
104 | ```
105 |
106 | #### Example
107 |
108 | - Refer to the following for how to use Next.js API Middleware
109 |
110 | - [Next.js API Middlewares Guide](https://nextjs.org/docs/api-routes/api-middlewares)
111 |
112 | ```ts
113 | // pages/api/[...all].ts
114 | import type { NextApiRequest, NextApiResponse } from "next";
115 | import httpProxyMiddleware from "next-http-proxy-middleware";
116 |
117 | const isDevelopment = process.env.NODE_ENV !== "production";
118 |
119 | export const config = {
120 | api: {
121 | // Enable `externalResolver` option in Next.js
122 | externalResolver: true,
123 | },
124 | }
125 |
126 | export default (req: NextApiRequest, res: NextApiResponse) => (
127 | isDevelopment
128 | ? httpProxyMiddleware(req, res, {
129 | // You can use the `http-proxy` option
130 | target: "https://www.example.com",
131 | // In addition, you can use the `pathRewrite` option provided by `next-http-proxy-middleware`
132 | pathRewrite: [{
133 | patternStr: "^/api/new",
134 | replaceStr: "/v2"
135 | }, {
136 | patternStr: "^/api",
137 | replaceStr: ""
138 | }],
139 | })
140 | : res.status(404).send(null)
141 | );
142 | ```
143 | - `externalResolver` is an explicit flag that tells the server that this route is being handled by an external resolver. Enabling this option disables warnings for unresolved requests.
144 | - See the issues below
145 | - https://github.com/stegano/next-http-proxy-middleware/issues/32
146 | - https://github.com/stegano/next-http-proxy-middleware/issues/21
147 |
148 | #### Using `multipart/form-data`
149 | * If you are using the `multipart/form-data`, refer to the Issues below
150 | * https://github.com/stegano/next-http-proxy-middleware/issues/33
151 | * https://github.com/vercel/next.js/pull/7686
152 |
153 |
154 | ## Other projects
155 | * [ReactRenderStateHook](https://www.npmjs.com/package/react-render-state-hook)
156 | * `react-render-state-hook` is a React hook that enables declarative management of components based on data processing states. It facilitates straightforward state management and data sharing among multiple components in a React.
157 |
158 |
159 | ## Contributors ✨
160 |
161 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
162 |
163 |
164 |
165 |
166 |
188 |
189 |
190 |
191 |
192 |
193 |
194 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
195 |
--------------------------------------------------------------------------------
/build/index.d.ts:
--------------------------------------------------------------------------------
1 | import { NextApiResponse, NextApiRequest } from "next";
2 | import httpProxy, { ServerOptions } from "http-proxy";
3 | export interface NextHttpProxyMiddlewareOptions extends ServerOptions {
4 | pathRewrite?: {
5 | [key: string]: string;
6 | } | {
7 | patternStr: string;
8 | replaceStr: string;
9 | }[];
10 | onProxyInit?: (httpProxy: httpProxy) => void;
11 | }
12 | /**
13 | * If pattern information matching the input url information is found in the `pathRewrite` array,
14 | * the url value is partially replaced with the `pathRewrite.replaceStr` value.
15 | * @param url
16 | * @param pathRewrite
17 | */
18 | export declare const rewritePath: (url: string, pathRewrite: {
19 | [key: string]: string;
20 | } | {
21 | patternStr: string;
22 | replaceStr: string;
23 | }[] | undefined) => string;
24 | /**
25 | * Next.js HTTP Proxy Middleware
26 | * @see https://nextjs.org/docs/api-routes/api-middlewares
27 | * @param {NextApiRequest} req
28 | * @param {NextApiResponse} res
29 | * @param {NextHttpProxyMiddlewareOptions} httpProxyOptions
30 | */
31 | declare const httpProxyMiddleware: (req: NextApiRequest, res: NextApiResponse, httpProxyOptions?: NextHttpProxyMiddlewareOptions) => Promise;
32 | export default httpProxyMiddleware;
33 |
--------------------------------------------------------------------------------
/build/index.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var httpProxy=require("http-proxy");function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var httpProxy__default=_interopDefaultLegacy(httpProxy),__assign=function(){return(__assign=Object.assign||function(e){for(var t,r=1,n=arguments.length;ri[0]&&t[1]",
13 | "Denny Lim",
14 | "Kristian Tryggestad",
15 | "Gunnlaugur Thor Briem",
16 | "Otto von Wesendonk",
17 | "Daniel Silva",
18 | "Yann Pringault",
19 | "Lorenzo",
20 | "Timon Grassl",
21 | "Abhinav Kumar",
22 | "Jack Cuthbert",
23 | "Vytenis",
24 | "Dario Varotto",
25 | "johannbrynjar"
26 | ],
27 | "dependencies": {
28 | "@types/http-proxy": "1.17.3",
29 | "http-proxy": "^1.18.1"
30 | },
31 | "devDependencies": {
32 | "@types/jest": "^25.1.3",
33 | "typescript": "^3.8.2",
34 | "jest": "^29.7.0",
35 | "next": "^14.1.1",
36 | "rollup": "^2.38.0",
37 | "rollup-plugin-typescript2": "^0.29.0",
38 | "rollup-plugin-uglify": "^6.0.4",
39 | "ts-jest": "^26.4.4"
40 | },
41 | "jest": {
42 | "transform": {
43 | "^.+\\.ts$": "ts-jest"
44 | },
45 | "testRegex": "\\.test\\.ts$",
46 | "moduleFileExtensions": [
47 | "ts",
48 | "js"
49 | ],
50 | "globals": {
51 | "ts-jest": {
52 | "enableTsDiagnostics": true
53 | }
54 | }
55 | },
56 | "license": "MIT",
57 | "bugs": {
58 | "url": "https://github.com/stegano/next-http-proxy-middleware/issues"
59 | },
60 | "keywords": [
61 | "reverse",
62 | "proxy",
63 | "middleware",
64 | "http",
65 | "https",
66 | "connect",
67 | "express",
68 | "websocket",
69 | "ws",
70 | "cors",
71 | "next",
72 | "next.js"
73 | ],
74 | "homepage": "https://github.com/stegano/next-http-proxy-middleware#readme",
75 | "engines": {
76 | "node": ">=10.0.0"
77 | }
78 | }
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import typescript from "rollup-plugin-typescript2";
2 | import { uglify } from "rollup-plugin-uglify";
3 |
4 | export default {
5 | input: "./src/index.ts",
6 | output: {
7 | file: "./build/index.js",
8 | format: "cjs",
9 | exports: "named"
10 | },
11 | plugins: [typescript(), uglify()],
12 | external: ['next', 'http-proxy']
13 | };
14 |
--------------------------------------------------------------------------------
/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import { rewritePath } from "./index";
2 |
3 | describe("Test `rewritePath` functionn ", () => {
4 | test("[deprecated] Replace root URI context", () => {
5 | const originUrl = "/api/a/b";
6 | expect("/auth/a/b").toEqual(rewritePath(originUrl, { "/api": "/auth" }));
7 | });
8 |
9 | test("[deprecated] Remove root URI context", () => {
10 | const originUrl = "/api/a/b";
11 | expect("/auth/a/b").toEqual(rewritePath(originUrl, { "/api": "/auth" }));
12 | });
13 |
14 | test("Replace root URI context", () => {
15 | const originUrl = "/api/a/b";
16 | expect("/auth/a/b").toEqual(rewritePath(originUrl, [{
17 | patternStr: "/api",
18 | replaceStr: "/auth"
19 | },
20 | ]));
21 | });
22 |
23 | test("Remove root URI context", () => {
24 | const originUrl = "/api/a/b";
25 | expect("/auth/a/b").toEqual(rewritePath(originUrl, [{
26 | patternStr: "/api",
27 | replaceStr: "/auth"
28 | }]));
29 | });
30 |
31 | test("Issue(#45) test", () => {
32 | const originUrl = "/test/api/graphql";
33 | expect("/test").toEqual(rewritePath(originUrl, {
34 | "/api/graphql": "",
35 | }));
36 | });
37 |
38 | test("Issue(#45) test", () => {
39 | const originUrl = "https://naver.com/test/api/graphql";
40 | expect("https://naver.com/test/api/graphql").toEqual(rewritePath(originUrl, [{
41 | patternStr: "/api/graphql",
42 | replaceStr: ""
43 | }]));
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { NextApiResponse, NextApiRequest } from "next";
2 | import httpProxy, { ServerOptions } from "http-proxy";
3 | export interface NextHttpProxyMiddlewareOptions extends ServerOptions {
4 | pathRewrite?: { [key: string]: string }
5 | | { patternStr: string, replaceStr: string }[];
6 | onProxyInit?: (httpProxy: httpProxy) => void
7 | }
8 |
9 | /**
10 | * Please refer to the following links for the specification document for HTTP.
11 | * @see https://tools.ietf.org/html/rfc7231
12 | * @see https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
13 | */
14 | const hasRequestBodyMethods: string[] = ["HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "PATCH"];
15 |
16 | /**
17 | * If pattern information matching the input url information is found in the `pathRewrite` array,
18 | * the url value is partially replaced with the `pathRewrite.replaceStr` value.
19 | * @param url
20 | * @param pathRewrite
21 | */
22 | export const rewritePath = (
23 | url: string,
24 | pathRewrite: NextHttpProxyMiddlewareOptions['pathRewrite']
25 | ) => {
26 | if(Array.isArray(pathRewrite)){
27 | for (const item of pathRewrite) {
28 | const {
29 | patternStr,
30 | replaceStr
31 | } = item;
32 | const pattern = RegExp(patternStr);
33 | if (pattern.test(url as string)) {
34 | return url.replace(pattern, replaceStr);
35 | }
36 | }
37 | } else {
38 | console.warn('[next-http-proxy-middleware] Use array instead of object for \`pathRewrite\` value '
39 | + '(related issue: https://github.com/stegano/next-http-proxy-middleware/issues/39)');
40 | for (const patternStr in pathRewrite) {
41 | const pattern = RegExp(patternStr);
42 | const path = pathRewrite[patternStr];
43 | if (pattern.test(url as string)) {
44 | return url.replace(pattern, path);
45 | }
46 | }
47 | }
48 | return url;
49 | };
50 |
51 | /**
52 | * Next.js HTTP Proxy Middleware
53 | * @see https://nextjs.org/docs/api-routes/api-middlewares
54 | * @param {NextApiRequest} req
55 | * @param {NextApiResponse} res
56 | * @param {NextHttpProxyMiddlewareOptions} httpProxyOptions
57 | */
58 | const httpProxyMiddleware = async (
59 | req: NextApiRequest,
60 | res: NextApiResponse,
61 | httpProxyOptions: NextHttpProxyMiddlewareOptions = {},
62 | ): Promise =>
63 | new Promise((resolve, reject) => {
64 | const { pathRewrite, onProxyInit, ...serverOptions } = httpProxyOptions;
65 |
66 | /**
67 | * @see https://www.npmjs.com/package/http-proxy
68 | */
69 | const proxy: httpProxy = httpProxy.createProxy();
70 |
71 | if(typeof onProxyInit === 'function') {
72 | onProxyInit(proxy);
73 | }
74 |
75 | if (pathRewrite) {
76 | req.url = rewritePath(req.url as string, pathRewrite);
77 | }
78 |
79 | if (hasRequestBodyMethods.indexOf(req.method as string) >= 0 && typeof req.body === "object") {
80 | req.body = JSON.stringify(req.body);
81 | }
82 | proxy
83 | .once("proxyReq", ((proxyReq: any, req: any): void => {
84 | if (hasRequestBodyMethods.indexOf(req.method as string) >= 0 && typeof req.body === "string") {
85 | proxyReq.write(req.body);
86 | proxyReq.end();
87 | }
88 | }) as any)
89 | .once("proxyRes", resolve as any)
90 | .once("error", reject)
91 | .web(req, res, {
92 | changeOrigin: true,
93 | ...serverOptions
94 | });
95 | });
96 |
97 | export default httpProxyMiddleware;
98 |
--------------------------------------------------------------------------------
/template.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is a configuration file generated by the `Template` extension on `vscode`
3 | * @see https://marketplace.visualstudio.com/items?itemName=yongwoo.template
4 | */
5 | module.exports = {
6 | // You can change the template path to another path
7 | templateRootPath: "./.templates",
8 | // After copying the template file the `replaceFileTextFn` function is executed
9 | replaceFileTextFn: (fileText, templateName, utils) => {
10 | // @see https://www.npmjs.com/package/change-case
11 | const { changeCase } = utils;
12 | // You can change the text in the file
13 | return fileText
14 | .replace(/__templateName__/gm, templateName)
15 | .replace(
16 | /__templateNameToPascalCase__/gm,
17 | changeCase.pascalCase(templateName)
18 | )
19 | .replace(
20 | /__templateNameToParamCase__/gm,
21 | changeCase.paramCase(templateName)
22 | );
23 | },
24 | replaceFileNameFn: (fileName, templateName, utils) => {
25 | const { path } = utils;
26 | // @see https://nodejs.org/api/path.html#path_path_parse_path
27 | const { base } = path.parse(fileName);
28 | // You can change the file name
29 | return base;
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "outDir": "build",
6 | "sourceMap": false,
7 | "strict": true,
8 | "lib": ["dom", "dom.iterable", "esnext"],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "noEmit": true,
13 | "esModuleInterop": true,
14 | "moduleResolution": "node",
15 | "resolveJsonModule": true,
16 | "isolatedModules": true,
17 | "jsx": "preserve",
18 | "declaration": true
19 | },
20 | "include": ["src/**/*"],
21 | "exclude": ["node_modules"]
22 | }
23 |
--------------------------------------------------------------------------------