npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

simple-schema-model-validator

v1.0.5

Published

El objetivo principal de este paquete es validar los objetos JSON a partir de un esquema definido con algunas reglas de negocio. Principalmente consiste en una clase de ES6 de la cuál se pueden extender diferentes definiciones de modelos, pudiendo estable

Downloads

7

Readme

Simple Model Schema Validator

El objetivo principal de este paquete es validar los objetos JSON a partir de un esquema definido con algunas reglas de negocio. Principalmente consiste en una clase de ES6 de la cuál se pueden extender diferentes definiciones de modelos, pudiendo establecer reglas como: required, type, maxLength, entre otros.

Instalar dependencia

npm i simple-schema-model-validator

Importar paquete en su proyecto

import { ModelSchema } from "simple-schema-model-validator";

Si utilizas un gestor de alias para rutas como module-alias podrías crear una ruta de la siguiente manera:

import path from 'path'
import * as moduleAlias from 'module-alias';

moduleAlias.addAliases({
    "@modelSchema": path.resolve(__dirname, "../../node_modules/simple-schema-model-validator/dist/modelSchema")
});

y luego importar el paquete tal como se muestra a continuación:

import { ModelSchema } from '@modelSchema';

Crear un nuevo modelo

En el siguiente ejemplo crearemos un modelo llamado UserModel con la siguiente definción:

{
    "userId": {
        "alias": "Usuario ID", // Corresponde a la llave primaria de la tabla que estamos representando
        "type": "number",
        "required": false,
        "notIncluded": true, // Para que no sea incluido como parte del body al hacer un insert o un update
        "nameFieldDatabase": "user_id"
    },
    "userNames": {
        "alias": "Nombres del usuario",
        "type": "string",
        "required": true,
        "maxLength": 25,
        "nameFieldDatabase": "user_name"
    },
    "userLastnames": {
        "alias": "Apellidos del usuario",
        "type": "string",
        "maxLength": 25,
        "required": true,
        "nameFieldDatabase": "user_lastnames"
    },
    "userEmail": {
        "alias": "Correo del usuario",
        "type": "string",
        "required": true,
        "nameFieldDatabase": "user_email"
    },
    "userAge": {
        "alias": "Edad del usuario",
        "type": "string",
        "required": false,
        "defaultValue": null,
        "nameFieldDatabase": "user_age"
    }
}

En el ejemplo anterior se han definido las propiedades que debe llevar nuestro objeto User que se definirá como una clase de JavaScript que se extenderá de la clase ModelSchema, como se muestra a continuación:

//importamos el paquete
import { ModelSchema } from "simple-schema-model-validator"; 
export class UserModel extends ModelSchema {
    // Contructor de la clase que representa User
    constructor () {
        //Definición del esquema, con reglas de negocio 
        const schemaModel = {
            "userId": {
                "alias": "Usuario ID", // Corresponde a la llave primaria de la tabla que estamos representando
                "type": "number",
                "required": false,
                "notIncluded": true, // Para que no sea incluido como parte del body al hacer un insert o un update
                "nameFieldDatabase": "user_id"
            },
            "userNames": {
                "alias": "Nombres del usuario",
                "type": "string",
                "required": true,
                "maxLength": 25,
                "nameFieldDatabase": "user_name"
            },
            "userLastnames": {
                "alias": "Apellidos del usuario",
                "type": "string",
                "maxLength": 25,
                "required": true,
                "nameFieldDatabase": "user_lastnames"
            },
            "userEmail": {
                "alias": "Correo del usuario",
                "type": "string",
                "required": true,
                "nameFieldDatabase": "user_email"
            },
            "userAge": {
                "alias": "Edad del usuario",
                "type": "string",
                "required": false,
                "defaultValue": null,
                "nameFieldDatabase": "user_age"
            }
        }

        super(schemaModel);
    }
}

Propiedades permitidas

| Propiedad | Descripcion | | :--- | :----: |
| alias | El nombre con el que aparecerá la propiedad en el manejo de errores, en caso de incumplir las reglas definidas en el modelo | | type | Tipo de dato de la propiedad definida | | notIncluded | Cuando queremos que una o más de las propiedades no forme parte del body resultante, se establece esta propiedad en true | | required | Indica si la propiedad es requerida | | defaultValue | Establece un valor por defecto en el caso de que required haya sido definido como false | | maxLength | Para el caso de los strings define la cantidad de caracteres máximo permitido | | nameFieldDatabase | Cuando se requiera hacer un match entre el nombre virtual definido en el esquema con el nombre real que tiene en base de datos | | validate | Propiedad especial para alojar una función que realice validaciones extras, como por ejemplo: validar correos, fechas o un rut |

Ejemplo de uso propiedad validate

En el siguiente ejemplo se emplea una validación para la propiedad userAge, en donde se verifica mediante el uso de una función que el usuario sea mayor de edad

const schemaModel = {
     "userId": {
        "alias": "Usuario ID", // Corresponde a la llave primaria de la tabla que estamos representando
        "type": "number",
        "required": false,
        "notIncluded": true, // Para que no sea incluido como parte del body al hacer un insert o un update
        "nameFieldDatabase": "user_id"
    },
    "userNames": {
        "alias": "Nombres del usuario",
        "type": "string",
        "required": true,
        "maxLength": 25,
        "nameFieldDatabase": "user_name"
    },
    "userLastnames": {
        "alias": "Apellidos del usuario",
        "type": "string",
        "maxLength": 25,
        "required": true,
        "nameFieldDatabase": "user_lastnames"
    },
    "userEmail": {
        "alias": "Correo del usuario",
        "type": "string",
        "required": true,
        "nameFieldDatabase": "user_email"
    },
    "userAge": {
        "alias": "Edad del usuario",
        "type": "number",
        "required": false,
        "defaultValue": null,
        "nameFieldDatabase": "user_age",
        "validate": function(value) {
            if(value < 18) {
                return {
                    ok: false,
                    message: "Eres menor de edad"
                }
            }
            return {
                ok: true
            }
        }
    }
}

El retorno que deben tener las funciones encapsuladas en la propiedad validate, deben tener el siguiente formato:

  1. Caso negativo :x:
return {
    "ok": false,
    "message": "Mensaje de error"
}
  1. Caso positivo :white_check_mark:
return {
    "ok": true
}

Usando el modelo UserModel

// Importtamos el modelo definido
import { UserModel } from "./models/UserModel.js";

// Creamos una nueva instancia
let userModel = new UserModel();

// Body de prueba con datos reales
const bodyAll = {
    "userNames": "Camilo",
    "userLastnames": "Bello",
    "userEmail": "[email protected]",
    "userAge": 29
};

const bodyParticular = {
    "userNames": "Camilo",
    "userLastnames": "Bello"
};

// Función de prueba que se ejecutará apenas corramos nuestro archivo
(async function () {
    // El paquete tiene un método disponible llamado "isValidSchema",
    // el cual es el encargado de llevar a cabo el proceso de validación
    // de nuestro body según lo definido en el modelo
    // análisis estricto (para validar antes de hacer un insert en BD)
    let bodyValidateAll = await userModel.isValidSchema(body);

    // analizará solo las propiedades enviadas (que se van a actualizar en BD)
    let bodyValidateParticular = await userModel.isValidSchema(bodyParticular, true);
    console.log(bodyValidateAll);
    console.log(bodyValidateParticular);
})()

Método isValidSchema

El método isValidSchema recibe 2 argumentos, el primero es el body con la data que se debe validar, y el segundo parámetro es particularFields que por defecto es false.

  1. Cuando está en false quiere decir que el análisis será más estricto y va más orientado a el análisis antes de realizar un insert en base de datos, debido a que el body analizado debe cumplir por completo con lo definido en el UserModel.
  2. Si el valor esta en true, quiere decir que solo analizará lo que se ha establecido en el body, es decir que por ejemplo para el caso de la constante bodyParticular definida anteriormente, solo analizará las propiedades userNames y userLastnames; esto va más orientado a realizar dicha validación antes de ejecutar un update en base datos

¿Que retorna el método isValidSchema?

Existen dos tipos de retorno los cuales serán especificados a continuación:

  1. Caso negativo :x:
{
    "ok": false,
    "dataErrors": {
        "userNames": [
            "Nombres es requerido"
        ],
        "userLastnames": [
            "Apellidos puede contener hasta 25 caracteres"    
        ]
    },
    "messages": [
        "Nombres es requerido",
        "Apellidos puede contener hasta 25 caracteres"
    ]
}

Cuando se han encontrado errores según lo definido en el modelo, se pueden identificar 3 propiedades fundamentales que son las siguientes:

| Propiedad | Descripcion | | :--- | :----: |
| ok | Propiedad que identifica si el proceso ha sido correcto o no (para este caso es false) | | dataErrors | Agrupa los errores según campo o columna, puede ser utilizado perfectamente para mostrar los errores de formulario desde el frontend | | messages | Propiedad que tiene todos los errores encontrados en formato de lista de strings |

  1. Caso positivo :white_check_mark:
{
    "ok": true,
    "body": {
        "userNames": "Camilo",
        "userLastnames": "Bello",
        "userEmail": "[email protected]",
        "userAge": 29
    }
}

Cuando la validación ha sido correcta, el retorno trae 2 propiedades. En donde una de ellas es el body, el cual se ordena tal cual como esta definido el modelo que lo valida (UserModel), lo ideal es utilizar este body ordenado si desea insertar o modificar registros en base de datos. Las propiedades mencionadas se describen a continuación:

| Propiedad | Descripcion | | :--- | :----: |
| ok | Propiedad que identifica si el proceso ha sido correcto o no (para este caso es true) | | body | Body ordenado según definición de modelo |

¿Otro ejemplo? :+1::+1::+1:

A continuación un código fuente de ejemplo, utilizando el modelo y el método isValidSchema

import { UserModel } from "../../../domain/model";
import { UserRepository } from "../../../domain/repository";
import * as EventsDomain from '@eventsDomain';
import * as UsertDTO from '../../../domain/DTO';

export const createNewUser = async (body) => {
    // instancia de modelo de usuario
    // definición de UserModel mencionado anteriormente
    const userModel = new UserModel();
    const userRepository = new UserRepository();

    // se ejecuta el metodo isValidSchema, pasando como parámetro el body
    // para este caso no se indica el 2° parámetro puesto que por defecto es **false**,
    // ya que se requiere el análisis sea estricto
    const bodyValidate = await userModel.isValidSchema(body);

    // en el caso de que la respuesta traiga la propiedad 'ok' con valor false
    // quiere decir que se han encontrados errores según lo definido en el modelo
    if (bodyValidate.hasOwnProperty('ok') && bodyValidate.ok === false) {
        // se detiene la ejecución del código enviando todos los errores encontrados
        return EventsDomain.schemaInvalid(bodyValidate);
    }

    // si todo ha ido bien, se procede a persistir en base datos el usuario, utilizando
    // el body que retorna el método isValidSchema (bodyValidate.body)
    const userCreated = await userRepository.save(bodyValidate.body);
    return EventsDomain.successfullySaved(UsertDTO.single(userCreated));
}

Método prepareQueryUpdate

Metodo encargado de preparar queries para modificación de datos ayudándose del esquema del modelo definido realizando un match del nombre del campo virtual con el nombre del campo físico en base de datos

// En nuestro respository.js
// Ejemplo de "criteria"
const criteria = { "where": { "userId": 1 } };
async updateByCriteria (connection, criteria, body) {
    // Instanciamos nuestro model que contiene las definciones de campos virtuales y físicos de base datos
    const userModel = new UserModel();
    // query base
    let query = "UPDATE user SET";
        * 
    // Invocamos el méotodo para realizar la creación de los campos a setear y la cláusula where
    let { setFields, whereFields } = userModel.prepareQueryUpdate(body, criteria);
        * 
    // Validamos que el body no esté vacío, si no está vacío se procede a la concatenación de la query
    if (Object.keys(body).length > 0) {
        // Concatenamos la query base con lo retonardo por el método
        query = `
            ${query}
            ${setFields}
            ${whereFields}
        ` ;
    }
}