Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 41bfafe

Browse files
committedFeb 25, 2020
init
0 parents  commit 41bfafe

File tree

17 files changed

+11527
-0
lines changed

17 files changed

+11527
-0
lines changed
 

‎.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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

‎.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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

‎.templates/.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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

‎.templates/.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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 <div className={cx("__templateNameToParamCase__")}>Hello :)</div>;
10+
}
11+
12+
export default __templateNameToPascalCase__;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.__templateNameToParamCase__ {
2+
display: inline-block;
3+
}

‎.templates/template-sample/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
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+
}

‎README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Next.js HTTP Proxy Middleware
2+
3+
HTTP Proxy middleware available in API Middleware provided by Next.js.
4+
5+
## Installation
6+
7+
The easiest way to install `next-http-proxy-middleware` is with [npm](https://www.npmjs.com/).
8+
9+
```bash
10+
11+
npm install next-http-proxy-middleware
12+
13+
```
14+
15+
Alternately, download the source.
16+
17+
```bash
18+
19+
git clone https://github.com/stegano/next-http-proxy-middleware.git
20+
21+
```
22+
23+
## Features
24+
25+
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.
26+
27+
- [http-proxy options](https://www.npmjs.com/package/http-proxy#options)
28+
29+
## Examples
30+
31+
- Refer to the following for how to use Nextjs API Middleware
32+
33+
- [Next.js API Middlewares Guide](https://nextjs.org/docs/api-routes/api-middlewares)
34+
35+
```typescript
36+
// pages/[...all].ts
37+
...
38+
export default (req: NextApiRequest, res: NextApiResponse) => (
39+
isDevelopment
40+
? httpProxyMiddleware(req, res, {
41+
target: 'https://www.example.com',
42+
pathRewrite: {
43+
'^/api/new': '/v2', // `/api/new/test` -> `/v2/test`
44+
'^/api': '', // `/api/test` -> `/test`
45+
},
46+
})
47+
: res.status(404).send(null)
48+
);
49+
```

‎build/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package-lock.json

Lines changed: 11161 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"name": "next-http-proxy-middleware",
3+
"version": "1.0.0",
4+
"description": "Nextjs HTTP Proxy Middleware",
5+
"main": "template.config.js",
6+
"scripts": {
7+
"test": "jest",
8+
"build": "rollup -c ./rollup.config.js"
9+
},
10+
"author": "Yongwoo Jung<stegano@naver.com>",
11+
"dependencies": {
12+
"@types/http-proxy": "1.17.3",
13+
"@types/jest": "^25.1.3",
14+
"@types/next": "^9.0.0",
15+
"http-proxy": "^1.18.0",
16+
"jest": "^25.1.0",
17+
"rollup": "^1.31.1",
18+
"rollup-plugin-typescript2": "^0.26.0",
19+
"rollup-plugin-uglify": "^6.0.4",
20+
"ts-jest": "^25.2.1",
21+
"typescript": "^3.8.2"
22+
},
23+
"jest": {
24+
"transform": {
25+
"^.+\\.ts$": "ts-jest"
26+
},
27+
"testRegex": "\\.test\\.ts$",
28+
"moduleFileExtensions": [
29+
"ts",
30+
"js"
31+
],
32+
"globals": {
33+
"ts-jest": {
34+
"enableTsDiagnostics": true
35+
}
36+
}
37+
},
38+
"license": "MIT",
39+
"bugs": {
40+
"url": "https://github.com/stegano/next-http-proxy-middleware/issues"
41+
},
42+
"keywords": [
43+
"reverse",
44+
"proxy",
45+
"middleware",
46+
"http",
47+
"https",
48+
"connect",
49+
"express",
50+
"websocket",
51+
"ws",
52+
"cors",
53+
"next",
54+
"next.js"
55+
],
56+
"homepage": "https://github.com/stegano/next-http-proxy-middleware#readme",
57+
"engines": {
58+
"node": ">=10.0.0"
59+
}
60+
}

‎rollup.config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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+
},
10+
plugins: [typescript(), uglify()]
11+
};

‎src/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { ServerOptions } from "http-proxy";
2+
export interface NextHttpProxyMiddlewareOptions extends ServerOptions {
3+
pathRewrite?: { [key: string]: string };
4+
}

‎src/index.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { rewritePath } from "./index";
2+
3+
describe("Test `rewritePath` functionn ", () => {
4+
test("Replace root URI context", () => {
5+
const originUrl = "/api/a/b";
6+
expect("/auth/a/b").toEqual(rewritePath(originUrl, { "/api": "/auth" }));
7+
});
8+
9+
test("Remove root URI context", () => {
10+
const originUrl = "/api/a/b";
11+
expect("/auth/a/b").toEqual(rewritePath(originUrl, { "/api": "/auth" }));
12+
});
13+
});

‎src/index.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { NextApiResponse, NextApiRequest } from "next";
2+
import httpProxy from "http-proxy";
3+
import { NextHttpProxyMiddlewareOptions } from "./index.d";
4+
5+
/**
6+
* @see https://www.npmjs.com/package/http-proxy
7+
*/
8+
const proxy: httpProxy = httpProxy.createProxy();
9+
10+
/**
11+
* If a key pattern is found in `pathRewrite` that matches the url value,
12+
* replace matched string of url with the `pathRewrite` value.
13+
* @param req
14+
* @param pathRewrite
15+
*/
16+
export const rewritePath = (
17+
url: string,
18+
pathRewrite: { [key: string]: string }
19+
) => {
20+
for (let patternStr in pathRewrite) {
21+
const pattern = RegExp(patternStr);
22+
const path = pathRewrite[patternStr];
23+
if (pattern.test(url as string)) {
24+
return url.replace(pattern, path);
25+
}
26+
}
27+
return url;
28+
};
29+
30+
/**
31+
* Next.js HTTP Proxy Middleware
32+
* @see https://nextjs.org/docs/api-routes/api-middlewares
33+
* @param {NextApiRequest} req
34+
* @param {NextApiResponse} res
35+
* @param {NextHttpProxyMiddlewareOptions} httpProxyOptions
36+
*/
37+
const httpProxyMiddleware = async (
38+
req: NextApiRequest,
39+
res: NextApiResponse,
40+
httpProxyOptions: NextHttpProxyMiddlewareOptions = {}
41+
) =>
42+
new Promise((resolve, reject) => {
43+
const { pathRewrite } = httpProxyOptions;
44+
if (pathRewrite) {
45+
req.url = rewritePath(req.url as string, pathRewrite);
46+
}
47+
proxy
48+
.once("proxyRes", resolve)
49+
.once("error", reject)
50+
.web(req, res, {
51+
changeOrigin: true,
52+
...httpProxyOptions
53+
});
54+
});
55+
56+
export default httpProxyMiddleware;

‎template.config.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
};

‎tsconfig.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
},
19+
"include": ["src/**/*"],
20+
"exclude": ["node_modules"]
21+
}

0 commit comments

Comments
 (0)
Please sign in to comment.