<commit_before>export const SPEC = Symbol('reference to Specification object that defines the data model');

export default class Schema {

    constructor(spec = { id: String }) {
        this[SPEC] = spec;
    }

    get spec() {
        return { ...this[SPEC] };
    }

    /*
     * create
     */
    create(data, spec = this[SPEC]) {
        for (let property in spec) {

            // if property is a nested Schema, recursively create them too
            if (spec[property].constructor.name === 'Schema') this.create(data[property], spec[property].spec);

            else {
                if (spec[property].default) {
                    data[property] = this.evalProperty(spec[property].default);
                }

                if (spec[property].value) {
                    data[property] = this.evalProperty(spec[property].value);
                }
            }
        }

        return data;
    }

    /*
     * update
     */
    update(data, spec = this[SPEC]) {
        for (let property in spec) {

            // if property is a nested Schema, recursively update them too
            if (spec[property].constructor.name === 'Schema') this.update(data[property], spec[property].spec);

            else if (spec[property].value) {
                data[property] = this.evalProperty(spec[property].value);
            }
        }

        return data;
    }

    /*
     * validate
     */
    validate(data, spec = this[SPEC]) {
        let valid = true;

        // loop over properties in the spec to validate the data
        for (let property in spec) {

            // if property is a nested Schema to recursively validate nested Schemas
            if (spec[property].name === 'Schema') this.validate(data[property], spec[property].spec);

            // else if only the data type has been provided
            else if (!spec[property].type) valid = this.assertType(data[property], spec[property]);

            else {
                if (data[property] && spec[property].type) valid = this.assertType(data[property], spec[property].type);

                // if still valid, validate if property is required
                if (valid && spec[property].required && !data[property]) valid = false;

                // if still valid, validate if custom validation function is defined
                if (valid && typeof spec[property].validate === 'function') valid = spec[property].validate(data[property]);
            }

            // break loop immediately on first error
            if (!valid) break;
        }<commit_msg>fixing error with nested Schema check<commit_after>export const SPEC = Symbol('reference to Specification object that defines the data model');

export default class Schema {

    constructor(spec = { id: String }) {
        this[SPEC] = spec;
    }

    get spec() {
        return { ...this[SPEC] };
    }

    /*
     * create
     */
    create(data, spec = this[SPEC]) {
        for (let property in spec) {

            // if property is a nested Schema, recursively create them too
            if (spec[property].constructor.name === 'Schema') this.create(data[property], spec[property].spec);

            else {
                if (spec[property].default) {
                    data[property] = this.evalProperty(spec[property].default);
                }

                if (spec[property].value) {
                    data[property] = this.evalProperty(spec[property].value);
                }
            }
        }

        return data;
    }

    /*
     * update
     */
    update(data, spec = this[SPEC]) {
        for (let property in spec) {

            // if property is a nested Schema, recursively update them too
            if (spec[property].constructor.name === 'Schema') this.update(data[property], spec[property].spec);

            else if (spec[property].value) {
                data[property] = this.evalProperty(spec[property].value);
            }
        }

        return data;
    }

    /*
     * validate
     */
    validate(data, spec = this[SPEC]) {
        let valid = true;

        // loop over properties in the spec to validate the data
        for (let property in spec) {

            // if property is a nested Schema to recursively validate nested Schemas
            if (spec[property].constructor.name === 'Schema') this.validate(data[property], spec[property].spec);

            // else if only the data type has been provided
            else if (!spec[property].type) valid = this.assertType(data[property], spec[property]);

            else {
                if (data[property] && spec[property].type) valid = this.assertType(data[property], spec[property].type);

                // if still valid, validate if property is required
                if (valid && spec[property].required && !data[property]) valid = false;

                // if still valid, validate if custom validation function is defined
                if (valid && typeof spec[property].validate === 'function') valid = spec[property].validate(data[property]);
            }

            // break loop immediately on first error
            if (!valid) break;
        }
{'fraction_non_alphanumeric': 0.11629256965944272, 'fraction_numerical': 0.0, 'mean_word_length': 1.8668885191347753, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '7344201', 'n_tokens_mistral': 1329, 'n_tokens_neox': 1257, 'n_words': 387}