Skip to content

Commit ef81294

Browse files
committed
feat(typescript): types support
1 parent 7a738ea commit ef81294

18 files changed

+266
-41
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "0.21.0-beta.1",
44
"description": "The one-liner node.js proxy middleware for connect, express and browser-sync",
55
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
67
"files": [
78
"dist"
89
],
@@ -51,7 +52,6 @@
5152
"@commitlint/cli": "^8.0.0",
5253
"@commitlint/config-conventional": "^8.0.0",
5354
"@types/express": "^4.17.0",
54-
"@types/http-proxy": "^1.17.0",
5555
"@types/is-glob": "^4.0.0",
5656
"@types/jest": "^24.0.15",
5757
"@types/lodash": "^4.14.136",
@@ -72,6 +72,7 @@
7272
"ws": "^7.1.0"
7373
},
7474
"dependencies": {
75+
"@types/http-proxy": "^1.17.0",
7576
"http-proxy": "^1.17.0",
7677
"is-glob": "^4.0.1",
7778
"lodash": "^4.17.14",

src/config-factory.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import * as _ from 'lodash';
2-
import * as url from 'url';
1+
import _ from 'lodash';
2+
import url from 'url';
33
import { ERRORS } from './errors';
44
import { getInstance } from './logger';
5+
import { Filter, Options } from './types';
56

67
const logger = getInstance();
78

89
export function createConfig(context, opts?) {
910
// structure of config object to be returned
1011
const config = {
1112
context: undefined,
12-
options: {} as any
13+
options: {} as Options
1314
};
1415

1516
// app.use('/api', proxy({target:'http://localhost:9000'}));
@@ -55,7 +56,7 @@ export function createConfig(context, opts?) {
5556
* @param {String} context [description]
5657
* @return {Boolean} [description]
5758
*/
58-
function isStringShortHand(context) {
59+
function isStringShortHand(context: Filter) {
5960
if (_.isString(context)) {
6061
return !!url.parse(context).host;
6162
}
@@ -72,11 +73,11 @@ function isStringShortHand(context) {
7273
* @param {*} opts [description]
7374
* @return {Boolean} [description]
7475
*/
75-
function isContextless(context, opts) {
76+
function isContextless(context: Filter, opts: Options) {
7677
return _.isPlainObject(context) && _.isEmpty(opts);
7778
}
7879

79-
function configureLogger(options) {
80+
function configureLogger(options: Options) {
8081
if (options.logLevel) {
8182
logger.setLevel(options.logLevel);
8283
}

src/context-matcher.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import * as isGlob from 'is-glob';
2-
import * as _ from 'lodash';
3-
import * as micromatch from 'micromatch';
4-
import * as url from 'url';
1+
import isGlob from 'is-glob';
2+
import _ from 'lodash';
3+
import micromatch from 'micromatch';
4+
import url from 'url';
55
import { ERRORS } from './errors';
66

77
export function match(context, uri, req) {

src/handlers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as _ from 'lodash';
1+
import _ from 'lodash';
22
import { getInstance } from './logger';
33
const logger = getInstance();
44

src/http-proxy-middleware.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import * as httpProxy from 'http-proxy';
2-
import * as _ from 'lodash';
1+
import express from 'express';
2+
import httpProxy from 'http-proxy';
3+
import _ from 'lodash';
34
import { createConfig } from './config-factory';
45
import * as contextMatcher from './context-matcher';
56
import * as handlers from './handlers';
67
import { getArrow, getInstance } from './logger';
78
import * as PathRewriter from './path-rewriter';
89
import * as Router from './router';
10+
import { Filter, IRequest, IRequestHandler, IResponse, Options } from './types';
911

1012
export class HttpProxyMiddleware {
1113
private logger = getInstance();
1214
private config;
1315
private wsInternalSubscribed = false;
14-
private proxyOptions;
15-
private proxy;
16+
private proxyOptions: Options;
17+
private proxy: httpProxy;
1618
private pathRewriter;
1719

18-
constructor(context, opts) {
20+
constructor(context: Filter | Options, opts?: Options) {
1921
this.config = createConfig(context, opts);
2022
this.proxyOptions = this.config.options;
2123

@@ -45,7 +47,11 @@ export class HttpProxyMiddleware {
4547
}
4648

4749
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
48-
public middleware = async (req, res, next) => {
50+
public middleware: IRequestHandler = async (
51+
req: IRequest,
52+
res: IResponse,
53+
next: express.NextFunction
54+
) => {
4955
if (this.shouldProxy(this.config.context, req)) {
5056
const activeProxyOptions = await this.prepareProxyRequest(req);
5157
this.proxy.web(req, res, activeProxyOptions);
@@ -55,7 +61,7 @@ export class HttpProxyMiddleware {
5561

5662
if (this.proxyOptions.ws === true) {
5763
// use initial request to access the server object to subscribe to http upgrade event
58-
this.catchUpgradeRequest(req.connection.server);
64+
this.catchUpgradeRequest((req.connection as any).server);
5965
}
6066
};
6167

@@ -68,7 +74,7 @@ export class HttpProxyMiddleware {
6874
}
6975
};
7076

71-
private handleUpgrade = async (req, socket, head) => {
77+
private handleUpgrade = async (req: IRequest, socket, head) => {
7278
if (this.shouldProxy(this.config.context, req)) {
7379
const activeProxyOptions = await this.prepareProxyRequest(req);
7480
this.proxy.ws(req, socket, head, activeProxyOptions);
@@ -84,7 +90,7 @@ export class HttpProxyMiddleware {
8490
* @param {Object} req [description]
8591
* @return {Boolean}
8692
*/
87-
private shouldProxy = (context, req) => {
93+
private shouldProxy = (context, req: IRequest) => {
8894
const path = req.originalUrl || req.url;
8995
return contextMatcher.match(context, path, req);
9096
};
@@ -97,7 +103,7 @@ export class HttpProxyMiddleware {
97103
* @param {Object} req
98104
* @return {Object} proxy options
99105
*/
100-
private prepareProxyRequest = async req => {
106+
private prepareProxyRequest = async (req: IRequest) => {
101107
// https://github.com/chimurai/http-proxy-middleware/issues/17
102108
// https://github.com/chimurai/http-proxy-middleware/issues/94
103109
req.url = req.originalUrl || req.url;
@@ -133,7 +139,7 @@ export class HttpProxyMiddleware {
133139
};
134140

135141
// Modify option.target when router present.
136-
private applyRouter = async (req, options) => {
142+
private applyRouter = async (req: IRequest, options) => {
137143
let newTarget;
138144

139145
if (options.router) {
@@ -151,7 +157,7 @@ export class HttpProxyMiddleware {
151157
};
152158

153159
// rewrite path
154-
private applyPathRewrite = (req, pathRewriter) => {
160+
private applyPathRewrite = (req: IRequest, pathRewriter) => {
155161
if (pathRewriter) {
156162
const path = pathRewriter(req.url, req);
157163

@@ -166,10 +172,11 @@ export class HttpProxyMiddleware {
166172
}
167173
};
168174

169-
private logError = (err, req, res) => {
175+
private logError = (err, req: IRequest, res: IResponse) => {
170176
const hostname =
171177
(req.headers && req.headers.host) || (req.hostname || req.host); // (websocket) || (node0.10 || node 4/5)
172-
const target = this.proxyOptions.target.host || this.proxyOptions.target;
178+
const target =
179+
(this.proxyOptions.target as any).host || this.proxyOptions.target;
173180
const errorMessage =
174181
'[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)';
175182
const errReference =

src/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { HttpProxyMiddleware } from './http-proxy-middleware';
2+
import { Filter, Options } from './types';
23

3-
function proxy(context, opts) {
4-
const { middleware } = new HttpProxyMiddleware(context, opts);
4+
function middleware(context: Filter | Options, options?: Options) {
5+
const { middleware } = new HttpProxyMiddleware(context, options);
56
return middleware;
67
}
78

8-
export = proxy;
9+
export = middleware;

src/logger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as _ from 'lodash';
2-
import * as util from 'util';
1+
import _ from 'lodash';
2+
import util from 'util';
33

44
let loggerInstance;
55

src/path-rewriter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as _ from 'lodash';
1+
import _ from 'lodash';
22
import { ERRORS } from './errors';
33
import { getInstance } from './logger';
44
const logger = getInstance();

src/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as _ from 'lodash';
1+
import _ from 'lodash';
22
import { getInstance } from './logger';
33
const logger = getInstance();
44

src/types.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import express from 'express';
2+
import http from 'http';
3+
import httpProxy from 'http-proxy';
4+
import net from 'net';
5+
6+
export interface IRequest extends express.Request {}
7+
export interface IResponse extends express.Response {}
8+
9+
export interface IRequestHandler extends express.RequestHandler {
10+
upgrade?: (req: IRequest, socket: net.Socket, head: any) => void;
11+
}
12+
13+
export type Filter = FilterPath | FilterWildcards | FilterFn;
14+
export type FilterFn = (pathname: string, req: IRequest) => boolean;
15+
export type FilterPath = string;
16+
export type FilterWildcards = string[];
17+
18+
export interface Options extends httpProxy.ServerOptions {
19+
pathRewrite?:
20+
| { [regexp: string]: string }
21+
| ((path: string, req: IRequest) => string);
22+
router?:
23+
| { [hostOrPath: string]: string }
24+
| ((req: IRequest) => string)
25+
| ((req: IRequest) => Promise<string>);
26+
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
27+
logProvider?(provider: LogProvider): LogProvider;
28+
29+
onError?(err: Error, req: IRequest, res: IResponse): void;
30+
onProxyRes?(
31+
proxyRes: http.ServerResponse,
32+
req: IRequest,
33+
res: IResponse
34+
): void;
35+
onProxyReq?(
36+
proxyReq: http.ClientRequest,
37+
req: IRequest,
38+
res: IResponse
39+
): void;
40+
onProxyReqWs?(
41+
proxyReq: http.ClientRequest,
42+
req: IRequest,
43+
socket: net.Socket,
44+
options: httpProxy.ServerOptions,
45+
head: any
46+
): void;
47+
onOpen?(proxySocket: net.Socket): void;
48+
onClose?(res: IResponse, socket: net.Socket, head: any): void;
49+
}
50+
51+
interface LogProvider {
52+
log: Logger;
53+
debug?: Logger;
54+
info?: Logger;
55+
warn?: Logger;
56+
error?: Logger;
57+
}
58+
59+
type Logger = (...args: any[]) => void;

test/e2e/_utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as express from 'express';
1+
import express from 'express';
22

33
// tslint:disable-next-line: no-var-requires
44
export const proxyMiddleware = require('../../dist/index');

test/e2e/express-router.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as express from 'express';
2-
import * as http from 'http';
1+
import express from 'express';
2+
import http from 'http';
33
import { proxyMiddleware as proxy } from './_utils';
44

55
describe('Usage in Express', () => {

test/e2e/http-proxy-middleware.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as http from 'http';
1+
import http from 'http';
22
import { createServer, proxyMiddleware } from './_utils';
33

44
describe('E2E http-proxy-middleware', () => {

test/e2e/path-rewriter.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as http from 'http';
1+
import http from 'http';
22
import { createServer, proxyMiddleware } from './_utils';
33

44
describe('E2E pathRewrite', () => {

test/e2e/router.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as http from 'http';
1+
import http from 'http';
22
import { createServer, proxyMiddleware } from './_utils';
33

44
describe('E2E router', () => {

test/e2e/websocket.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as http from 'http';
2-
import * as WebSocket from 'ws';
1+
import http from 'http';
2+
import WebSocket from 'ws';
33
// tslint:disable-next-line: no-duplicate-imports
44
import { Server as WebSocketServer } from 'ws';
55
import { createServer, proxyMiddleware } from './_utils';

0 commit comments

Comments
 (0)