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

field-creator

v2.1.0

Published

Define los atributos de un modelo Sequelize.

Downloads

8

Readme

Field Creator

Sequelize es una excelente herramienta para realizar consultas con la base de datos. Cuando se define un modelo, se especifica el tipo de dato, el tipo de validador, si acepta valores nulos o no. Propiedades que pueden ser requeridas en otros lugares, por ejemplo para crear el APIDOC, para validar los datos, etc.

Aprovechando la implementación de estos modelos, Field Creator permite reutilizar estas propiedades para crear objetos de tipo FieldGroup que pueden ser utilizados en todas estas situaciones.

Además se cuenta con una serie de campos predefinidos que facilitan la creación de modelos.

Características

  • Es posible crear atributos predefinidos que con la propiedad validate incluida por defecto.
  • Es posible crear objetos de tipo FieldGroup. Un fieldGroup es un objeto formado por los campos de los modelos.
  • Incluye varios tipos de datos personalizados.
  • Los tipos de datos personalizados pueden ser sobreescritos con el método add junto con la opción { force: true }.

Tipos de datos básicos

| Tipo | Descripción | Validadores por defecto | |------------|------------------------------|--------------------------------------------| | STRING | Cadena de texto. | len: [0, LENGHT] | | TEXT | Bloque de texto. | len: [0, 2147483647] | | INTEGER | Número entero. | isInt: true, min: 0, max: 2147483647 | | FLOAT | Número en coma flotante. | isFloat: true, min: 0, max: 1E+308 | | BOOLEAN | Valor booleano. | isBoolean: true | | DATE | Fecha (día y hora). | isDate: true | | DATEONLY | Solamente fecha. | isDate: true | | TIME | Solamente hora. | isTime: custom | | JSON | Objeto de tipo JSON. | isJson: custom | | JSONB | Objeto de tipo JSONB. | isJson: custom | | UUID | Código de tipo UUID. | isUUID: 4 | | ENUM | Tipo enumerado. | isIn: [VALUES] | | ARRAY | Lista de valores. | isArray: custom |

Tipos de datos personalizados

Algunos tipos de datos se usan con mayor frecuencia, es por eso que se definieron en base a los tipos de datos básicos.

- Clave primaria

Field.add('ID', Field.INTEGER({
  primaryKey    : true,
  autoIncrement : true,
  allowNull     : false,
  validate      : { min: 1 }
}))
Field.add('PK_INTEGER', Field.INTEGER({
  primaryKey : true,
  allowNull  : false,
  validate   : { min: 1 }
}))
Field.add('PK_UUID', Field.UUID({
  primaryKey : true,
  allowNull  : false
}))

- Auditoria

Field.add('_STATUS', Field.ENUM(['ACTIVO', 'INACTIVO', 'ELIMINADO'], {
  comment      : 'Estado en el que se encuentra el registro.',
  defaultValue : 'ACTIVO'
}))
Field.add('_CREATED_AT', Field.DATE({
  comment: 'Fecha de creación del registro.'
}))
Field.add('_UPDATED_AT', Field.DATE({
  comment: 'Fecha de modificación del registro.'
}))
Field.add('_DELETED_AT', Field.DATE({
  comment: 'Fecha de eliminación del registro.'
}))
Field.add('_CREATED_USER', Field.INTEGER({
  comment: 'ID del usuario que crea el registro.'
}))
Field.add('_UPDATED_USER', Field.INTEGER({
  comment: 'ID del usuario que modifica el registro.'
}))
Field.add('_DELETED_USER', Field.INTEGER({
  comment: 'ID del usuario que elimina el registro.'
}))

- Filtros y consultas

Field.add('FIELDS', Field.STRING({
  comment : 'Campos a devolver en el resultado.',
  example : 'id_usuario,username,persona(id_persona,nombres)'
}))
Field.add('ORDER', Field.STRING({
  comment : 'Orden en el que se devolverá el resultado.',
  example : 'apellido,-nombres'
}))
Field.add('LIMIT', Field.INTEGER({
  comment      : 'Límite de registros por página.',
  defaultValue : 50,
  validate     : { min: 1 }
}))
Field.add('PAGE', Field.INTEGER({
  comment      : 'Número de página de una lista de registros.',
  defaultValue : 1,
  validate     : { min: 1 }
}))

- Autenticación

Field.add('BASIC_AUTHORIZATION', Field.TEXT({
  comment : 'Credenciales de acceso. <code>Basic [username:password] base64</code>',
  example : 'Basic FDS234SF=='
}))
Field.add('BEARER_AUTHORIZATION', Field.TEXT({
  comment : 'Credenciales del acceso. <code>Bearer [accessToken]</code>',
  example : 'Bearer s83hs7.sdf423.f23f'
}))
Field.add('ACCESS_TOKEN', Field.TEXT({
  comment : 'Token de acceso.',
  example : 's83hs7.sdf423.f23f'
}))
Field.add('REFRESH_TOKEN', Field.TEXT({
  comment : 'Token de refresco.',
  example : 's83hs7.sdf423.f23f'
}))
Field.add('TOKEN_EXPIRATION_DATE', Field.DATE({
  comment: 'Fecha de expiración del token.'
}))
Field.add('TOKEN_EXPIRE_IN', Field.DATE({
  comment : 'Tiempo de expiración del token en segundos.',
  example : '86400'
}))
Field.add('TOKEN_TYPE', Field.DATE({
  comment : 'Tipo de token.',
  example : 'Bearer'
}))
Field.add('ACCESS_TYPE', Field.ENUM(['offline', 'online'], {
  comment      : 'Parámetro que indica el tipo de acceso. <code>offline</code> incluirá en la respuesta un token de refresco.',
  defaultValue : 'online'
}))
Field.add('USERNAME', Field.STRING(100, {
  comment  : 'Nombre de usuario.',
  example  : 'admin',
  validate : { len: { args: [3, 100], msg: 'El nombre de usuario debe tener entre 3 y 100 caracteres.' } }
}))
Field.add('PASSWORD', Field.STRING(50, {
  comment  : 'Contraseña de usuario.',
  example  : '123',
  validate : { len: { args: [3, 50], msg: 'La contraseña debe tener entre 3 y 50 caracteres.' } }
}))

- Otros tipos de datos

Field.add('EMAIL', Field.STRING({
  comment  : 'Dirección de correo electrónico',
  example  : '[email protected]',
  validate : { isEmail: true }
}))

Propiedades de un atributo

| Propiedad | Descripción | | ------------------|---------------------------------------------------------------------| | primaryKey | Indica si es una clave primaria. | | autoIncrement | Indica si es autoincrementable. | | unique | Indica si el registro debe ser único. | | defaultValue | Valor por defecto. | | example | Valor de ejemplo. | | allowNull | Indica si el campo acepta valores nulos. | | allowNullObj | Indica si el objeto al que pertenece el campo acepta valores nulos. | | comment | Descripción del atributo. | | uniqueMsg | Mensaje de error para validar unique. | | allowNullMsg | Mensaje de error para validar allowNull. | | allowNullObjMsg | Mensaje de error para validar allowNullObj. | | validate | Objeto para validar el tipo de dato. |

A continuación se muestra un ejemplo para crear un campo de tipo ID:

const ID = Field.INTEGER({
  primaryKey    : true,
  autoIncrement : true,
  unique        : true,
  defaultValue  : null,
  example       : 1
  allowNull     : false,
  comment       : 'Identificador único.',
  uniqueMsg     : 'El campo ID debe ser único.',
  allowNullMsg  : 'El campo ID es requerido.',
  validate      : { min: { args: 1, msg: 'Debe ser mayor o igual a 1.' } },
})

Propiedad validate

Un validador puede tener uno de los siguientes formatos:

const validate = { min: 10 }
const validate = { min: { args: 10 } }
const validate = { min: { args: 10, msg: 'Mensaje de error personalizado.' } }

const validate = { len: [2, 5] }
const validate = { len: { args: [2, 5] } }
const validate = { len: { args: [2, 5], msg: 'Mensaje de error personalizado.' } }

const validate = { isIn: [['A', 'B']] }
const validate = { isIn: { args: [['A', 'B']] } }
const validate = { isIn: { args: [['A', 'B']], msg: 'Mensaje de error personalizado.' } }

Cuando se trata de validadores booleanos, son válidos los siguientes formatos:

const validate = { isEmail: true }
const validate = { isEmail: { msg: 'Mensaje de error personalizado.' } }

Para validadores personalizados:

const validate = {
  esNumeroPar: (value) => {
    if (parseInt(value) % 2 !== 0) {
      throw new Error(`Debe ser un número par.`)
    }
  }
}

Lista de validadores

A continuación se muestra una lista de opciones de la propiedad validate. Puede encontrar más información en: http://docs.sequelizejs.com/manual/tutorial/models-definition.html#validations

const validate = {
  is             : ['^[a-z]+$', 'i'],
  is             : /^[a-z]+$/i,
  not            : ['[a-z]', 'i'],
  isEmail        : true,
  isUrl          : true,
  isIP           : true,
  isIPv4         : true,
  isIPv6         : true,
  isAlpha        : true,
  isAlphanumeric : true,
  isNumeric      : true,
  isInt          : true,
  isFloat        : true,
  isDecimal      : true,
  isLowercase    : true,
  isUppercase    : true,
  notEmpty       : true,
  equals         : 'ABC123',
  contains       : 'def',
  notContains    : 'def',
  notIn          : [['A', 'B']],
  isIn           : [['A', 'B']],
  len            : [2, 5],
  isUUID         : 4,
  isDate         : true,
  isAfter        : '2010-05-30',
  isBefore       : '2020-05-30',
  min            : 10,
  max            : 12,
  isCreditCard   : true,
}

Función clone

Crea una copia a partir de otro atributo, modificando algunas de sus propiedades si fuera necesario.

const ID = Field.ID()

const INPUT = {
  id: Field.clone(ID, { allowNull: false })
}

Función add

Adiciona un tipo de dato personalizado que luego puede ser utilizado como un tipo de dato básico.

// Es posible adicionar nuevos tipos de datos.
Field.add('TITULO', Field.INTEGER({
  comment: 'Título del libro'
}))

// Es posible actualizar los valores de un tipo de dato personalizado.
Field.add('ID', Field.INTEGER({
  comment       : 'Identificador único',
  autoIncrement : false
}), { force: true })

const LIBRO = sequelize.define('libro', {
  id     : Field.ID(),
  titulo : Field.TITULO(),
  precio : Field.FLOAT()
})

Función use

Adiciona o modifica un tipo de dato. Similar a la función add pero con la opción force por defecto en true.

// Modifica el tipo de dato ID predefinido.
Field.use('ID', Field.INTEGER({
  comment       : 'Identificador único del autor',
  autoIncrement : false
}))

const AUTOR = sequelize.define('autor', {
  id     : Field.ID(),
  nombre : Field.STRING()
})

Field.use('ID', Field.INTEGER({
  comment       : 'Identificador único del libro',
  autoIncrement : false
}))

const LIBRO = sequelize.define('libro', {
  id     : Field.ID(),
  precio : Field.FLOAT()
})

Función group

Crea un objeto de tipo FieldGroup. Un fieldGroupd es un objeto formado por atributos de un modelo Sequelize.

Por ejemplo, si se tienen los modelos autor y libro, relacionados de 1:N.

const AUTOR = sequelize.define('autor', {
  id_autor : Field.ID(),
  nombre   : Field.STRING()
})
const LIBRO = sequelize.define('libro', {
  id_libro : Field.ID(),
  titulo   : Field.STRING(10),
  precio   : Field.FLOAT()
})
LIBRO.belongsTo(AUTOR, { as: 'autor' })
AUTOR.hasMany(LIBRO, { as: 'libros' })

Se pueden crear los siguientes FieldGroups.

const AUTOR_OUTPUT = Field.group(AUTOR, {
  id_autor : THIS(),
  nombre   : THIS(),
  libros   : [{ // Lista de libros
    id_libro : THIS(),
    titulo   : THIS(),
    precio   : THIS()
  }]
})

const LIBRO_OUTPUT = Field.group(LIBRO, {
  id_libro : THIS(),
  titulo   : THIS(),
  precio   : THIS(),
  autor    : { // Un autor
    id_autor : THIS(),
    titulo   : THIS(),
    precio   : THIS()
  }
})

La función THIS, indica que el campo, es parte del modelo especificado en el group.

Instalación

Para instalar sobre un proyecto, ejecutar el siguiente comando:

$ npm install --save field-creator

Ejemplo 1. Creando un modelo

Definición de un modelo libro de la forma tradicional:

const LIBRO = sequelize.define('libro', {
  id: {
    type          : Sequelize.INTEGER(),
    primaryKey    : true,
    autoIncrement : true,
    allowNull     : false,
    validate      : {
      isInt : true,
      min   : 1,
      max   : 2147483647
    }
  },
  titulo: {
    type: Sequelize.STRING(10),
    validate: {
      len: [0, 10]
    }
  },
  precio: {
    type: Sequelize.FLOAT(),
    validate: {
      isFloat : true,
      min     : 0,
      max     : 1E+308
    }
  }
})

Definición del mismo modelo libro utilizando la librería:

const LIBRO = sequelize.define('libro', {
  id_libro : Field.ID(),
  titulo   : Field.STRING(10),
  precio   : Field.FLOAT()
})

Ejemplo 2. Definiendo FieldGroups anidados

const { Field, THIS } = require('field-creator')

const fieldGroup = Field.group(LIBRO, {
  id_libro : THIS(),
  titulo   : THIS({ allowNull: false }),
  precio   : THIS({ allowNull: false }),
  autor    : Field.group(AUTOR, {
    id_autor : THIS(),
    nombre   : THIS()
  }),
  other: Field.STRING({ comment: 'other field.' })
})