//TODO: Solucionar eslint //TODO: Dividir correctamente la librería en clases //TODO: Hacer nuevo tipo de dato: array-enum -> array en el que los elementos solo pueden tomar determinados valores //TODO: Que no sea necesario pasar un objeto vacío ({}) para instanciar un mcfDefinedObject sin argumentos //TODO: Modificar getValue para que acepte como parámetro el nombre del campo que se quiere obtener: getvalue(fieldName) //TODO: Añadir las funciones: createListFromDictionary, createCheckboxListFromDictionary, updateDefinedObjectArray a ¿una clase UI genérica (DefinedUI)? //TODO: Mover la herencia de las clases derivadas a la clase padre MCF_DefinedObject //TODO: Hacer una función que permita cambiar un atributo de un mcf_component a partir del id del componente, el nombre del atributo y el nuevo valor del atributo //TODO: Hacer una función que permita encontrar un mcf_component a partir de su id // --== OBJECTS LIBRARY ==-- // ======================================== class MCF_Type { constructor(definition) { this.definition = definition; this.validations = {}; } setValue(value) { this.validate(value); this.value = value; } getValue() { return this.value; } validate(value) { for (let validation in this.validations) { this.validations[validation](value, this.definition); } } } class MCF_String extends MCF_Type { constructor(definition) { super(definition); this.addValidations(); } addValidations() { this.validations.type = function(value) { if (typeof(value) !== "string") { throw new Error(`MCF_String creation: the type of ${value} isn't "string"`); } }; for (let param in this.definition) { switch (param) { case 'maxLength': this.validations.maxLength = function(value, definition) { if (value.length > definition.maxLength) { throw new Error(`MCF_String creation: the length of the string "${value}" is higher than the maximum defined: ${definition.maxLength}`); } }; break; case 'minLength': this.validations.minLength = function(value, definition) { if (value.length < definition.minLength) { throw new Error(`MCF_String creation: the length of the string "${value}" is lower than the minimum defined: ${definition.minLength}`); } }; break; } } } } class MCF_Number extends MCF_Type { constructor(definition) { super(definition); this.addValidations(); } addValidations() { this.validations.type = function(value) { if (typeof(value) !== "number") { throw new Error(`MCF_Number creation: the type of the value ${value} isn't "number"`); } }; for (let param in this.definition) { switch (param) { case 'max': this.validations.max = function(value, definition) { if (value > definition.max) { throw new Error(`MCF_Number creation: the value ${value} is higher than the maximum defined: ${definition.max}`); } }; break; case 'min': this.validations.min = function(value, definition) { if (value < definition.min) { throw new Error(`MCF_Number creation: the value ${value} is lower than the minimum defined: ${definition.min}`); } }; break; } } } } class MCF_Boolean extends MCF_Type { constructor(definition) { super(definition); this.addValidations(); } addValidations() { this.validations.type = function(value) { if (typeof(value) !== "boolean") { throw new Error(`MCF_Boolean creation: the type of the value ${value} isn't "boolean"`); } }; } } class MCF_Array extends MCF_Type { constructor(definition) { super(definition); this.addValidations(); } addValidations() { this.validations.type = function(value) { if (!Array.isArray(value)) { throw new Error(`MCF_Array creation: the type of ${value} isn't "array"`); } }; for (let param in this.definition) { switch (param) { case 'maxLength': this.validations.maxLength = function(value, definition) { if (value.length > definition.maxLength) { throw new Error(`MCF_Array creation: the length of the array "${value}" is higher than the maximum defined: ${definition.maxLength}`); } }; break; case 'minLength': this.validations.minLength = function(value, definition) { if (value.length < definition.minLength) { throw new Error(`MCF_Array creation: the length of the array "${value}" is lower than the minimum defined: ${definition.minLength}`); } }; break; } } } } class MCF_Enum extends MCF_Type { constructor(definition) { super(definition); this.addValidations(); } addValidations() { this.validations.isAvailable = function(value, definition) { const valueIsAvailable = definition.availableValues.reduce(function(isAvailable, availableValue) { if (value === availableValue) return true; return isAvailable; }, false); if (!valueIsAvailable) { throw new Error(`MCF_Enum creation: the value "${value}" isn't one of the next values, included in the field definition: ${definition.availableValues.toString()}`); } } } } class MCF_TypeFactory { static buildDefinedObject(definedObject) { const objectDefinition = definedObject.getDefinition(); let fields = objectDefinition.fields; let dictionary = {}; for (let field in fields) { switch (fields[field]['TYPE']) { case 'string': dictionary[field] = new MCF_String(fields[field]); break; case 'number': dictionary[field] = new MCF_Number(fields[field]); break; case 'boolean': dictionary[field] = new MCF_Boolean(fields[field]); break; case 'enum': dictionary[field] = new MCF_Enum(fields[field]); break; case 'array': dictionary[field] = new MCF_Array(fields[field]); break; } } return dictionary; } } class MCF_DefinedObject { constructor(definition) { this.definition = definition; this.validations = {}; this.fields = MCF_TypeFactory.buildDefinedObject(this); this.validateValue(definition.value) this.setValue(definition.value) } getDefinition() { return this.definition; } getValue() { let value = {}; for (let field in this.fields) { value[field] = this.fields[field].value; } return value; } validateValue(value) { for (let field in this.definition.fields) { if (value[field] === undefined || value === null) { if (this.definition.fields[field].required === true) { throw new Error(`The field ${field} is required`); } if (this.definition.fields[field].defaultValue !== undefined) { value[field] = this.definition.fields[field].defaultValue; } if (this.definition.fields[field].null === false) { throw new Error(`The field ${field} can't be undefined`); } } } } setValue(value) { for (let valueKey in value) { if (value[valueKey] === undefined) { this.fields[valueKey].value = undefined; } else { this.fields[valueKey].setValue(value[valueKey]); } } } setPropertiesValue(value) { for (let field in value) { this.fields[field].setValue(value[field]); } } } const fileDefinition = { filename: { TYPE: 'string' }, extension: { TYPE: 'string' }, mimeType: { TYPE: 'string' }, path: { TYPE: 'string' }, content: { TYPE: 'string' }, } class MCF_File extends MCF_DefinedObject { constructor(params) { const fields = (params.fields) ? params.fields : {} const value = (params.value) ? params.value : params super({ fields: {...fileDefinition, ...fields }, value: value, }) } } export { MCF_DefinedObject as definedObject, MCF_File as mcfFile, };