Commit Graph

27 Commits

Author SHA1 Message Date
Jacob Fletcher
82820312e8 feat: expose multipart/form-data parsing options (#13766)
When sending REST API requests with multipart/form-data, e.g. PATCH or
POST within the admin panel, a request body larger than 1MB throws the
following error:

```
Unterminated string in JSON at position...
```

This is because there are sensible defaults imposed by the HTML form
data parser (currently using
[busboy](https://github.com/fastify/busboy)). If your documents exceed
this limit, you may run into this error when editing them within the
admin panel.

To support large documents over 1MB, use the new `bodyParser` property
on the root config:

```ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  bodyParser: {
    limits: {
      fieldSize: 2 * 1024 * 1024, // This will allow requests containing up to 2MB of multipart/form-data
    }
  }
}
```

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211317005907885
2025-09-11 09:14:56 -04:00
Sasha
a20b43624b feat: add findDistinct operation (#13102)
Adds a new operation findDistinct that can give you distinct values of a
field for a given collection
Example:
Assume you have a collection posts with multiple documents, and some of
them share the same title:
```js
// Example dataset (some titles appear multiple times)
[
  { title: 'title-1' },
  { title: 'title-2' },
  { title: 'title-1' },
  { title: 'title-3' },
  { title: 'title-2' },
  { title: 'title-4' },
  { title: 'title-5' },
  { title: 'title-6' },
  { title: 'title-7' },
  { title: 'title-8' },
  { title: 'title-9' },
]
```
You can now retrieve all unique title values using findDistinct:
```js
const result = await payload.findDistinct({
  collection: 'posts',
  field: 'title',
})

console.log(result.values)
// Output:
// [
//   'title-1',
//   'title-2',
//   'title-3',
//   'title-4',
//   'title-5',
//   'title-6',
//   'title-7',
//   'title-8',
//   'title-9'
// ]
```
You can also limit the number of distinct results:
```js
const limitedResult = await payload.findDistinct({
  collection: 'posts',
  field: 'title',
  sortOrder: 'desc',
  limit: 3,
})

console.log(limitedResult.values)
// Output:
// [
//   'title-1',
//   'title-2',
//   'title-3'
// ]
```

You can also pass a `where` query to filter the documents.
2025-07-16 17:18:14 -04:00
Sasha
a22c0e62fa feat: add populate property to Local / REST API (#8969)
### What?
Adds `populate` property to Local API and REST API operations that can
be used to specify `select` for a specific collection when it's
populated
```ts
const result = await payload.findByID({
  populate: {
   // type safe if you have generated types
    posts: {
      text: true,
    },
  },
  collection: 'pages',
  depth: 1,
  id: aboutPage.id,
})

result.relatedPost // only has text and id properties
``` 

```ts
fetch('https://localhost:3000/api/pages?populate[posts][text]=true') // highlight-line
  .then((res) => res.json())
  .then((data) => console.log(data))
```

It also overrides
[`defaultPopulate`](https://github.com/payloadcms/payload/pull/8934)

Ensures `defaultPopulate` doesn't affect GraphQL.

### How?
Implements the property for all operations that have the `depth`
argument.
2024-11-06 13:50:19 -05:00
Sasha
9ce2ba6a3f fix: custom endpoints with method: 'put' (#9037)
### What?
Fixes support for custom endpoints with `method: 'put'`.
Previously, this didn't work:
```ts
export default buildConfigWithDefaults({
  collections: [ ],
  endpoints: [
    {
      method: 'put',
      handler: () => new Response(),
      path: '/put',
    },
  ],
})
```

### Why?
We supported this in 2.0 and docs are saying that we can use `'put'` as
`method`
https://payloadcms.com/docs/beta/rest-api/overview#custom-endpoints

### How?
Implements the `REST_PUT` export for `@payloadcms/next/routes`, updates
all templates. Additionally, adds tests to ensure root/collection level
custom endpoints with all necessary methods execute properly.

Fixes https://github.com/payloadcms/payload/issues/8807

-->
2024-11-05 23:14:34 +02:00
Sasha
dae832c288 feat: select fields (#8550)
Adds `select` which is used to specify the field projection for local
and rest API calls. This is available as an optimization to reduce the
payload's of requests and make the database queries more efficient.

Includes:
- [x] generate types for the `select` property
- [x] infer the return type by `select` with 2 modes - include (`field:
true`) and exclude (`field: false`)
- [x] lots of integration tests, including deep fields / localization
etc
- [x] implement the property in db adapters
- [x] implement the property in the local api for most operations
- [x] implement the property in the rest api 
- [x] docs

---------

Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
2024-10-29 21:47:18 +00:00
Alessio Gravili
1afcaa30ed feat!: upgrade next, react and react-dom, move react/next dependency checker from payload to next package (#8323)
Fixes https://github.com/payloadcms/payload/issues/8013

**BREAKING:**
- Upgrades minimum supported @types/react version from
npm:types-react@19.0.0-rc.0 to npm:types-react@19.0.0-rc.1
- Upgrades minimum supported @types/react-dom version from
npm:types-react-dom@19.0.0-rc.0 to npm:types-react-dom@19.0.0-rc.1
- Upgrades minimum supported react and react-dom version from
19.0.0-rc-06d0b89e-20240801 to 19.0.0-rc-5dcb0097-20240918
- Upgrades minimum supported Next.js version from 15.0.0-canary.104 to
15.0.0-canary.160

---------

Co-authored-by: PatrikKozak <patrik@payloadcms.com>
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
2024-09-20 12:09:42 -04:00
Dan Ribbens
6ef2bdea15 feat!: join field (#7518)
## Description

- Adds a new "join" field type to Payload and is supported by all database adapters
- The UI uses a table view for the new field
- `db-mongodb` changes relationships to be stored as ObjectIDs instead of strings (for now querying works using both types internally to the DB so no data migration should be necessary unless you're querying directly, see breaking changes for details
- Adds a reusable traverseFields utility to Payload to make it easier to work with nested fields, used internally and for plugin maintainers

```ts
export const Categories: CollectionConfig = {
    slug: 'categories',
    fields: [
        {
            name: 'relatedPosts',
            type: 'join',
            collection: 'posts',
            on: 'category',
        }
    ]
}
```

BREAKING CHANGES:
All mongodb relationship and upload values will be stored as MongoDB ObjectIDs instead of strings going forward. If you have existing data and you are querying data directly, outside of Payload's APIs, you get different results. For example, a `contains` query will no longer works given a partial ID of a relationship since the ObjectID requires the whole identifier to work. 

---------

Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: James <james@trbl.design>
2024-09-20 11:10:16 -04:00
Alessio Gravili
a7b0f8ba36 feat!: new server-only, faster and immediate autoLogin (#7224)
- When autoLogin is enabled, it will no longer flash an unresponsive
"login" screen. Instead, it will straight up open the admin panel.
That's because, on the server, we will now always & immediately see the
user as authenticated, thus no initial login view is pushed to the
client until the client component sends the auth request anymore. Less
useless requests. Additionally, jwt verification is now completely
skipped
- No more auto-login related frontend code. autoLogin handling has been
removed from the frontend `Auth` component
- less code to maintain, this is way simpler now

**For reviewers:**
- The new logic for autoFill without prefillOnly is here: [jwt auth
strategy](https://github.com/payloadcms/payload/pull/7224/files#diff-7d40839079a8b2abb58233e5904513ab321023a70538229dfaf1dfee067dc8bfR21)
- The new logic for autoFill with prefillOnly is here: [Server Login
View](https://github.com/payloadcms/payload/pull/7224/files#diff-683770104f196196743398a698fbf8987f00e4426ca1c0ace3658d18ab80e82dL72)
=> [Client Login
Form](https://github.com/payloadcms/payload/pull/7224/files#diff-ac3504d3b3b0489455245663649bef9e84477bf0c1185da5a4d3a612450f01eeL20)

**BREAKING**
`autoLogin` without `prefillOnly` set now also affects graphQL/Rest
operations. Only the user specified in `autoLogin` will be returned.
Within the graphQL/Rest/Local API, this should still allow you to
authenticate with a different user, as the autoLogin user is only used
if no token is set.
2024-07-20 23:25:50 +00:00
Paul
014ee1a1b2 feat(ui): change autosave logic to send updates as soon as possible, improving live preview speed (#7201)
Now has a minimum animation time for the autosave but it fires off the
send events sooner to improve the live preview timing.
2024-07-19 15:24:53 -04:00
Jarrod Flesch
7b3b02198c feat: ability to login with email, username or both (#7086)
`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.
2024-07-18 10:29:44 -04:00
Alessio Gravili
83fd4c6622 chore: run lint and prettier on entire codebase 2024-07-11 15:27:01 -04:00
Alessio Gravili
6c99326d59 feat: replace qs with qs-esm (#6966)
qs-esm is a qs fork I created and doesn't add bloated polyfills, is
ESM-only, has a smaller bundle size and comes with types included.

qs:
https://bundlephobia.com/package/qs@6.12.1 (11kb)
https://npm.anvaka.com/#/view/2d/qs (15 dependencies)

qs-esm:
https://bundlephobia.com/package/qs-esm@7.0.0 (4.2kb)
https://npm.anvaka.com/#/view/2d/qs-esm (1 dependency)

I don't agree with the backwards philosophy of qs:
https://github.com/ljharb/qs/issues/404#issuecomment-806392831 ("more
deps is better", lower bundle size as opt-in, maximum environment
compatibility as opt-out)

qs imports waaay too many useless dependencies
2024-07-09 14:33:38 +00:00
Alessio Gravili
2920a5d0a8 feat: replace bloated deep-equal dependency and minimize usage of qs (#6912) 2024-06-25 13:40:16 +00:00
Jacob Fletcher
9e76c8f4e3 feat!: prebundle payload, ui, richtext-lexical (#6579)
# Breaking Changes

### New file import locations

Exports from the `payload` package have been _significantly_ cleaned up.
Now, just about everything is able to be imported from `payload`
directly, rather than an assortment of subpath exports. This means that
things like `import { buildConfig } from 'payload/config'` are now just
imported via `import { buildConfig } from 'payload'`. The mental model
is significantly simpler for developers, but you might need to update
some of your imports.

Payload now exposes only three exports:

1. `payload` - all types and server-only Payload code
2. `payload/shared` - utilities that can be used in either the browser
or in Node environments
3. `payload/node` - heavy utilities that should only be imported in Node
scripts and never be imported into bundled code like Next.js

### UI library pre-bundling

With this release, we've dramatically sped up the compile time for
Payload by pre-bundling our entire UI package for use inside of the
Payload admin itself. There are new exports that should be used within
Payload custom components:

1. `@payloadcms/ui/client` - all client components 
2. `@payloadcms/ui/server` - all server components

For all of your custom Payload admin UI components, you should be
importing from one of these two pre-compiled barrel files rather than
importing from the more deeply nested exports directly. That will keep
compile times nice and speedy, and will also make sure that the bundled
JS for your admin UI is kept small.

For example, whereas before, if you imported the Payload `Button`, you
would have imported it like this:

```ts
import { Button } from '@payloadcms/ui/elements/Button'
```

Now, you would import it like this:

```ts
import { Button } from '@payloadcms/ui/client'
```

This is a significant DX / performance optimization that we're pretty
pumped about.

However, if you are importing or re-using Payload UI components
_outside_ of the Payload admin UI, for example in your own frontend
apps, you can import from the individual component exports which will
make sure that the bundled JS is kept to a minimum in your frontend
apps. So in your own frontend, you can continue to import directly to
the components that you want to consume rather than importing from the
pre-compiled barrel files.

Individual component exports will now come with their corresponding CSS
and everything will work perfectly as-expected.

### Specific exports have changed

- `'@payloadcms/ui/templates/Default'` and
`'@payloadcms/ui/templates/Minimal`' are now exported from
`'@payloadcms/next/templates'`
- Old: `import { LogOut } from '@payloadcms/ui/icons/LogOut'` new:
`import { LogOutIcon } from '@payloadcms/ui/icons/LogOut'`

## Background info

In effort to make local dev as fast as possible, we need to import as
few files as possible so that the compiler has less to process. One way
we've achieved this in the Admin Panel was to _remove_ all .scss imports
from all components in the `@payloadcms/ui` module using a build
process. This stripped all `import './index.scss'` statements out of
each component before injecting them into `dist`. Instead, it bundles
all of the CSS into a single `main.css` file, and we import _that_ at
the root of the app.

While this concept is _still_ the right solution to the problem, this
particular approach is not viable when using these components outside
the Admin Panel, where not only does this root stylesheet not exist, but
where it would also bloat your app with unused styles. Instead, we need
to _keep_ these .scss imports in place so they are imported directly
alongside your components, as expected. Then, we need create a _new_
build step that _separately_ compiles the components _without_ their
stylesheets—this way your app can consume either as needed from the new
`client` and `server` barrel files within `@payloadcms/ui`, i.e. from
within `@payloadcms/next` and all other admin-specific packages and
plugins.

This way, all other applications will simply import using the direct
file paths, just as they did before. Except now they come with
stylesheets.

And we've gotten a pretty awesome initial compilation performance boost.

---------

Co-authored-by: James <james@trbl.design>
Co-authored-by: Alessio Gravili <alessio@gravili.de>
2024-06-17 14:25:36 -04:00
Jarrod Flesch
697a0f1ecf fix: ensure body limit is respected (#5807)
Co-authored-by: James <james@trbl.design>
2024-04-16 09:22:41 -04:00
Elliot DeNolf
c5ecf48d94 chore: add test/ to workspace, update most references 2024-03-19 00:59:56 -04:00
Elliot DeNolf
92471b0beb chore: fix @payloadcms/ui refs in test dir 2024-03-18 16:55:27 -04:00
Alessio Gravili
8895f6420f chore: fix all esm test suite imports 2024-03-08 14:42:24 -05:00
Jarrod Flesch
a5e2fa80e8 chore: adds schema path to useFieldPath provider, more passing tests 2024-02-20 15:56:11 -05:00
Jarrod Flesch
19a4a99e76 chore: partial passing upload int tests 2024-02-19 10:03:35 -05:00
Jarrod Flesch
1c9ba5b512 passing relationships int tests 2024-02-17 01:00:48 -05:00
Jarrod Flesch
3d99ea5cbf chore: passing localization int tests 2024-02-16 23:22:01 -05:00
Jarrod Flesch
e597ecfe78 feat: passing hooks int test suite 2024-02-16 22:27:43 -05:00
Jarrod Flesch
5927bf8149 feat: passing collections-rest int suite 2024-02-16 13:41:48 -05:00
Jarrod Flesch
366db1623b chore: passing graphql test suite 2024-02-16 09:08:37 -05:00
James
6f7a3ed031 chore: restores payload-config tsconfig path temporarily 2024-02-15 11:34:50 -05:00
Jarrod Flesch
db6758f7f7 chore: adds rest client for Next handlers 2024-02-15 10:01:13 -05:00