<commit_before>﻿import {SchemaItem} from "./schema-items/schema-item";
import {SchemaForeignKey} from "./schema-items/schema-foreign-key";
import * as mongodb from "mongodb"
import {ModelInstance, Model} from "./model"
import {IModelEntry, ISchemaOptions} from "modepress-api";

/**
* Gives an overall description of each property in a model
*/
export class Schema
{
	private _items: Array<SchemaItem<any>>;

	constructor()
	{
		this._items = [];
	}

	/**
	* Creates a copy of the schema
	* @returns {Schema}
	*/
	public clone(): Schema
	{
		var items = this._items;
		var copy = new Schema();

		for (var i = 0, l = items.length; i < l; i++)
			copy._items.push(items[i].clone());

		return copy;
    }

    /**
	* Sets a schema value by name
	* @param {any} data The data object we are setting
	*/
    set(data: any)
    {
        var items = this._items,
            l = items.length;

        for (var i in data)
        {
            for (var ii = 0; ii < l; ii++)
                if (items[ii].name == i)
                    items[ii].setValue( data[i] );
        }
    }

	/**
	* Sets a schema value by name
	* @param {string} name The name of the schema item
	* @param {any} val The new value of the item
	*/
	setVal(name: string, val: any)
	{
		var items = this._items;

		for (var i = 0, l = items.length; i < l; i++)
            if (items[i].name == name)
                items[i].setValue( val );
	}

	/**
	* De-serializes the schema items from the mongodb data entry.
    * I.e. the data is the document from the DB and the schema item sets its values from the document
	* @param {any} data
	*/
	public deserialize(data: any): any
	{
		for (var i in data)
			this.setVal(i, data[i]);
	}

	/**
	* Serializes the schema items into the JSON format for mongodb
	* @returns {any}
	*/
	public serialize(): any
	{
		var toReturn = {};
		var items = this._items;

		for (var i = 0, l = items.length; i < l; i++)
            toReturn[items[i].name] = items[i].getDbValue();

		return toReturn;
    }

    /**
	* Serializes the schema items into a JSON
    * @param {ObjectID} id The models dont store the _id property directly, and so this has to be passed for serialization
    * @param {ISchemaOptions} options [Optional] A set of options that can be passed to control how the data must be returned
	* @returns {Promise<T>}
	*/
    public async getAsJson<T extends Modepress.IModelEntry>( id: mongodb.ObjectID, options : ISchemaOptions ): Promise<T>
    {
        var toReturn : T = <T><Modepress.IModelEntry>{ _id : id };
        var items = this._items;
        var fKey : SchemaForeignKey;
        var model : Model;
        var promises: Array<Promise<any>> = [];

        for (var i = 0, l = items.length; i < l; i++)
        {
            // If this data is sensitive and the request must be sanitized
            // then skip the item
            if ( items[i].getSensitive() && options.verbose == false )
                continue;

            promises.push( items[i].getValue(options) );
        }

        // Wait for all the promises to resolve
        var returns = await Promise.all<any>(promises);

        // Assign the promise values
        for ( var i = 0, l = returns.length; i < l; i++ )
            toReturn[ items[i].name ] = returns[i];

        return Promise.resolve(toReturn);
    }

	/**
	* Checks the values stored in the items to see if they are correct
	* @param {boolean} checkForRequiredFields If true, then required fields must be present otherwise an error is flagged
    * @returns {Promise<Schema>} Returns true if successful
	*/
	public async validate( checkForRequiredFields: boolean ): Promise<Schema>
	{
		var items = this._items;
        var promises : Array<Promise<any>> = [];

        for (var i = 0, l = items.length; i < l; i++)
        {
            if ( checkForRequiredFields && !items[i].getModified() && items[i].getRequired() )
                throw new Error(`${items[i].name} is required`);

            promises.push(items[i].validate());
        }

        var validations = await Promise.all(promises);
        return this;<commit_msg>Bug fix: getAsJson issue with items set as sensitive not being returned as undefined<commit_after>﻿import {SchemaItem} from "./schema-items/schema-item";
import {SchemaForeignKey} from "./schema-items/schema-foreign-key";
import * as mongodb from "mongodb"
import {ModelInstance, Model} from "./model"
import {IModelEntry, ISchemaOptions} from "modepress-api";

/**
* Gives an overall description of each property in a model
*/
export class Schema
{
	private _items: Array<SchemaItem<any>>;

	constructor()
	{
		this._items = [];
	}

	/**
	* Creates a copy of the schema
	* @returns {Schema}
	*/
	public clone(): Schema
	{
		var items = this._items;
		var copy = new Schema();

		for (var i = 0, l = items.length; i < l; i++)
			copy._items.push(items[i].clone());

		return copy;
    }

    /**
	* Sets a schema value by name
	* @param {any} data The data object we are setting
	*/
    set(data: any)
    {
        var items = this._items,
            l = items.length;

        for (var i in data)
        {
            for (var ii = 0; ii < l; ii++)
                if (items[ii].name == i)
                    items[ii].setValue( data[i] );
        }
    }

	/**
	* Sets a schema value by name
	* @param {string} name The name of the schema item
	* @param {any} val The new value of the item
	*/
	setVal(name: string, val: any)
	{
		var items = this._items;

		for (var i = 0, l = items.length; i < l; i++)
            if (items[i].name == name)
                items[i].setValue( val );
	}

	/**
	* De-serializes the schema items from the mongodb data entry.
    * I.e. the data is the document from the DB and the schema item sets its values from the document
	* @param {any} data
	*/
	public deserialize(data: any): any
	{
		for (var i in data)
			this.setVal(i, data[i]);
	}

	/**
	* Serializes the schema items into the JSON format for mongodb
	* @returns {any}
	*/
	public serialize(): any
	{
		var toReturn = {};
		var items = this._items;

		for (var i = 0, l = items.length; i < l; i++)
            toReturn[items[i].name] = items[i].getDbValue();

		return toReturn;
    }

    /**
	* Serializes the schema items into a JSON
    * @param {ObjectID} id The models dont store the _id property directly, and so this has to be passed for serialization
    * @param {ISchemaOptions} options [Optional] A set of options that can be passed to control how the data must be returned
	* @returns {Promise<T>}
	*/
    public async getAsJson<T extends Modepress.IModelEntry>( id: mongodb.ObjectID, options : ISchemaOptions ): Promise<T>
    {
        var toReturn : T = <T><Modepress.IModelEntry>{ _id : id };
        var items = this._items;
        var fKey : SchemaForeignKey;
        var model : Model;
        var promises: Array<Promise<any>> = [];
        var itemsInUse = [];

        for (var i = 0, l = items.length; i < l; i++)
        {
            // If this data is sensitive and the request must be sanitized
            // then skip the item
            if ( items[i].getSensitive() && options.verbose == false )
                continue;

            itemsInUse.push(items[i]);
            promises.push( items[i].getValue( options ) );
        }

        // Wait for all the promises to resolve
        var returns = await Promise.all<any>(promises);

        // Assign the promise values
        for ( var i = 0, l = returns.length; i < l; i++ )
            toReturn[ itemsInUse[i].name ] = returns[i];

        return Promise.resolve(toReturn);
    }

	/**
	* Checks the values stored in the items to see if they are correct
	* @param {boolean} checkForRequiredFields If true, then required fields must be present otherwise an error is flagged
    * @returns {Promise<Schema>} Returns true if successful
	*/
	public async validate( checkForRequiredFields: boolean ): Promise<Schema>
	{
		var items = this._items;
        var promises : Array<Promise<any>> = [];

        for (var i = 0, l = items.length; i < l; i++)
        {
            if ( checkForRequiredFields && !items[i].getModified() && items[i].getRequired() )
                throw new Error(`${items[i].name} is required`);

            promises.push(items[i].validate());
        }

        var validations = await Promise.all(promises);
        return this;
{'fraction_non_alphanumeric': 0.1235914648765284, 'fraction_numerical': 0.001678254615200192, 'mean_word_length': 2.4080882352941178, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 31, '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': '6498901', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2519, 'n_words': 894}