lib/util/parseSearchQuery.js
function parseSearchQuery(query, options) {
    options = Object.assign({ throwOnInvalid: false }, options);

    // Parse query into object
    query = searchQueryParser.parse(query, { keywords: qualifiers });
    query = typeof query === 'string' ? { text: query } : query;
    query = mapKeys(query, (value, key) => camelCase(key)); // CamelCase keys
    delete query.exclude; // We do not use the exclusion feature from search-query-parser
    delete query.offsets; // Remove `offsets` otherwise validation will fail

    // Convert & validate
    const validation = Joi.validate(query, paramsSchema, { abortEarly: options.throwOnInvalid });
    let params = validation.value;

    if (validation.error) {
        // Throw if there's an error and `options.throwOnInvalid` is enabled
        if (options.throwOnInvalid && validation.error) {
            throw validation.error;
        }

        // If `options.throwOnInvalid` is enabled, remove all failed validation props and fill it with defaults
        validation.error.details
        .reverse()
        .forEach((detail) => unset(params, detail.path));

        params = deepCompact(params);
    }

    // Fill in defaults
    params = assignWith(params, paramsDefaults, (tartgetValue, srcValue) => tartgetValue == null ? srcValue : tartgetValue);

    // Post process
    normalizeWeights(params);
    parseKeywords(params);
    uniquifyFlags(params);

    // If no mandatory params were specified (that actually filter results) then we return null
    return hasMandatoryParams(params) ? params : null;
}
function parseSearchQuery(query, options) {
    options = Object.assign({ throwOnInvalid: false }, options);

    // Parse query into object
    query = searchQueryParser.parse(query, { keywords: qualifiers });
    query = typeof query === 'string' ? { text: query } : query;
    query = mapKeys(query, (value, key) => camelCase(key)); // CamelCase keys
    delete query.exclude; // We do not use the exclusion feature from search-query-parser
    delete query.offsets; // Remove `offsets` otherwise validation will fail

    // Convert & validate
    const validation = Joi.validate(query, paramsSchema, { abortEarly: options.throwOnInvalid });
    let params = validation.value;

    if (validation.error) {
        // Throw if there's an error and `options.throwOnInvalid` is enabled
        if (options.throwOnInvalid && validation.error) {
            throw validation.error;
        }

        // If `options.throwOnInvalid` is enabled, remove all failed validation props and fill it with defaults
        validation.error.details
        .reverse()
        .forEach((detail) => unset(params, detail.path));

        params = deepCompact(params);
    }

    // Fill in defaults
    params = assignWith(params, paramsDefaults, (tartgetValue, srcValue) => tartgetValue == null ? srcValue : tartgetValue);

    // Post process
    normalizeWeights(params);
    parseKeywords(params);
    uniquifyFlags(params);

    // If no mandatory params were specified (that actually filter results) then we return null
    return hasMandatoryParams(params) ? params : null;
}
-------------------------------------------------