Commit Graph

35 Commits

Author SHA1 Message Date
Germán Jabloñski
97e2e77ff4 chore: run dev:generate-types (#11994) 2025-04-08 17:25:29 -03:00
Dan Ribbens
975bbb756f feat: add find to payloadDataLoader to cache local API queries (#11685)
### What?
Extends our dataloader to add a momiozed payload find function. This way
it will cache the query for the same find request using a cacheKey from
find operation args.

### Why?
This was needed internally for `filterOptions` that exist in an array or
other sitautions where you have the same exact query being made and
awaited many times.

### How?

- Added `find` to payloadDataLoader. Marked `@experimental` in case it
needs to change.
- Created a cache key from the args
- Validate filterOptions changed from `payload.find` to
`payloadDataLoader.find`
- Made `payloadDataLoader` no longer optional on `PayloadRequest`, since
other args are required which are created from createLocalReq (context
for example), I don't see a reason why dataLoader shouldn't be required
also.

Example usage: 
```ts
const result = await req.payloadDataLoader.find({
    collection,
    req,
    where,
  })
```
2025-03-18 21:14:33 +00:00
Sasha
117949b8d9 test: regenerate payload-types.ts for all test suites (#11238)
Regenerates `payload-types.ts` for all test suites.
2025-02-18 00:45:59 +02:00
Alessio Gravili
c7138b9aab chore: update generated types for all test suites (#9577) 2024-11-27 20:36:37 +00:00
Jacob Fletcher
c96fa613bc feat!: on demand rsc (#8364)
Currently, Payload renders all custom components on initial compile of
the admin panel. This is problematic for two key reasons:
1. Custom components do not receive contextual data, i.e. fields do not
receive their field data, edit views do not receive their document data,
etc.
2. Components are unnecessarily rendered before they are used

This was initially required to support React Server Components within
the Payload Admin Panel for two key reasons:
1. Fields can be dynamically rendered within arrays, blocks, etc.
2. Documents can be recursively rendered within a "drawer" UI, i.e.
relationship fields
3. Payload supports server/client component composition 

In order to achieve this, components need to be rendered on the server
and passed as "slots" to the client. Currently, the pattern for this is
to render custom server components in the "client config". Then when a
view or field is needed to be rendered, we first check the client config
for a "pre-rendered" component, otherwise render our client-side
fallback component.

But for the reasons listed above, this pattern doesn't exactly make
custom server components very useful within the Payload Admin Panel,
which is where this PR comes in. Now, instead of pre-rendering all
components on initial compile, we're able to render custom components
_on demand_, only as they are needed.

To achieve this, we've established [this
pattern](https://github.com/payloadcms/payload/pull/8481) of React
Server Functions in the Payload Admin Panel. With Server Functions, we
can iterate the Payload Config and return JSX through React's
`text/x-component` content-type. This means we're able to pass
contextual props to custom components, such as data for fields and
views.

## Breaking Changes

1. Add the following to your root layout file, typically located at
`(app)/(payload)/layout.tsx`:

    ```diff
    /* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
    /* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
    + import type { ServerFunctionClient } from 'payload'

    import config from '@payload-config'
    import { RootLayout } from '@payloadcms/next/layouts'
    import { handleServerFunctions } from '@payloadcms/next/utilities'
    import React from 'react'

    import { importMap } from './admin/importMap.js'
    import './custom.scss'

    type Args = {
      children: React.ReactNode
    }

+ const serverFunctions: ServerFunctionClient = async function (args) {
    +  'use server'
    +  return handleServerFunctions({
    +    ...args,
    +    config,
    +    importMap,
    +  })
    + }

    const Layout = ({ children }: Args) => (
      <RootLayout
        config={config}
        importMap={importMap}
    +  serverFunctions={serverFunctions}
      >
        {children}
      </RootLayout>
    )

    export default Layout
    ```

2. If you were previously posting to the `/api/form-state` endpoint, it
no longer exists. Instead, you'll need to invoke the `form-state` Server
Function, which can be done through the _new_ `getFormState` utility:

    ```diff
    - import { getFormState } from '@payloadcms/ui'
    - const { state } = await getFormState({
    -   apiRoute: '',
    -   body: {
    -     // ...
    -   },
    -   serverURL: ''
    - })

    + const { getFormState } = useServerFunctions()
    +
    + const { state } = await getFormState({
    +   // ...
    + })
    ```

## Breaking Changes

```diff
- useFieldProps()
- useCellProps()
```

More details coming soon.

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Co-authored-by: James <james@trbl.design>
2024-11-11 13:59:05 -05:00
Elliot DeNolf
040c2a2fbb chore(eslint): FlatConfig type deprecated, set to Config 2024-09-20 22:46:40 -04:00
Alessio Gravili
86fdad0bb8 chore: significantly improve eslint performance, lint and prettier everything 2024-08-29 21:25:50 -04:00
Alessio Gravili
bc367ab73c chore(eslint): upgrade to typescript-eslint v8, upgrade all eslint packages (#7082) 2024-08-29 16:27:58 -04:00
Alessio Gravili
dc12047723 feat: reduce package size and amount of dependencies by upgrading json-schema-to-typescript (#7938)
Closes https://github.com/payloadcms/payload/issues/7934
2024-08-28 21:59:32 +00:00
Alessio Gravili
90b7b20699 feat!: beta-next (#7620)
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:**
![CleanShot 2024-07-29 at 22 49
12@2x](https://github.com/user-attachments/assets/4428e766-b368-4bcf-8c18-d0187ab64f3e)

**dev /admin after:**
![CleanShot 2024-07-29 at 22 50
49@2x](https://github.com/user-attachments/assets/f494c848-7247-4b02-a650-a3fab4000de6)

---

**dev /test before:**
![CleanShot 2024-07-29 at 22 56
18@2x](https://github.com/user-attachments/assets/1a7e9500-b859-4761-bf63-abbcdac6f8d6)

**dev /test after:**
![CleanShot 2024-07-29 at 22 47
45@2x](https://github.com/user-attachments/assets/f89aa76d-f2d5-4572-9753-2267f034a45a)

---

**build before:**
![CleanShot 2024-07-29 at 22 57
14@2x](https://github.com/user-attachments/assets/5f8f7281-2a4a-40a5-a788-c30ddcdd51b5)

**build after::**
![CleanShot 2024-07-29 at 22 56
39@2x](https://github.com/user-attachments/assets/ea8772fd-512f-4db0-9a81-4b014715a1b7)

### 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.

![CleanShot 2024-07-29 at 23 07
07@2x](https://github.com/user-attachments/assets/1e75aa4c-7a4c-419f-9070-216bb7b9a5e5)

![CleanShot 2024-07-29 at 23 09
40@2x](https://github.com/user-attachments/assets/b4c96450-6b7e-496c-a4f7-59126bfd0991)

- [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>
2024-08-13 12:54:33 -04:00
Alessio Gravili
e5d5126d14 chore: regenerate all types in test dir, and add to eslint & prettier ignores 2024-07-11 15:59:38 -04:00
Alessio Gravili
83fd4c6622 chore: run lint and prettier on entire codebase 2024-07-11 15:27:01 -04:00
Alessio Gravili
1038e1c228 chore: move to eslint v9 (#7041)
- Upgrades eslint from v8 to v9
- Upgrades all other eslint packages. We will have to do a new
full-project lint, as new rules have been added
- Upgrades husky from v8 to v9
- Upgrades lint-staged from v14 to v15
- Moves the old .eslintrc.cjs file format to the new eslint.config.js
flat file format.

Previously, we were very specific regarding which rules are applied to
which files. Now that `extends` is no longer a thing, I have to use
deepMerge & imports instead.

This is rather uncommon and is not a documented pattern - e.g.
typescript-eslint docs want us to add the default typescript-eslint
rules to the top-level & then disable it in files using the
disable-typechecked config.

However, I hate this opt-out approach. The way I did it here adds a lot
of clarity as to which rules are applied to which files, and is pretty
easy to read. Much less black magic

## .eslintignore

These files are no longer supported (see
https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files).
I moved the entries to the ignores property in the eslint config. => one
less file in each package folder!
2024-07-09 09:50:37 -04:00
Patrik
fb72d19d6c fix: graphql query concurrency issues (#6925)
## Description

This is the beta (v3) PR for the v2 PR
[here](https://github.com/payloadcms/payload/pull/6857)

Addresses #6800, #5108

- [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
2024-07-08 15:55:04 +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
Elliot DeNolf
7309d474ee feat!: type auto-generation (#6657)
Types are now auto-generated by default.

You can opt-out of this behavior by setting:
```ts
buildConfig({
  // Rest of config
  typescript: {
    autoGenerate: false
  },
})
```
2024-06-10 13:42:44 -04:00
Elliot DeNolf
095e4402ac test: type fixes (#6331) 2024-05-13 01:37:52 +00:00
Elliot DeNolf
354ad7092c chore: type gen formatting (#6309) 2024-05-09 23:55:55 -04:00
Alessio Gravili
f7a2cf96b9 chore: properly working generated types within tests (#6288) 2024-05-09 17:12:51 -04:00
Elliot DeNolf
c5ecf48d94 chore: add test/ to workspace, update most references 2024-03-19 00:59:56 -04:00
Elliot DeNolf
14eb66c87d test: refactor int tests to use initPayloadInt which reduces boilerplate 2024-03-16 10:11:00 -04:00
Alessio Gravili
6789e61488 chore: run lint & prettier on everything 2024-03-14 23:53:47 -04:00
Dan Ribbens
d193c677c7 chore: attach mongoMemoryServer to db and destroy in tests (#5326)
* chore: attach mongoMemoryServer to db and destroy in tests

* bump mongodb-memory-server to 9.x

---------

Co-authored-by: Paul Popus <paul@nouance.io>
2024-03-14 15:41:20 -04:00
Dan Ribbens
04fcf57d0a Fix/alpha/int tests (#5311)
* chore: converts dynamic imports to esm require

* chore: adjusts require and import usage

* chore: reverts bin script change

* chore: adjust dataloaded tests to use slate editor

* fix: converts custom auth strategy

* chore: fixes to form builder int test config

* chore: adjusts plugin-stripe and int tests

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2024-03-12 16:27:43 -04:00
Alessio Gravili
da1326a336 chore: eslint perf improvements for test suite, make use of cascading for all eslint configs to minimize duplicative rule 2024-03-12 09:15:38 -04:00
Alessio Gravili
8895f6420f chore: fix all esm test suite imports 2024-03-08 14:42:24 -05:00
Jarrod Flesch
28c4046300 chore: more passing int suites 2024-02-16 15:09:51 -05:00
James
0f3b364e46 chore: hoists tests out of payload package 2023-09-01 14:45:41 -04:00
Alessio Gravili
a67278b29f chore: move to monorepo structure 2023-08-23 12:20:30 +02:00
Jarrod Flesch
641c765fb9 feat: solidifies bundler adapter pattern (#3044) 2023-07-21 17:20:51 -04:00
Jacob Fletcher
120e2936fe chore: removes cms text from instances of payload name (#2793) 2023-06-14 10:31:29 -04:00
James
3a8e730b9c chore: typo in tests 2023-02-07 14:40:33 -05:00
James
ac2e174643 fix: #1887, dataloader rich text population infinite loop 2023-02-07 14:35:37 -05:00
Dan Ribbens
040833ead8 test: move endpoints tests to new suite 2022-08-17 12:57:07 -04:00
James Mikrut
0a40dd43cb test: adds dataloader test (#936)
* chore: adds dataloader test config

* test: passing dataloader test
2022-08-14 11:04:05 -07:00