<commit_before>var _ = require("lodash");
var Bootprint = require("./bootprint.js");
var debug = require("debug")("bootprint:builder");

var jsonschema = require('jsonschema');
var extra = require('jsonschema-extra');

var validator = new (jsonschema.Validator)();
extra(validator);

/**
 * This class is responsible for storing and adapting configuration options
 * for the [Bootprint](#Bootprint) object. The constructor is not
 * accessible outside the module. An instance of this class can be obtained
 * via `require("bootprint")`. Configurations can be changed using
 * [merge({...})](#BootprintBuilder#merge) and [load(require("bootprint-module"))](#BootprintBuilder#load)
 *
 * This class is immutable. All functions return new instances rather than mutating the current instance.
 *
 * @param {object} options new options for this builder.
 * @param {object} [parentOptions] a build to inherit options from
 * @class
 */
function BootprintBuilder(options, parentOptions) {

    debug("additional options:", options);
    var validationErrors = validator.validate(options, require("./config-schema")).errors;
    if (validationErrors.length > 0) {
        console.error("Error while validating config",options);
        console.error("Errors: ",validationErrors.map(String).join("\n"));
        throw new Error("Error while validating options-object",validationErrors);
    }
    require("assert")(validationErrors.length === 0, "Error: " + validationErrors);
    var _options = overrideOptions(options || {}, parentOptions);
    debug("merged options:", _options);

    // Accessible for testcases
    this._options = _options;

    /**
     * Creates a new instance of BootprintBuilder. The options of the current BootprintBuilder
     * are used as default values and are overridden by the options provided as parameter.
     * @param {object} options options overriding the options of this builder
     * @return {BootprintBuilder} new Builder instance
     */
    this.merge = function (options) {
        return new BootprintBuilder(options, _options);
    };

    /**
     * Inherit configuration options from another module.
     * `require("bootprint-modulename")` usually return a function(builder)
     * and this functions needs to be passed in here.
     * A new BootprintBuilder will be returned that overrides the current options
     * with options from the builderFunction's result.
     * @param builderFunction {function} that receives a BootprintBuilder as paramater
     *  and returns a BootprintBuilder with changed configuration.
     * @return {BootprintBuilder} the result of the builderFunction
     */
    this.load = function (builderFunction) {
        return builderFunction(this);
    };

    /**
     * Build the configured Bootprint-instance.
     * @param {string} jsonFile path the a file containing the data to pass into the template
     * @param {string} targetDir path to a directory where the HTML and CSS file should be created
     * @return {Bootprint} a Bootprint-instance
     */
    this.build = function (jsonFile, targetDir) {
        debug("Building converter with config: %o", _options);
        return new Bootprint(jsonFile, _options, targetDir);
    };
}

module.exports = BootprintBuilder;

// Helper functions

// Function for overriding options as described in the Builder-JSDoc
function overrideOptions(options, parentOptions) {
    // Inherit options from parent build or use empty object if not set
    var copy = _.clone(options, true);
    coerceToArray(copy, "partials");
    if (copy.less) {
        coerceToArray(copy.less, "main");
        coerceToArray(copy.less, "paths");
    }

    if (!parentOptions) {
        return copy;
    }
    var parentPreprocessor = parentOptions.preprocessor;
    // The preprocessor must be able to call the parent preprocessor.
    if (copy.preprocessor) {
        copy.preprocessor = copy.preprocessor.bind({
            parent: parentPreprocessor
        });
    }
    // Merge without mutating the parentOptions
    return _.merge({}, parentOptions, copy, function (a, b) {
        if (_.isArray(a)) {<commit_msg>Helper file is now configured as file, not as object of functions<commit_after>var _ = require("lodash");
var Bootprint = require("./bootprint.js");
var debug = require("debug")("bootprint:builder");

var jsonschema = require('jsonschema');
var extra = require('jsonschema-extra');

var validator = new (jsonschema.Validator)();
extra(validator);

/**
 * This class is responsible for storing and adapting configuration options
 * for the [Bootprint](#Bootprint) object. The constructor is not
 * accessible outside the module. An instance of this class can be obtained
 * via `require("bootprint")`. Configurations can be changed using
 * [merge({...})](#BootprintBuilder#merge) and [load(require("bootprint-module"))](#BootprintBuilder#load)
 *
 * This class is immutable. All functions return new instances rather than mutating the current instance.
 *
 * @param {object} options new options for this builder.
 * @param {object} [parentOptions] a build to inherit options from
 * @class
 */
function BootprintBuilder(options, parentOptions) {

    debug("additional options:", options);
    var validationErrors = validator.validate(options, require("./config-schema")).errors;
    if (validationErrors.length > 0) {
        console.error("Error while validating config",options);
        console.error("Errors: ",validationErrors.map(String).join("\n"));
        throw new Error("Error while validating options-object",validationErrors);
    }
    require("assert")(validationErrors.length === 0, "Error: " + validationErrors);
    var _options = overrideOptions(options || {}, parentOptions);
    debug("merged options:", _options);

    // Accessible for testcases
    this._options = _options;

    /**
     * Creates a new instance of BootprintBuilder. The options of the current BootprintBuilder
     * are used as default values and are overridden by the options provided as parameter.
     * @param {object} options options overriding the options of this builder
     * @return {BootprintBuilder} new Builder instance
     */
    this.merge = function (options) {
        return new BootprintBuilder(options, _options);
    };

    /**
     * Inherit configuration options from another module.
     * `require("bootprint-modulename")` usually return a function(builder)
     * and this functions needs to be passed in here.
     * A new BootprintBuilder will be returned that overrides the current options
     * with options from the builderFunction's result.
     * @param builderFunction {function} that receives a BootprintBuilder as paramater
     *  and returns a BootprintBuilder with changed configuration.
     * @return {BootprintBuilder} the result of the builderFunction
     */
    this.load = function (builderFunction) {
        return builderFunction(this);
    };

    /**
     * Build the configured Bootprint-instance.
     * @param {string} jsonFile path the a file containing the data to pass into the template
     * @param {string} targetDir path to a directory where the HTML and CSS file should be created
     * @return {Bootprint} a Bootprint-instance
     */
    this.build = function (jsonFile, targetDir) {
        debug("Building converter with config: %o", _options);
        return new Bootprint(jsonFile, _options, targetDir);
    };
}

module.exports = BootprintBuilder;

// Helper functions

// Function for overriding options as described in the Builder-JSDoc
function overrideOptions(options, parentOptions) {

    // Clone "options" to perform some modifications on the copy
    var copy = _.clone(options, true);
    coerceToArray(copy, "partials");
    if (copy.less) {
        coerceToArray(copy.less, "main");
        coerceToArray(copy.less, "paths");
    }
    copy.helpers = require(copy.helpers);

    if (!parentOptions) {
        return copy;
    }
    var parentPreprocessor = parentOptions.preprocessor;
    // The preprocessor must be able to call the parent preprocessor.
    if (copy.preprocessor) {
        copy.preprocessor = copy.preprocessor.bind({
            parent: parentPreprocessor
        });
    }
    // Merge without mutating the parentOptions
    return _.merge({}, parentOptions, copy, function (a, b) {
        if (_.isArray(a)) {
{'fraction_non_alphanumeric': 0.10280710172744721, 'fraction_numerical': 0.0004798464491362764, 'mean_word_length': 3.6035339591385975, 'pattern_counts': {'":': 0, '<': 3, '<?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': '1746218', 'n_tokens_mistral': 2174, 'n_tokens_neox': 2130, 'n_words': 764}