48 Commits

Author SHA1 Message Date
T. R. Bernstein
4a5f01a78f chore: Update code to new repo
Some checks failed
ci / changes (push) Has been cancelled
ci / lint (push) Has been cancelled
ci / build (push) Has been cancelled
ci / tests-unit (push) Has been cancelled
ci / tests-types (push) Has been cancelled
ci / int-cosmosdb (push) Has been cancelled
ci / int-documentdb (push) Has been cancelled
ci / int-firestore (push) Has been cancelled
ci / int-mongodb (push) Has been cancelled
ci / int-postgres (push) Has been cancelled
ci / int-postgres-custom-schema (push) Has been cancelled
ci / int-postgres-uuid (push) Has been cancelled
ci / int-sqlite (push) Has been cancelled
ci / int-sqlite-uuid (push) Has been cancelled
ci / int-supabase (push) Has been cancelled
ci / e2e-_community (push) Has been cancelled
ci / e2e-access-control (push) Has been cancelled
ci / e2e-admin-bar (push) Has been cancelled
ci / e2e-admin-root (push) Has been cancelled
ci / e2e-admin__e2e__document-view (push) Has been cancelled
ci / e2e-admin__e2e__general (push) Has been cancelled
ci / e2e-admin__e2e__list-view (push) Has been cancelled
ci / e2e-auth (push) Has been cancelled
ci / e2e-auth-basic (push) Has been cancelled
ci / e2e-bulk-edit (push) Has been cancelled
ci / e2e-field-error-states (push) Has been cancelled
ci / e2e-fields-relationship (push) Has been cancelled
ci / e2e-fields__collections__Array (push) Has been cancelled
ci / e2e-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-fields__collections__Blocks (push) Has been cancelled
ci / e2e-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-fields__collections__CustomID (push) Has been cancelled
ci / e2e-fields__collections__Date (push) Has been cancelled
ci / e2e-fields__collections__Email (push) Has been cancelled
ci / e2e-fields__collections__Indexed (push) Has been cancelled
ci / e2e-fields__collections__JSON (push) Has been cancelled
ci / e2e-fields__collections__Number (push) Has been cancelled
ci / e2e-fields__collections__Point (push) Has been cancelled
ci / e2e-fields__collections__Radio (push) Has been cancelled
ci / e2e-fields__collections__Relationship (push) Has been cancelled
ci / e2e-fields__collections__Row (push) Has been cancelled
ci / e2e-fields__collections__Select (push) Has been cancelled
ci / e2e-fields__collections__Tabs (push) Has been cancelled
ci / e2e-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-fields__collections__Text (push) Has been cancelled
ci / e2e-fields__collections__UI (push) Has been cancelled
ci / e2e-fields__collections__Upload (push) Has been cancelled
ci / e2e-folders (push) Has been cancelled
ci / e2e-form-state (push) Has been cancelled
ci / e2e-group-by (push) Has been cancelled
ci / e2e-hooks (push) Has been cancelled
ci / e2e-i18n (push) Has been cancelled
ci / e2e-joins (push) Has been cancelled
ci / e2e-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-lexical__collections__RichText (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-live-preview (push) Has been cancelled
ci / e2e-localization (push) Has been cancelled
ci / e2e-locked-documents (push) Has been cancelled
ci / e2e-plugin-cloud-storage (push) Has been cancelled
ci / e2e-plugin-form-builder (push) Has been cancelled
ci / e2e-plugin-import-export (push) Has been cancelled
ci / e2e-plugin-multi-tenant (push) Has been cancelled
ci / e2e-plugin-nested-docs (push) Has been cancelled
ci / e2e-plugin-seo (push) Has been cancelled
ci / e2e-query-presets (push) Has been cancelled
ci / e2e-sort (push) Has been cancelled
ci / e2e-trash (push) Has been cancelled
ci / e2e-uploads (push) Has been cancelled
ci / e2e-versions (push) Has been cancelled
ci / e2e-turbo-_community (push) Has been cancelled
ci / e2e-turbo-access-control (push) Has been cancelled
ci / e2e-turbo-admin-bar (push) Has been cancelled
ci / e2e-turbo-admin-root (push) Has been cancelled
ci / e2e-turbo-admin__e2e__document-view (push) Has been cancelled
ci / e2e-turbo-admin__e2e__general (push) Has been cancelled
ci / e2e-turbo-admin__e2e__list-view (push) Has been cancelled
ci / e2e-turbo-auth (push) Has been cancelled
ci / e2e-turbo-auth-basic (push) Has been cancelled
ci / e2e-turbo-bulk-edit (push) Has been cancelled
ci / e2e-turbo-field-error-states (push) Has been cancelled
ci / e2e-turbo-fields-relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Array (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks (push) Has been cancelled
ci / e2e-turbo-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-turbo-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-turbo-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-turbo-fields__collections__CustomID (push) Has been cancelled
ci / e2e-turbo-fields__collections__Date (push) Has been cancelled
ci / e2e-turbo-fields__collections__Email (push) Has been cancelled
ci / e2e-turbo-fields__collections__Indexed (push) Has been cancelled
ci / e2e-turbo-fields__collections__JSON (push) Has been cancelled
ci / e2e-turbo-fields__collections__Number (push) Has been cancelled
ci / e2e-turbo-fields__collections__Point (push) Has been cancelled
ci / e2e-turbo-fields__collections__Radio (push) Has been cancelled
ci / e2e-turbo-fields__collections__Relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Row (push) Has been cancelled
ci / e2e-turbo-fields__collections__Select (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-turbo-fields__collections__Text (push) Has been cancelled
ci / e2e-turbo-fields__collections__UI (push) Has been cancelled
ci / e2e-turbo-fields__collections__Upload (push) Has been cancelled
ci / e2e-turbo-folders (push) Has been cancelled
ci / e2e-turbo-form-state (push) Has been cancelled
ci / e2e-turbo-group-by (push) Has been cancelled
ci / e2e-turbo-hooks (push) Has been cancelled
ci / e2e-turbo-i18n (push) Has been cancelled
ci / e2e-turbo-joins (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-turbo-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-turbo-lexical__collections__RichText (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-turbo-live-preview (push) Has been cancelled
ci / e2e-turbo-localization (push) Has been cancelled
ci / e2e-turbo-locked-documents (push) Has been cancelled
ci / e2e-turbo-plugin-cloud-storage (push) Has been cancelled
ci / e2e-turbo-plugin-form-builder (push) Has been cancelled
ci / e2e-turbo-plugin-import-export (push) Has been cancelled
ci / e2e-turbo-plugin-multi-tenant (push) Has been cancelled
ci / e2e-turbo-plugin-nested-docs (push) Has been cancelled
ci / e2e-turbo-plugin-seo (push) Has been cancelled
ci / e2e-turbo-query-presets (push) Has been cancelled
ci / e2e-turbo-sort (push) Has been cancelled
ci / e2e-turbo-trash (push) Has been cancelled
ci / e2e-turbo-uploads (push) Has been cancelled
ci / e2e-turbo-versions (push) Has been cancelled
ci / build-template-blank-mongodb (push) Has been cancelled
ci / build-template-website-mongodb (push) Has been cancelled
ci / build-template-with-payload-cloud-mongodb (push) Has been cancelled
ci / build-template-with-vercel-mongodb-mongodb (push) Has been cancelled
ci / build-template-plugin- (push) Has been cancelled
ci / build-template-with-postgres-postgres (push) Has been cancelled
ci / build-template-with-vercel-postgres-postgres (push) Has been cancelled
ci / tests-type-generation (push) Has been cancelled
ci / All Green (push) Has been cancelled
ci / Publish Canary (push) Has been cancelled
ci / analyze (push) Has been cancelled
publish-prerelease / publish-prerelease-${{ github.ref_name }}-${{ github.sha }} (push) Has been cancelled
lock-issues / lock_issues (push) Has been cancelled
stale / stale (push) Has been cancelled
audit-dependencies / audit (push) Has been cancelled
activity-notifications / run (push) Has been cancelled
2025-10-08 23:27:45 +02:00
Jarrod Flesch
9a841df38c fix(examples): secure mt example users collection (#13810) 2025-09-15 18:31:00 -04:00
Jessica Rynkar
6e5ddc8873 fix(examples): only allow super admins to create users with super admin role (#13015)
### What?

This PR updates the `create` access control on the `users` collection in
the `multi-tenant` example to prevent unauthorized creation of
`super-admin` users.

### Why?

Previously, any authenticated user could create a new user and assign
them the `super-admin` role — even if they didn’t have that role
themselves. This bypassed role-based restrictions and introduced a
security vulnerability, allowing users to escalate their own privileges
by working around role restrictions during user creation.

### How?

The `create` access function now checks whether the current user has the
`super-admin` role before allowing the creation of another
`super-admin`. If not, the request is denied.


**Fixes:** `CMS2-Q225-01`
2025-07-02 15:42:55 +01:00
Jessica Rynkar
50029532aa fix(examples): checks requested tenant matches user tenant permissions (#13012)
### What

This PR updates the `create` access control functions in the
`multi-tenant` example to ensure that any `tenant` specified in a create
request matches a tenant the user has admin access to.

### Why

Previously, while the admin panel UI restricted the tenant selection, it
was still possible to bypass this by making a request directly to the
API with a different `tenant`. This allowed users to create documents
under tenants they shouldn't have access to.

### How

The `access` functions on the `users` and `pages` collections now
explicitly check whether the tenant(s) in the request are included in
the user's tenant permissions. If not, access is denied by returning
`false`.

**Fixes: CMS2-Q225-03**
2025-07-02 14:30:47 +01:00
Alessio Gravili
5f6bb92501 feat!: bump minimum next version to 15.2.3 (#11823)
**BREAKING CHANGE:**
This bumps the **minimum required Next.js** version from 15.0.0 to
15.2.3. This update is necessary due to a critical security
vulnerability found in earlier Next.js versions, which requires an
exception to our standard semantic versioning process.

Additionally, this bumps all templates to the latest Next.js and Payload
versions.
2025-03-24 09:41:33 -04:00
Jarrod Flesch
39d783a361 chore(plugin-multi-tenant): remove SELECT_ALL constant (#11660) 2025-03-12 11:23:03 -04:00
Jarrod Flesch
4ddf96502c fix(examples): ensure working multi-tenant example with pg (#11501)
### What?
There were a couple issues with the implementation within the example
when using postgres.
- `ensureUniqueUsername` tenant was being extracted incorrectly, should
not constrain query unless it was present
- `ensureUniqueSlug` was querying by NaN when tenant was not present on
data or originalDoc
- `users` read access was not correctly extracting the tenant id in the
correct type depending on DB

Fixes https://github.com/payloadcms/payload/issues/11484
2025-03-03 10:21:55 -05:00
Jarrod Flesch
81e8a9d50d chore(examples): update multi-tenant example (#11459)
Bumps deps inside examples repo lockfile. Fixes import map, supersedes
https://github.com/payloadcms/payload/pull/10804
2025-02-28 14:57:58 -05:00
Roy Barber
48e613b61f fix(examples): replace depreciated 'mergeHeaders' import in the MultiTenant example (#11306) 2025-02-28 17:13:46 +00:00
Jarrod Flesch
b65ae073d2 fix(plugin-multi-tenant): corrects default value for tenantsArrayTenantFieldName (#11189)
Incorrect default value on exported `tenantsArrayField` field. Should
have been `tenant` but was using `tenants`. This affected the
multi-tenant example which uses a custom tenants array field.

You would not notice this issue unless you were using:
```ts
tenantsArrayField: {
  includeDefaultField: false,
}
```

Fixes https://github.com/payloadcms/payload/issues/11125
2025-02-14 10:55:19 -05:00
Boyan Bratvanov
ae0736b738 examples: multi-tenant seed script, readme and other improvements (#10702) 2025-02-04 09:09:26 -05:00
Jacob Fletcher
82f1bb9864 perf: skips field validations until the form is submitted (#10580)
Field validations can be expensive, especially custom validations that
are async or highly complex. This can lead to slow form state response
times when generating form state for many such fields. Ideally, we only
run validations on fields whose values have changed. This is not
possible, however, because field validation functions might reference
_other_ field values with their args, and there is no good way of
detecting exactly which fields should run in this case. The next best
thing here is to only run validations _after the form has been
submitted_, and then every `onChange` event thereafter until a
successful submit has taken place. This is an elegant solution because
we currently don't _render_ field errors until submission anyway.

This change will significantly speed up form state response times, at
least until the form has been submitted. From then on, all field
validations will run regardless, just as they do now. If custom
validations continue to slow down form state response times, there is a
new `event` arg introduced in #10738 that can be used to control whether
heavy operations occur on change or on submit.

Related: #10638
2025-01-27 20:21:33 +00:00
Jarrod Flesch
e6d02600e1 fix(plugin-multi-tenant): selected tenant could become incorrect when navigating out of doc (#10723)
### What?
When switching tenants from within a document and then navigating back
out to the list view, the tenant would not be set correctly.

### Why?
This was because we handle the tenant selector selection differently
when viewing a document.

### How?
Now when you navigate out, the page will refresh the cookie.

Also adds test suite config that shows how the dom can be used to
manipulate styles per tenant.
2025-01-22 11:37:18 -05:00
Jarrod Flesch
a9c08323cc fix(plugin-multi-tenant): prevent throwing when no user exists (#10699)
### What?
Fixes issue where the provider would throw an error and prevent the
login screen from loading if there was no user.

### Why?
Missing try/catch around tenant find for the provider. (Missed because
test suites have autoLogin: true)

### How?
Adds try/catch around find query.
2025-01-21 12:07:47 -05:00
Jarrod Flesch
813e70be1f feat: adds multi-tenant plugin (#10447)
### Multi Tenant Plugin
This PR adds a `@payloadcms/plugin-multi-tenant` package. The goal is to
consolidate a source of truth for multi-tenancy. Currently we are
maintaining different implementations for clients, users in discord and
our examples repo. When updates or new paradigms arise we need to
communicate this with everyone and update code examples which is hard to
maintain.

### What does it do?
- adds a tenant selector to the sidebar, above the nav links
- adds a hidden tenant field to every collection that you specify
- adds an array field to your users collection, allowing you to assign
users to tenants
- by default combines the access control (to enabled collections) that
you define, with access control based on the tenants assigned to user on
the request
- by default adds a baseListFilter that filters the documents shown in
the list view with the selected tenant in the admin panel

### What does it not do?
- it does not implement multi-tenancy for your frontend. You will need
to query data for specific tenants to build your website/application
- it does not add a tenants collection, you **NEED** to add a tenants
collection, where you can define what types of fields you would like on
it

### The plugin config

Most of the options listed below are _optional_, but it is easier to
just lay out all of the configuration options.

**TS Type**
```ts
type MultiTenantPluginConfig<ConfigTypes = unknown> = {
  /**
   * After a tenant is deleted, the plugin will attempt to clean up related documents
   * - removing documents with the tenant ID
   * - removing the tenant from users
   *
   * @default true
   */
  cleanupAfterTenantDelete?: boolean
  /**
   * Automatically
   */
  collections: {
    [key in CollectionSlug]?: {
      /**
       * Set to `true` if you want the collection to behave as a global
       *
       * @default false
       */
      isGlobal?: boolean
      /**
       * Set to `false` if you want to manually apply the baseListFilter
       *
       * @default true
       */
      useBaseListFilter?: boolean
      /**
       * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied
       *
       * @default true
       */
      useTenantAccess?: boolean
    }
  }
  /**
   * Enables debug mode
   * - Makes the tenant field visible in the admin UI within applicable collections
   *
   * @default false
   */
  debug?: boolean
  /**
   * Enables the multi-tenant plugin
   *
   * @default true
   */
  enabled?: boolean
  /**
   * Field configuration for the field added to all tenant enabled collections
   */
  tenantField?: {
    access?: RelationshipField['access']
    /**
     * The name of the field added to all tenant enabled collections
     *
     * @default 'tenant'
     */
    name?: string
  }
  /**
   * Field configuration for the field added to the users collection
   *
   * If `includeDefaultField` is `false`, you must include the field on your users collection manually
   * This is useful if you want to customize the field or place the field in a specific location
   */
  tenantsArrayField?:
    | {
        /**
         * Access configuration for the array field
         */
        arrayFieldAccess?: ArrayField['access']
        /**
         * When `includeDefaultField` is `true`, the field will be added to the users collection automatically
         */
        includeDefaultField?: true
        /**
         * Additional fields to include on the tenants array field
         */
        rowFields?: Field[]
        /**
         * Access configuration for the tenant field
         */
        tenantFieldAccess?: RelationshipField['access']
      }
    | {
        arrayFieldAccess?: never
        /**
         * When `includeDefaultField` is `false`, you must include the field on your users collection manually
         */
        includeDefaultField?: false
        rowFields?: never
        tenantFieldAccess?: never
      }
  /**
   * The slug for the tenant collection
   *
   * @default 'tenants'
   */
  tenantsSlug?: string
  /**
   * Function that determines if a user has access to _all_ tenants
   *
   * Useful for super-admin type users
   */
  userHasAccessToAllTenants?: (
    user: ConfigTypes extends { user: User } ? ConfigTypes['user'] : User,
  ) => boolean
}
```

**Example usage**
```ts
import type { Config } from './payload-types'
import { buildConfig } from 'payload'

export default buildConfig({
  plugins: [
    multiTenantPlugin<Config>({
      collections: {
        pages: {},
      },
      userHasAccessToAllTenants: (user) => isSuperAdmin(user),
    }),
  ],
})
```


### How to configure Collections as Globals for multi-tenant

When using multi-tenant, globals need to actually be configured as
collections so the content can be specific per tenant.
To do that, you can mark a collection with `isGlobal` and it will behave
like a global and users will not see the list view.

```ts
multiTenantPlugin({
  collections: {
    navigation: {
      isGlobal: true,
    },
  },
})
```
2025-01-15 14:47:46 -05:00
Sasha
6b4842d44d feat(cpa): create project from example using --example CLI arg (#10172)
Adds the ability to create a project using an existing in the Payload
repo example through `create-payload-app`:

For example:
`pnpx create-payload-app --example custom-server` - creates a project
from the
[custom-server](https://github.com/payloadcms/payload/tree/main/examples/custom-server)
example.

This is much easier and faster then downloading the whole repo and
copying the example to another folder.
Note that we don't configure the payload config with the storage / DB
adapter there because examples can be very specific.
2024-12-27 20:16:34 +02:00
Alessio Gravili
8f3f44922e feat: upgrade to React 19 stable and Next.js 15.0.4 (#9801)
No need for those ugly @types/react overrides anymore!
2024-12-06 14:53:36 -05:00
Sasha
4a854f86ae chore(examples): multi-tenant compatible with postgres ID check (#9568)
Fixes https://github.com/payloadcms/payload/issues/9565 multi-tenant
compatibility with Postgres (and custom IDs)

Adds a useful `extractID` utility:
```ts
import { Config } from '@/payload-types'
import type { CollectionSlug } from 'payload'

export const extractID = <T extends Config['collections'][CollectionSlug]>(
  objectOrID: T | T['id'],
): T['id'] => {
  if (objectOrID && typeof objectOrID === 'object') return objectOrID.id

  return objectOrID
}
```
2024-11-27 11:27:44 -05:00
Jacob Fletcher
b61622019e chore(examples): removes external auth examples (#8605)
In effort to keep the Examples Directory as easy to navigate as
possible, and to keep the Payload Monorepo only as verbose as it needs
to be, we need to remove all alternatives from the Examples Directory.
This includes setups that interact with Payload from a standalone
server, keeping only the Payload recommended "combined" Next.js +
Payload setups. This will also be applied to all other examples that use
this setup, i.e. draft preview, live preview, etc.
2024-11-26 19:07:56 +00:00
Alessio Gravili
13fc94dc4d chore: upgrade to TypeScript 5.7, ensure tsconfig targed and lib properties match the APIs we support (#9473)
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
2024-11-23 16:35:27 -07:00
Patrik
f338c5c40c chore(examples): updates custom-components,email & multi-tenant to latest payload version (#9411)
### What?

Although the following examples:

- `custom-components`
- `email`
- `multi-tenant`

were recently migrated to 3.0 - they were still using the latest `beta`
version instead of latest payload (i.e `3.0`)
2024-11-21 14:56:34 -05:00
Jarrod Flesch
7989563bc1 chore: updates multi tenant example to use baseListFilter (#9308)
### What?
Implements new `baseListFilter` into the multi-tenant example

---------

Co-authored-by: Patrik Kozak <patrik@payloadcms.com>
2024-11-18 15:59:54 -05:00
Patrik
7babe6bcf5 chore(examples): migrates multi-tenant example to latest beta (#9300) 2024-11-18 15:45:20 -05:00
James Mikrut
31b32ef941 feat: deprecates getPayloadHMR in favor of simpler getPayload (#9249)
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.
2024-11-16 15:30:05 -05:00
Paul
f4d526d6e5 fix: fallbackLocale not respecting default settings, locale specific fallbacks and not respecting 'none' or false (#8591)
This PR fixes and improves a few things around localisation and
fallbackLocale:
- For the REST API `fallbackLocale` and `fallback-locale` are treated
the same for consistency with the Local API
- `fallback: false` in config is now respected, by default results will
not fallback to `defaultLocale` unless this config is true, can also be
overridden by providing an explicit `fallbackLocale` in the request
- locale specific fallbacks will now take priority over `defaultLocale`
unless an explicit fallback is provided
- Fixes types on operations to allow `'none'` as a value for
fallbackLocale
- `fallback` is now true by default if unspecified

Closes https://github.com/payloadcms/payload/issues/8443
2024-11-13 12:13:31 -06: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
Paul
6b9f178fcb fix: graphql missing options route resulting in failed cors preflight checks in production (#8987)
GraphQL currently doesn't pass CORS checks as we don't expose an OPTIONS
endpoint which is used for browser preflights.

Should also fix situations like this
https://github.com/payloadcms/payload/issues/8974
2024-11-04 14:20:09 -05:00
Jarrod Flesch
a9c6a91c1c chore(examples): correct where path comes from in multi-tenant (#8698) 2024-10-16 08:28:28 -04:00
Patrik
4343b970eb chore(examples): adds optional tenant-based cookie handling by domain in multi-tenant example (#8490)
- Adds optional tenant-based cookie handling based by domain (commented
out to leave functionality out by default)

- Removes 2.0 multi-tenant example

- Updates `examples/multi-tenant-single-domain` -->
`examples/multi-tenant`
2024-10-09 14:32:48 -04:00
Elliot DeNolf
08fdbcacc0 chore: proper error log format (#8105)
Fix some error log formatting to use `{ msg, err }` properly
2024-09-07 02:48:59 +00:00
Alessio Gravili
86fdad0bb8 chore: significantly improve eslint performance, lint and prettier everything 2024-08-29 21:25:50 -04:00
Elliot DeNolf
a4ef359660 chore: examples linting (#6269) 2024-05-08 14:58:57 -04:00
Alessio Gravili
b70bf81d6c chore: fix all eslint configs to work with esm 2024-03-06 12:48:15 -05:00
Dan Ribbens
b9dec2f714 Chore/next poc merge main (#5204)
* wip moves payload, user and data into partial req

* chore: adjust req type

* chore(next): installs sass and resolves type errors

* feat: working login route/view

* fix: me route

* chore(next): scaffolds access routes (#4562)

* chore(next): scaffolds admin layout and dashboard view (#4566)

* chore(next): builds initPage utility (#4589)

* feat(3.0): next route handlers (#4590)

* chore: removes old files

* chore(next): ssr list view (#4594)

* chore: removes old files

* chore: adjusts graphql file imports to align with new operation exports

* chore: allows for custom endpoints

* chore: cleanup

* chore(next): ssr edit view (#4614)

* chore(ui): ssr main nav (#4619)

* chore(next): ssr account view (#4620)

* chore(next): ssr auth views and document create (#4631)

* chore(next): ssr globals view (#4640)

* chore(next): scaffolds document layout (#4644)

* chore(next): ssr versions view (#4645)

* chore(next): ssr field conditions (#4675)

* chore(next): ssr field validations (#4700)

* chore(next): moves dashboard view into next dir

* chore(next): moves account view into next dir

* chore(next): moves global edit view into next dir

* chore(next): returns isolated configs and locale from initPage

* chore(next): ssr api view (#4721)

* feat: adds i18n functionality within Rest API, Local and Client contexts (#4749)

* chore: separate client translation groups with empty line

* chore: add missing translation used in db adapters

* chore: simplify next/routes export and import paths

* chore: renames PayloadT to Payload

* chore(next): custom views (#4748)

* chore: fix translation tsconfig

* chore: adjust other package ts-configs that rely on translations

* chore(next): installs @payloadcms/ui as direct dependency

* chore(next): progress to build

* chore(next): migrates types (#4792)

* fixes acccept-language detection

* chore(next): moves remaining components out from payload core (#4794)

* chore(deps): removes all unused dependencies from payload core (#4797)

* chore(next): achieves buildable state (#4803)

* adds Translation component and removes more react-i18next

* fixes up remaining translation strings

* fixes a few i18n TODO's

* chore: remaining translation strings without colons

* chore: adds missing ja translations

* chore(next): ssr group field (#4830)

* chore: removes placeholder t function

* chore: removes old file

* chore(bundler-webpack): removes webpack bundler

* chore(bundler-vite): removes vite bundler

* chore(next): ssr tabs field (#4863)

* chore(next): ssr row field

* chore(next): ssr textarea field

* chore(next): wires server action into document edit view (#4873)

* chore(next): conditional logic (#4880)

* chore(next): ssr radio, point, code, json, ui, and hidden fields (#4891)

* chore(next): ssr collapsible field (#4894)

* chore: remove findByID from req

* chore: adjusts file property on request type

* comment clarification

* chore: wires up busboy with Requst readstream

* chore: ports over express-fileupload into a NextJS compatible format

* chore: adjust upload file structure

* chore: adds try/catch around routes, corrects a few route responses

* chore: renames file/function

* chore: improve req type safety in local operations, misc req.files replacements

* chore: misc type and fn export changes

* chore: ensures root routes take pass unmodified request to root routes

* chore: improve types

* chore: consolidates locale api req initialization (#4922)

* chore(next): overhauls field rendering strategy (#4924)

* chore(next): ssr array field (#4937)

* chore(next): ssr blocks field (#4942)

* chore(next): ssr upload field and document drawer (#4957)

* chore(next): wires form submissions (#4982)

* chore: api handler adjustments

* feat: adds graphql playground handler

* adds credentials include setting to playground

* remove old playground init, stub graphql handler location

* fix: allow for null fallbackLocale

* fix: correctly prioritize locales passed as null

* chore: move all graphql code into next package

* graphql changes

* chore: semi working version of graphql http layer

* gql fix attempts

* rm console log

* chore: partial gql changes

* chore: adds gql and gql-http back into payload

* chore: removes collection from req

* chore: separates graphql package out for schema generation

* chore: dep cleanup

* chore: move graphql handlers

* chore: removes unused deps

* chore(next): ssr list view (#5032)

* chore: refactor response handler order for custom endpoints

* chore: add back in condition for collection GET path with 2 slugs

* chore: rm optional chain

* chore: import sort route file

* chore: allows custom endpoints to attempt before erroring

* feat: adds memoization to translation functions (#5036)

* chore: fix APIError import

* chore: return attemptCustomEndpointBeforeError responses

* chore(next): properly instantiates table columns

* fix(next): attaches params to req and properly assigns prefs key (#5042)

* chore: reorganize next route order

* chore(next): adds RouteError handler to next routes

* chore: builds payload successfully

* chore: misc file omissions

* fix(ui): maintains proper column order

* fix(ui): ensures first cell is a link

* fix(next): properly copies url object in createPayloadRequest (#5064)

* fix(ui): bumps react-toastify to v10.0.4 to fix hydration warnings

* feat: add route for static file GET requests (#5065)

* chore(next): allows resolved config promise to be thread through initPage (#5071)

* chore(ui): conditionally renders field label from props

* feat(next): next install script

* chore: pass config to route handlers

* feat: initial test suite framework (#4929)

* chore(next): renderable account, api, and create first user views (#5084)

* fix(next): properly parses search params in find, update, and delete handlers (#5088)

* chore(next): ssr versions view (#5085)

* chore: adds homepage for scss testing

* chore: moves dev folder to top, establishes new test pattern

* chore: working turbopack

* chore: sets up working dynamic payload-config imports

* remove unused code

* chore: rm console log

* misc

* feat: correctly subs out ability to boot REST API within same process

* chore: WIP dev suites

* chore: removes need for REST_API folder in test dir

* removes duplicate bootAdminPanel fn

* misc

* specify default export

* chore: sets up jest to work with next/jest

* chore: progress to mongodb and sharp builds

* chore: passing community tests

* chore: sorta workin

* chore: adjust payload-config import

* chore: adds rest client for Next handlers

* chore: removes test garb

* chore: restores payload-config tsconfig path temporarily

* chore: establishes pattern for memory db during tests

* chore: bumps mongoose to 7

* chore(next): 404s on nested create urls

* chore: functional _community e2e

* chore: increases e2e expect timeout

* fix(next): sanitizes locale toString from client config

* chore: type fixes

* chore: pulls mongodb from main

* chore: uses graphql to log user in

* feat: passing auth test suite

* chore(ui): threads params through context and conditionally renders document tabs (#5094)

* feat(ui): adds params context (#5095)

* chore: removes unecessary memory allocation for urlPropertiesObject object

* chore: passing graphql test suite

* chore: removes references to bson

* chore: re-enables mongodb memory server for auth test suite

* chore: replace bson with bson-objectid

* feat: passing collections-rest int suite

* chore: fixes bad imports

* chore: more passing int suites

* feat: passing globals int tests

* feat: passing hooks int test suite

* chore: remove last express file

* chore: start live-preview int test migration

* chore: passing localization int tests

* passing relationships int tests

* chore: partial passing upload int tests

* chore: fixes scss imports

* chore(ui): renders document info provider at root (#5106)

* chore: adds schema path to useFieldPath provider, more passing tests

* chore: begins work to optimize translation imports

* chore: add translations to ui ts-config references

* chore: add exports folder to package json exports

* chore: adds readme how-to-use instructions

* chore: attempts refactor of translation imports

* chore: adds authentication:account translation key to server keys

* chore: finishes translation optimization

* chore: ignores warnings from mongodb

* chore(ui): renders live document title (#5115)

* chore(ui): ssr document tabs (#5116)

* chore: handles redirecting from login

* chore: handle redirect with no searchParams

* chore: handle missing segments

* chore(next): migrates server action into standalone api endpoint (#5122)

* chore: adjust dashboard colection segments

* test: update e2e suites

* fix(ui): prevents unnecessary calls to form state

* chore: fix finding global config fields from schema path

* fix(next): executes root POST endpoints

* chore(ui): ignores values returned by form state polling

* chore: scaffolds ssr rte

* chore: renders client leaves

* chore: server-side rendered rich text elements

* chore: defines ClientFunction pattern

* chore(ui): migrates relationship field

* chore: adds translations, cleans up slate

* chore: functional slate link

* chore: slate upload ssr

* chore: relationship slate ssr

* chore: remaining slate ssr

* chore: fixes circular workspace dep

* chore: correct broken int test import paths

* chore: remove media files from root

* chore: server renders custom edit view

* fix(ui): resolves infinite loading in versions view

* fix(next): resolves global edit view lookup

* chore: payload builds

* chore: delete unused files

* chore: removes local property from payload

* chore: adds mongodb as dev dep in db-mongodb package

* chore: hide deprecation warnings for tempfile and jest-environment-jsdom

* chore: remove all translations from translations dist

* chore: clean ts-config files

* chore: simple type fixes

* chore(ui): server renders custom list view

* chore: fix next config payload-config alias

* chore: adds turbo alias paths

* chore: adjusts translation generation

* chore: improve auth function

* chore: eslint config for packages/ui

* chore(ui): exports FormState

* chore(next): migrates account view to latest patterns

* chore: disable barbie mode

* chore(ui): lints

* chore(next): lints

* chore: for alexical

* chore: custom handler type signature adjustment

* fix: non-boolean condition result causes infinite looping (#4579)

* chore(richtext-lexical): upgrade lexical from v0.12.5 to v0.12.6 (#4732)

* chore(richtext-lexical): upgrade all lexical packages from 0.12.5 to 0.12.6

* fix(richtext-lexical): fix TypeScript errors

* fix indenting

* feat(richtext-lexical): Blocks: generate type definitions for blocks fields (#4529)

* feat(richtext-lexical)!: Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground (#5066)

* feat(richtext-lexical): Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground

* chore: upgrade lexical version used in monorepo

* chore: remove the 3

* chore: upgrade nodemon versions (#5059)

* feat: add more options to addFieldStatePromise so that it can be used for field flattening (#4799)

* feat(plugin-seo)!: remove support for payload <2.7.0 (#4765)

* chore(plugin-seo): remove test script from package.json (#4762)

* chore: upgrade @types/nodemailer from v6.4.8 to v6.4.14 (#4733)

* chore: revert auth and initPage changes

* chore(next): moves edit and list views (#5170)

* fix: "The punycode module is deprecated" warning by updating nodemailer

* chore: adjust translations tsconfig paths in root

* chore: fix merge build

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
Co-authored-by: Elliot DeNolf <denolfe@gmail.com>
Co-authored-by: James <james@trbl.design>
Co-authored-by: Alessio Gravili <alessio@gravili.de>
Co-authored-by: Alessio Gravili <70709113+AlessioGr@users.noreply.github.com>
2024-02-28 13:44:17 -05:00
Jacob Fletcher
d8f265fb94 chore(examples): bumps deps to latest (#3655) 2023-10-14 16:49:47 -04:00
Elliot DeNolf
a154adf066 chore(examples): update nodemon to respond to prompts 2023-10-10 18:37:33 -04:00
Jacob Fletcher
b5c56efb4b chore(examples/multi-tenant): migrates to 2.0 (#3512) 2023-10-09 14:02:44 -04:00
Elliot DeNolf
b398c44bfe chore: update all references to main in docs, examples, and templates 2023-10-08 19:45:54 -04:00
Jacob Fletcher
360291c407 chore: merges examples 2023-10-08 16:57:52 -04:00
Elliot DeNolf
986ceea246 chore: nodemon stdin:false, -I flag 2023-10-05 16:49:58 -04:00
Elliot DeNolf
2ad94e48f7 chore: add stdin: true to all nodemon.json files 2023-10-03 12:42:22 -04:00
Jarrod Flesch
156c3eeb08 chore: adds updated yarn lock files for examples and templates folders 2023-07-25 14:22:53 -04:00
Jarrod Flesch
9755a55672 chore: sets payload to latest within templates and examples 2023-07-25 14:11:33 -04:00
Jarrod Flesch
a69c3ec476 chore: updates example folder mongodb uri's to work with node 18 2023-07-18 16:51:22 -04:00
Jacob Fletcher
120e2936fe chore: removes cms text from instances of payload name (#2793) 2023-06-14 10:31:29 -04:00
Jacob Fletcher
1aa257df4b chore: uses discord vanity urls (#2786) 2023-06-06 15:07:24 -04:00
Jacob Fletcher
908d5747a8 chore: allows super-admins to view as tenant in multi-tenant example (#2719) 2023-05-30 13:10:14 -04:00
Jacob Fletcher
2fc9288870 feat: builds multi-tenant example (#2689)
* feat: builds multi-tenant example

* chore: updates seed script logic
2023-05-23 16:40:18 -04:00