all files / http-proxy-middleware/lib/ context-matcher.js

100% Statements 41/41
100% Branches 20/20
100% Functions 8/8
100% Lines 41/41
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95             106× 38×       68× 32×       36× 22×   14× 13×           14× 10× 10×                   49× 49×     45× 45× 45×     13×               11× 11×                     104×     133×     95×    
var _ = require('lodash');
var url = require('url');
var isGlob = require('is-glob');
var micromatch = require('micromatch');
 
module.exports = {
    match: matchContext
};
 
function matchContext(context, uri, req) {
 
    // single path
    if (isStringPath(context)) {
        return matchSingleStringPath(context, uri);
    }
 
    // single glob path
    if (isGlobPath(context)) {
        return matchSingleGlobPath(context, uri);
    }
 
    // multi path
    if (Array.isArray(context)) {
        if (context.every(isStringPath)) {
            return matchMultiPath(context, uri);
        }
        if (context.every(isGlobPath)) {
            return matchMultiGlobPath(context, uri);
        }
 
        throw new Error('[HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]');
    }
 
    // custom matching
    if (_.isFunction(context)) {
        var pathname = getUrlPathName(uri);
        return context(pathname, req);
    }
 
    throw new Error('[HPM] Invalid context. Expecting something like: "/api" or ["/api", "/ajax"]');
}
 
/**
 * @param  {String} context '/api'
 * @param  {String} uri     'http://example.org/api/b/c/d.html'
 * @return {Boolean}
 */
function matchSingleStringPath(context, uri) {
    var pathname = getUrlPathName(uri);
    return pathname.indexOf(context) === 0;
}
 
function matchSingleGlobPath(pattern, uri) {
    var pathname = getUrlPathName(uri);
    var matches = micromatch(pathname, pattern);
    return matches && (matches.length > 0);
}
 
function matchMultiGlobPath(patternList, uri) {
    return matchSingleGlobPath(patternList, uri);
}
 
/**
 * @param  {String} context ['/api', '/ajax']
 * @param  {String} uri     'http://example.org/api/b/c/d.html'
 * @return {Boolean}
 */
function matchMultiPath(contextList, uri) {
    for (var i = 0; i < contextList.length; i++) {
        var context = contextList[i];
        if (matchSingleStringPath(context, uri)) {
            return true;
        }
    }
    return false;
}
 
/**
 * Parses URI and returns RFC 3986 path
 *
 * @param  {String} uri from req.url
 * @return {String}     RFC 3986 path
 */
function getUrlPathName(uri) {
    return uri && url.parse(uri).pathname;
}
 
function isStringPath(context) {
    return _.isString(context) && !isGlob(context);
}
 
function isGlobPath(context) {
    return isGlob(context);
}