## Description
Adds bulk upload functionality to upload enabled configs.
You can disable the ability by defining `upload.bulkUpload: false` in
your upload enabled config.
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## Checklist:
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
## Description
Closes#7784 by properly handling custom collection description
components via `admin.components.Description`. This component was
incorrectly added to the `admin.components.edit` key, and also was never
handled on the front-end. This was especially misleading because the
client-side config had a duplicative key in the proper position.
## Breaking Changes
This PR is only labeled as a breaking change because the key has changed
position within the config. If you were previously defining a custom
description component on a collection, simply move it into the correct
position:
Old:
```ts
{
admin: {
components: {
edit: {
Description: ''
}
}
}
}
```
New:
```ts
{
admin: {
components: {
Description: ''
}
}
}
```
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] This change requires a documentation update
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
## Description
Threads the field config to all "field subcomponents" through props,
i.e. field label, description, error, etc. This way, the field config
that controls any particular component is easily accessible and strongly
typed, i.e. `props.field.maxLength`. This is true for both server and
client components, whose server-side props are now also contextually
typed. This behavior was temporarily removed in #7474 due to bloating
HTML, but has since been resolved in #7620. This PR also makes
significant improvements to component types by exporting explicit types
for _every component of every field_, each with its own client/server
variation. Now, a custom component can look something like this:
```tsx
import type { TextFieldLabelServerComponent } from 'payload'
import React from 'react'
export const CustomLabel: TextFieldLabelServerComponent = (props) => {
return (
<div>{`The max length of this field is: ${props?.field?.maxLength}`}</div>
)
}
```
The following types are now available:
```ts
import type {
TextFieldClientComponent,
TextFieldServerComponent,
TextFieldLabelClientComponent,
TextFieldLabelServerComponent,
TextFieldDescriptionClientComponent,
TextFieldDescriptionServerComponent,
TextFieldErrorClientComponent,
TextFieldErrorServerComponent,
// ...and so one for each field
} from 'payload'
```
BREAKING CHANGES:
In order to strictly type these components, a few breaking changes have
been made _solely to type definitions_. This only effects you if you are
heavily using custom components.
Old
```ts
import type { ErrorComponent, LabelComponent, DescriptionComponent } from 'payload'
```
New:
```ts
import type {
FieldErrorClientComponent,
FieldErrorServerComponent,
FieldLabelClientComponent,
FieldLabelServerComponent,
FieldDescriptionClientComponent,
FieldDescriptionServerComponent,
// Note: these are the generic, underlying types of the more stricter types described above ^
// For example, you should use the type that is explicit for your particular field and environment
// i.e. `TextFieldLabelClientComponent` and not simply `FieldLabelClientComponent`
} from 'payload'
```
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
Fixes https://github.com/payloadcms/payload/issues/7677
- Payload bin scripts were not properly working on windows
- Use tsx by default instead of swc, as swc does not handle next/cache
imports without the .js at the end
- Support other node runtimes through --disable-transpile flag
## Description
We've since lost the ability to override the document view at the
root-level. This was a feature that made it possible to override _the
entire document routing/view structure_, including the document
header/tabs and all nested routes within, i.e. the API route/view, the
Live Preview route/view, etc. This is distinct from the "default" edit
view, which _only_ targets the component rendered within the "edit" tab.
This regression was introduced when types were simplified down to better
support "component paths" here: #7620. The `default` key was incorrectly
used as the "root" view override. To continue to support stricter types
_and_ root view overrides, a new `root` key has been added to the
`views` config.
You were previously able to do this:
```tsx
import { MyComponent } from './MyComponent.js'
export const MyCollection = {
// ...
admin: {
views: {
Edit: MyComponent
}
}
}
```
This is now done like this:
```tsx
export const MyCollection = {
// ...
admin: {
views: {
edit: {
root: {
Component: './path-to-my-component.js'
}
}
}
}
}
```
Some of the documentation was also incorrect according to the new
component paths API.
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] This change requires a documentation update
## Checklist:
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
This lowers the module count by 31 modules
BREAKING: Migration-related lexical modules are now exported from
`@payloadcms/richtext-lexical/migrate` instead of
`@payloadcms/richtext-lexical`
Allow a compound index to be used for upload collections via a
`filenameCompoundIndex` field. Previously, `filename` was always treated
as unique.
Usage:
```ts
{
slug: 'upload-field',
upload: {
// Slugs to include in compound index
filenameCompoundIndex: ['filename', 'alt'],
},
}
```
This PR makes three major changes to the codebase:
1. [Component Paths](#component-paths)
Instead of importing custom components into your config directly, they
are now defined as file paths and rendered only when needed. That way
the Payload config will be significantly more lightweight, and ensures
that the Payload config is 100% server-only and Node-safe. Related
discussion: https://github.com/payloadcms/payload/discussions/6938
2. [Client Config](#client-config)
Deprecates the component map by merging its logic into the client
config. The main goal of this change is for performance and
simplification. There was no need to deeply iterate over the Payload
config twice, once for the component map, and another for the client
config. Instead, we can do everything in the client config one time.
This has also dramatically simplified the client side prop drilling
through the UI library. Now, all components can share the same client
config which matches the exact shape of their Payload config (with the
exception of non-serializable props and mapped custom components).
3. [Custom client component are no longer
server-rendered](#custom-client-components-are-no-longer-server-rendered)
Previously, custom components would be server-rendered, no matter if
they are server or client components. Now, only server components are
rendered on the server. Client components are automatically detected,
and simply get passed through as `MappedComponent` to be rendered fully
client-side.
## Component Paths
Instead of importing custom components into your config directly, they
are now defined as file paths and rendered only when needed. That way
the Payload config will be significantly more lightweight, and ensures
that the Payload config is 100% server-only and Node-safe. Related
discussion: https://github.com/payloadcms/payload/discussions/6938
In order to reference any custom components in the Payload config, you
now have to specify a string path to the component instead of importing
it.
Old:
```ts
import { MyComponent2} from './MyComponent2.js'
admin: {
components: {
Label: MyComponent2
},
},
```
New:
```ts
admin: {
components: {
Label: '/collections/Posts/MyComponent2.js#MyComponent2', // <= has to be a relative path based on a baseDir configured in the Payload config - NOT relative based on the importing file
},
},
```
### Local API within Next.js routes
Previously, if you used the Payload Local API within Next.js pages, all
the client-side modules are being added to the bundle for that specific
page, even if you only need server-side functionality.
This `/test` route, which uses the Payload local API, was previously 460
kb. It is now down to 91 kb and does not bundle the Payload client-side
admin panel anymore.
All tests done
[here](https://github.com/payloadcms/payload-3.0-demo/tree/feat/path-test)
with beta.67/PR, db-mongodb and default richtext-lexical:
**dev /admin before:**

**dev /admin after:**

---
**dev /test before:**

**dev /test after:**

---
**build before:**

**build after::**

### Usage of the Payload Local API / config outside of Next.js
This will make it a lot easier to use the Payload config / local API in
other, server-side contexts. Previously, you might encounter errors due
to client files (like .scss files) not being allowed to be imported.
## Client Config
Deprecates the component map by merging its logic into the client
config. The main goal of this change is for performance and
simplification. There was no need to deeply iterate over the Payload
config twice, once for the component map, and another for the client
config. Instead, we can do everything in the client config one time.
This has also dramatically simplified the client side prop drilling
through the UI library. Now, all components can share the same client
config which matches the exact shape of their Payload config (with the
exception of non-serializable props and mapped custom components).
This is breaking change. The `useComponentMap` hook no longer exists,
and most component props have changed (for the better):
```ts
const { componentMap } = useComponentMap() // old
const { config } = useConfig() // new
```
The `useConfig` hook has also changed in shape, `config` is now a
property _within_ the context obj:
```ts
const config = useConfig() // old
const { config } = useConfig() // new
```
## Custom Client Components are no longer server rendered
Previously, custom components would be server-rendered, no matter if
they are server or client components. Now, only server components are
rendered on the server. Client components are automatically detected,
and simply get passed through as `MappedComponent` to be rendered fully
client-side.
The benefit of this change:
Custom client components can now receive props. Previously, the only way
for them to receive dynamic props from a parent client component was to
use hooks, e.g. `useFieldProps()`. Now, we do have the option of passing
in props to the custom components directly, if they are client
components. This will be simpler than having to look for the correct
hook.
This makes rendering them on the client a little bit more complex, as
you now have to check if that component is a server component (=>
already has been rendered) or a client component (=> not rendered yet,
has to be rendered here). However, this added complexity has been
alleviated through the easy-to-use `<RenderMappedComponent />` helper.
This helper now also handles rendering arrays of custom components (e.g.
beforeList, beforeLogin ...), which actually makes rendering custom
components easier in some cases.
## Misc improvements
This PR includes misc, breaking changes. For example, we previously
allowed unions between components and config object for the same
property. E.g. for the custom view property, you were allowed to pass in
a custom component or an object with other properties, alongside a
custom component.
Those union types are now gone. You can now either pass an object, or a
component. The previous `{ View: MyViewComponent}` is now `{ View: {
Component: MyViewComponent} }` or `{ View: { Default: { Component:
MyViewComponent} } }`.
This dramatically simplifies the way we read & process those properties,
especially in buildComponentMap. We can now simply check for the
existence of one specific property, which always has to be a component,
instead of running cursed runtime checks on a shared union property
which could contain a component, but could also contain functions or
objects.


- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
---------
Co-authored-by: PatrikKozak <patrik@payloadcms.com>
Co-authored-by: Paul <paul@payloadcms.com>
Co-authored-by: Paul Popus <paul@nouance.io>
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: James <james@trbl.design>
Form Builder Plugin BeforeEmail hook now takes a generic for your
generated types and it has the full hook params available to it.
```ts
import type { BeforeEmail } from '@payloadcms/plugin-form-builder'
// Your generated FormSubmission type
import type {FormSubmission} from '@payload-types'
// Pass it through and 'data' or 'originalDoc' will now be typed
const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangeParams) => {
// modify the emails in any way before they are sent
return emails.map((email) => ({
...email,
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
}))
}
```
## Description
https://github.com/payloadcms/payload/pull/5015 's version for beta
branch. @JessChowdhury
- [X] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
<!-- Please delete options that are not relevant. -->
- [X] New feature (non-breaking change which adds functionality)
- [X] This change requires a documentation update
## Checklist:
- [X] I have added tests that prove my fix is effective or that my
feature works
- [X] Existing test suite passes locally with my changes
- [X] I have made corresponding changes to the documentation
## Description
Prior to this change, the `defaultValue` for fields have only been used
in the application layer of Payload. With this change, you get the added
benefit of having the database columns get the default also. This is
especially helpful when adding new columns to postgres with existing
data to avoid needing to write complex migrations. In MongoDB this
change applies the default to the Mongoose model which is useful when
calling payload.db.create() directly.
This only works for statically defined values.
🙏 A big thanks to @r1tsuu for the feature and implementation idea as I
lifted some code from PR https://github.com/payloadcms/payload/pull/6983
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
## Description
Currently, there is no way to read field props from within a custom
field component, i.e. `admin.components.Description`. For example, if
you set `maxLength: 100` on your field, your custom description
component cannot read it from `props.maxLength` or any other methods.
Because these components are rendered on the server, there is also no
way of using `admin.component.Field` to inject custom props yourself,
either. To support this, we can simply pass the base component props
into these components on the server, as expected. This has also led to
custom field component props becoming more strictly typed within the
config.
This change is considered breaking only because the types have changed.
This only affects you if you were previously importing the following
types into your own custom components. To migrate, simply change the
import paths for that type.
Old:
```ts
import type {
ArrayFieldProps,
ReducedBlock,
BlocksFieldProps,
CheckboxFieldProps,
CodeFieldProps,
CollapsibleFieldProps,
DateFieldProps,
EmailFieldProps,
GroupFieldProps,
HiddenFieldProps,
JSONFieldProps,
NumberFieldProps,
PointFieldProps,
RadioFieldProps,
RelationshipFieldProps,
RichTextComponentProps,
RowFieldProps,
SelectFieldProps,
TabsFieldProps,
TextFieldProps,
TextareaFieldProps,
UploadFieldProps,
ErrorProps,
FormFieldBase,
FieldComponentProps,
FieldMap,
MappedField,
MappedTab,
ReducedBlock,
} from '@payloadcms/ui'
```
New:
```ts
import type {
FormFieldBase,
// etc.
} from 'payload'
```
Custom field components are now much more strongly typed. To make this
happen, an explicit type for every custom component has been generated
for every field type. The convention is to append
`DescriptionComponent`, `LabelComponent`, and `ErrorComponent` onto the
end of the field name, i.e. `TextFieldDescriptionComponent`. Here's an
example:
```ts
import type { TextFieldDescriptionComponent } from 'payload'
import React from 'react'
export const CustomDescription: TextFieldDescriptionComponent = (props) => {
return (
<div id="custom-field-description">{`The max length of this field is: ${props?.maxLength}`}</div>
)
}
```
Here's the full list of all new types:
Label Components:
```ts
import type {
ArrayFieldLabelComponent,
BlocksFieldLabelComponent,
CheckboxFieldLabelComponent,
CodeFieldLabelComponent,
CollapsibleFieldLabelComponent,
DateFieldLabelComponent,
EmailFieldLabelComponent,
GroupFieldLabelComponent,
HiddenFieldLabelComponent,
JSONFieldLabelComponent,
NumberFieldLabelComponent,
PointFieldLabelComponent,
RadioFieldLabelComponent,
RelationshipFieldLabelComponent,
RichTextFieldLabelComponent,
RowFieldLabelComponent,
SelectFieldLabelComponent,
TabsFieldLabelComponent,
TextFieldLabelComponent,
TextareaFieldLabelComponent,
UploadFieldLabelComponent
} from 'payload'
```
Error Components:
```tsx
import type {
ArrayFieldErrorComponent,
BlocksFieldErrorComponent,
CheckboxFieldErrorComponent,
CodeFieldErrorComponent,
CollapsibleFieldErrorComponent,
DateFieldErrorComponent,
EmailFieldErrorComponent,
GroupFieldErrorComponent,
HiddenFieldErrorComponent,
JSONFieldErrorComponent,
NumberFieldErrorComponent,
PointFieldErrorComponent,
RadioFieldErrorComponent,
RelationshipFieldErrorComponent,
RichTextFieldErrorComponent,
RowFieldErrorComponent,
SelectFieldErrorComponent,
TabsFieldErrorComponent,
TextFieldErrorComponent,
TextareaFieldErrorComponent,
UploadFieldErrorComponent
} from 'payload'
```
Description Components:
```tsx
import type {
ArrayFieldDescriptionComponent,
BlocksFieldDescriptionComponent,
CheckboxFieldDescriptionComponent,
CodeFieldDescriptionComponent,
CollapsibleFieldDescriptionComponent,
DateFieldDescriptionComponent,
EmailFieldDescriptionComponent,
GroupFieldDescriptionComponent,
HiddenFieldDescriptionComponent,
JSONFieldDescriptionComponent,
NumberFieldDescriptionComponent,
PointFieldDescriptionComponent,
RadioFieldDescriptionComponent,
RelationshipFieldDescriptionComponent,
RichTextFieldDescriptionComponent,
RowFieldDescriptionComponent,
SelectFieldDescriptionComponent,
TabsFieldDescriptionComponent,
TextFieldDescriptionComponent,
TextareaFieldDescriptionComponent,
UploadFieldDescriptionComponent
} from 'payload'
```
This PR also:
- Standardizes the `FieldBase['label']` type with a new `LabelStatic`
type. This makes type usage much more consistent across components.
- Simplifies some of the typings in the field component map, removes
unneeded `<Omit>`, etc.
- Fixes misc. linting issues around voiding promises
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
## Description
V2 PR [here](https://github.com/payloadcms/payload/pull/7359)
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update
## Checklist:
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
## Description
Fixes#6951
`Feat`: Adds new prop `withMetadata` to `uploads` config that allows the
user to allow media metadata to be appended to the file of the output
media.
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] This change requires a documentation update
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
- Abstract shared sql code to a new drizzle package
- Adds sqlite package, not ready to publish until drizzle patches some
issues
- Add `transactionOptions` to allow customizing or disabling db
transactions
- Adds "experimental" label to the `schemaName` property until drizzle
patches an issue
Fixes#7101Fixes#7006
Drawers were sending duplicate query params. This new approach modeled after the fix in V2, ensures that each drawer has its own action url created per document and the query params will be created when that is generated.
Also fixes the following:
- incorrect focal point cropping
- generated filenames for animated image names used incorrect heights
`auth.loginWithUsername`:
```ts
auth: {
loginWithUsername: {
allowEmailLogin: true, // default: false
requireEmail: false, // default: false
}
}
```
#### `allowEmailLogin`
This property will allow you to determine if users should be able to
login with either email or username. If set to `false`, the default
value, then users will only be able to login with usernames when using
the `loginWithUsername` property.
#### `requireEmail`
Require that users also provide emails when using usernames.
## Description
Currently, the Payload doesn't support to extend the Allowed Headers in
CORS context. With this PR, `cors` property can be an object with
`origins` and `headers`.
- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.
## Type of change
- [ ] Chore (non-breaking change which does not add functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [x] This change requires a documentation update
## Checklist:
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [x] I have made corresponding changes to the documentation
Co-authored-by: Alessio Gravili <alessio@gravili.de>
We now validate the names of the field against an array of protected
field names.
Also added JSDoc since we can't enforce type strictness yet if `string |
const[]` as it always evaluates to `string`.
```
The name of the field. Must be alphanumeric and cannot contain ' . '
Must not be one of protected field names: ['__v', 'salt', 'hash', 'file']
@link — [https://payloadcms.com/docs/fields/overview#field-names](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-sandbox/workbench/workbench.html)
```
searchPlugin's searchOverrides for the collection now takes in a fields
function instead of array similar to other plugins and patterns we use
to allow you to map over existing fields as well if needed.
```ts
// before
searchPlugin({
searchOverrides: {
slug: 'search-results',
fields: [
{
name: 'excerpt',
type: 'textarea',
admin: {
position: 'sidebar',
},
},
]
},
}),
// current
searchPlugin({
searchOverrides: {
slug: 'search-results',
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'excerpt',
type: 'textarea',
admin: {
position: 'sidebar',
},
},
]
},
}),
```