<commit_before>'use strict';

const Path = require('path');

const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');


const internals = {};


internals.schema = {
    options: Joi.object({
        relativeTo: Joi.string(),
        preRegister: Joi.func().allow(false)
    }),
    manifest: Joi.object({
        server: Joi.object(),
        register: Joi.object({
            plugins: Joi.array(),
            options: Joi.any()
        })
    })
};


exports.compose = async function (manifest, options = {}) {

    Joi.assert(options, internals.schema.options, 'Invalid options');
    Joi.assert(manifest, internals.schema.manifest, 'Invalid manifest');

    const serverOpts = internals.parseServer(manifest.server || {}, options.relativeTo);
    const server = Hapi.server(serverOpts);

    if (options.preRegister) {
        await options.preRegister(server);
    }

    if (manifest.register && manifest.register.plugins) {
        const plugins = manifest.register.plugins.map((plugin) => {

            return internals.parsePlugin(plugin, options.relativeTo);
        });

        await server.register(plugins, manifest.register.options || {});
    }

    return server;
};


internals.parseServer = function (serverOpts, relativeTo) {

    if (serverOpts.cache) {
        serverOpts = Hoek.clone(serverOpts);

        const caches = [];
        const config = [].concat(serverOpts.cache);
        for (let i = 0; i < config.length; ++i) {
            let item = config[i];
            if (typeof item === 'string') {
                item = { provider: item };
            }

            if (typeof item.provider === 'string') {
                let strategy = item.provider;
                if (relativeTo && strategy[0] === '.') {
                    strategy = Path.join(relativeTo, strategy);
                }

                item.provider = require(strategy);
            }

            caches.push(item);
        }

        serverOpts.cache = caches;
    }

    return serverOpts;<commit_msg>#128 Add support for constructor property and additional options in server cache configuration<commit_after>'use strict';

const Path = require('path');

const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');


const internals = {};


internals.schema = {
    options: Joi.object({
        relativeTo: Joi.string(),
        preRegister: Joi.func().allow(false)
    }),
    manifest: Joi.object({
        server: Joi.object(),
        register: Joi.object({
            plugins: Joi.array(),
            options: Joi.any()
        })
    })
};


exports.compose = async function (manifest, options = {}) {

    Joi.assert(options, internals.schema.options, 'Invalid options');
    Joi.assert(manifest, internals.schema.manifest, 'Invalid manifest');

    const serverOpts = internals.parseServer(manifest.server || {}, options.relativeTo);
    const server = Hapi.server(serverOpts);

    if (options.preRegister) {
        await options.preRegister(server);
    }

    if (manifest.register && manifest.register.plugins) {
        const plugins = manifest.register.plugins.map((plugin) => {

            return internals.parsePlugin(plugin, options.relativeTo);
        });

        await server.register(plugins, manifest.register.options || {});
    }

    return server;
};


internals.parseServer = function (serverOpts, relativeTo) {

    if (serverOpts.cache) {
        serverOpts = Hoek.clone(serverOpts);

        const caches = [];
        const config = [].concat(serverOpts.cache);
        for (let i = 0; i < config.length; ++i) {
            let item = config[i];
            if (typeof item === 'string') {
                item = { provider: item };
            }

            if (typeof item.provider === 'string') {
                let strategy = item.provider;
                if (relativeTo && strategy[0] === '.') {
                    strategy = Path.join(relativeTo, strategy);
                }

                item.provider = require(strategy);
            } else if (typeof item.provider === 'object' && typeof item.provider.constructor === 'string') {
                let strategy = item.provider.constructor;
                if (relativeTo && strategy[0] === '.') {
                    strategy = Path.join(relativeTo, strategy);
                }
                item.provider.constructor = require(strategy);
            }

            caches.push(item);
        }

        serverOpts.cache = caches;
    }

    return serverOpts;
{'fraction_non_alphanumeric': 0.13785557986870897, 'fraction_numerical': 0.00175054704595186, 'mean_word_length': 2.156767955801105, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1816432', 'n_tokens_mistral': 1300, 'n_tokens_neox': 1261, 'n_words': 272}