Skip to content

v0.13.0

Latest

Choose a tag to compare

@github-actions github-actions released this 09 Jun 16:22
Immutable release. Only release title and notes can be modified.
a3904ac

v0.13.0

This release makes namespaces a first-class part of the query surface, adds cross-contract foreign keys to the SQL ORM, makes many-to-many a validatable contract shape, introduces a per-object control policy (@@control) that decides what Prisma manages, ships domain enums backed by storage value-sets, and gives the migration CLI a unified graph-tree view across list / log / status / show. Telemetry also flips from opt-in to opt-out. A few changes require a one-time contract re-emit — all are covered by the linked upgrade recipes.

Breaking changes

  • Telemetry is now opt-out — anonymous CLI telemetry is collected by default and you opt out, where previously you opted in. Set PRISMA_NEXT_DISABLE_TELEMETRY=1 (or DO_NOT_TRACK=1) to turn it off. See docs/Telemetry.md for what is collected and every opt-out signal. (#676)

  • MTI variant tables materialize a base-PK link column — a PSL @@base(Parent, "tag") variant that carries its own @@map (and is therefore stored in its own table) now emits a base-PK link column in storage: the variant table gains a copy of the base table's primary-key column(s), a primary key over them, and a cascading foreign key (ON DELETE CASCADE) referencing the base table's primary key. Previously the variant table held only the variant-specific columns with no primary key and no link to its base. This changes the emitted contract.json / contract.d.ts and the contract's storageHash. Re-emit your contract, then plan and apply the matching migration. Variants that share the base table (no own @@map) are unaffected. See the 0.12→0.13 upgrade recipe. (#669)

    Before (emitted contract.json, variant table bug):

    "bug": {
      "columns": {
        "severity": { "codecId": "pg/text@1", "nullable": false }
      }
    }

    After:

    "bug": {
      "columns": {
        "id": { "codecId": "sql/char@1", "nullable": false },
        "severity": { "codecId": "pg/text@1", "nullable": false }
      },
      "primaryKey": { "columns": ["id"] },
      "foreignKeys": [
        {
          "name": "bug_id_fkey",
          "columns": ["id"],
          "references": { "table": "task", "columns": ["id"] },
          "onDelete": "cascade"
        }
      ]
    }
  • Contract storage IR moved to a namespace envelope — the SQL/Mongo storage IR is now keyed by namespace (storage.namespaces.<ns>.entries.<kind>), and cross-references are explicit { namespace, model } objects in domain. Consumer impact is mechanical: re-emit with prisma-next contract emit to pick up the new shape. No codemod or source change is required, but the contract's storageHash changes, so plan and apply a migration afterward. (#715)

  • Extension authors: codec-resolution SPI takes a leading namespaceIdCodecDescriptorRegistry.codecRefForColumn(table, column) is now codecRefForColumn(namespaceId, table, column), and the free codecRefForStorageColumn(storage, table, column) is now codecRefForStorageColumn(storage, namespaceId, table, column) (both in @prisma-next/sql-relational-core). Thread the namespace the table lives in through every call site that stamps codec onto AST nodes. There is no codemod — the right namespace is call-site-specific. See the 0.12→0.13 extension-author recipe. (#715)

    Before:

    const ref = descriptors.codecRefForColumn('document', 'embedding');

    After:

    const ref = descriptors.codecRefForColumn('public', 'document', 'embedding');
  • Extension authors: empty typeParams stripped from storage.types — the canonicalizer now omits typeParams from storage.types entries when it is an empty object (e.g. a types { Uuid = String @db.Uuid } named-type alias). Runtime behaviour is unchanged, but the emitted contract.json and its storageHash differ. If your extension shipped a contract.json with "typeParams": {}, re-emit and re-pin your migration baselines. See the 0.12→0.13 extension-author recipe. (#753)

Features

  • Namespace-aware DSL/ORM surface — the typed query and ORM surface now exposes namespaced accessors so models in different namespaces are addressed explicitly and two same-named tables in different namespaces no longer collide. Additive — existing single-namespace code is unchanged. (#720)

  • Many-to-many is now a validatable contract shapeN:M relations carrying a through junction descriptor are now a first-class, validatable part of the contract (they previously failed validation). The ORM runtime surface for M:N — .include() across the junction, some/every/none filters, and junction writes — is not wired up yet and lands in a follow-up release; nested M:N mutations currently throw. (#669, #678)

  • Cross-contract foreign keys — a relation field can reference a model owned by another contract space (e.g. supabase:auth.AuthUser), with named-type aliases (types { Uuid = String @db.Uuid }) for database-native column types. The planner and verifier resolve the cross-space reference and emit the foreign key, including cascading deletes. See the 0.12→0.13 upgrade recipe for the authoring pattern. (#745, #752, #756, #765)

    types {
      Uuid = String @db.Uuid
    }
    
    namespace public {
      model Profile {
        id       String @id @default(uuid())
        username String
        userId   Uuid   @unique
        user     supabase:auth.AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
        @@map("profile")
      }
    }
  • Per-object control policy (@@control) — a model or other contract object can declare whether Prisma manages its schema, and a contract can set a defaultControlPolicy. Migration DDL generation and schema verification react to each object's policy, so you can keep externally-owned objects out of Prisma's managed surface. (#717, #711)

  • Domain enums with storage value-sets — enums are now a domain concept backed by storage value-sets. On Postgres, enum blocks lower to a native enum type (CREATE TYPE … AS ENUM); SQL targets without native enum support approximate the allowed values with check constraints. (#750, #755)

  • Unified migration graph view in the CLImigration list, log, status, and show now render the migration history as a consistent graph tree with colored lanes, a --legend, and one schema-locked --json shape across the read commands. migrate --show previews the migration path read-only before you apply it. (#706, #704, #705, #735, #741, #767)

  • Readable per-migration ledger — the migration apply ledger is now a per-migration journal, read back as one flat chronological table by migration log. (#665, #704)

  • db.transaction() on the SQLite facade@prisma-next/sqlite gains a facade-level transaction API (db.transaction(async (tx) => …)), mirroring the Postgres facade. (#737)

  • Declarative SPI for extension-contributed PSL blocks — extensions can declare top-level PSL blocks declaratively, and contract infer round-trips them through a generic PSL printer. (#753, #754, #757)

  • @prisma-next/extension-supabase — a new extension package and an examples/supabase walking skeleton that wires a cross-contract foreign key from an app model to Supabase's auth schema. (#746, #765)

  • STI variants can declare their own fields — a PSL @@base(Parent, "tag") variant with no own @@map (single-table inheritance) may now declare its own scalar fields. Each is materialized as a (nullable) column on the shared base table, and the variant no longer emits a stray shadow table. Previously such a contract failed to emit with references non-existent column. Existing contracts re-emit identically. (#669)

  • Backward cursor paginationOrderByItem.reverse() flips an order-by direction for fetching the previous page. (#671)

  • Postgres JSON defaults emit a ::jsonb / ::json cast — JSON column defaults now carry the explicit cast in generated DDL. (#763)

Fixes

  • Constraintless foreign keys are skipped in offline schema projection. (#744)
  • Storage-sort comparison is now collation-independent. (#721)