Compare commits

..

10 commits

Author SHA1 Message Date
Daniel Garcia
22affbdfe1 Add dist directory 2021-09-09 16:14:27 +02:00
Daniel Garcia
c489ffec4f Refactor the library completly 2021-09-09 11:34:26 +02:00
Daniel Garcia
b095bed5ca WIP - 21.08.31 2021-08-31 22:35:42 +02:00
Daniel Garcia
7ea0be8551 Add README.md 2021-06-21 16:44:37 +02:00
Daniel Garcia
e9efc459e7 Add pending TODO list 2021-03-17 17:43:34 +01:00
dgarcia
7a3949790c Update version 2020-10-19 18:09:11 +02:00
dgarcia
19554d6848 Add minor fixes 2020-10-19 18:02:44 +02:00
dgarcia
e4ab9caf94 Change name propertie to filename in mcfFile class 2020-10-05 17:06:28 +02:00
dgarcia
af14515bcd Change File class name to export 2020-10-05 16:44:23 +02:00
dgarcia
424e3e4df0 Add class MCF_File. Update packages 2020-10-05 16:34:08 +02:00
20 changed files with 5389 additions and 1987 deletions

52
.eslintrc.js Normal file
View file

@ -0,0 +1,52 @@
module.exports = {
// 'plugins': ['jest'],
'env': {
'commonjs': true,
'es6': true,
'node': true,
// 'jest/globals': true,
},
'extends': 'eslint:recommended',
'globals': {
'Atomics': 'readonly',
'SharedArrayBuffer': 'readonly',
},
'parserOptions': {
'ecmaVersion': 2018,
'sourceType': 'module',
},
'rules': {
'indent': [
'error',
2,
],
'linebreak-style': [
'error',
'unix',
],
'quotes': [
'error',
'single',
{ 'avoidEscape': true },
],
'semi': [
'error',
'never',
],
'comma-dangle': [
'error',
'always-multiline',
],
'arrow-parens': [
'error',
'as-needed',
],
'no-var': [
'error',
],
'prefer-const': ['error', {
'destructuring': 'all',
'ignoreReadBeforeAssign': true,
}],
},
}

3
.gitignore vendored
View file

@ -1 +1,2 @@
node_modules/
/node_modules/
/.idea/

View file

@ -1,10 +1,25 @@
# MCF-Components-Lib
# MCF-Objects
This library exports an unique method to render components using *React* and *Material-UI* through a javascript object where is placed all
the information needed.
Se trata de una librería para la gestión de objetos que añade tipos estáticos y verificaciones.
The method is **render**
Admite los siguientes tipos básicos:
- String
- Number
- Boolean
- Array
- Enum
## Installation
Mediante la definición de los objetos estáticos se pueden establecer límites a los valores, listas de valores permitidos...
To install the library you can get the repository or install it as a dependency.
## Entorno de desarrollo
La bibioteca se transpila usando `babel` y se compila con `webpack`.
## Arquitectura
En el archivo `index.js`, se exporta la clase definedObject.
El constructor de clase lee la definición pasada como argumento cuando crea una instancia de clase y efectúa las verificaciones necesarias antes de devolver dicha instancia.
Cuando se asignan valores a los campos del objeto también se realizar las verificaciones indicadas sobre estos.

2
dist/mcf-objects.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6722
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{
"name": "mcf-objects",
"version": "0.1.2",
"description": "Library to create custom typed objects with custom types",
"version": "0.2.0",
"description": "Library to create typed objects",
"main": "dist/mcf-objects.js",
"scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js",
@ -10,15 +10,16 @@
"test:watch": "jest --watch"
},
"devDependencies": {
"@babel/core": "^7.7.5",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/preset-env": "^7.7.6",
"@babel/preset-react": "^7.7.4",
"babel-loader": "^8.0.6",
"@babel/core": "^7.14.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/preset-env": "^7.14.7",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"eslint": "^7.29.0",
"jest": "^24.9.0",
"webpack": "^4.41.3",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^4.2.2"
},
"dependencies": {}

65
src/definedObject.js Normal file
View file

@ -0,0 +1,65 @@
import MCF_TypeFactory from './types/typeFactory'
export default class MCF_DefinedObject {
constructor(definition) {
this.definition = definition
this.validations = {}
this.fields = MCF_TypeFactory.buildDefinedObject(this)
this.validateValue(definition.values)
this.setValue(definition.values)
}
getValue() {
const value = {}
for (const field in this.fields) {
value[field] = this.fields[field].value
}
return value
}
setValue(value) {
for (const valueKey in value) {
if (value[valueKey] === undefined) {
this.fields[valueKey].value = undefined
} else {
if (this.fields[valueKey] === undefined) {
throw new Error(`The field ${valueKey} doesn't exist in the current DefinedObject: ${JSON.stringify(Object.keys(this.fields), null, 2)}`)
}
this.fields[valueKey].setValue(value[valueKey])
}
}
}
getDefinition() {
return this.definition
}
validateValue(value) {
for (const 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`)
}
}
}
}
updateArrayField(field, arrayItem, mustBeIncluded) {
const fieldArray = this.getValue()[field] || []
if (!fieldArray.includes(arrayItem) && mustBeIncluded) fieldArray.push(arrayItem)
if (fieldArray.includes(arrayItem) && !mustBeIncluded) fieldArray.splice(fieldArray.indexOf(arrayItem), 1)
const newValue = {}
newValue[field] = fieldArray
this.setValue(newValue)
}
}

View file

@ -1,235 +1,14 @@
// --== OBJECTS LIBRARY ==--
// ========================================
//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)
class MCF_Type {
constructor(definition){
this.definition = definition;
this.validations = {};
}
import MCF_DefinedObject from './definedObject'
import MCF_File from './objects/file'
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);
}
}
export {
MCF_DefinedObject as DefinedObject,
MCF_File as File,
}
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.setValue(definition.value)
}
getDefinition(){
return this.definition;
}
getValue(){
let value = {};
for (let field in this.fields){
value[field] = this.fields[field].value;
}
return value;
}
setValue(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`);
}
}
}
for (let field in value){
if (value[field] === undefined){
this.fields[field].value = undefined;
} else {
this.fields[field].setValue(value[field]);
}
}
}
setPropertiesValue(value){
for (let field in value){
this.fields[field].setValue(value[field]);
}
}
}
export {MCF_DefinedObject as definedObject};

19
src/objects/file.js Normal file
View file

@ -0,0 +1,19 @@
import MCF_DefinedObject from '../definedObject'
const fileFieldsDefition = {
name: { TYPE: 'string', required: true },
extension: { TYPE: 'string' },
mimeType: { TYPE: 'string' },
content: { TYPE: 'string', defaultValue: '' },
}
export default class MCF_File extends MCF_DefinedObject {
constructor(definition) {
super({
fields: { ...fileFieldsDefition, ...definition.fields },
values: definition.values ? definition.values : definition,
})
}
}

37
src/types/array.js Normal file
View file

@ -0,0 +1,37 @@
import MCF_BaseType from './base'
export default class MCF_Array extends MCF_BaseType {
constructor(definition) {
super(definition)
this.addValidations()
}
addValidations() {
this.validations.type = function(value) {
if (!Array.isArray(value)) {
throw new Error(`MCF-Objects ==> MCF_Array validation: the type of ${value} isn't "array"`)
}
}
for (const param in this.definition) {
switch (param) {
case 'maxLength':
this.validations.maxLength = function(value, definition) {
if (value.length > definition.maxLength) {
throw new Error(`MCF-Objects ==> MCF_Array validation: 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-Objects ==> MCF_Array validation: the length of the array "${value}" is lower than the minimum defined: ${definition.minLength}`)
}
}
break
}
}
}
}

21
src/types/base.js Normal file
View file

@ -0,0 +1,21 @@
export default class MCF_BaseType {
constructor(definition) {
this.definition = definition
this.validations = {}
}
getValue() {
return this.value
}
setValue(value) {
this.validate(value)
this.value = value
}
validate(value) {
for (const validation in this.validations) {
this.validations[validation](value, this.definition)
}
}
}

18
src/types/boolean.js Normal file
View file

@ -0,0 +1,18 @@
import MCF_BaseType from './base'
export default class MCF_Boolean extends MCF_BaseType {
constructor(definition) {
super(definition)
this.addValidations()
}
addValidations() {
this.validations.type = function(value) {
if (typeof(value) !== 'boolean') {
throw new Error(`MCF-Objects ==> MCF_Boolean creation: the type of the value ${value} isn't "boolean"`)
}
}
}
}

22
src/types/enum.js Normal file
View file

@ -0,0 +1,22 @@
import MCF_BaseType from './base'
export default class MCF_Enum extends MCF_BaseType {
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-Objects ==> MCF_Enum validation: the value "${value}" isn't one of the next values, included in the field definition: ${definition.availableValues.toString()}`)
}
}
}
}

36
src/types/number.js Normal file
View file

@ -0,0 +1,36 @@
import MCF_BaseType from './base'
export default class MCF_Number extends MCF_BaseType {
constructor(definition) {
super(definition)
this.addValidations()
}
addValidations() {
this.validations.type = function(value) {
if (typeof(value) !== 'number') {
throw new Error(`MCF-Objects ==> MCF_Number validation: the type of the value ${value} isn't "number"`)
}
}
for (const param in this.definition) {
switch (param) {
case 'max':
this.validations.max = function(value, definition) {
if (value > definition.max) {
throw new Error(`MCF-Objects ==> MCF_Number validation: 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-Objects ==> MCF_Number validation: the value ${value} is lower than the minimum defined: ${definition.min}`)
}
}
break
}
}
}
}

37
src/types/string.js Normal file
View file

@ -0,0 +1,37 @@
import MCF_BaseType from './base'
export default class MCF_String extends MCF_BaseType {
constructor(definition) {
super(definition)
this.addValidations()
}
addValidations() {
this.validations.type = function(value) {
if (typeof(value) !== 'string') {
throw new Error(`MCF-Objects ==> MCF_String validation: the type of ${value} isn't "string"`)
}
}
for (const param in this.definition) {
switch (param) {
case 'maxLength':
this.validations.maxLength = function(value, definition) {
if (value.length > definition.maxLength) {
throw new Error(`MCF-Objects ==> MCF_String validation: 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-Objects ==> MCF_String validation: the length of the string "${value}" is lower than the minimum defined: ${definition.minLength}`)
}
}
break
}
}
}
}

37
src/types/typeFactory.js Normal file
View file

@ -0,0 +1,37 @@
import MCF_Array from './array'
import MCF_Boolean from './boolean'
import MCF_Enum from './enum'
import MCF_Number from './number'
import MCF_String from './string'
export default class MCF_TypeFactory {
static buildDefinedObject(definedObject) {
const objectDefinition = definedObject.getDefinition()
const fields = objectDefinition.fields
const dictionary = {}
for (const field in fields) {
switch (fields[field]['TYPE']) {
case 'array':
dictionary[field] = new MCF_Array(fields[field])
break
case 'boolean':
dictionary[field] = new MCF_Boolean(fields[field])
break
case 'enum':
dictionary[field] = new MCF_Enum(fields[field])
break
case 'number':
dictionary[field] = new MCF_Number(fields[field])
break
case 'string':
dictionary[field] = new MCF_String(fields[field])
break
default:
throw new Error(`MCF-Objects ==> The object type ${fields[field]['TYPE']} does not exist. Check the field definition in the object definition ${objectDefinition}`)
}
}
return dictionary
}
}

View file

@ -1,4 +1,4 @@
const path = require('path');
const path = require('path')
module.exports = {
entry: './src/index.js',
@ -6,7 +6,7 @@ module.exports = {
path: path.resolve(__dirname, 'dist'),
filename: 'mcf-objects.js',
library: 'mcfObjects',
libraryTarget: 'umd'
libraryTarget: 'umd',
},
module: {
rules: [
@ -19,4 +19,4 @@ module.exports = {
},
],
},
};
}

View file

@ -1,5 +1,5 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'development',
@ -7,4 +7,4 @@ module.exports = merge(common, {
devServer: {
contentBase: './dist',
},
});
})

View file

@ -1,7 +1,7 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map',
});
})