Ir al contenido

Actualizar de 0.17 a 0.18

0.18.0 ya está publicada. Son las entradas ### Breaking de su sección del changelog, una a una, con lo que cada una te pide cambiar. En 0.x la versión menor es la que rompe, así que este es el muro entre 0.17.3 y 0.18.0: léelo antes de actualizar, no después.

Todos son un error de compilación o un arranque rechazado, y no un cambio silencioso de comportamiento, salvo el último, que reescribe una restricción que el próximo db push planificará por ti.


Eran tres sobrecargas —Postgres, Firestore, MongoDB— y una llamada que fallaba producía un único diagnóstico sobre defineCollection(, con el primer fallo de cada sobrecarga. Ahora hay una sola firma, discriminada por engine (Postgres cuando falta), y los errores se reportan sobre la clave equivocada, todos a la vez.

Qué cambiar: nada, en una llamada que ya compilaba. Lo que cambia es dónde cae el subrayado rojo. Dos exports de tipos se movieron con ello: UnknownPropertyKey ahora es NoSuchKey (y lleva un miembro didYouMean), y PropertyTypeNotOnThisEngine es nuevo. Ambos son maquinaria interna del constructor, así que solo el código que importaba el nombre antiguo tiene algo que editar.

21. defineCollection sigue comprobando tras la primera propiedad errónea

Sección titulada «21. defineCollection sigue comprobando tras la primera propiedad errónea»

El constructor restringía su mapa de propiedades, y una restricción que TypeScript no puede satisfacer es una de la que retrocede en silencio: así, un solo defaultValue incorrecto ensanchaba la entidad inferida a Record<string, unknown> y desactivaba todas las comprobaciones sobre display.title, listProperties, propertiesOrder y previewProperties.

Qué cambiar: nada que escribir, pero espera errores nuevos en archivos de colección que antes compilaban. Ya estaban mal entonces; el compilador había dejado de mirar. Corrige la propiedad que nombra el primer error y vuelve a compilar: el resto de ese archivo se está comprobando por primera vez.

22. El campo de enlace de una relación debe pertenecer a su kind

Sección titulada «22. El campo de enlace de una relación debe pertenecer a su kind»

Relation es una unión cerrada desde 0.11 —belongsTo es dueño de localKey, hasOne/hasMany de foreignKeyOnTarget, manyToMany de through, via de joinPath—, pero la comprobación de propiedades sobrantes se ejecutaba contra la unión entera, así que { kind: "belongsTo", foreignKeyOnTarget: "author_id" } compilaba y luego se resolvía a un enlace distinto del que se había escrito.

Qué cambiar: escribe el campo de enlace que corresponde a esa clase de relación.

author: {
type: "relation",
relation: { kind: "belongsTo", foreignKeyOnTarget: "author_id", target: () => authors }
relation: { kind: "belongsTo", localKey: "author_id", target: () => authors }
}

El validador de arranque ya rechazaba esto, así que el aviso pasa de un despliegue fallido a un error de compilación. Si tu proyecto arranca hoy, compila hoy.

23. La validation de una relación sube a la propiedad

Sección titulada «23. La validation de una relación sube a la propiedad»

RelationBase.validation y ResolvedRelationBase.validation se han eliminado. Había dos sitios donde escribir required y dos generadores que leían uno distinto: el DDL consultaba la propiedad (así que la columna salía NOT NULL) mientras que el generador de tipos del SDK consultaba la relación (así que el tipo Insert generado hacía opcional el campo), y un create() que omitía la relación pasaba la comprobación de tipos y luego fallaba en la base de datos.

Qué cambiar: súbela un nivel, junto a la de cualquier otro campo.

author: {
type: "relation",
validation: { required: true },
relation: { kind: "belongsTo", validation: { required: true }, target: () => authors }
relation: { kind: "belongsTo", target: () => authors }
}

El arranque rechaza la clave antigua por su nombre en lugar de ignorarla. El código que preguntaba a una relación si era obligatoria ahora usa import { isRelationRequired, relationDeclaringProperty } from "@rebasepro/common".

24. Un belongsTo obligatorio borra con RESTRICT, no con CASCADE

Sección titulada «24. Un belongsTo obligatorio borra con RESTRICT, no con CASCADE»

validation: { required: true } dice que el hijo no puede existir sin un padre. No dice que borrar al padre deba borrar al hijo, pero eso es lo que inferaba el generador, de modo que cada DELETE FROM authors cascadeaba por los posts, sus comentarios y todo lo que colgaba de ellos. Ahora el valor por defecto es RESTRICT: el borrado falla y nombra la restricción. Las relaciones opcionales no cambian (SET NULL), ni tampoco una tabla de unión manyToMany (CASCADE: la fila que borra es el enlace).

Esto es un cambio de DDL. El próximo rebase db push planifica un DROP CONSTRAINT / ADD CONSTRAINT para cada relación obligatoria que nunca declaró un onDelete, y después los borrados del padre empiezan a fallar donde antes cascadeaban.

Qué cambiar: si quieres conservar el comportamiento anterior, escríbelo.

relation: { kind: "belongsTo", target: () => authors }
relation: { kind: "belongsTo", onDelete: "cascade", target: () => authors }

Revisa el plan antes de aplicarlo — rebase db push imprime las sentencias.

En 0.17.3 todos los paquetes publicados declaraban >=20 —@rebasepro/cli no declaraba engines en absoluto— y en main todos declaran >=22.22.0. La única fuente es el .nvmrc del repositorio.

Qué cambiar: pásate a Node 22.22.0 antes de actualizar. pnpm install responde a un desajuste de engines con [WARN] Unsupported engine e instala igualmente, así que el fallo no llega al instalar: llega más tarde, en un sitio donde no se menciona Node.

26. rebase.data ya no existe en tiempo de ejecución

Sección titulada «26. rebase.data ya no existe en tiempo de ejecución»

RebaseServerClient quitó data de su tipo para que el código de servidor tenga que decir bajo qué identidad corre una lectura, y la propiedad quedó luego en el objeto como alias en tiempo de ejecución. Ahora se borra en el arranque: rebase.data es undefined.

Qué cambiar: en el código de servidor —funciones, crons, callbacks— escribe rebase.dataAsAdmin donde quieras el plano de administración y context.data donde quieras el del llamante. El código tipado ya recibía el error desde que cambió el tipo; lo que se rompe ahora es el código sin tipos, y el ai-instructions.md de un scaffold que todavía le dice a un asistente que use rebase.data.<slug> —rebase init reescribe ese archivo, así que regéneralo o corrige la regla a mano—. El código de navegador no cambia: rebase.data en el SDK tipado es el plano del usuario y se queda.

src/index.ts reexportaba dieciséis módulos y ponía 95 nombres en npm. Ahora exporta entry, manifest y bundle.

Qué cambiar: nada, salvo que importes de @rebasepro/cli —cosa improbable, porque no lo hacía ni este repositorio ni el plano de control—. Si lo haces: la CLI es un binario. Llama a rebase <command> como proceso en lugar de importar sus funciones de comando, cuyas firmas nunca fueron un contrato.

ui, forms, firebase, plugin-insights y cms-types declaraban react >=19.0.0, un rango cuya mitad inferior no puede satisfacer a app y cms en 19.2.7: un instalador que eligiera 19.0.0 producía un árbol que resolvía limpio y rompía al renderizar. Los cinco dicen ^19.2.7. El peer typescript de @rebasepro/app pasa de >=5.0.0 a ^6.0.0.

Qué cambiar: estar en React 19.2.7 o posterior, y en TypeScript 6 si usas el plugin de Vite de @rebasepro/app. Si tu instalación resolvía React 19.0.x, verás un aviso de peer hasta que subas; ese aviso es el árbol que ya estabas ejecutando, dicho en voz alta.

29. rebase cloud webhooks create toma --endpoint

Sección titulada «29. rebase cloud webhooks create toma --endpoint»

--url nombra el plano de control en toda esta familia de comandos, así que el segundo --url que este declaraba para el endpoint del cliente nunca podía ganar: el ejemplo documentado enviaba la URL del webhook al cliente como el host contra el que autenticarse.

Qué cambiar: rebase cloud webhooks create --endpoint https://… en cualquier script que cree uno. La grafía antigua no podía funcionar, así que no hay comportamiento que preservar: solo líneas que corregir.

El codificador de hojas compartido parsea con manga ancha, porque un código corto llega por el cable, y emite estricto, porque quien se lo pasa al serializador ha construido la condición a mano. serializeFilter({ a: ["gt", 5] }) lanza en vez de devolver gte.

Qué cambiar: solo si llamas directamente a los serializadores de @rebasepro/common. Usa los nombres de operador que declaran los tipos (>, >=, <, <=, …) en lugar de los códigos cortos de REST (gt, gte, …). Los constructores de consultas y el SDK ya los escribían así; lo nuevo es que la grafía equivocada ahora lo dice.


Siguiente: la lista de verificación de actualización · 0.14 → 0.17, el salto previo a este · Changelog, las notas de la versión que estas secciones resumen.