Ir al contenido

Validación y condiciones

Se utiliza con propiedades de tipo string o number para renderizar selects:

import type { StringProperty } from "@rebasepro/types";
// Simple: each value mapped to its label
const simple: StringProperty = {
type: "string",
name: "Status",
enum: { draft: "Draft", published: "Published", archived: "Archived" }
};
// As a list, which keeps the order you write
const listed: StringProperty = {
type: "string",
name: "Status",
enum: [
{ id: "draft", label: "Draft" },
{ id: "published", label: "Published" },
{ id: "archived", label: "Archived" }
]
};
// With colors (for Kanban columns and chips)
const colored: StringProperty = {
type: "string",
name: "Status",
enum: [
{ id: "draft", label: "Draft", color: "grayDark" },
{ id: "published", label: "Published", color: "greenDark" },
{ id: "archived", label: "Archived", color: "orangeDark" }
]
};

Una lista simple de valores, enum: ["draft", "published", "archived"], no forma parte del tipo. Una configuración en JavaScript que escriba una sigue funcionando: el enum de la base de datos, los tipos generados y el desplegable del administrador la leen como esos valores, cada uno con sí mismo como etiqueta.

Cada regla reside en el bloque validation de la propiedad, y qué reglas acepta una propiedad depende de su tipo: min cuenta caracteres en un string, compara magnitudes en un number y cuenta elementos en un array.

properties: {
title: {
type: "string",
name: "Title",
validation: { required: true, min: 2, max: 200 }
},
slug: {
type: "string",
name: "Slug",
validation: {
unique: true,
matches: /^[a-z0-9-]+$/,
matchesMessage: "Lowercase letters, digits and hyphens only",
trim: true,
lowercase: true
}
},
readingMinutes: {
type: "number",
name: "Reading time",
validation: { integer: true, moreThan: 0, max: 120 }
}
}

El servidor comprueba validation en el límite de la petición — REST, el socket en tiempo real y MCP — sobre lo que envió el emisor, antes de que se ejecute beforeSave, y responde a una escritura que rompe una regla con un 400 que nombra todos los campos que fallan. El código de servidor que escribe en proceso es de confianza y no se comprueba contra estas reglas: rebase.data y rebase.dataAsAdmin en una función o cron job, context.data en un callback, un script de siembra. Lo que se mantiene ahí es lo que impone la base de datos — required (NOT NULL), unique (un índice único), el tipo de un enum y el ancho de una columna varchar o char. Cualquier otra cosa que escriba tu propio código de servidor, compruébala en el código que la escribe.

El panel de administración comprueba las mismas reglas antes de guardar, en el formulario del registro y en el editor en línea de la tabla de la colección. Una celda de la tabla juzga un valor cuando lo editas: un valor almacenado que incumple una regla añadida después no muestra ningún error en la tabla hasta que alguien edita esa celda.

Regla Tipo Descripción
required boolean El valor debe estar presente. En un string, "" cuenta como ausente: la API lo rechaza en toda escritura, una creación o una actualización, con la misma violación required (salvo que la colección tenga un beforeSave, que puede rellenarlo)
requiredMessage string Lo que se dice cuando no lo está: por el formulario de administración, y como el message de la entrada required del campo en el 400 de la API. El NOT NULL de la base de datos no lleva mensaje
unique boolean Solo una fila de la tabla puede contener este valor. El formulario de administración también lo comprueba al guardar un valor que la edición cambió, de modo que un duplicado se señala en su campo antes de la escritura
uniqueInArray boolean Solo una entrada por array puede contenerlo. Se aplica a un hijo directo de una propiedad array, o a un hijo de primer nivel de un map dentro de uno. Solo en el formulario de administración; no lo impone la API ni la base de datos.
Regla Tipo Descripción
min / max number Mínimo / máximo de caracteres, inclusivo. Con columnType: "varchar" o "char", max también define el tamaño de la columna (VARCHAR(max)), por lo que reducirlo en una tabla que ya contiene filas más largas es una migración que la base de datos rechazará, y el editor de colecciones avisa cuando una edición lo reduce. La columna por defecto es TEXT, que max deja sin límite — el único límite es entonces la comprobación de la petición del servidor
length number Exactamente esta cantidad de caracteres: un código de país, una referencia de ancho fijo
matches string | RegExp Un patrón con el que debe coincidir el valor completo. Un string se compila por petición, por lo que uno que no compile se rechazará al arrancar en lugar de convertirse silenciosamente en ninguna regla
matchesMessage string Lo que muestra el formulario cuando matches falla
trim boolean Elimina los espacios en blanco iniciales y finales antes de guardar. Es una transformación, no una comprobación: cambia lo que se escribe, lo que la convierte en la solución para “la misma etiqueta dos veces, una con un espacio al final”. Solo en el formulario de administración; no lo impone la API ni la base de datos.
lowercase / uppercase boolean Convierte a minúsculas/mayúsculas el valor antes de guardar, igual que trim. Solo en el formulario de administración; no lo impone la API ni la base de datos.

Los formatos de correo electrónico (email) y URL no son reglas de validación. email y url son flags en la propiedad misma, junto a type: declaraciones sobre los datos a partir de las cuales se genera el contrato OpenAPI, en lugar del comportamiento del formulario:

properties: {
email: { type: "string", name: "Email", email: true },
website: { type: "string", name: "Website", url: true }
}

Consulta Propiedades de string.

Regla Tipo Descripción
min / max number Valor mínimo / máximo aceptado, inclusivo
moreThan / lessThan number Las contrapartes exclusivas de min y max
positive / negative boolean Estrictamente mayor / menor que cero. 0 es rechazado por ambos; usa min: 0 para permitirlo
integer boolean Sin parte fraccionaria. No cambia el tipo de columna; columnType sí lo hace
Regla Tipo Descripción
min / max Date Fecha más temprana / más tardía aceptada, inclusivo. Un instante fijo, no “hoy”
Regla Tipo Descripción
min / max number Mínimo / máximo de elementos, inclusivo. Elementos, no caracteres

Puedes hacer que los campos sean dinámicos para que reaccionen a los valores de la entidad. Hay dos formas de hacer esto:

Puedes utilizar la propiedad conditions para definir reglas declarativas de JSON Logic que pueden ser serializadas y modificadas visualmente en el editor de colecciones.

price: {
type: "number",
name: "Price",
conditions: {
disabled: { "==": [{ "var": "values.is_free" }, true] },
required: { "!=": [{ "var": "values.is_free" }, true] },
min: 0,
clearOnDisabled: true // Set to null if field gets disabled
}
}

El objeto de condiciones te da acceso a:

  • disabled, disabledMessage, clearOnDisabled, hidden, readOnly
  • required, requiredMessage, min, max
  • defaultValue
  • enumConditions, allowedEnumValues, excludedEnumValues
  • referencePath, referenceFilter
  • canAddElements, sortable (para arrays)
  • acceptedFiles, maxFileSize (para subidas de archivos)

disabledMessage es la frase que el usuario ve en lugar del control. Sin ella, un campo deshabilitado no explica nada, lo cual marca la diferencia entre un formulario que guía a alguien y uno que simplemente lo rechaza.

Para comportamientos complejos que no se pueden expresar mediante JSON Logic, puedes utilizar dynamicProps, que evalúa una función de Javascript.

price: {
type: "number",
name: "Price",
dynamicProps: ({ values, authController }) => ({
admin: { disabled: values.is_free === true || !authController.user?.roles?.includes("admin") },
validation: values.is_free ? {} : { required: true, min: 0 }
})
}

Se aplica la misma advertencia, y de forma más estricta: la función se empaqueta en el panel y se ejecuta en cada renderizado del formulario. Solo en el formulario de administración; no lo impone la API ni la base de datos.