Skip to content

Commit

Permalink
refactor: avoid using lodash where possible
Browse files Browse the repository at this point in the history
Using lodash methods does not add value where native methods and
operators can be used. In this diff I avoided lodash where possible.
  • Loading branch information
TrySound committed Sep 10, 2020
1 parent 5384dcf commit 4e79852
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 49 deletions.
10 changes: 5 additions & 5 deletions src/config-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function createConfig(context, opts?) {
// app.use('/api', proxy({target:'http://localhost:9000'}));
if (isContextless(context, opts)) {
config.context = '/';
config.options = _.assign(config.options, context);
config.options = Object.assign(config.options, context);

// app.use('/api', proxy('http://localhost:9000'));
// app.use(proxy('http://localhost:9000/api'));
Expand All @@ -25,15 +25,15 @@ export function createConfig(context, opts?) {
const target = [oUrl.protocol, '//', oUrl.host].join('');

config.context = oUrl.pathname || '/';
config.options = _.assign(config.options, { target }, opts);
config.options = Object.assign(config.options, { target }, opts);

if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
config.options.ws = true;
}
// app.use('/api', proxy({target:'http://localhost:9000'}));
} else {
config.context = context;
config.options = _.assign(config.options, opts);
config.options = Object.assign(config.options, opts);
}

configureLogger(config.options);
Expand All @@ -57,7 +57,7 @@ export function createConfig(context, opts?) {
* @return {Boolean} [description]
*/
function isStringShortHand(context: Filter) {
if (_.isString(context)) {
if (typeof context === 'string') {
return !!url.parse(context).host;
}
}
Expand All @@ -74,7 +74,7 @@ function isStringShortHand(context: Filter) {
* @return {Boolean} [description]
*/
function isContextless(context: Filter, opts: Options) {
return _.isPlainObject(context) && _.isEmpty(opts);
return _.isPlainObject(context) && (opts == null || Object.keys(opts).length === 0);
}

function configureLogger(options: Options) {
Expand Down
5 changes: 2 additions & 3 deletions src/context-matcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as isGlob from 'is-glob';
import * as _ from 'lodash';
import * as micromatch from 'micromatch';
import * as url from 'url';
import { ERRORS } from './errors';
Expand Down Expand Up @@ -28,7 +27,7 @@ export function match(context, uri, req) {
}

// custom matching
if (_.isFunction(context)) {
if (typeof context === 'function') {
const pathname = getUrlPathName(uri);
return context(pathname, req);
}
Expand Down Expand Up @@ -85,7 +84,7 @@ function getUrlPathName(uri) {
}

function isStringPath(context) {
return _.isString(context) && !isGlob(context);
return typeof context === 'string' && !isGlob(context);
}

function isGlobPath(context) {
Expand Down
8 changes: 4 additions & 4 deletions src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ export function getHandlers(options) {
// loop through options and try to find these handlers
// and add them to the handlers object for subscription in init().
const eventName = _.camelCase('on ' + event);
const fnHandler = _.get(options, eventName);
const fnHandler = options ? options[eventName] : null;

if (_.isFunction(fnHandler)) {
if (typeof fnHandler === 'function') {
handlers[event] = fnHandler;
}
}

// add default error handler in absence of error handler
if (!_.isFunction(handlers.error)) {
if (typeof handlers.error !== 'function') {
handlers.error = defaultErrorHandler;
}

// add default close handler in absence of close handler
if (!_.isFunction(handlers.close)) {
if (typeof handlers.close !== 'function') {
handlers.close = logClose;
}

Expand Down
3 changes: 1 addition & 2 deletions src/http-proxy-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as express from 'express';
import * as httpProxy from 'http-proxy';
import * as _ from 'lodash';
import { createConfig } from './config-factory';
import * as contextMatcher from './context-matcher';
import * as handlers from './handlers';
Expand Down Expand Up @@ -110,7 +109,7 @@ export class HttpProxyMiddleware {

// store uri before it gets rewritten for logging
const originalPath = req.url;
const newProxyOptions = _.assign({}, this.proxyOptions);
const newProxyOptions = Object.assign({}, this.proxyOptions);

// Apply in order:
// 1. option.router
Expand Down
8 changes: 3 additions & 5 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as _ from 'lodash';
import * as util from 'util';

let loggerInstance;
Expand Down Expand Up @@ -82,7 +81,7 @@ class Logger {
public isValidProvider(fnProvider) {
const result = true;

if (fnProvider && !_.isFunction(fnProvider)) {
if (fnProvider && typeof fnProvider !== 'function') {
throw new Error('[HPM] Log provider config error. Expecting a function.');
}

Expand Down Expand Up @@ -118,9 +117,8 @@ class Logger {

// make sure logged messages and its data are return interpolated
// make it possible for additional log data, such date/time or custom prefix.
private _interpolate() {
const fn = _.spread(util.format);
const result = fn(_.slice(arguments));
private _interpolate(format, ...args) {
const result = util.format(format, ...args);

return result;
}
Expand Down
20 changes: 10 additions & 10 deletions src/path-rewriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function createPathRewriter(rewriteConfig) {
return;
}

if (_.isFunction(rewriteConfig)) {
if (typeof rewriteConfig === 'function') {
const customRewriteFn = rewriteConfig;
return customRewriteFn;
} else {
Expand All @@ -27,26 +27,26 @@ export function createPathRewriter(rewriteConfig) {
function rewritePath(path) {
let result = path;

_.forEach(rulesCache, (rule) => {
for (const rule of rulesCache) {
if (rule.regex.test(path)) {
result = result.replace(rule.regex, rule.value);
logger.debug('[HPM] Rewriting path from "%s" to "%s"', path, result);
return false;
break;
}
});
}

return result;
}
}

function isValidRewriteConfig(rewriteConfig) {
if (_.isFunction(rewriteConfig)) {
if (typeof rewriteConfig === 'function') {
return true;
} else if (!_.isEmpty(rewriteConfig) && _.isPlainObject(rewriteConfig)) {
} else if (_.isPlainObject(rewriteConfig) && Object.keys(rewriteConfig).length !== 0) {
return true;
} else if (
_.isUndefined(rewriteConfig) ||
_.isNull(rewriteConfig) ||
rewriteConfig === undefined ||
rewriteConfig === null ||
_.isEqual(rewriteConfig, {})
) {
return false;
Expand All @@ -59,13 +59,13 @@ function parsePathRewriteRules(rewriteConfig) {
const rules = [];

if (_.isPlainObject(rewriteConfig)) {
_.forIn(rewriteConfig, (value, key) => {
for (const [key] of Object.entries(rewriteConfig)) {
rules.push({
regex: new RegExp(key),
value: rewriteConfig[key],
});
logger.info('[HPM] Proxy rewrite rule created: "%s" ~> "%s"', key, rewriteConfig[key]);
});
}
}

return rules;
Expand Down
10 changes: 5 additions & 5 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function getTarget(req, config) {

if (_.isPlainObject(router)) {
newTarget = getTargetFromProxyTable(req, router);
} else if (_.isFunction(router)) {
} else if (typeof router === 'function') {
newTarget = await router(req);
}

Expand All @@ -22,23 +22,23 @@ function getTargetFromProxyTable(req, table) {

const hostAndPath = host + path;

_.forIn(table, (value, key) => {
for (const [key] of Object.entries(table)) {
if (containsPath(key)) {
if (hostAndPath.indexOf(key) > -1) {
// match 'localhost:3000/api'
result = table[key];
logger.debug('[HPM] Router table match: "%s"', key);
return false;
break;
}
} else {
if (key === host) {
// match 'localhost:3000'
result = table[key];
logger.debug('[HPM] Router table match: "%s"', host);
return false;
break;
}
}
});
}

return result;
}
Expand Down
6 changes: 3 additions & 3 deletions test/unit/path-rewriter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('Path rewriting', () => {
return changed;
};

expect(rewriter(rewriteFn)).resolves.toBe('/123/456');
return expect(rewriter(rewriteFn)).resolves.toBe('/123/456');
});

it('is async and should return alternative path', () => {
Expand All @@ -126,7 +126,7 @@ describe('Path rewriting', () => {
return changed;
};

expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar');
return expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar');
});

it('is async and should return replaced path', () => {
Expand All @@ -138,7 +138,7 @@ describe('Path rewriting', () => {
return changed;
};

expect(rewriter(rewriteFn)).resolves.toBe('/123/789');
return expect(rewriter(rewriteFn)).resolves.toBe('/123/789');
});
});

Expand Down
24 changes: 12 additions & 12 deletions test/unit/router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('router unit test', () => {
expect(request.url).toBe('/');
});
it('should return new target', () => {
expect(result).resolves.toBe('http://foobar.com:666');
return expect(result).resolves.toBe('http://foobar.com:666');
});
});
});
Expand All @@ -66,7 +66,7 @@ describe('router unit test', () => {
expect(request.url).toBe('/');
});
it('should return new target', () => {
expect(result).resolves.toBe('http://foobar.com:666');
return expect(result).resolves.toBe('http://foobar.com:666');
});
});
});
Expand All @@ -90,71 +90,71 @@ describe('router unit test', () => {
describe('without router config', () => {
it('should return the normal target when router not present in config', () => {
result = getTarget(fakeReq, config);
expect(result).resolves.toBeUndefined();
return expect(result).resolves.toBeUndefined();
});
});

describe('with just the host in router config', () => {
it('should target http://localhost:6001 when for router:"alpha.localhost"', () => {
fakeReq.headers.host = 'alpha.localhost';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6001');
return expect(result).resolves.toBe('http://localhost:6001');
});

it('should target http://localhost:6002 when for router:"beta.localhost"', () => {
fakeReq.headers.host = 'beta.localhost';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6002');
return expect(result).resolves.toBe('http://localhost:6002');
});
});

describe('with host and host + path config', () => {
it('should target http://localhost:6004 without path', () => {
fakeReq.headers.host = 'gamma.localhost';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6004');
return expect(result).resolves.toBe('http://localhost:6004');
});

it('should target http://localhost:6003 exact path match', () => {
fakeReq.headers.host = 'gamma.localhost';
fakeReq.url = '/api';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6003');
return expect(result).resolves.toBe('http://localhost:6003');
});

it('should target http://localhost:6004 when contains path', () => {
fakeReq.headers.host = 'gamma.localhost';
fakeReq.url = '/api/books/123';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6003');
return expect(result).resolves.toBe('http://localhost:6003');
});
});

describe('with just the path', () => {
it('should target http://localhost:6005 with just a path as router config', () => {
fakeReq.url = '/rest';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6005');
return expect(result).resolves.toBe('http://localhost:6005');
});

it('should target http://localhost:6005 with just a path as router config', () => {
fakeReq.url = '/rest/deep/path';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6005');
return expect(result).resolves.toBe('http://localhost:6005');
});

it('should target http://localhost:6000 path in not present in router config', () => {
fakeReq.url = '/unknow-path';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBeUndefined();
return expect(result).resolves.toBeUndefined();
});
});

describe('matching order of router config', () => {
it('should return first matching target when similar paths are configured', () => {
fakeReq.url = '/some/specific/path';
result = getTarget(fakeReq, proxyOptionWithRouter);
expect(result).resolves.toBe('http://localhost:6006');
return expect(result).resolves.toBe('http://localhost:6006');
});
});
});
Expand Down

0 comments on commit 4e79852

Please sign in to comment.