# 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
    951×
    1×
    1×
    1×

    1×

    1×

    106×
    38×

    68×
    32×

    36×
    22×
    8×

    14×
    13×

    1×

    14×
    10×
    10×

    4×

    1×
    49×
    49×

    1×
    45×
    45×
    45×

    1×
    13×

    1×
    8×
    11×
    11×
    4×

    4×

    1×
    104×

    1×
    133×

    1×
    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);
    }