Skip to content

Version Packages (alpha) - #2145

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

⚠️⚠️⚠️⚠️⚠️⚠️

main is currently in pre mode so this branch has prereleases rather than normal releases. If you want to exit prereleases, run changeset pre exit on main.

⚠️⚠️⚠️⚠️⚠️⚠️

Releases

@opensaas/stack-auth@0.44.0-alpha.6

Minor Changes

  • #2201 0933b4b Thanks @dependabot! - Upgrade to Prisma ORM 8.0.0-rc.22 and the prisma CLI to 8.0.0-rc.30

    The stack's date and time columns are unchanged: timestamp() and calendarDay() keep reading and writing ISO strings, and contract.json is byte-identical. Prisma ORM now refuses to run from two installed copies, so every @prisma/orm-* package and the prisma CLI must move together:

    {
      "dependencies": { "@prisma/orm-postgres": "8.0.0-rc.22" },
      "devDependencies": { "prisma": "8.0.0-rc.30" }
    }

    Then run pnpm generate and commit what it writes. A project using ragPlugin or another pgvector declaration gets a new head for migrations/pgvector/: run prisma db migrate on each database to move the pack's marker.

Patch Changes

  • #2144 8bbaeae Thanks @borisno2! - Auth adapter update and incrementOne now throw AuthWhereError on an empty where instead of silently no-oping (completes #1980).

@opensaas/stack-cli@0.44.0-alpha.6

Minor Changes

  • #2201 0933b4b Thanks @dependabot! - Upgrade to Prisma ORM 8.0.0-rc.22 and the prisma CLI to 8.0.0-rc.30

    The stack's date and time columns are unchanged: timestamp() and calendarDay() keep reading and writing ISO strings, and contract.json is byte-identical. Prisma ORM now refuses to run from two installed copies, so every @prisma/orm-* package and the prisma CLI must move together:

    {
      "dependencies": { "@prisma/orm-postgres": "8.0.0-rc.22" },
      "devDependencies": { "prisma": "8.0.0-rc.30" }
    }

    Then run pnpm generate and commit what it writes. A project using ragPlugin or another pgvector declaration gets a new head for migrations/pgvector/: run prisma db migrate on each database to move the pack's marker.

Patch Changes

  • #2142 bb87f3b Thanks @borisno2! - Fix the dev loop reading accessWidening instead of the accessChanges the Prisma CLI reports, so access changes now count as destructive and reach the plan id and --allow.

  • #2196 80c9ac0 Thanks @borisno2! - Fix opensaas dev freezing on stale config after a failed load; db update --plan <id> now refuses a plan the current config no longer wants.

  • #2205 dec240b Thanks @borisno2! - Render the admin's Sign Out control only with an onSignOut handler, instead of a button that only redirected, warn the user if the handler rejects, and reload an admin page restored from the back-forward cache.
    The feature generator now emits signOutAction and tells you to pass it as onSignOut.

  • #2209 4a8b631 Thanks @borisno2! - Fix opensaas generate failing with "gen is not defined" when a config uses the cuid id strategy and no list uses uuid7, cuid2 or updatedAt

  • #2146 28650ed Thanks @borisno2! - opensaas generate now refuses to write live artifacts while an opensaas dev loop is running for the project, so a parked destructive change is no longer promoted over the loop's database.

  • Updated dependencies [eaeee36, 0933b4b, 357f9bb, ddb9e8c, 0dd7eb4, 4a8b631, fa03c43, a854243, af04b65, ca51e67]:

    • @opensaas/stack-core@0.44.0-alpha.6

@opensaas/stack-core@0.44.0-alpha.6

Minor Changes

  • #2201 0933b4b Thanks @dependabot! - Upgrade to Prisma ORM 8.0.0-rc.22 and the prisma CLI to 8.0.0-rc.30

    The stack's date and time columns are unchanged: timestamp() and calendarDay() keep reading and writing ISO strings, and contract.json is byte-identical. Prisma ORM now refuses to run from two installed copies, so every @prisma/orm-* package and the prisma CLI must move together:

    {
      "dependencies": { "@prisma/orm-postgres": "8.0.0-rc.22" },
      "devDependencies": { "prisma": "8.0.0-rc.30" }
    }

    Then run pnpm generate and commit what it writes. A project using ragPlugin or another pgvector declaration gets a new head for migrations/pgvector/: run prisma db migrate on each database to move the pack's marker.

  • #2232 fa03c43 Thanks @borisno2! - A field's read rule now denies when it reaches for a relation the row does not carry, closing a count, a combine of counts or an absent relation making a rule fail open.

    This changes what rules see. A relation the read did not deliver whole — not included, narrowed by the caller with where, limit, offset, orderBy, select or a nested include, or reduced to counts with no rows — is withheld, and reading it denies that rule. A foreign key's rule takes the same decision on the same rows as every other rule on the row.

    const notes = relationship({
      ref: 'Note.ticket',
      many: true,
      access: { read: ({ item }) => !item.notes?.some((note) => note.private) },
    })
    
    await context.db.Ticket.include('notes').all() // decides on the rows, as before
    await context.db.Ticket.include('notes', (rows) => rows.count()).all() // denies, and used to pass
    await context.db.Ticket.include('notes', (rows) => rows.limit(10)).all() // denies, and used to pass
    • A rule that throws the TypeError of reading it, like item.logs.length, denies rather than failing the read, so the admin item view renders where it showed "Item not found". The section says it can't be shown, and the list view shows no count, rather than a false empty or 0.
    • An included to-one the related list's access left out is withheld, not null, so !item.owner?.banned no longer grants under include('owner'). null on a to-one with no foreign key set is a real answer. The inverse side of a one-to-one has no column to tell the two apart, so a rule reading it denies whenever the related list's access can leave a row out, even where there is no row. Rules that never read a relation, like an ownership check, are unaffected.
    • A rule that catches a throw from item is now row-dependent, so select and where can no longer open it.
    • A rule that enumerates or spreads item denies on a row withholding any relation, and a rule that writes through item denies and changes nothing. Use toSorted() rather than sort() on a relation.
    • Everything a rule can see of a related list is what the session can see, so never grant on an absence there. Grant on a row the session can see, or keep the fact in a column on the row that only rises. See "What a read rule sees" in the access control docs and ADR-0082.

Patch Changes

  • #2217 eaeee36 Thanks @borisno2! - Fix create, update and delete throwing or returning a wrong value on a list whose computed field declares a relation in needs; a write now returns that field exactly as first() does.

  • #2218 357f9bb Thanks @borisno2! - Fix optional JSON, select and text admin fields not clearing to null; json() now refuses a null for a NOT NULL column with an error on the field.
    A hook on an optional text field now receives null, not '', when it's emptied in the admin, so an === '' check no longer fires. Guard with typeof value === 'string', not ?., which turns null into undefined and silently drops the write.

  • #2195 ddb9e8c Thanks @borisno2! - Root update locks FOR NO KEY UPDATE, fixing the deadlock between racers that insert a child and update its parent.
    A transaction that then needs FOR UPDATE on that row, or changes a column in a unique index, can now deadlock with a racer holding its foreign-key lock (ADR-0078).

  • #2208 0dd7eb4 Thanks @borisno2! - Fix a caller-shaped combine() rows branch, or an MCP count beside take: 0, bypassing a relationship's own read rule and revealing the count.
    A combine() with a rows branch now strips as the plain include does.

  • #2209 4a8b631 Thanks @borisno2! - Fix opensaas generate failing with "gen is not defined" when a config uses the cuid id strategy and no list uses uuid7, cuid2 or updatedAt

  • #2143 a854243 Thanks @borisno2! - MCP where relation predicates into a list with mcp.enabled: false, mcp.tools.read: false or denied query access are now refused as an unknown key.

  • #2211 af04b65 Thanks @borisno2! - Fix admin lists emptying on a sort the column cannot take: sorting now follows the ORM's own order answer per column, and orderBy refuses a virtual or multi-column field as a ValidationError.
    A failed list read now shows an error state rather than the first-run empty state.

  • #2239 ca51e67 Thanks @borisno2! - An update/delete operation rule and a field update rule that reach for a relation the write did not deliver now deny instead of reading absence as permission (#2233). A rule that enumerates item (spread, Object.keys) on a list with a relationship denies too.

@opensaas/stack-rag@0.44.0-alpha.6

Minor Changes

  • #2201 0933b4b Thanks @dependabot! - Upgrade to Prisma ORM 8.0.0-rc.22 and the prisma CLI to 8.0.0-rc.30

    The stack's date and time columns are unchanged: timestamp() and calendarDay() keep reading and writing ISO strings, and contract.json is byte-identical. Prisma ORM now refuses to run from two installed copies, so every @prisma/orm-* package and the prisma CLI must move together:

    {
      "dependencies": { "@prisma/orm-postgres": "8.0.0-rc.22" },
      "devDependencies": { "prisma": "8.0.0-rc.30" }
    }

    Then run pnpm generate and commit what it writes. A project using ragPlugin or another pgvector declaration gets a new head for migrations/pgvector/: run prisma db migrate on each database to move the pack's marker.

@opensaas/stack-tiptap@0.44.0-alpha.6

Minor Changes

  • #2222 97a9e88 Thanks @borisno2! - The admin now works by keyboard: relationship pickers are ARIA comboboxes, sort headers are buttons, every control is named, and a failed submit focuses the first error.

    FieldRenderer passes each field an id that is unique to the form, so a create drawer and the form under it can share a field name. A built-in field's control no longer has id equal to name, so a host's #title selector or <label htmlFor="title"> stops matching it. name is unchanged, so select with [name="title"].

    A custom field should use id for its control, and tie its error and help text with the new helpers from @opensaas/stack-ui/fields. After a failed submit the form focuses the control marked aria-invalid:

    import {
      FieldError,
      FieldHelp,
      FieldLabel,
      FieldRoot,
      describeField,
      fieldErrorId,
      fieldHelpId,
    } from '@opensaas/stack-ui/fields'
    
    export function ColorField({ name, id = name, label, value, onChange, error, helpText }) {
      return (
        <FieldRoot>
          <FieldLabel htmlFor={id}>{label}</FieldLabel>
          <input
            id={id}
            name={name}
            value={value ?? ''}
            onChange={(e) => onChange(e.target.value)}
            {...describeField(id, { error, helpText })}
          />
          {helpText && <FieldHelp id={fieldHelpId(id)}>{helpText}</FieldHelp>}
          {error && <FieldError id={fieldErrorId(id)}>{error}</FieldError>}
        </FieldRoot>
      )
    }

    Also new: fieldLabelId and fieldValueId for a button control named by its label and shown value, TableSortButton from @opensaas/stack-ui/primitives, and disabled and auxiliary on ComboboxItem. ComboboxEmpty is now a status line to keep mounted beside ComboboxList, passing null when there is nothing to say.

    File and image fields holding a file now show a Replace control, which carries the field's label and error. The Radix dialog, popover and select packages are pinned exactly so they share one focus and dismiss stack, which is what lets a picker or date popover work inside a drawer.

Patch Changes

  • #2202 bd03766 Thanks @dependabot! - Move every @tiptap/* dependency to ^3.32.2 together, so the package resolves a single @tiptap/core and its editor commands type-check

@opensaas/stack-ui@0.44.0-alpha.6

Minor Changes

  • #2201 0933b4b Thanks @dependabot! - Upgrade to Prisma ORM 8.0.0-rc.22 and the prisma CLI to 8.0.0-rc.30

    The stack's date and time columns are unchanged: timestamp() and calendarDay() keep reading and writing ISO strings, and contract.json is byte-identical. Prisma ORM now refuses to run from two installed copies, so every @prisma/orm-* package and the prisma CLI must move together:

    {
      "dependencies": { "@prisma/orm-postgres": "8.0.0-rc.22" },
      "devDependencies": { "prisma": "8.0.0-rc.30" }
    }

    Then run pnpm generate and commit what it writes. A project using ragPlugin or another pgvector declaration gets a new head for migrations/pgvector/: run prisma db migrate on each database to move the pack's marker.

  • #2232 fa03c43 Thanks @borisno2! - An unknown relationship count no longer reads as zero: the list view renders no number for a relation a rule withholds, and the item page says the section can't be shown rather than "No related rows yet".

    RelationshipTableClient takes an unavailable prop for that state.

  • #2212 bea32ad Thanks @borisno2! - Item forms refuse to submit while a field holds input it can't commit, and focus the first invalid field

    JSON, decimal and bigInt fields holding text that doesn't parse, and a password that isn't confirmed, now stop the submit with nothing written. A third-party field can do the same with the new useFieldValidity hook, and shows its own error:

    import { useRef, useState } from 'react'
    import { FieldError, useFieldValidity } from '@opensaas/stack-ui/fields'
    
    export function HexColorField({ name, value, onChange, mode = 'edit' }) {
      const inputRef = useRef<HTMLInputElement>(null)
      const [text, setText] = useState(value ?? '')
      const isInvalid = text !== '' && !/^#[0-9a-f]{6}$/i.test(text)
    
      useFieldValidity(name, mode === 'edit' && isInvalid, inputRef)
    
      // render the input with ref={inputRef}, and <FieldError> while isInvalid
    }

    The hook is optional, so existing fields need no change.

  • #2222 97a9e88 Thanks @borisno2! - The admin now works by keyboard: relationship pickers are ARIA comboboxes, sort headers are buttons, every control is named, and a failed submit focuses the first error.

    FieldRenderer passes each field an id that is unique to the form, so a create drawer and the form under it can share a field name. A built-in field's control no longer has id equal to name, so a host's #title selector or <label htmlFor="title"> stops matching it. name is unchanged, so select with [name="title"].

    A custom field should use id for its control, and tie its error and help text with the new helpers from @opensaas/stack-ui/fields. After a failed submit the form focuses the control marked aria-invalid:

    import {
      FieldError,
      FieldHelp,
      FieldLabel,
      FieldRoot,
      describeField,
      fieldErrorId,
      fieldHelpId,
    } from '@opensaas/stack-ui/fields'
    
    export function ColorField({ name, id = name, label, value, onChange, error, helpText }) {
      return (
        <FieldRoot>
          <FieldLabel htmlFor={id}>{label}</FieldLabel>
          <input
            id={id}
            name={name}
            value={value ?? ''}
            onChange={(e) => onChange(e.target.value)}
            {...describeField(id, { error, helpText })}
          />
          {helpText && <FieldHelp id={fieldHelpId(id)}>{helpText}</FieldHelp>}
          {error && <FieldError id={fieldErrorId(id)}>{error}</FieldError>}
        </FieldRoot>
      )
    }

    Also new: fieldLabelId and fieldValueId for a button control named by its label and shown value, TableSortButton from @opensaas/stack-ui/primitives, and disabled and auxiliary on ComboboxItem. ComboboxEmpty is now a status line to keep mounted beside ComboboxList, passing null when there is nothing to say.

    File and image fields holding a file now show a Replace control, which carries the field's label and error. The Radix dialog, popover and select packages are pinned exactly so they share one focus and dismiss stack, which is what lets a picker or date popover work inside a drawer.

  • #2259 f2af7cb Thanks @borisno2! - Refresh the admin list table: a column picker, density, page sizes, a toolbar sort control and cards on phones

    • ?columns=title,status,views sets the visible columns, in order. The toolbar's Columns menu writes it. ListView resolves it on the server (new visibleColumns prop, which AdminUI fills from the URL), so a to-many count in an added column is read and correct. Unknown names are ignored, a column initialColumns names is accepted even outside the list's fields, and Field Visibility still applies. A pick that lands back on the default set drops ?columns=.
    • Density is comfortable or compact, remembered in this browser under opensaas-list-density (DENSITY_STORAGE_KEY) like the theme choice, and rendered comfortable on the server. When this browser refuses to store a choice (private mode, quota, blocked site data), the density and theme choices still apply for the page.
    • Rows per page offers 25, 50 and 100 once there are more than 25 rows, and shows a ?pageSize= outside those as its own pressed option. The default stays 50 and the ?pageSize= cap stays 200.
    • A toolbar Sort menu sits beside header sorting. Sort stays single-column; relationship columns stay unsortable.
    • Below md, rows render as labelled cards with no sideways scrolling. This replaces the sticky Actions column in the list view.
    • New DropdownMenu primitive on @radix-ui/react-dropdown-menu, exported from @opensaas/stack-ui/primitives.
    import {
      DropdownMenu,
      DropdownMenuTrigger,
      DropdownMenuContent,
      DropdownMenuCheckboxItem,
    } from '@opensaas/stack-ui/primitives'
    
    ;<DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline">View</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuCheckboxItem checked={showDrafts} onCheckedChange={setShowDrafts}>
          Show drafts
        </DropdownMenuCheckboxItem>
      </DropdownMenuContent>
    </DropdownMenu>

    ListView gains urlControls, which AdminUI sets: it says the page reads ?columns= and ?pageSize= back, and without it ListView offers neither control. ListViewClient gains availableColumns, defaultColumns, columnsChosen and pageSizeControl; the Columns menu renders only when availableColumns is supplied, and the rows-per-page control only when pageSizeControl is set. New slots: list-view-toolbar, list-view-sort, list-view-columns, list-view-density, list-view-table (with data-density), list-view-pagination, list-view-page-size, and dropdown-menu-* on the primitive's rendered parts.

Patch Changes

  • #2218 357f9bb Thanks @borisno2! - Fix optional JSON, select and text admin fields not clearing to null; json() now refuses a null for a NOT NULL column with an error on the field.
    A hook on an optional text field now receives null, not '', when it's emptied in the admin, so an === '' check no longer fires. Guard with typeof value === 'string', not ?., which turns null into undefined and silently drops the write.

  • #2238 2ae9247 Thanks @borisno2! - Fix the singleton editor showing a set to-one relationship as empty, and stop logging an error for a singleton with a required field and no row yet.

  • #2205 dec240b Thanks @borisno2! - Render the admin's Sign Out control only with an onSignOut handler, instead of a button that only redirected, warn the user if the handler rejects, and reload an admin page restored from the back-forward cache.
    The feature generator now emits signOutAction and tells you to pass it as onSignOut.

  • #2219 9a87cfa Thanks @borisno2! - Make the admin usable at phone width: below md the sidebar moves to a drawer behind a menu button and main takes the full width.
    loading.tsx should now render the new AdminLoading, which shares that frame.

  • #2230 ad45bd0 Thanks @borisno2! - Item forms set noValidate and read the browser's constraint check themselves, so a failed submit focuses the first error, with its message on the field.

  • #2211 af04b65 Thanks @borisno2! - Fix admin lists emptying on a sort the column cannot take: sorting now follows the ORM's own order answer per column, and orderBy refuses a virtual or multi-column field as a ValidationError.
    A failed list read now shows an error state rather than the first-run empty state.

  • #2231 5177197 Thanks @borisno2! - Fix date pickers showing every date one column right of its weekday: the calendar's weeks now start on Monday and its header is derived from the grid.

  • #2237 75c6df4 Thanks @borisno2! - A successful save through a redirecting server action no longer shows "NEXT_REDIRECT" as an error (fixes #2227).

create-opensaas-app@0.4.0-alpha.4

Patch Changes

@opensaas/stack-storage@0.44.0-alpha.6

Patch Changes

  • #2141 2f287d5 Thanks @borisno2! - Refuse whitespace and control characters in stored file/image urls, closing "/\t/host" resolving to another host.

  • #2198 1a6333f Thanks @borisno2! - Fix stored XSS where a malformed declared type such as text/html x passed the active-content check; one strict parser now serves the check and the stored extension, and a malformed or browser-sniffed type (unknown/unknown, application/unknown, */*) is stored as application/octet-stream.
    text/xsl and the remaining WHATWG JavaScript essences are now refused by default, and isActiveMimeType returns true for a non-empty type that is not a usable essence.

@opensaas/stack-storage-s3@0.44.0-alpha.6

No changes in this release.

@opensaas/stack-storage-vercel@0.44.0-alpha.6

No changes in this release.

@vercel

vercel Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
stack-docs Ready Ready Preview Nov 7, 2026 1:16pm UTC

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 3 times, most recently from 3235ebc to f2a5c73 Compare November 5, 2026 01:17
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from f2a5c73 to 9e9fb1b Compare November 5, 2026 01:46
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 9e9fb1b to a14f943 Compare November 5, 2026 09:35
@github-actions
github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from d34a54d to 9709db4 Compare November 5, 2026 10:26
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 9709db4 to 738b8f9 Compare November 5, 2026 10:28
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 738b8f9 to d6c5433 Compare November 5, 2026 10:42
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from d6c5433 to 5d8ef4e Compare November 5, 2026 11:15
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 5d8ef4e to b870e72 Compare November 5, 2026 11:20
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from b870e72 to 69347a5 Compare November 5, 2026 11:28
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 69347a5 to 5fe01ac Compare November 5, 2026 11:32
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 5fe01ac to 718df74 Compare November 5, 2026 11:53
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 718df74 to af4c3a1 Compare November 5, 2026 12:24
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from af4c3a1 to bfafa49 Compare November 5, 2026 13:02
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from a79802b to e5c68f2 Compare November 5, 2026 22:14
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from e5c68f2 to 5b375ce Compare November 5, 2026 23:11
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 5b375ce to 823b59c Compare November 6, 2026 00:20
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 823b59c to 5b20729 Compare November 6, 2026 02:06
@github-actions
github-actions Bot force-pushed the changeset-release/main branch 3 times, most recently from 54b64b3 to 838c5ba Compare November 6, 2026 04:51
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 838c5ba to 36e623d Compare November 6, 2026 05:15
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 36e623d to 089a641 Compare November 6, 2026 06:41
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 089a641 to 7c60faf Compare November 7, 2026 05:21
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 7c60faf to d5ac424 Compare November 7, 2026 05:52
@github-actions
github-actions Bot force-pushed the changeset-release/main branch 5 times, most recently from 23bf9ea to 7fc68a5 Compare November 7, 2026 09:32

This branch was successfully deployed

1 active deployment
Preview — fe1c6d67 Deployed Nov 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ui: "NEXT_REDIRECT" shows as a red error after a successful save in starter-auth and the with-auth scaffold

0 participants