http-proxy-middleware 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -3
- package/README.md +58 -51
- package/dist/config-factory.js +79 -0
- package/dist/context-matcher.js +81 -0
- package/dist/errors.js +9 -0
- package/dist/handlers.js +70 -0
- package/dist/http-proxy-middleware.js +140 -0
- package/dist/index.js +7 -0
- package/dist/logger.js +135 -0
- package/dist/path-rewriter.js +67 -0
- package/dist/router.js +45 -0
- package/package.json +43 -31
- package/index.js +0 -5
- package/lib/config-factory.js +0 -129
- package/lib/context-matcher.js +0 -94
- package/lib/errors.js +0 -12
- package/lib/handlers.js +0 -82
- package/lib/index.js +0 -182
- package/lib/logger.js +0 -172
- package/lib/path-rewriter.js +0 -79
- package/lib/router.js +0 -51
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const httpProxy = require("http-proxy");
|
|
12
|
+
const _ = require("lodash");
|
|
13
|
+
const config_factory_1 = require("./config-factory");
|
|
14
|
+
const contextMatcher = require("./context-matcher");
|
|
15
|
+
const handlers = require("./handlers");
|
|
16
|
+
const logger_1 = require("./logger");
|
|
17
|
+
const PathRewriter = require("./path-rewriter");
|
|
18
|
+
const Router = require("./router");
|
|
19
|
+
class HttpProxyMiddleware {
|
|
20
|
+
constructor(context, opts) {
|
|
21
|
+
this.logger = logger_1.getInstance();
|
|
22
|
+
this.wsInternalSubscribed = false;
|
|
23
|
+
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
|
|
24
|
+
this.middleware = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
if (this.shouldProxy(this.config.context, req)) {
|
|
26
|
+
const activeProxyOptions = this.prepareProxyRequest(req);
|
|
27
|
+
this.proxy.web(req, res, activeProxyOptions);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
next();
|
|
31
|
+
}
|
|
32
|
+
if (this.proxyOptions.ws === true) {
|
|
33
|
+
// use initial request to access the server object to subscribe to http upgrade event
|
|
34
|
+
this.catchUpgradeRequest(req.connection.server);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
this.catchUpgradeRequest = server => {
|
|
38
|
+
if (!this.wsInternalSubscribed) {
|
|
39
|
+
server.on('upgrade', this.handleUpgrade);
|
|
40
|
+
// prevent duplicate upgrade handling;
|
|
41
|
+
// in case external upgrade is also configured
|
|
42
|
+
this.wsInternalSubscribed = true;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
this.handleUpgrade = (req, socket, head) => {
|
|
46
|
+
if (this.shouldProxy(this.config.context, req)) {
|
|
47
|
+
const activeProxyOptions = this.prepareProxyRequest(req);
|
|
48
|
+
this.proxy.ws(req, socket, head, activeProxyOptions);
|
|
49
|
+
this.logger.info('[HPM] Upgrading to WebSocket');
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Determine whether request should be proxied.
|
|
54
|
+
*
|
|
55
|
+
* @private
|
|
56
|
+
* @param {String} context [description]
|
|
57
|
+
* @param {Object} req [description]
|
|
58
|
+
* @return {Boolean}
|
|
59
|
+
*/
|
|
60
|
+
this.shouldProxy = (context, req) => {
|
|
61
|
+
const path = req.originalUrl || req.url;
|
|
62
|
+
return contextMatcher.match(context, path, req);
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Apply option.router and option.pathRewrite
|
|
66
|
+
* Order matters:
|
|
67
|
+
* Router uses original path for routing;
|
|
68
|
+
* NOT the modified path, after it has been rewritten by pathRewrite
|
|
69
|
+
* @param {Object} req
|
|
70
|
+
* @return {Object} proxy options
|
|
71
|
+
*/
|
|
72
|
+
this.prepareProxyRequest = req => {
|
|
73
|
+
// https://github.com/chimurai/http-proxy-middleware/issues/17
|
|
74
|
+
// https://github.com/chimurai/http-proxy-middleware/issues/94
|
|
75
|
+
req.url = req.originalUrl || req.url;
|
|
76
|
+
// store uri before it gets rewritten for logging
|
|
77
|
+
const originalPath = req.url;
|
|
78
|
+
const newProxyOptions = _.assign({}, this.proxyOptions);
|
|
79
|
+
// Apply in order:
|
|
80
|
+
// 1. option.router
|
|
81
|
+
// 2. option.pathRewrite
|
|
82
|
+
this.applyRouter(req, newProxyOptions);
|
|
83
|
+
this.applyPathRewrite(req, this.pathRewriter);
|
|
84
|
+
// debug logging for both http(s) and websockets
|
|
85
|
+
if (this.proxyOptions.logLevel === 'debug') {
|
|
86
|
+
const arrow = logger_1.getArrow(originalPath, req.url, this.proxyOptions.target, newProxyOptions.target);
|
|
87
|
+
this.logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target);
|
|
88
|
+
}
|
|
89
|
+
return newProxyOptions;
|
|
90
|
+
};
|
|
91
|
+
// Modify option.target when router present.
|
|
92
|
+
this.applyRouter = (req, options) => {
|
|
93
|
+
let newTarget;
|
|
94
|
+
if (options.router) {
|
|
95
|
+
newTarget = Router.getTarget(req, options);
|
|
96
|
+
if (newTarget) {
|
|
97
|
+
this.logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget);
|
|
98
|
+
options.target = newTarget;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
// rewrite path
|
|
103
|
+
this.applyPathRewrite = (req, pathRewriter) => {
|
|
104
|
+
if (pathRewriter) {
|
|
105
|
+
const path = pathRewriter(req.url, req);
|
|
106
|
+
if (typeof path === 'string') {
|
|
107
|
+
req.url = path;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
this.logError = (err, req, res) => {
|
|
115
|
+
const hostname = (req.headers && req.headers.host) || (req.hostname || req.host); // (websocket) || (node0.10 || node 4/5)
|
|
116
|
+
const target = this.proxyOptions.target.host || this.proxyOptions.target;
|
|
117
|
+
const errorMessage = '[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)';
|
|
118
|
+
const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
|
|
119
|
+
this.logger.error(errorMessage, req.url, hostname, target, err.code || err, errReference);
|
|
120
|
+
};
|
|
121
|
+
this.config = config_factory_1.createConfig(context, opts);
|
|
122
|
+
this.proxyOptions = this.config.options;
|
|
123
|
+
// create proxy
|
|
124
|
+
this.proxy = httpProxy.createProxyServer({});
|
|
125
|
+
this.logger.info(`[HPM] Proxy created: ${this.config.context} -> ${this.proxyOptions.target}`);
|
|
126
|
+
this.pathRewriter = PathRewriter.createPathRewriter(this.proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
|
|
127
|
+
// attach handler to http-proxy events
|
|
128
|
+
handlers.init(this.proxy, this.proxyOptions);
|
|
129
|
+
// log errors for debug purpose
|
|
130
|
+
this.proxy.on('error', this.logError);
|
|
131
|
+
// https://github.com/chimurai/http-proxy-middleware/issues/19
|
|
132
|
+
// expose function to upgrade externally
|
|
133
|
+
this.middleware.upgrade = (req, socket, head) => {
|
|
134
|
+
if (!this.wsInternalSubscribed) {
|
|
135
|
+
this.handleUpgrade(req, socket, head);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.HttpProxyMiddleware = HttpProxyMiddleware;
|
package/dist/index.js
ADDED
package/dist/logger.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const _ = require("lodash");
|
|
4
|
+
const util = require("util");
|
|
5
|
+
let loggerInstance;
|
|
6
|
+
const defaultProvider = {
|
|
7
|
+
// tslint:disable: no-console
|
|
8
|
+
log: console.log,
|
|
9
|
+
debug: console.log,
|
|
10
|
+
info: console.info,
|
|
11
|
+
warn: console.warn,
|
|
12
|
+
error: console.error
|
|
13
|
+
};
|
|
14
|
+
// log level 'weight'
|
|
15
|
+
var LEVELS;
|
|
16
|
+
(function (LEVELS) {
|
|
17
|
+
LEVELS[LEVELS["debug"] = 10] = "debug";
|
|
18
|
+
LEVELS[LEVELS["info"] = 20] = "info";
|
|
19
|
+
LEVELS[LEVELS["warn"] = 30] = "warn";
|
|
20
|
+
LEVELS[LEVELS["error"] = 50] = "error";
|
|
21
|
+
LEVELS[LEVELS["silent"] = 80] = "silent";
|
|
22
|
+
})(LEVELS || (LEVELS = {}));
|
|
23
|
+
function getInstance() {
|
|
24
|
+
if (!loggerInstance) {
|
|
25
|
+
loggerInstance = new Logger();
|
|
26
|
+
}
|
|
27
|
+
return loggerInstance;
|
|
28
|
+
}
|
|
29
|
+
exports.getInstance = getInstance;
|
|
30
|
+
class Logger {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.setLevel('info');
|
|
33
|
+
this.setProvider(() => defaultProvider);
|
|
34
|
+
}
|
|
35
|
+
// log will log messages, regardless of logLevels
|
|
36
|
+
log() {
|
|
37
|
+
this.provider.log(this._interpolate.apply(null, arguments));
|
|
38
|
+
}
|
|
39
|
+
debug() {
|
|
40
|
+
if (this._showLevel('debug')) {
|
|
41
|
+
this.provider.debug(this._interpolate.apply(null, arguments));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
info() {
|
|
45
|
+
if (this._showLevel('info')) {
|
|
46
|
+
this.provider.info(this._interpolate.apply(null, arguments));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
warn() {
|
|
50
|
+
if (this._showLevel('warn')) {
|
|
51
|
+
this.provider.warn(this._interpolate.apply(null, arguments));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
error() {
|
|
55
|
+
if (this._showLevel('error')) {
|
|
56
|
+
this.provider.error(this._interpolate.apply(null, arguments));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
setLevel(v) {
|
|
60
|
+
if (this.isValidLevel(v)) {
|
|
61
|
+
this.logLevel = v;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
setProvider(fn) {
|
|
65
|
+
if (fn && this.isValidProvider(fn)) {
|
|
66
|
+
this.provider = fn(defaultProvider);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
isValidProvider(fnProvider) {
|
|
70
|
+
const result = true;
|
|
71
|
+
if (fnProvider && !_.isFunction(fnProvider)) {
|
|
72
|
+
throw new Error('[HPM] Log provider config error. Expecting a function.');
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
isValidLevel(levelName) {
|
|
77
|
+
const validLevels = Object.keys(LEVELS);
|
|
78
|
+
const isValid = validLevels.includes(levelName);
|
|
79
|
+
if (!isValid) {
|
|
80
|
+
throw new Error('[HPM] Log level error. Invalid logLevel.');
|
|
81
|
+
}
|
|
82
|
+
return isValid;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Decide to log or not to log, based on the log levels 'weight'
|
|
86
|
+
* @param {String} showLevel [debug, info, warn, error, silent]
|
|
87
|
+
* @return {Boolean}
|
|
88
|
+
*/
|
|
89
|
+
_showLevel(showLevel) {
|
|
90
|
+
let result = false;
|
|
91
|
+
const currentLogLevel = LEVELS[this.logLevel];
|
|
92
|
+
if (currentLogLevel && currentLogLevel <= LEVELS[showLevel]) {
|
|
93
|
+
result = true;
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
// make sure logged messages and its data are return interpolated
|
|
98
|
+
// make it possible for additional log data, such date/time or custom prefix.
|
|
99
|
+
_interpolate() {
|
|
100
|
+
const fn = _.spread(util.format);
|
|
101
|
+
const result = fn(_.slice(arguments));
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* -> normal proxy
|
|
107
|
+
* => router
|
|
108
|
+
* ~> pathRewrite
|
|
109
|
+
* ≈> router + pathRewrite
|
|
110
|
+
*
|
|
111
|
+
* @param {String} originalPath
|
|
112
|
+
* @param {String} newPath
|
|
113
|
+
* @param {String} originalTarget
|
|
114
|
+
* @param {String} newTarget
|
|
115
|
+
* @return {String}
|
|
116
|
+
*/
|
|
117
|
+
function getArrow(originalPath, newPath, originalTarget, newTarget) {
|
|
118
|
+
const arrow = ['>'];
|
|
119
|
+
const isNewTarget = originalTarget !== newTarget; // router
|
|
120
|
+
const isNewPath = originalPath !== newPath; // pathRewrite
|
|
121
|
+
if (isNewPath && !isNewTarget) {
|
|
122
|
+
arrow.unshift('~');
|
|
123
|
+
}
|
|
124
|
+
else if (!isNewPath && isNewTarget) {
|
|
125
|
+
arrow.unshift('=');
|
|
126
|
+
}
|
|
127
|
+
else if (isNewPath && isNewTarget) {
|
|
128
|
+
arrow.unshift('≈');
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
arrow.unshift('-');
|
|
132
|
+
}
|
|
133
|
+
return arrow.join('');
|
|
134
|
+
}
|
|
135
|
+
exports.getArrow = getArrow;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const _ = require("lodash");
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
const logger = logger_1.getInstance();
|
|
7
|
+
/**
|
|
8
|
+
* Create rewrite function, to cache parsed rewrite rules.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} rewriteConfig
|
|
11
|
+
* @return {Function} Function to rewrite paths; This function should accept `path` (request.url) as parameter
|
|
12
|
+
*/
|
|
13
|
+
function createPathRewriter(rewriteConfig) {
|
|
14
|
+
let rulesCache;
|
|
15
|
+
if (!isValidRewriteConfig(rewriteConfig)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (_.isFunction(rewriteConfig)) {
|
|
19
|
+
const customRewriteFn = rewriteConfig;
|
|
20
|
+
return customRewriteFn;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
rulesCache = parsePathRewriteRules(rewriteConfig);
|
|
24
|
+
return rewritePath;
|
|
25
|
+
}
|
|
26
|
+
function rewritePath(path) {
|
|
27
|
+
let result = path;
|
|
28
|
+
_.forEach(rulesCache, rule => {
|
|
29
|
+
if (rule.regex.test(path)) {
|
|
30
|
+
result = result.replace(rule.regex, rule.value);
|
|
31
|
+
logger.debug('[HPM] Rewriting path from "%s" to "%s"', path, result);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.createPathRewriter = createPathRewriter;
|
|
39
|
+
function isValidRewriteConfig(rewriteConfig) {
|
|
40
|
+
if (_.isFunction(rewriteConfig)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
else if (!_.isEmpty(rewriteConfig) && _.isPlainObject(rewriteConfig)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
else if (_.isUndefined(rewriteConfig) ||
|
|
47
|
+
_.isNull(rewriteConfig) ||
|
|
48
|
+
_.isEqual(rewriteConfig, {})) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
throw new Error(errors_1.ERRORS.ERR_PATH_REWRITER_CONFIG);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function parsePathRewriteRules(rewriteConfig) {
|
|
56
|
+
const rules = [];
|
|
57
|
+
if (_.isPlainObject(rewriteConfig)) {
|
|
58
|
+
_.forIn(rewriteConfig, (value, key) => {
|
|
59
|
+
rules.push({
|
|
60
|
+
regex: new RegExp(key),
|
|
61
|
+
value: rewriteConfig[key]
|
|
62
|
+
});
|
|
63
|
+
logger.info('[HPM] Proxy rewrite rule created: "%s" ~> "%s"', key, rewriteConfig[key]);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return rules;
|
|
67
|
+
}
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const _ = require("lodash");
|
|
4
|
+
const logger_1 = require("./logger");
|
|
5
|
+
const logger = logger_1.getInstance();
|
|
6
|
+
function getTarget(req, config) {
|
|
7
|
+
let newTarget;
|
|
8
|
+
const router = config.router;
|
|
9
|
+
if (_.isPlainObject(router)) {
|
|
10
|
+
newTarget = getTargetFromProxyTable(req, router);
|
|
11
|
+
}
|
|
12
|
+
else if (_.isFunction(router)) {
|
|
13
|
+
newTarget = router(req);
|
|
14
|
+
}
|
|
15
|
+
return newTarget;
|
|
16
|
+
}
|
|
17
|
+
exports.getTarget = getTarget;
|
|
18
|
+
function getTargetFromProxyTable(req, table) {
|
|
19
|
+
let result;
|
|
20
|
+
const host = req.headers.host;
|
|
21
|
+
const path = req.url;
|
|
22
|
+
const hostAndPath = host + path;
|
|
23
|
+
_.forIn(table, (value, key) => {
|
|
24
|
+
if (containsPath(key)) {
|
|
25
|
+
if (hostAndPath.indexOf(key) > -1) {
|
|
26
|
+
// match 'localhost:3000/api'
|
|
27
|
+
result = table[key];
|
|
28
|
+
logger.debug('[HPM] Router table match: "%s"', key);
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if (key === host) {
|
|
34
|
+
// match 'localhost:3000'
|
|
35
|
+
result = table[key];
|
|
36
|
+
logger.debug('[HPM] Router table match: "%s"', host);
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function containsPath(v) {
|
|
44
|
+
return v.indexOf('/') > -1;
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "http-proxy-middleware",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "The one-liner node.js proxy middleware for connect, express and browser-sync",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
7
|
-
"
|
|
8
|
-
"lib"
|
|
7
|
+
"dist"
|
|
9
8
|
],
|
|
10
9
|
"scripts": {
|
|
11
|
-
"clean": "rm -rf coverage",
|
|
12
|
-
"lint": "prettier
|
|
13
|
-
"lint:
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
10
|
+
"clean": "rm -rf dist && rm -rf coverage",
|
|
11
|
+
"lint": "yarn lint:prettier && yarn lint:tslint",
|
|
12
|
+
"lint:prettier": "prettier --check \"**/*.{js,ts,md}\"",
|
|
13
|
+
"lint:tslint": "yarn tslint -c tslint.json '{lib,test}/**/*.ts'",
|
|
14
|
+
"lint:fix": "prettier --write \"**/*.{js,ts,md}\"",
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"pretest": "yarn build",
|
|
17
|
+
"test": "jest --runInBand",
|
|
18
|
+
"precover": "yarn clean && yarn build",
|
|
19
|
+
"cover": "jest --runInBand --coverage",
|
|
20
|
+
"precoveralls": "yarn clean && yarn build",
|
|
21
|
+
"coveralls": "jest --runInBand --coverage --coverageReporters=text-lcov | coveralls",
|
|
22
|
+
"postcoveralls": "yarn clean",
|
|
23
|
+
"prepare": "yarn clean && yarn build"
|
|
17
24
|
},
|
|
18
25
|
"repository": {
|
|
19
26
|
"type": "git",
|
|
@@ -41,36 +48,41 @@
|
|
|
41
48
|
},
|
|
42
49
|
"homepage": "https://github.com/chimurai/http-proxy-middleware",
|
|
43
50
|
"devDependencies": {
|
|
44
|
-
"@commitlint/cli": "^
|
|
45
|
-
"@commitlint/config-conventional": "^
|
|
46
|
-
"
|
|
47
|
-
"
|
|
51
|
+
"@commitlint/cli": "^8.0.0",
|
|
52
|
+
"@commitlint/config-conventional": "^8.0.0",
|
|
53
|
+
"@types/express": "^4.17.0",
|
|
54
|
+
"@types/http-proxy": "^1.17.0",
|
|
55
|
+
"@types/is-glob": "^4.0.0",
|
|
56
|
+
"@types/jest": "^24.0.15",
|
|
57
|
+
"@types/lodash": "^4.14.136",
|
|
58
|
+
"@types/micromatch": "^3.1.0",
|
|
59
|
+
"@types/node": "^12.6.2",
|
|
60
|
+
"browser-sync": "^2.26.7",
|
|
48
61
|
"connect": "^3.6.6",
|
|
49
|
-
"coveralls": "^3.0.
|
|
62
|
+
"coveralls": "^3.0.5",
|
|
50
63
|
"express": "^4.16.4",
|
|
51
|
-
"husky": "^
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"ws": "^
|
|
64
|
+
"husky": "^3.0.0",
|
|
65
|
+
"jest": "^24.5.0",
|
|
66
|
+
"open": "^6.4.0",
|
|
67
|
+
"prettier": "^1.18.2",
|
|
68
|
+
"ts-jest": "^24.0.0",
|
|
69
|
+
"tslint": "^5.18.0",
|
|
70
|
+
"tslint-config-prettier": "^1.18.0",
|
|
71
|
+
"typescript": "^3.5.3",
|
|
72
|
+
"ws": "^7.1.0"
|
|
60
73
|
},
|
|
61
74
|
"dependencies": {
|
|
62
|
-
"http-proxy": "^1.
|
|
63
|
-
"is-glob": "^4.0.
|
|
64
|
-
"lodash": "^4.17.
|
|
65
|
-
"micromatch": "^
|
|
75
|
+
"http-proxy": "^1.17.0",
|
|
76
|
+
"is-glob": "^4.0.1",
|
|
77
|
+
"lodash": "^4.17.14",
|
|
78
|
+
"micromatch": "^4.0.2"
|
|
66
79
|
},
|
|
67
80
|
"engines": {
|
|
68
|
-
"node": ">=
|
|
81
|
+
"node": ">=8.0.0"
|
|
69
82
|
},
|
|
70
83
|
"husky": {
|
|
71
84
|
"hooks": {
|
|
72
|
-
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
|
73
|
-
"pre-commit": "precise-commits"
|
|
85
|
+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
|
74
86
|
}
|
|
75
87
|
},
|
|
76
88
|
"commitlint": {
|
package/index.js
DELETED
package/lib/config-factory.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
var _ = require('lodash')
|
|
2
|
-
var url = require('url')
|
|
3
|
-
var ERRORS = require('./errors')
|
|
4
|
-
var logger = require('./logger').getInstance()
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
createConfig: createConfig
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function createConfig(context, opts) {
|
|
11
|
-
// structure of config object to be returned
|
|
12
|
-
var config = {
|
|
13
|
-
context: undefined,
|
|
14
|
-
options: {}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// app.use('/api', proxy({target:'http://localhost:9000'}));
|
|
18
|
-
if (isContextless(context, opts)) {
|
|
19
|
-
config.context = '/'
|
|
20
|
-
config.options = _.assign(config.options, context)
|
|
21
|
-
|
|
22
|
-
// app.use('/api', proxy('http://localhost:9000'));
|
|
23
|
-
// app.use(proxy('http://localhost:9000/api'));
|
|
24
|
-
} else if (isStringShortHand(context)) {
|
|
25
|
-
var oUrl = url.parse(context)
|
|
26
|
-
var target = [oUrl.protocol, '//', oUrl.host].join('')
|
|
27
|
-
|
|
28
|
-
config.context = oUrl.pathname || '/'
|
|
29
|
-
config.options = _.assign(config.options, { target: target }, opts)
|
|
30
|
-
|
|
31
|
-
if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
|
|
32
|
-
config.options.ws = true
|
|
33
|
-
}
|
|
34
|
-
// app.use('/api', proxy({target:'http://localhost:9000'}));
|
|
35
|
-
} else {
|
|
36
|
-
config.context = context
|
|
37
|
-
config.options = _.assign(config.options, opts)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
configureLogger(config.options)
|
|
41
|
-
|
|
42
|
-
if (!config.options.target) {
|
|
43
|
-
throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Legacy option.proxyHost
|
|
47
|
-
config.options = mapLegacyProxyHostOption(config.options)
|
|
48
|
-
|
|
49
|
-
// Legacy option.proxyTable > option.router
|
|
50
|
-
config.options = mapLegacyProxyTableOption(config.options)
|
|
51
|
-
|
|
52
|
-
return config
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Checks if a String only target/config is provided.
|
|
57
|
-
* This can be just the host or with the optional path.
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* app.use('/api', proxy('http://localhost:9000'));
|
|
61
|
-
app.use(proxy('http://localhost:9000/api'));
|
|
62
|
-
*
|
|
63
|
-
* @param {String} context [description]
|
|
64
|
-
* @return {Boolean} [description]
|
|
65
|
-
*/
|
|
66
|
-
function isStringShortHand(context) {
|
|
67
|
-
if (_.isString(context)) {
|
|
68
|
-
return !!url.parse(context).host
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Checks if a Object only config is provided, without a context.
|
|
74
|
-
* In this case the all paths will be proxied.
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* app.use('/api', proxy({target:'http://localhost:9000'}));
|
|
78
|
-
*
|
|
79
|
-
* @param {Object} context [description]
|
|
80
|
-
* @param {*} opts [description]
|
|
81
|
-
* @return {Boolean} [description]
|
|
82
|
-
*/
|
|
83
|
-
function isContextless(context, opts) {
|
|
84
|
-
return _.isPlainObject(context) && _.isEmpty(opts)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function mapLegacyProxyHostOption(options) {
|
|
88
|
-
// set options.headers.host when option.proxyHost is provided
|
|
89
|
-
if (options.proxyHost) {
|
|
90
|
-
logger.warn('*************************************')
|
|
91
|
-
logger.warn('[HPM] Deprecated "option.proxyHost"')
|
|
92
|
-
logger.warn(
|
|
93
|
-
' Use "option.changeOrigin" or "option.headers.host" instead'
|
|
94
|
-
)
|
|
95
|
-
logger.warn(' "option.proxyHost" will be removed in future release.')
|
|
96
|
-
logger.warn('*************************************')
|
|
97
|
-
|
|
98
|
-
options.headers = options.headers || {}
|
|
99
|
-
options.headers.host = options.proxyHost
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return options
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Warn deprecated proxyTable api usage
|
|
106
|
-
function mapLegacyProxyTableOption(options) {
|
|
107
|
-
if (options.proxyTable) {
|
|
108
|
-
logger.warn('*************************************')
|
|
109
|
-
logger.warn('[HPM] Deprecated "option.proxyTable"')
|
|
110
|
-
logger.warn(' Use "option.router" instead')
|
|
111
|
-
logger.warn(' "option.proxyTable" will be removed in future release.')
|
|
112
|
-
logger.warn('*************************************')
|
|
113
|
-
|
|
114
|
-
options.router = _.clone(options.proxyTable)
|
|
115
|
-
_.omit(options, 'proxyTable')
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return options
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function configureLogger(options) {
|
|
122
|
-
if (options.logLevel) {
|
|
123
|
-
logger.setLevel(options.logLevel)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (options.logProvider) {
|
|
127
|
-
logger.setProvider(options.logProvider)
|
|
128
|
-
}
|
|
129
|
-
}
|