Deprecates `react-animate-height` in favor of native CSS, specifically
the `interpolate-size: allow-keywords;` property which can be used to
animate to `height: auto`—the primary reason this package exists. This
is one less dependency in our `node_modules`. Tried to replicate the
current DOM structure, class names, and API of `react-animate-height`
for best compatibility.
Note that this CSS property is experimental BUT this PR includes a patch
for browsers without native support. Once full support is reached, the
patch can be safely removed.
### What?
We sorted migrations by `-name` in `getMigrations` as by assumption from
generated file names, however, it may be not true as the improved (+
unflaked, previously it failed sometimes) test for `migrate:down` can
reproduce. As in result, `migrateDown` / `migrateRefresh` may execute in
order different from `migrate`.
Unflakes the 'should commit multiple operations async' test.
We shouldn't pass the same `req` that doesn't contain a transaction to
different operations that execute in parallel (via `Promise.all`)
without either creating a transaction before or using
`isolateObjectProperty(req, 'transactionID')`. It leads to a race
condition because operation can commit a wrong transaction, different
from inited
### What?
Previously, using Postgres, select fields with `hasMany: true` weren't
clearable.
Meaning, you couldn't pass an empty array:
```ts
const updatedDoc = await payload.update({
id,
collection: 'select-fields',
data: {
selectHasMany: [],
},
})
```
### Why?
To achieve the same behavior with MongoDB.
### How?
Modifies logic in `packages/drizzle/src/upsertRow/index.ts` to include
empty arrays.
Removes unnecessary `deepCopyObject(docPermissions)` in the Version View
which slows down loading speed.
The comment seems to be resolved, I'm not getting this error and here
for example in the same case
3c0e832a9a/packages/next/src/views/Document/index.tsx (L327)
we don't do deep copying.
TS 5.7 added support for ES2024. By keeping target: “esnext”, we would
have accidentally set our minimum supported ES version to ES2024.
This sets it to ES2022, which is the version supported by Node 18
When using Client-side Live Preview, array fields are unable to clear
all their rows. This is because `reduceFieldsToValues` sets the array's
value as 0 within form-state when no rows exist, as opposed to an empty
array as one might expect. For now, we can simply handle this data shape
within Live Preview's merge logic. In the future we may want to take to
consider changing the behavior of empty arrays within form-state itself.
Now, custom Lexical block & inline block components are re-rendered if
the fields drawer is saved. This ensures that RSCs receive the updated
values, without having to resort to a client component that utilizes the
`useForm` hook.
Additionally, this PRs fixes the lexical selection jumping around after
opening a Block or InlineBlock drawer and clicking inside of it.
When defining custom providers as server components, they currently do
not receive any of the server props that custom components expect to
receive, like `payload`, `i18n`, `user`, and so on.
### What?
Non-standard ids caused an issue when finding the document on the
server.
This is an odd regression, in 2.0 we were fetching the document on the
client so the request would handle decoding the url. Now we are fetching
the document on the server and need to do this manually when reading id
from route params.
### Why?
The slug pulled out of the url for an id of `id 1` would equate to
`id%201` which would fail in the `payload.find` call since there is not
an id stored as `id%201` but instead `id 1`.
### How?
Wherever we are calling payload.find in the views and querying by `id`
it gets ran through a helper function that decodes it properly.
Fixes#9373
Fixes errors when having joins with versions +drafts on `hasMany: true`
relationships.
Removes `joinQuery` overhead if we don't need it for the current
operation. Right now, in all adapters we support joins only for `find`,
`findOne`, and `queryDrafts`.
Fixes https://github.com/payloadcms/payload/issues/9369
Fixes https://github.com/payloadcms/payload/issues/9363
This fixes the following issues that caused fields to be either hidden,
or incorrectly set to readOnly in certain configurations:
- In some cases, permissions were sanitized incorrectly. This PR
rewrites the sanitizePermissions function and adds new unit tests
- after a document save, the client was receiving unsanitized
permissions. Moving the sanitization logic to the endpoint fixes this
- Various incorrect handling of permissions in our form state endpoints
/ RenderFields
Fixes#9351. When using Postgres, doc ids were being treated as a string
as opposed to a number within the admin panel. This led to issues for
anything relying on the `docID` from context, such as the join field not
properly populating initial data when creating new documents, etc.
Closes#9242 and #9365. Autosave-enabled documents rendered within a
drawer were not being properly handled. This was causing multiple draft
documents to be created upon opening the drawer, as well as an empty
document returned from the server function, etc.
Fixes#9337. The version view was not able to render its diff because of
an invalid permissions lookup. This was a result of a change to how
access results are returned from the API, which are now sanitized:
https://github.com/payloadcms/payload/pull/7335
Fixes#9264. When externally updating array or block rows through the
`addFieldRow` or `replaceFieldRow` methods, nested rich text fields
along with any custom components within them are never rendered. This is
because unless the form is explicitly set to modified, as the default
array and blocks fields currently do, the newly generated form-state
will skip the rendering step. Now, the underlying callbacks themselves
automatically set the form to modified to trigger rendering.
The biggest difference comes from calling `RenderServerComponent` as a
function, instead of rendering it by using `<RenderServerComponent`.
This gets rid of wasteful blocks of codes sent to the client that look
like this:

HTML size comparison:
## Admin test suite
| View | Before | After |
|------|---------|--------|
| Dashboard | 331 kB | 83 kB |
| collections/custom-views-one Edit | 285 kB | 76.6 kB |
## Fields test suite
| View | Before | After |
|------|---------|--------|
| collections/lexical Edit | 189 kB | 94.4 kB |
| collections/lexical List | 152 kB | 62.9 kB |
## Community test suite
| View | Before | After |
|------|---------|--------|
| Dashboard | 78.9 kB | 43.1 kB |
The problem was that the uploads test suite was trying to log in to
payload before it was even initialized.
In the rare event where payload started up before the uploads test suite
was trying to log in, our tests passed.
Fixes types for workflows / jobs `input` and `output` when using
`strict: true` or `strictNullChecks: true` by ensuring that all
properties in generates types are requried
Supports bi-directional import/export between MDX <=> Lexical. JSX will
be mapped to lexical blocks back and forth.
This will allow editing our mdx docs in payload while keeping mdx as the
source of truth
---------
Co-authored-by: Germán Jabloñski <43938777+GermanJablo@users.noreply.github.com>
### What?
Fixes the issue when visiting the create view with the Join Field and
using postgres adapter
```
invalid input syntax for type integer: "NaN"
```
This happens because we don't have an ID yet and we send to the
database:
`WHERE id = NaN`
### How?
Avoids calling `getTableState` inside of `RelationshipTable` if there's
no ID yet, as it will always lead to the same empty result. While we
_could_ avoid error directly in the database adapter, I don't think we
should do that render request
Fixes https://github.com/payloadcms/payload/issues/9193
### What?
Previously, this code led to a validation error because `movie` is an
object and you needed to use `movie.id` instead.
```ts
const movie = await payload.create({ collection: 'movies', data: {} })
const result = await payload.create({
collection: 'object-writes',
data: {
many: [movie],
manyPoly: [{ relationTo: 'movies', value: movie }],
one: movie,
onePoly: {
relationTo: 'movies',
value: movie,
},
},
})
```
While it's simple to modify this example, it's more painful when you
have a data with `depth` > 0 and then you want to update that document.
### Why?
Better DX as less checks needed, and TypeScript says that we can pass an
object.
### How?
Sanitizes the field value in the root `beforeValidate` hook
The field RSC now provides an initial state for all lexical blocks. This
completely obliterates any flashes and lexical block loading states when
loading or saving a document.
Previously, when a document is loaded or saved, every lexical block was
sending a network request in order to fetch their form state. Now, this
is batched and handled in the lexical server component. All lexical
block form states are sent to the client together with the parent
lexical field, and are thus available immediately.
We also do the same with block collapsed preferences. Thus, there are no
loading states or layout shifts/flashes of blocks anymore.
Additionally, when saving a document while your cursor is inside a
lexical field, the cursor position is preserved. Previously, a document
save would kick your cursor out of the lexical field.
## Look at how nice this is:
https://github.com/user-attachments/assets/21d736d4-8f80-4df0-a782-7509edd993da
**BREAKING:**
This removes the `feature.hooks.load` and `feature.hooks.save`
interfaces from custom lexical features, as they weren't used internally
and added unnecessary, additional overhead.
If you have custom features that use those, you can migrate to using
normal payload hooks that run on the server instead of the client.
With this PR, you can now customize the way that `blocks` and
`inlineBlocks` are rendered within Lexical's `BlocksFeature` by passing
your own React components.
This is super helpful when you need to create "previews" or more
accurate UI for your Lexical blocks.
For example, let's say you have a `gallery` block where your admins
select a bunch of images. By default, Lexical would just render a
collapsible with your block's fields in it. But now you can customize
the `admin.components.Block` property on your `block` config by passing
it a custom React component for us to render instead.
So using that, with this `gallery` example, you could make a dynamic
gallery React component that shows the images to your editors - and then
render our built-in `BlockEditButton` to allow your editors to manage
your gallery in a drawer.
Here is an example where the BlockEditButton is added to the default
Block Collapsible/Header:

---------
Co-authored-by: James <james@trbl.design>
Deprecates `getPayloadHMR` and simplifies this pattern into a single
`import { getPayload } from 'payload'`.
We will still retain the exported `getPayloadHMR` but it now will throw
a deprecation warning with instructions for how to migrate.
This PR fixes cases where you may have a field called `id` within a
group or a named tab, which would have incorrectly been treated as a
custom ID field for the collection.
However, custom IDs need to be defined at the root level - and now
Payload only respects custom IDs defined at the root level.
### What?
Upgrades mongoose from 6 to latest `v8.8.1`
Fixes https://github.com/payloadcms/payload/issues/9171
### Why?
Compatibilty with Mongodb Atlas
### How?
- Updates deps
- Changed ObjectId from bson-objectid to use `new Type.ObjectId` from
mongoose for compatibility (only inside of db-mongodb)
- Internal type adjustments
https://github.com/payloadcms/payload/discussions/9088
BREAKING CHANGES:
All projects with existing data having versions enabled, or relationship or upload fields will want to create the predefined migration that converts all strings to ObjectIDs where needed. This can be created using `payload migrate:create --file @payloadcms/mongodb/relationships-v2-v3`.
For projects making use of the exposed Models from mongoose, review the
upgrade guides from [v6 to
v7](https://mongoosejs.com/docs/7.x/docs/migrating_to_7.html) and [v7 to
v8](https://mongoosejs.com/docs/migrating_to_8.html) and make
adjustments as needed.
---------
Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com>
Upgrade uploadthing to v7
The `options` that can be passed to the plugin now mirror the
`UTApiOptions` of v7.
The most notable change is to pass `token` with
`process.env.UPLOADTHING_TOKEN` instead of `apiKey` with
`process.env.UPLOADTHING_SECRET`.
```diff
options: {
- apiKey: process.env.UPLOADTHING_SECRET,
+ token: process.env.UPLOADTHING_TOKEN,
acl: 'public-read',
},