All files ConstQueryTemplate.js

100% Statements 74/74
100% Branches 22/22
100% Functions 12/12
100% Lines 72/72
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145                        188x   188x 188x 188x 188x   188x   109x 109x 109x   109x 218x     218x 22x 22x 22x 22x 22x 2x 2x     196x 196x   218x 218x       188x 188x       458x 458x 458x   458x         458x 330x 330x 330x 291x 288x 288x     42x     416x 416x       260x 260x 260x   260x 112x 112x 112x 3x   109x     260x 260x 260x 260x       196x 293x 293x 293x 14x   279x 279x 279x 18x   261x         196x       22x 31x 31x 31x 6x   31x   22x               22x             188x      
import {
    getRegExp,
    getPartConstructor,
    convertMatchItemsToFunctions,
    convertGenerateItemsToFunctions
} from './utils.js';
import DefaultTemplate from './DefaultTemplate.js';
import MatchFragment from './MatchFragment.js';
import QueryComponent from './QueryComponent.js';
 
export default class ConstQueryTemplate extends DefaultTemplate {
    constructor (templateUri, routeParams) {
        super(...arguments);
 
        const matchObjects = {true: {}, false: {}};
        const generateObjects = {true: {}, false: {}};
        const templateUriQuery = templateUri.getParsedUri(this._partName);
        const templateUriQueryObject = templateUriQuery.toObject();
 
        for (let templateUriQueryCoupleKey in templateUriQueryObject) {
 
            const templateUriQueryCoupleValue = templateUriQueryObject[templateUriQueryCoupleKey];
            let queryCoupleParsedValue = new QueryComponent(templateUriQueryCoupleValue);
            const queryParamMatch = queryCoupleParsedValue.toString().match(getRegExp('param'));
 
            for (let caseSensitive of [true, false]) {
                let queryCoupleKey = new QueryComponent(templateUriQueryCoupleKey).toLowerCase(!caseSensitive);
                let matchFunctions;
                let generateFunctions;
                if (queryParamMatch) {
                    const queryParamName = queryParamMatch[1];
                    const queryParamValue = routeParams.getParam(queryParamName);
                    matchFunctions = this._getParamMatchFunctions(queryCoupleKey, queryParamName, queryParamValue);
                    generateFunctions = this._getParamGenerateFunctions(queryCoupleKey, queryParamName, queryParamValue);
                    if (queryParamMatch[2] === '*') {
                        matchFunctions.isOptional = true;
                        generateFunctions.isOptional = true;
                    }
                } else {
                    matchFunctions = this._getConstMatchFunctions(queryCoupleKey, queryCoupleParsedValue);
                    generateFunctions = this._getConstGenerateFunctions(queryCoupleKey, queryCoupleParsedValue);
                }
                matchObjects[caseSensitive][queryCoupleKey] = matchFunctions;
                generateObjects[caseSensitive][queryCoupleKey] = generateFunctions;
            }
        }
 
        this._matchObjects = matchObjects;
        this._generateObjects = generateObjects;
    }
 
    matchParsedValue (userUri, contextOptions) {
        const matchObject = this._matchObjects[!!contextOptions.caseSensitive];
        const value = userUri.getParsedUri('query').toObject();
        const params = {};
 
        this._currentUserUriQueryObject = userUri
            .getParsedUri('query')
            .toLowerCase(!contextOptions.caseSensitive)
            .toObject();
 
        for (let m in matchObject) {
            const matchFunctions = matchObject[m];
            const queryMatchFragment = super.matchParsedValue(userUri, contextOptions, matchFunctions);
            if (queryMatchFragment) {
                if (queryMatchFragment.value !== null || matchFunctions.isOptional) {
                    Object.assign(params, queryMatchFragment.params);
                    continue;
                }
            }
            return null;
        }
 
        const matchFragment = new MatchFragment(value, params);
        return matchFragment;
    }
 
    generateParsedValue (userParams, contextOptions) {
        const {partName} = contextOptions;
        const generateObject = this._generateObjects[!!contextOptions.caseSensitive];
        let rawValue = [];
 
        for (let g in generateObject) {
            const generateFunctions = generateObject[g];
            const queryCoupleParsedValue = super.generateParsedValue(userParams, contextOptions, generateFunctions);
            if (generateFunctions.isOptional && queryCoupleParsedValue.isEmpty()) {
                continue;
            }
            rawValue.push(encodeURIComponent(g) + '=' + encodeURIComponent(queryCoupleParsedValue.toString()));
        }
 
        rawValue = rawValue.join('&');
        const PartConstructor = getPartConstructor(partName);
        const parsedValue = new PartConstructor(rawValue);
        return parsedValue;
    }
 
    _getConstMatchFunctions (queryCoupleKey, queryCoupleParsedValue) {
        return [(userUri, contextOptions) => {
            const userUriQueryObject = this._currentUserUriQueryObject;
            const userUriQueryCoupleParsedValue = new QueryComponent(userUriQueryObject[queryCoupleKey]);
            if (userUriQueryCoupleParsedValue.isEmpty()) {
                return null;
            }
            const userUriQueryCoupleString = userUriQueryCoupleParsedValue.toLowerCase(!contextOptions.caseSensitive).toString();
            const queryCoupleString = queryCoupleParsedValue.toLowerCase(!contextOptions.caseSensitive).toString();
            if (userUriQueryCoupleString !== queryCoupleString) {
                return null;
            }
            return new MatchFragment(userUriQueryCoupleParsedValue.toString());
        }];
    }
 
    _getConstGenerateFunctions (queryCoupleKey, queryCoupleParsedValue) {
        return [(userParams) => queryCoupleParsedValue];
    }
 
    _getParamMatchFunctions (queryCoupleKey, paramName, paramValue) {
        const getUserUriPart = (userUri) => {
            const userUriQueryObject = this._currentUserUriQueryObject;
            const userUriQueryCoupleParsedValue = new QueryComponent(userUriQueryObject[queryCoupleKey]);
            if (!paramValue.match.length && userUriQueryCoupleParsedValue.isEmpty()) {
                userUriQueryCoupleParsedValue.toString = () => null;
            }
            return userUriQueryCoupleParsedValue;
        };
        return convertMatchItemsToFunctions(paramValue.match, {
            partName: 'queryComponent',
            paramName,
            getUserUriPart
        });
    }
 
    _getParamGenerateFunctions (queryCoupleKey, paramName, paramValue) {
        return convertGenerateItemsToFunctions(paramValue.generate, {
            partName: 'queryComponent',
            paramName
        });
    }
 
    _getPartName () {
        return 'query';
    }
}