chore: run lint & prettier on everything

This commit is contained in:
Alessio Gravili
2024-03-14 23:53:47 -04:00
parent 051fdfb081
commit 6789e61488
695 changed files with 7321 additions and 5142 deletions

View File

@@ -33,7 +33,7 @@ import { webpackBundler } from '@payloadcms/bundler-webpack'
export default buildConfig({
// highlight-start
admin: {
bundler: webpackBundler() // or viteBundler()
bundler: webpackBundler(), // or viteBundler()
},
// highlight-end
})
@@ -48,7 +48,7 @@ Since the bundled file is sent to the browser, it can't include any server-only
<Banner type="warning">
<strong>Using environment variables in the admin UI</strong>
<br />
Bundles should not contain sensitive information. By default, Payload
excludes env variables from the bundle. If you need to use env variables in your payload config,
you need to prefix them with `PAYLOAD_PUBLIC_` to make them available to the client-side code.
Bundles should not contain sensitive information. By default, Payload excludes env variables from
the bundle. If you need to use env variables in your payload config, you need to prefix them with
`PAYLOAD_PUBLIC_` to make them available to the client-side code.
</Banner>

View File

@@ -13,8 +13,8 @@ To swap in your own React component, first, consult the list of available compon
<Banner type="success">
<strong>Tip:</strong>
<br />
Custom components will automatically be provided with all props that the default component normally
accepts.
Custom components will automatically be provided with all props that the default component
normally accepts.
</Banner>
### Base Component Overrides
@@ -22,7 +22,7 @@ To swap in your own React component, first, consult the list of available compon
You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
| Path | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
@@ -78,7 +78,7 @@ export default buildConfig({
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| --------------- | ----------------------------------------------------------------------------- |
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`Dashboard`** | The main landing page of the Admin panel. |
@@ -135,7 +135,10 @@ To add a _new_ view to the Admin Panel, simply add another key to the `views` ob
<Banner type="warning">
<strong>Note:</strong>
<br />
Routes are cascading. This means that unless explicitly given the `exact` property, they will match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all routes in your application. Alternatively, you could define your nested route _before_ your parent route.
Routes are cascading. This means that unless explicitly given the `exact` property, they will
match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all
routes in your application. Alternatively, you could define your nested route _before_ your parent
route.
</Banner>
_For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
@@ -214,7 +217,7 @@ export const MyCollection: SanitizedCollectionConfig = {
PreviewButton: CustomPreviewButton,
},
},
}
},
}
```
@@ -223,7 +226,7 @@ export const MyCollection: SanitizedCollectionConfig = {
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| ---------- | ------------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
| **`List`** | The List view is used to show a list of documents for a given collection. |
@@ -311,7 +314,7 @@ As with Collections, you can override components on a global-by-global basis via
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| ---------- | ------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
@@ -380,7 +383,7 @@ You can also add _new_ tabs to the `Edit` view by adding another key to the `com
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **`Default`** | The Default view is the primary view in which your document is edited. |
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
@@ -396,7 +399,8 @@ export const MyCollection: SanitizedCollectionConfig = {
admin: {
components: {
views: {
Edit: { // You can also define `components.views.Edit` as a component, this will override _all_ nested views
Edit: {
// You can also define `components.views.Edit` as a component, this will override _all_ nested views
Default: MyCustomDefaultTab,
Versions: MyCustomVersionsTab,
Version: MyCustomVersionTab,
@@ -423,7 +427,7 @@ export const MyCollection: SanitizedCollectionConfig = {
Component: MyCustomTab,
path: '/my-custom-tab',
// You an swap the entire tab component out for your own
Tab: MyCustomTab
Tab: MyCustomTab,
},
AnotherCustomView: {
Component: AnotherCustomView,
@@ -432,7 +436,7 @@ export const MyCollection: SanitizedCollectionConfig = {
Tab: {
label: 'Another Custom View',
href: '/another-custom-view',
}
},
},
},
},
@@ -539,7 +543,6 @@ const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
const { value, setValue } = useField<string>({ path })
// highlight-end
return <input onChange={(e) => setValue(e.target.value)} value={value} />
}
```
@@ -554,7 +557,7 @@ const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
These are the props that will be passed to your custom Label.
| Property | Description |
| ---------------- | ---------------------------------------------------------------- |
| -------------- | ---------------------------------------------------------------- |
| **`htmlFor`** | Property used to set `for` attribute for label. |
| **`label`** | Label value provided in field, it can be used with i18n. |
| **`required`** | A boolean value that represents if the field is required or not. |
@@ -579,10 +582,12 @@ const CustomLabel: React.FC<Props> = (props) => {
const { i18n } = useTranslation()
if (label) {
return (<span>
return (
<span>
{getTranslation(label, i18n)}
{required && <span className="required">*</span>}
</span>);
</span>
)
}
return null
@@ -594,7 +599,7 @@ const CustomLabel: React.FC<Props> = (props) => {
These are the props that will be passed to your custom Error.
| Property | Description |
| ---------------- | ------------------------------------------------------------- |
| --------------- | ------------------------------------------------------------- |
| **`message`** | The error message. |
| **`showError`** | A boolean value that represents if the error should be shown. |
@@ -613,7 +618,7 @@ const CustomError: React.FC<Props> = (props) => {
if (showError) {
return <p style={{ color: 'red' }}>{message}</p>
} else return null;
} else return null
}
```
@@ -630,7 +635,15 @@ import { Field } from 'payload/types'
import './style.scss'
const ClearButton: React.FC = () => {
return <button onClick={() => {/* ... */}}>X</button>
return (
<button
onClick={() => {
/* ... */
}}
>
X
</button>
)
}
const titleField: Field = {
@@ -638,12 +651,12 @@ const titleField: Field = {
type: 'text',
admin: {
components: {
afterInput: [ClearButton]
}
}
afterInput: [ClearButton],
},
},
}
export default titleField;
export default titleField
```
## Custom providers

View File

@@ -104,6 +104,7 @@ By default the browser bundle will now include all the code from that file and a
To fix this, we need to alias the `createStripeSubscription` file to a different file that can safely be included in the browser bundle.
First, we will create a mock file to replace the server-only file when bundling:
```js
// mocks/modules.js
@@ -131,7 +132,7 @@ import { Subscriptions } from './collections/Subscriptions'
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
const fullFilePath = path.resolve(
__dirname,
'collections/Subscriptions/hooks/createStripeSubscription'
'collections/Subscriptions/hooks/createStripeSubscription',
)
export default buildConfig({
@@ -173,24 +174,23 @@ export default buildConfig({
admin: {
bundler: viteBundler(),
vite: (incomingViteConfig) => {
const existingAliases = incomingViteConfig?.resolve?.alias || {};
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
const existingAliases = incomingViteConfig?.resolve?.alias || {}
let aliasArray: { find: string | RegExp; replacement: string }[] = []
// Pass the existing Vite aliases
if (Array.isArray(existingAliases)) {
aliasArray = existingAliases;
aliasArray = existingAliases
} else {
aliasArray = Object.values(existingAliases);
aliasArray = Object.values(existingAliases)
}
// highlight-start
// Add your own aliases using the find and replacement keys
// remember, vite aliases are exact-match only
aliasArray.push({
find: '../server-only-module',
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
});
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js'),
})
// highlight-end
return {
@@ -198,8 +198,8 @@ export default buildConfig({
resolve: {
...(incomingViteConfig?.resolve || {}),
alias: aliasArray,
},
}
};
},
},
})

View File

@@ -640,7 +640,7 @@ export const CustomArrayManager = () => {
The `useCollapsible` hook allows you to control parent collapsibles:
| Property | Description |
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
| ----------------------- | ------------------------------------------------------------------------------------------------------------ | --- |
| **`collapsed`** | State of the collapsible. `true` if open, `false` if collapsed |
| **`isVisible`** | If nested, determine if the nearest collapsible is visible. `true` if no parent is closed, `false` otherwise |
| **`toggle`** | Toggles the state of the nearest collapsible |
@@ -671,7 +671,7 @@ const CustomComponent: React.FC = () => {
The `useDocumentInfo` hook provides lots of information about the document currently being edited, including the following:
| Property | Description |
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **`collection`** | If the doc is a collection, its collection config will be returned |
| **`global`** | If the doc is a global, its global config will be returned |
| **`id`** | If the doc is a collection, its ID will be returned |
@@ -804,10 +804,12 @@ const MyComponent: React.FC = () => {
return (
<>
<span>The current theme is {theme} and autoMode is {autoMode}</span>
<span>
The current theme is {theme} and autoMode is {autoMode}
</span>
<button
type="button"
onClick={() => setTheme(prev => prev === "light" ? "dark" : "light")}
onClick={() => setTheme((prev) => (prev === 'light' ? 'dark' : 'light'))}
>
Toggle theme
</button>
@@ -833,10 +835,7 @@ const MyComponent: React.FC = () => {
// highlight-end
return (
<button
type="button"
onClick={resetColumns}
>
<button type="button" onClick={resetColumns}>
Reset columns
</button>
)
@@ -848,7 +847,7 @@ const MyComponent: React.FC = () => {
The `useDocumentEvents` hook provides a way of subscribing to cross-document events, such as updates made to nested documents within a drawer. This hook will report document events that are outside the scope of the document currently being edited. This hook provides the following:
| Property | Description |
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **`mostRecentUpdate`** | An object containing the most recently updated document. It contains the `entitySlug`, `id` (if collection), and `updatedAt` properties |
| **`reportUpdate`** | A method used to report updates to documents. It accepts the same arguments as the `mostRecentUpdate` property. |
@@ -860,14 +859,11 @@ import { useDocumentEvents } from 'payload/components/hooks'
const ListenForUpdates: React.FC = () => {
const { mostRecentUpdate } = useDocumentEvents()
return (
<span>
{JSON.stringify(mostRecentUpdate)}
</span>
)
return <span>{JSON.stringify(mostRecentUpdate)}</span>
}
```
<Banner type="info">
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future it will track more document-related events as needed, such as document creation, deletion, etc.
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future
it will track more document-related events as needed, such as document creation, deletion, etc.
</Banner>

View File

@@ -6,7 +6,8 @@ desc: NEEDS TO BE WRITTEN
---
<Banner type="info">
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love
to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
</Banner>
Payload has a Vite bundler that you can install and bundle the Admin Panel with. This is an alternative to the [Webpack](/docs/admin/webpack) bundler and might give some performance boosts to your development workflow.
@@ -27,7 +28,7 @@ export default buildConfig({
collections: [],
admin: {
bundler: viteBundler(),
}
},
})
```
@@ -36,7 +37,8 @@ Vite works fundamentally differently than Webpack. In development mode, it will
It then uses Rollup to create production builds of your admin UI. With Vite, you should see a decent performance boost—especially after your first cold start. However, that first cold start might take a few more seconds.
<Banner type="warning">
In most cases, Vite should work out of the box. But existing Payload plugins may need to make compatibility changes to support Vite.
In most cases, Vite should work out of the box. But existing Payload plugins may need to make
compatibility changes to support Vite.
</Banner>
This is because Vite aliases work fundamentally differently than Webpack aliases, and Payload relies on aliasing server-only code out of the Payload config to ensure that the bundled admin JS works within your browser.

View File

@@ -27,7 +27,7 @@ import { webpackBundler } from '@payloadcms/bundler-webpack'
export default buildConfig({
// highlight-start
admin: {
bundler: webpackBundler()
bundler: webpackBundler(),
},
// highlight-end
})

View File

@@ -49,7 +49,8 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
<strong>Important:</strong>
If you change your `PAYLOAD_SECRET`, you will need to regenerate your API keys.
<br />
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will no longer be valid.
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will
no longer be valid.
</Banner>
#### Authenticating via API Key

View File

@@ -57,12 +57,7 @@ export const Admins: CollectionConfig = {
name: 'role',
type: 'select',
required: true,
options: [
'user',
'admin',
'editor',
'developer',
],
options: ['user', 'admin', 'editor', 'developer'],
},
],
}

View File

@@ -14,7 +14,7 @@ It's often best practice to write your Collections in separate files and then im
## Options
| Option | Description |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
@@ -68,7 +68,7 @@ You can customize the way that the Admin panel behaves on a collection-by-collec
property on a collection's config.
| Option | Description |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
@@ -129,7 +129,7 @@ export const Posts: CollectionConfig = {
Here are a few options that you can specify options for pagination on a collection-by-collection basis:
| Option | Description |
|----------------|-----------------------------------------------------------------------------------------------------|
| -------------- | --------------------------------------------------------------------------------------------------- |
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List view. |

View File

@@ -66,7 +66,7 @@ You can find a few [example Global configs](https://github.com/payloadcms/public
You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a Global's config.
| Option | Description |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |

View File

@@ -105,7 +105,7 @@ language and country codes (ISO 31661) such as `en-US`, `en-UK`, `es-MX`, etc
### Locale Properties:
| Option | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale` |
| **`label`** | A string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use. |
| **`rtl`** | A boolean that when true will make the admin UI display in Right-To-Left. |

View File

@@ -20,8 +20,8 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
## Options
| Option | Description |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `admin` \* | Base Payload admin configuration. Specify bundler*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `admin` \* | Base Payload admin configuration. Specify bundler\*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |

View File

@@ -20,7 +20,8 @@ Ensure you have an npm script called "payload" in your `package.json` file.
```
<Banner>
Note that you need to run Payload migrations through the package manager that you are using, because Payload should not be globally installed on your system.
Note that you need to run Payload migrations through the package manager that you are using,
because Payload should not be globally installed on your system.
</Banner>
### Migration file contents
@@ -45,11 +46,11 @@ export async function up ({ payload, req }: MigrateUpArgs): Promise<void> {
// Perform changes to your database here.
// You have access to `payload` as an argument, and
// everything is done in TypeScript.
};
}
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
// Do whatever you need to revert changes if the `up` function fails
};
}
```
### Migrations Directory

View File

@@ -31,7 +31,7 @@ export default buildConfig({
### Options
| Option | Description |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
| `autoPluralization` | Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
| `connectOptions` | Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |

View File

@@ -67,7 +67,7 @@ export default buildConfig({
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URI,
}
},
}),
})
```

View File

@@ -9,7 +9,8 @@ keywords: Postgres, documentation, typescript, Content Management System, cms, h
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.
<Banner>
The Postgres database adapter is currently in beta. If you would like to help us test this package, we'd love to hear if you find any bugs or issues!
The Postgres database adapter is currently in beta. If you would like to help us test this
package, we'd love to hear if you find any bugs or issues!
</Banner>
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
@@ -30,7 +31,7 @@ export default buildConfig({
// `pool` is required.
pool: {
connectionString: process.env.DATABASE_URI,
}
},
}),
})
```
@@ -38,7 +39,7 @@ export default buildConfig({
### Options
| Option | Description |
|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pool` | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
@@ -84,5 +85,7 @@ Migrations are extremely powerful thanks to the seamless way that Payload and Dr
1. Now your production database is in sync with your Payload config!
<Banner type="warning">
Warning: do not mix "push" and migrations with your local development database. If you use "push" locally, and then try to migrate, Payload will throw a warning, telling you that these two methods are not meant to be used interchangeably.
Warning: do not mix "push" and migrations with your local development database. If you use "push"
locally, and then try to migrate, Payload will throw a warning, telling you that these two methods
are not meant to be used interchangeably.
</Banner>

View File

@@ -26,7 +26,7 @@ in the `email` property object of your payload init call. Payload will make use
The following options are configurable in the `email` property object as part of the options object when calling payload.init().
| Option | Description |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`fromName`** \* | The name part of the From field that will be seen on the delivered email |
| **`fromAddress`** \* | The email address part of the From field that will be used when delivering email |
| **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set |

View File

@@ -18,7 +18,7 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |

View File

@@ -24,7 +24,7 @@ This field uses the `monaco-react` editor syntax highlighting.
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |

View File

@@ -23,7 +23,7 @@ This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepic
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
@@ -45,7 +45,7 @@ _\* An asterisk denotes that a property is required._
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can customize the following fields that will adjust how the component displays in the admin panel via the `date` property.
| Property | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------- |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`placeholder`** | Placeholder text for the field. |
| **`date`** | Pass options to customize date field appearance. |
| **`date.displayFormat`** | Format date to be shown in field **cell**. |

View File

@@ -18,7 +18,7 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |

View File

@@ -24,7 +24,7 @@ This field uses the `monaco-react` editor syntax highlighting.
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
@@ -47,7 +47,7 @@ _\* An asterisk denotes that a property is required._
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
| Option | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`editorOptions`** | Options that can be passed to the monaco editor, [view the full list](https://microsoft.github.io/monaco-editor/typedoc/variables/editor.EditorOptions.html). |
### Example

View File

@@ -21,7 +21,7 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`min`** | Minimum value accepted. Used in the default `validation` function. |

View File

@@ -28,7 +28,7 @@ The data structure in the database matches the GeoJSON structure to represent po
### Config
| Option | Description |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |

View File

@@ -21,7 +21,7 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |

View File

@@ -27,7 +27,7 @@ caption="Admin panel screenshot of a Relationship field"
### Config
| Option | Description |
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
@@ -132,7 +132,7 @@ prevent all, or a `Where` query. When using a function, it will be
called with an argument object with the following properties:
| Property | Description |
|---------------|--------------------------------------------------------------------------------------------------------------|
| ------------- | ----------------------------------------------------------------------------------------------------- |
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
| `data` | An object containing the full collection or global document currently being edited |
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
@@ -287,10 +287,7 @@ To save the to `hasMany` relationship field we need to send an array of IDs:
```json
{
"owners": [
"6031ac9e1289176380734024",
"602c3c327b811235943ee12b"
]
"owners": ["6031ac9e1289176380734024", "602c3c327b811235943ee12b"]
}
```
@@ -362,5 +359,6 @@ Since we are referencing multiple collections, the field you are querying on may
<Banner type="warning">
<strong>Note:</strong>
<br />
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a non-polymorphic relationship.
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a
non-polymorphic relationship.
</Banner>

View File

@@ -26,7 +26,13 @@ Right now, Payload is officially supporting two rich text editors:
2. [Lexical](/docs/rich-text/lexical) - beta, where things will be moving
<Banner type="success">
<strong>Consistent with Payload's goal of making you learn as little of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em> rich text editor.</strong> Instead, you can invest your time and effort into learning the underlying open-source tools that will allow you to apply your learnings elsewhere as well.
<strong>
Consistent with Payload's goal of making you learn as little of Payload as possible, customizing
and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em>{' '}
rich text editor.
</strong>{' '}
Instead, you can invest your time and effort into learning the underlying open-source tools that
will allow you to apply your learnings elsewhere as well.
</Banner>
### Config

View File

@@ -21,7 +21,7 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
@@ -122,7 +122,7 @@ export const CustomSelectField: Field = {
],
}),
},
}
},
}
```
@@ -174,9 +174,9 @@ export const CustomSelectComponent: React.FC<CustomSelectProps> = ({ path, optio
If you are looking to create a dynamic select field, the following tutorial will walk you through the process of creating a custom select field that fetches its options from an external API.
<VideoDrawer
id='Efn9OxSjA6Y'
label='How to Create a Custom Select Field'
drawerTitle='How to Create a Custom Select Field: A Step-by-Step Guide'
id="Efn9OxSjA6Y"
label="How to Create a Custom Select Field"
drawerTitle="How to Create a Custom Select Field: A Step-by-Step Guide"
/>
If you want to learn more about custom components check out the [Admin > Custom Component](/docs/admin/components#field-component) docs.

View File

@@ -21,7 +21,7 @@ keywords: text, fields, config, configuration, documentation, Content Management
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
@@ -41,6 +41,7 @@ keywords: text, fields, config, configuration, documentation, Content Management
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
_\* An asterisk denotes that a property is required._
### Admin config

View File

@@ -21,7 +21,7 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
### Config
| Option | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |

View File

@@ -35,7 +35,7 @@ caption="Admin panel screenshot of an Upload field"
### Config
| Option | Description |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
@@ -86,7 +86,7 @@ prevent all, or a `Where` query. When using a function, it will be
called with an argument object with the following properties:
| Property | Description |
|---------------|--------------------------------------------------------------------------------------------------------------|
| ------------- | ----------------------------------------------------------------------------------------------------- |
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
| `data` | An object containing the full collection or global document currently being edited |
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |

View File

@@ -62,9 +62,7 @@ import express from 'express'
const app = express()
app.listen(3000, async () => {
console.log(
"Express is now listening for incoming connections on port 3000."
)
console.log('Express is now listening for incoming connections on port 3000.')
})
```
@@ -86,9 +84,7 @@ const start = async () => {
})
app.listen(3000, async () => {
console.log(
"Express is now listening for incoming connections on port 3000."
)
console.log('Express is now listening for incoming connections on port 3000.')
})
}
@@ -105,6 +101,7 @@ PAYLOAD_SECRET=your-payload-secret
Here is a list of all properties available to pass through `payload.init`:
##### secret
**Required**. This is a secure string that will be used to authenticate with Payload. It can be random but should be at least 14 characters and be very difficult to guess.
Payload uses this secret key to generate secure user tokens (JWT). Behind the scenes, we do not use your secret key to encrypt directly - instead, we first take the secret key and create an encrypted string using the SHA-256 hash function. Then, we reduce the encrypted string to its first 32 characters. This final value is what Payload uses for encryption.
@@ -126,6 +123,7 @@ A boolean that disables the database connection when Payload starts up.
An object used to configure SMTP. [Read more](/docs/email/overview).
##### express
This is your Express app as shown above. Payload will tie into your existing `app` and scope all of its functionalities to sub-routers. By default, Payload will add an `/admin` router and an `/api` router, but you can customize these paths.
##### local

View File

@@ -17,7 +17,8 @@ development process, but importantly, stay out of your way as your apps get more
<Banner type="success">
<strong>Payload 2.0 has been released!</strong>
<br />
Includes Postgres support, Live Preview, Lexical Editor, and more. <a href="/blog/payload-2-0">Read the announcement</a>.
Includes Postgres support, Live Preview, Lexical Editor, and more.{' '}
<a href="/blog/payload-2-0">Read the announcement</a>.
</Banner>
Out of the box, Payload gives you a lot of the things that you often need when developing a new website, web app, or native app:

View File

@@ -17,7 +17,7 @@ The labels you provide for your Collections and Globals are used to name the Gra
At the top of your Payload config you can define all the options to manage GraphQL.
| Option | Description |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |

View File

@@ -64,7 +64,7 @@ which field hook you are utilizing.
Field Hooks receive one `args` argument that contains the following properties:
| Option | Description |
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`data`** | The data passed to update the document within `create` and `update` operations, and the full document itself in the `afterRead` hook. |
| **`siblingData`** | The sibling data passed to a field that the hook is running against. |
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many within the `afterRead` hook. |
@@ -111,11 +111,13 @@ const usernameField: Field = {
name: 'username',
type: 'text',
hooks: {
beforeValidate: [({ value }) => {
beforeValidate: [
({ value }) => {
// Trim whitespace and convert to lowercase
return value.trim().toLowerCase()
}],
}
},
],
},
}
```
@@ -136,13 +138,15 @@ const emailField: Field = {
name: 'email',
type: 'email',
hooks: {
beforeChange: [({ value, operation }) => {
beforeChange: [
({ value, operation }) => {
if (operation === 'create') {
// Perform additional validation or transformation for 'create' operation
}
return value
}],
}
},
],
},
}
```
@@ -164,17 +168,21 @@ const membershipStatusField: Field = {
options: [
{ label: 'Standard', value: 'standard' },
{ label: 'Premium', value: 'premium' },
{ label: 'VIP', value: 'vip' }
{ label: 'VIP', value: 'vip' },
],
hooks: {
afterChange: [({ value, previousValue, req }) => {
afterChange: [
({ value, previousValue, req }) => {
if (value !== previousValue) {
// Log or perform an action when the membership status changes
console.log(`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`)
console.log(
`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`,
)
// Here, you can implement actions that could track conversions from one tier to another
}
}],
}
},
],
},
}
```
@@ -195,11 +203,13 @@ const dateField: Field = {
name: 'createdAt',
type: 'date',
hooks: {
afterRead: [({ value }) => {
afterRead: [
({ value }) => {
// Format date for display
return new Date(value).toLocaleDateString()
}],
}
},
],
},
}
```

View File

@@ -13,7 +13,7 @@ Wiring your front-end into Live Preview is easy. If your front-end application i
By default, all hooks accept the following args:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | -------------------------------------------------------------------------------------- |
| **`serverURL`** \* | The URL of your Payload server. |
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
| **`depth`** | The depth of the relationships to fetch. Defaults to `0`. |
@@ -24,12 +24,16 @@ _\* An asterisk denotes that a property is required._
And return the following values:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --------------- | ---------------------------------------------------------------- |
| **`data`** | The live data of the document, merged with the initial data. |
| **`isLoading`** | A boolean that indicates whether or not the document is loading. |
<Banner type="info">
If your front-end is tightly coupled to required fields, you should ensure that your UI does not break when these fields are removed. For example, if you are rendering something like `data.relatedPosts[0].title`, your page will break once you remove the first related post. To get around this, use conditional logic, optional chaining, or default values in your UI where needed. For example, `data?.relatedPosts?.[0]?.title`.
If your front-end is tightly coupled to required fields, you should ensure that your UI does not
break when these fields are removed. For example, if you are rendering something like
`data.relatedPosts[0].title`, your page will break once you remove the first related post. To get
around this, use conditional logic, optional chaining, or default values in your UI where needed.
For example, `data?.relatedPosts?.[0]?.title`.
</Banner>
### React
@@ -45,8 +49,8 @@ npm install @payloadcms/live-preview-react
Then, use the `useLivePreview` hook in your React component:
```tsx
'use client';
import { useLivePreview } from '@payloadcms/live-preview-react';
'use client'
import { useLivePreview } from '@payloadcms/live-preview-react'
import { Page as PageType } from '@/payload-types'
// Fetch the page in a server component, pass it to the client component, then thread it through the hook
@@ -63,14 +67,14 @@ export const PageClient: React.FC<{
depth: 2,
})
return (
<h1>{data.title}</h1>
)
return <h1>{data.title}</h1>
}
```
<Banner type="info">
If is important that the `depth` argument matches exactly with the depth of your initial page request. The depth property is used to populated relationships and uploads beyond their IDs. See [Depth](../getting-started/concepts#depth) for more information.
If is important that the `depth` argument matches exactly with the depth of your initial page
request. The depth property is used to populated relationships and uploads beyond their IDs. See
[Depth](../getting-started/concepts#depth) for more information.
</Banner>
## Building your own hook
@@ -86,7 +90,7 @@ npm install @payloadcms/live-preview
This package provides the following functions:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| **`subscribe`** | Subscribes to the Admin panel's `window.postMessage` events and calls the provided callback function. |
| **`unsubscribe`** | Unsubscribes from the Admin panel's `window.postMessage` events. |
| **`ready`** | Sends a `window.postMessage` event to the Admin panel to indicate that the front-end is ready to receive messages. |
@@ -94,7 +98,7 @@ This package provides the following functions:
The `subscribe` function takes the following args:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | ------------------------------------------------------------------------------------------- |
| **`callback`** \* | A callback function that is called with `data` every time a change is made to the document. |
| **`serverURL`** \* | The URL of your Payload server. |
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
@@ -103,7 +107,7 @@ The `subscribe` function takes the following args:
With these functions, you can build your own hook using your front-end framework of choice:
```tsx
import { subscribe, unsubscribe } from '@payloadcms/live-preview';
import { subscribe, unsubscribe } from '@payloadcms/live-preview'
// To build your own hook, subscribe to Live Preview events using the`subscribe` function
// It handles everything from:
@@ -159,7 +163,7 @@ export const useLivePreview = <T extends any>(props: {
hasSentReadyMessage.current = true
ready({
serverURL
serverURL,
})
}
@@ -177,7 +181,8 @@ export const useLivePreview = <T extends any>(props: {
```
<Banner type="info">
When building your own hook, ensure that the args and return values are consistent with the ones listed at the top of this document. This will ensure that all hooks follow the same API.
When building your own hook, ensure that the args and return values are consistent with the ones
listed at the top of this document. This will ensure that all hooks follow the same API.
</Banner>
## Example
@@ -226,8 +231,8 @@ const { docs } = await payload.find({
where: {
slug: {
equals: 'home',
}
}
},
},
})
```

View File

@@ -13,7 +13,11 @@ Live Preview works by rendering an iframe on the page that loads your front-end
{/* IMAGE OF LIVE PREVIEW HERE */}
<Banner type="warning">
Live Preview is currently in beta. You may use this feature in production, but please be aware that it is subject to change and may not be fully stable for all use cases. If you encounter any issues, please [report them](https://github.com/payloadcms/payload/issues/new?assignees=jacobsfletch&labels=possible-bug&projects=&title=Live%20Preview&template=1.bug_report.yml) with as much detail as possible.
Live Preview is currently in beta. You may use this feature in production, but please be aware
that it is subject to change and may not be fully stable for all use cases. If you encounter any
issues, please [report
them](https://github.com/payloadcms/payload/issues/new?assignees=jacobsfletch&labels=possible-bug&projects=&title=Live%20Preview&template=1.bug_report.yml)
with as much detail as possible.
</Banner>
## Setup
@@ -21,7 +25,7 @@ Live Preview works by rendering an iframe on the page that loads your front-end
Setting up Live Preview is easy. You first need to enable it through the `admin.livePreview` property of your Payload config. It takes the following options:
| Path | Description |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`url`** \* | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
| **`collections`** | Array of collection slugs to enable Live Preview on. |
@@ -69,7 +73,7 @@ The `url` property is a string that points to your front-end application. This v
You can also pass a function in order to dynamically format URLs. This function is called with the following arguments:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **`data`** | The data of the document being edited. This includes changes that have not yet been saved. |
| **`documentInfo`** | Information about the document being edited like collection slug. [More details](../admin/hooks#usedocumentinfo). |
| **`locale`** | The locale currently being edited (if applicable). [More details](../configuration/localization). |
@@ -101,7 +105,7 @@ Here is an example of using a function that returns a dynamic URL:
The breakpoints property is an array of objects which are used as “device sizes” in the preview window. Each item will render as an option in the toolbar. When selected, the preview window will resize to the exact dimensions specified in that breakpoint. Each breakpoint takes the following properties:
| Path | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --------------- | --------------------------------------------------------------------------- |
| **`label`** \* | The label to display in the drop-down. This is what the user will see. |
| **`name`** \* | The name of the breakpoint. |
| **`width`** \* | The width of the breakpoint. This is used to set the width of the iframe. |

View File

@@ -70,7 +70,7 @@ You can specify more options within the Local API vs. REST or GraphQL due to the
executed in.
| Local Option | Description |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
| `data` | The data to use within the operation. Required for `create`, `update`. |
| `depth` | [Control auto-population](/docs/getting-started/concepts#depth) of nested relationship and upload fields. |

View File

@@ -9,14 +9,16 @@ keywords: plugins, template, config, configuration, extensions, custom, document
Building your own plugin is easy, and if you&apos;re already familiar with Payload then you&apos;ll have everything you need to get started. You can either start from scratch or use the Payload plugin template to get up and running quickly.
<Banner type="success">
To use the template, run `npx create-payload-app@latest -t plugin -n my-new-plugin` directly in your terminal or [clone the template directly from GitHub](https://github.com/payloadcms/payload-plugin-template).
To use the template, run `npx create-payload-app@latest -t plugin -n my-new-plugin` directly in
your terminal or [clone the template directly from
GitHub](https://github.com/payloadcms/payload-plugin-template).
</Banner>
Our plugin template includes everything you need to build a full life-cycle plugin:
* Example files and functions for extending the payload config
* A local dev environment to develop the plugin
* Test suite with integrated GitHub workflow
- Example files and functions for extending the payload config
- A local dev environment to develop the plugin
- Test suite with integrated GitHub workflow
By abstracting your code into a plugin, you&apos;ll be able to reuse your feature across multiple projects and make it available for other developers to use.
@@ -24,7 +26,6 @@ By abstracting your code into a plugin, you&apos;ll be able to reuse your featur
Here is a brief recap of how to integrate plugins with Payload, to learn more head back to the [plugin overview page](https://payloadcms.com/docs/plugins/overview).
#### How to install a plugin
To install any plugin, simply add it to your Payload config in the plugins array.
@@ -44,7 +45,6 @@ const config = buildConfig({
export default config;
```
#### Initialization
The initialization process goes in the following order:
@@ -55,7 +55,6 @@ The initialization process goes in the following order:
4. Sanitization cleans and validates data
5. Final config gets initialized
### Plugin Template
In the [Payload plugin template](https://github.com/payloadcms/payload-plugin-template), you will see a common file structure that is used across plugins:
@@ -64,14 +63,12 @@ In the [Payload plugin template](https://github.com/payloadcms/payload-plugin-te
2. /src folder - everything related to the plugin
3. /dev folder - sanitized test project for development
#### Root
In the root folder, you will see various files related to the configuration of the plugin. We set up our environment in a similar manner in Payload core and across other projects. The only two files you need to modify are:
* **README**.md - This contains instructions on how to use the template. When you are ready, update this to contain instructions on how to use your Plugin.
* **package**.json - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
- **README**.md - This contains instructions on how to use the template. When you are ready, update this to contain instructions on how to use your Plugin.
- **package**.json - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
#### Dev
@@ -104,7 +101,6 @@ When you&apos;re ready to start development, navigate into this folder with `cd
And then start the project with `yarn dev` and pull up `http://localhost:3000` in your browser.
### Testing
Another benefit of the dev folder is that you have the perfect environment established for testing.
@@ -133,7 +129,6 @@ describe('Plugin tests', () => {
})
```
### Seeding data
For development and testing, you will likely need some data to work with. You can streamline this process by seeding and dropping your database - instead of manually entering data.
@@ -164,17 +159,14 @@ export const seed = async (payload: Payload): Promise<void> => {
```
#### Src
Now that we have our environment setup and dev project ready to go - it&apos;s time to build the plugin!
**index.ts**
First up, the `src/index.ts` file - this is where the plugin should be imported from. It is best practice not to build the plugin directly in this file, instead we use this to export the plugin and types from their respective files.
**Plugin.ts**
To reiterate, the essence of a payload plugin is simply to extend the Payload config - and that is exactly what we are doing in this file.
@@ -196,7 +188,6 @@ export const samplePlugin =
3. From here, you can extend the config however you like!
4. Finally, return the config and you&apos;re all set.
### Spread Syntax
[Spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) (or the spread operator) is a feature in JavaScript that uses the dot notation **(...)** to spread elements from arrays, strings, or objects into various contexts.
@@ -244,7 +235,6 @@ If you wish to add to the `onInit`, you must include the async/await. We don&apo
In the template, we have stubbed out a basic `onInitExtension` file that you can use, if not needed feel free to delete it.
### Webpack
If any of your files use server only packages such as fs, stripe, nodemailer, etc, they will need to be removed from the browser bundle. To do that, you can [alias the file imports with webpack](https://payloadcms.com/docs/admin/webpack#aliasing-server-only-modules).
@@ -283,12 +273,21 @@ If possible, include [JSDoc comments](https://www.typescriptlang.org/docs/handbo
In addition to the setup covered above, here are other best practices to follow:
##### Providing an enable / disable option:
For a better user experience, provide a way to disable the plugin without uninstalling it. This is especially important if your plugin adds additional webpack aliases, this will allow you to still let the webpack run to prevent errors.
##### Include tests in your GitHub CI workflow:
If you&apos;ve configured tests for your package, integrate them into your workflow to run the tests each time you commit to the plugin repository. Learn more about [how to configure tests into your GitHub CI workflow.](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs)
##### Publish your finished plugin to NPM:
The best way to share and allow others to use your plugin once it is complete is to publish an NPM package. This process is straightforward and well documented, find out more about [creating and publishing a NPM package here](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
##### Add payload-plugin topic tag:
Apply the tag **payload-plugin** to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with [existing payload plugins](https://github.com/topics/payload-plugin).
##### Use [Semantic Versioning](https://semver.org/) (SemVer):
With the SemVer system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.

View File

@@ -15,7 +15,12 @@ All form submissions are stored directly in your database and are managed direct
Forms can be as simple or complex as you need, from a basic contact form, to a multi-step lead generation engine, or even a donation form that processes payment. You may not need to reach for third-party services like HubSpot or Mailchimp for this, but instead use your own first-party tooling, built directly into your own application.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-form-builder). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20form-builder&template=bug_report.md&title=plugin-form-builder%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-form-builder). If you need
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
found a bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20form-builder&template=bug_report.md&title=plugin-form-builder%3A)
with as much detail as possible.
</Banner>
##### Core Features
@@ -52,7 +57,7 @@ const config = buildConfig({
plugins: [
formBuilder({
// see below for a list of available options
})
}),
],
})
@@ -79,8 +84,8 @@ formBuilder({
checkbox: true,
number: true,
message: true,
payment: false
}
payment: false,
},
})
```
@@ -92,7 +97,7 @@ The `redirectRelationships` property is an array of collection slugs that, when
// payload.config.ts
formBuilder({
// ...
redirectRelationships: ['pages']
redirectRelationships: ['pages'],
})
```
@@ -110,7 +115,7 @@ formBuilder({
...email,
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
}))
}
},
})
```
@@ -123,18 +128,18 @@ Override anything on the `forms` collection by sending a [Payload Collection Con
formBuilder({
// ...
formOverrides: {
slug: "contact-forms",
slug: 'contact-forms',
access: {
read: () => true,
update: () => false,
},
fields: [
{
name: "custom-field",
type: "text"
}
]
}
name: 'custom-field',
type: 'text',
},
],
},
})
```
@@ -143,7 +148,12 @@ formBuilder({
Override anything on the `form-submissions` collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) to the `formSubmissionOverrides` property.
<Banner type="warning">
By default, this plugin relies on [Payload access control](https://payloadcms.com/docs/access-control/collections) to restrict the `update` and `read` operations on the `form-submissions` collection. This is because _anyone_ should be able to create a form submission, even from a public-facing website, but _no one_ should be able to update a submission one it has been created, or read a submission unless they have permission. You can override this behavior or any other property as needed.
By default, this plugin relies on [Payload access
control](https://payloadcms.com/docs/access-control/collections) to restrict the `update` and
`read` operations on the `form-submissions` collection. This is because _anyone_ should be able to
create a form submission, even from a public-facing website, but _no one_ should be able to update
a submission one it has been created, or read a submission unless they have permission. You can
override this behavior or any other property as needed.
</Banner>
```ts
@@ -151,8 +161,8 @@ Override anything on the `form-submissions` collection by sending a [Payload Col
formBuilder({
// ...
formSubmissionOverrides: {
slug: "leads",
}
slug: 'leads',
},
})
```
@@ -164,7 +174,7 @@ First import the utility function. This will execute all of the price conditions
```ts
// payload.config.ts
import { getPaymentTotal } from '@payloadcms/plugin-form-builder';
import { getPaymentTotal } from '@payloadcms/plugin-form-builder'
```
Then in your plugin's config:
@@ -175,14 +185,14 @@ formBuilder({
// ...
handlePayment: async ({ form, submissionData }) => {
// first calculate the price
const paymentField = form.fields?.find((field) => field.blockType === 'payment');
const paymentField = form.fields?.find((field) => field.blockType === 'payment')
const price = getPaymentTotal({
basePrice: paymentField.basePrice,
priceConditions: paymentField.priceConditions,
fieldValues: submissionData,
});
})
// then asynchronously process the payment here
}
},
})
```
@@ -192,7 +202,8 @@ Each field represents a form input. To override default settings pass either a b
<Banner type="info">
<strong>Note:</strong>
"Fields" here is in reference to the _fields to build forms with_, not to be confused with the _fields of a collection_ which are set via `formOverrides.fields`.
"Fields" here is in reference to the _fields to build forms with_, not to be confused with the _fields
of a collection_ which are set via `formOverrides.fields`.
</Banner>
#### Text
@@ -200,7 +211,7 @@ Each field represents a form input. To override default settings pass either a b
Maps to a `text` input in your front-end. Used to collect a simple string.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -212,7 +223,7 @@ Maps to a `text` input in your front-end. Used to collect a simple string.
Maps to a `textarea` input on your front-end. Used to collect a multi-line string.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -224,7 +235,7 @@ Maps to a `textarea` input on your front-end. Used to collect a multi-line strin
Maps to a `select` input on your front-end. Used to display a list of options.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | -------------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -237,7 +248,7 @@ Maps to a `select` input on your front-end. Used to display a list of options.
Maps to a `text` input with type `email` on your front-end. Used to collect an email address.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -249,7 +260,7 @@ Maps to a `text` input with type `email` on your front-end. Used to collect an e
Maps to a `select` input on your front-end. Used to collect a US state.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -261,7 +272,7 @@ Maps to a `select` input on your front-end. Used to collect a US state.
Maps to a `select` input on your front-end. Used to collect a country.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -273,7 +284,7 @@ Maps to a `select` input on your front-end. Used to collect a country.
Maps to a `checkbox` input on your front-end. Used to collect a boolean value.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | checkbox | The default value of the field. |
@@ -285,7 +296,7 @@ Maps to a `checkbox` input on your front-end. Used to collect a boolean value.
Maps to a `number` input on your front-end. Used to collect a number.
| Property | Type | Description |
| --- | --- | --- |
| -------------- | -------- | ---------------------------------------------------- | --- | -------------- | ------ | ------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | string | The default value of the field. |
@@ -297,7 +308,7 @@ Maps to a `number` input on your front-end. Used to collect a number.
Maps to a `RichText` component on your front-end. Used to display an arbitrary message to the user anywhere in the form.
| property | type | description |
| --- | --- | --- |
| --------- | -------- | ----------------------------------- |
| `message` | richText | The message to display on the form. |
#### Payment
@@ -305,7 +316,7 @@ Maps to a `RichText` component on your front-end. Used to display an arbitrary m
Add this field to your form if it should collect payment. Upon submission, the `handlePayment` callback is executed with the form and submission data. You can use this to integrate with any third-party payment processing API.
| property | type | description |
| --- | --- | --- |
| ----------------- | -------- | --------------------------------------------------------------------------------- |
| `name` | string | The name of the field. |
| `label` | string | The label of the field. |
| `defaultValue` | number | The default value of the field. |
@@ -318,7 +329,7 @@ Add this field to your form if it should collect payment. Upon submission, the `
Each of the `priceConditions` are executed by the `getPaymentTotal` utility that this plugin provides. You can call this function in your `handlePayment` callback to dynamically calculate the total price of a form upon submission based on the user's input. For example, you could create a price condition that says "if the user selects 'yes' for this checkbox, add $10 to the total price".
| property | type | description |
| --- | --- | --- |
| ------------------ | ------------ | ------------------------------------------------ |
| `fieldToUse` | relationship | The field to use to determine the price. |
| `condition` | string | The condition to use to determine the price. |
| `valueForOperator` | string | The value to use for the operator. |
@@ -344,11 +355,11 @@ formBuilder({
text: {
...fields.text,
labels: {
singular: "Custom Text Field",
plural: "Custom Text Fields",
}
}
}
singular: 'Custom Text Field',
plural: 'Custom Text Fields',
},
},
},
})
```
@@ -388,6 +399,7 @@ Below are some common troubleshooting tips. To help other developers, please con
## Screenshots
![screenshot 1](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-1.jpg?raw=true)
<br />
![screenshot 2](https://github.com/payloadcms/plugin-form-builder/blob/main/images/screenshot-2.jpg?raw=true)
<br />

View File

@@ -25,7 +25,12 @@ field instead of the original title. This is especially useful if you happen to
but different parents.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-nested-docs). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20nested-docs&template=bug_report.md&title=plugin-nested-docs%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-nested-docs). If you need
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
found a bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20nested-docs&template=bug_report.md&title=plugin-nested-docs%3A)
with as much detail as possible.
</Banner>
##### Core features
@@ -96,7 +101,7 @@ The `breadcrumbs` field is an array which dynamically populates all parent relat
level and stores the following fields.
| Field | Description |
|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label` | The label of the breadcrumb. This field is automatically set to either the `collection.admin.useAsTitle` (if defined) or is set to the `ID` of the document. You can also dynamically define the `label` by passing a function to the options property of [`generateLabel`](#generateLabel). |
| `url` | The URL of the breadcrumb. By default, this field is undefined. You can manually define this field by passing a property called function to the plugin options property of [`generateURL`](#generateURL). |
@@ -117,14 +122,14 @@ You can also pass a function to dynamically set the `label` of your breadcrumb.
// payload.config.ts
nestedDocs({
//...
generateLabel: (_, doc) => doc.title // NOTE: 'title' is a hypothetical field
generateLabel: (_, doc) => doc.title, // NOTE: 'title' is a hypothetical field
})
```
The function takes two arguments and returns a string:
| Argument | Type | Description |
|----------|----------|----------------------------------------------|
| -------- | -------- | -------------------------------------------- |
| `docs` | `Array` | An array of the breadcrumbs up to that point |
| `doc` | `Object` | The current document being edited |
@@ -143,7 +148,7 @@ nestedDocs({
```
| Argument | Type | Description |
|----------|----------|----------------------------------------------|
| -------- | -------- | -------------------------------------------- |
| `docs` | `Array` | An array of the breadcrumbs up to that point |
| `doc` | `Object` | The current document being edited |
@@ -161,7 +166,9 @@ own `breadcrumbs` field to each collection manually. Set this property to the `n
<Banner type="info">
<strong>Note:</strong>
<br />
If you opt out of automatically being provided a `parent` or `breadcrumbs` field, you need to make sure that both fields are placed at the top-level of your document. They cannot exist within any nested data structures like a `group`, `array`, or `blocks`.
If you opt out of automatically being provided a `parent` or `breadcrumbs` field, you need to make
sure that both fields are placed at the top-level of your document. They cannot exist within any
nested data structures like a `group`, `array`, or `blocks`.
</Banner>
## Overrides
@@ -170,48 +177,49 @@ You can also extend the built-in `parent` and `breadcrumbs` fields per collectio
and `createBreadcrumbField` methods. They will merge your customizations overtop the plugin's base field configurations.
```ts
import { CollectionConfig } from "payload/types";
import { createParentField } from "@payloadcms/plugin-nested-docs/fields";
import { createBreadcrumbsField } from "@payloadcms/plugin-nested-docs/fields";
import { CollectionConfig } from 'payload/types'
import { createParentField } from '@payloadcms/plugin-nested-docs/fields'
import { createBreadcrumbsField } from '@payloadcms/plugin-nested-docs/fields'
const examplePageConfig: CollectionConfig = {
slug: "pages",
slug: 'pages',
fields: [
createParentField(
// First argument is equal to the slug of the collection
// that the field references
"pages",
'pages',
// Second argument is equal to field overrides that you specify,
// which will be merged into the base parent field config
{
admin: {
position: "sidebar",
position: 'sidebar',
},
// Note: if you override the `filterOptions` of the `parent` field,
// be sure to continue to prevent the document from referencing itself as the parent like this:
// filterOptions: ({ id }) => ({ id: {not_equals: id }})`
}
},
),
createBreadcrumbsField(
// First argument is equal to the slug of the collection
// that the field references
"pages",
'pages',
// Argument equal to field overrides that you specify,
// which will be merged into the base `breadcrumbs` field config
{
label: "Page Breadcrumbs",
}
label: 'Page Breadcrumbs',
},
),
],
};
}
```
<Banner type="warning">
<strong>Note:</strong>
<br />
If overriding the `name` of either `breadcrumbs` or `parent` fields, you must specify the `breadcrumbsFieldSlug` or `parentFieldSlug` respectively.
If overriding the `name` of either `breadcrumbs` or `parent` fields, you must specify the
`breadcrumbsFieldSlug` or `parentFieldSlug` respectively.
</Banner>
## Localization

View File

@@ -13,7 +13,12 @@ This plugin allows you to easily manage redirects for your application from with
For example, if you have a page at `/about` and you want to change it to `/about-us`, you can create a redirect from the old page to the new one, then you can use this data to write HTTP redirects into your front-end application. This will ensure that users are redirected to the correct page without penalty because search engines are notified of the change at the request level. This is a very lightweight plugin that will allow you to integrate managed redirects for any front-end framework.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%redirects&template=bug_report.md&title=plugin-redirects%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
found a bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%redirects&template=bug_report.md&title=plugin-redirects%3A)
with as much detail as possible.
</Banner>
##### Core features
@@ -35,30 +40,30 @@ Install the plugin using any JavaScript package manager like [Yarn](https://yarn
In the `plugins` array of your [Payload config](https://payloadcms.com/docs/configuration/overview), call the plugin with [options](#options):
```ts
import { buildConfig } from "payload/config";
import redirects from "@payloadcms/plugin-redirects";
import { buildConfig } from 'payload/config'
import redirects from '@payloadcms/plugin-redirects'
const config = buildConfig({
collections: [
{
slug: "pages",
slug: 'pages',
fields: [],
},
],
plugins: [
redirects({
collections: ["pages"],
collections: ['pages'],
}),
],
});
})
export default config;
export default config
```
### Options
| Option | Type | Description |
| --- | --- | --- |
| ------------- | ---------- | ----------------------------------------------------------------------------------------------- |
| `collections` | `string[]` | An array of collection slugs to populate in the `to` field of each redirect. |
| `overrides` | `object` | A partial collection config that allows you to override anything on the `redirects` collection. |
@@ -67,7 +72,7 @@ export default config;
All types can be directly imported:
```ts
import { PluginConfig } from "@payloadcms/plugin-redirects/types";
import { PluginConfig } from '@payloadcms/plugin-redirects/types'
```
## Examples

View File

@@ -17,7 +17,12 @@ To query search results, use all the existing Payload APIs that you are already
This plugin is a great way to implement a fast, immersive search experience such as a search bar in a front-end application. Many applications may not need the power and complexity of a third-party service like Algolia or ElasticSearch. This plugin provides a first-party alternative that is easy to set up and runs entirely on your own database.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-search). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20search&template=bug_report.md&title=plugin-search%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-search). If you need help,
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20search&template=bug_report.md&title=plugin-search%3A)
with as much detail as possible.
</Banner>
##### Core Features

View File

@@ -15,7 +15,12 @@ As users are editing documents within the admin panel, they have the option to "
To help you visualize what your page might look like in a search engine, a preview is rendered on page just beneath the meta fields. This preview is updated in real-time as you edit your metadata. There are also visual indicators to help you write effective meta, such as a character counter for the title and description fields. You can even inject your own custom fields into the `meta` field group as your application requires, like `og:title` or `json-ld`. If you've ever used something like Yoast SEO, this plugin might feel very familiar.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-seo). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20seo&template=bug_report.md&title=plugin-seo%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-seo). If you need help,
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20seo&template=bug_report.md&title=plugin-seo%3A)
with as much detail as possible.
</Banner>
##### Core features
@@ -100,7 +105,9 @@ Set the `uploadsCollection` to your application's upload-enabled collection slug
When the `tabbedUI` property is `true`, it appends an `SEO` tab onto your config using Payload's [Tabs Field](https://payloadcms.com/docs/fields/tabs). If your collection is not already tab-enabled, meaning the first field in your config is not of type `tabs`, then one will be created for you called `Content`. Defaults to `false`.
<Banner type="info">
If you wish to continue to use top-level or sidebar fields with `tabbedUI`, you must not let the default `Content` tab get created for you (see the note above). Instead, you must define the first field of your config with type `tabs` and place all other fields adjacent to this one.
If you wish to continue to use top-level or sidebar fields with `tabbedUI`, you must not let the
default `Content` tab get created for you (see the note above). Instead, you must define the first
field of your config with type `tabs` and place all other fields adjacent to this one.
</Banner>
##### `generateTitle`
@@ -126,7 +133,7 @@ A function that allows you to return any meta description, including from docume
{
// ...
seoPlugin({
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt?.value
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt?.value,
})
}
```
@@ -140,7 +147,7 @@ A function that allows you to return any meta image, including from document's c
{
// ...
seoPlugin({
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage?.value
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage?.value,
})
}
```
@@ -154,7 +161,8 @@ A function called by the search preview component to display the actual URL of y
{
// ...
seoPlugin({
generateURL: ({ ...docInfo, doc, locale }) => `https://yoursite.com/${collection?.slug}/${doc?.slug?.value}`
generateURL: ({ ...docInfo, doc, locale }) =>
`https://yoursite.com/${collection?.slug}/${doc?.slug?.value}`,
})
}
```
@@ -168,7 +176,7 @@ Rename the meta group interface name that is generated for TypeScript and GraphQ
{
// ...
seoPlugin({
interfaceName: 'customInterfaceNameSEO'
interfaceName: 'customInterfaceNameSEO',
})
}
```

View File

@@ -17,7 +17,12 @@ To build a checkout flow on your front-end you can either use [Stripe Checkout](
The beauty of this plugin is the entirety of your application's content and business logic can be handled in Payload while Stripe handles solely the billing and payment processing. You can build a completely proprietary application that is endlessly customizable and extendable, on APIs and databases that you own. Hosted services like Shopify or BigCommerce might fracture your application's content then charge you for access.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-stripe). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20stripe&template=bug_report.md&title=plugin-stripe%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-stripe). If you need help,
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
bug, please [open a new
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20stripe&template=bug_report.md&title=plugin-stripe%3A)
with as much detail as possible.
</Banner>
##### Core features
@@ -59,7 +64,7 @@ export default config
### Options
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| ------------------------------ | ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `stripeSecretKey` \* | string | `undefined` | Your Stripe secret key |
| `stripeWebhooksEndpointSecret` | string | `undefined` | Your Stripe webhook endpoint secret |
| `rest` | boolean | `false` | When `true`, opens the `/api/stripe/rest` endpoint |
@@ -74,7 +79,7 @@ _\* An asterisk denotes that a property is required._
The following custom endpoints are automatically opened for you:
| Endpoint | Method | Description |
| --- | --- | --- |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/api/stripe/rest` | `POST` | Proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. See the [REST Proxy](#stripe-rest-proxy) section for more details. |
| `/api/stripe/webhooks` | `POST` | Handles all Stripe webhook events |
@@ -104,7 +109,8 @@ const res = await fetch(`/api/stripe/rest`, {
<Banner type="info">
<strong>Note:</strong>
<br />
The `/api` part of these routes may be different based on the settings defined in your Payload config.
The `/api` part of these routes may be different based on the settings defined in your Payload
config.
</Banner>
## Webhooks
@@ -220,7 +226,8 @@ This option will setup a basic sync between Payload collections and Stripe resou
<Banner type="info">
<strong>Note:</strong>
<br />
If you wish to enable a _two-way_ sync, be sure to setup [`webhooks`](#webhooks) and pass the `stripeWebhooksEndpointSecret` through your config.
If you wish to enable a _two-way_ sync, be sure to setup [`webhooks`](#webhooks) and pass the
`stripeWebhooksEndpointSecret` through your config.
</Banner>
```ts
@@ -255,7 +262,10 @@ export default config
<Banner type="warning">
<strong>Note:</strong>
<br />
Due to limitations in the Stripe API, this currently only works with top-level fields. This is because every Stripe object is a separate entity, making it difficult to abstract into a simple reusable library. In the future, we may find a pattern around this. But for now, cases like that will need to be hard-coded.
Due to limitations in the Stripe API, this currently only works with top-level fields. This is
because every Stripe object is a separate entity, making it difficult to abstract into a simple
reusable library. In the future, we may find a pattern around this. But for now, cases like that
will need to be hard-coded.
</Banner>
Using `sync` will do the following:
@@ -288,4 +298,3 @@ import {
## Examples
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) contains an official [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommerce) which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end. You can also check out [How to Build An E-Commerce Site With Next.js](https://payloadcms.com/blog/how-to-build-an-e-commerce-site-with-nextjs) post for a bit more context around this template.

View File

@@ -44,7 +44,10 @@ Because _**you**_ are in complete control of who can do what with your data, you
wield that power responsibly before deploying to Production.
<Banner type="error">
<strong>By default, all Access Control functions require that a user is successfully logged in to Payload to create, read, update, or delete data.</strong>{' '}
<strong>
By default, all Access Control functions require that a user is successfully logged in to
Payload to create, read, update, or delete data.
</strong>{' '}
But, if you allow public user registration, for example, you will want to make sure that your
access control functions are more strict - permitting <strong>only appropriate users</strong> to
perform appropriate actions.

View File

@@ -9,7 +9,9 @@ keywords: query, documents, overview, documentation, Content Management System,
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
<Banner>
<strong>Here, "querying" relates to filtering or searching through documents within a Collection.</strong>{' '}
<strong>
Here, "querying" relates to filtering or searching through documents within a Collection.
</strong>{' '}
You can build queries to pass to Find operations as well as to [restrict which documents certain
users can access](/docs/access-control/overview) via access control functions.
</Banner>

View File

@@ -11,7 +11,9 @@ One of Payload's goals is to build the best rich text editor experience that we
Classically, we've used SlateJS to work toward this goal, but building custom elements into Slate has proven to be more difficult than we'd like, and we've been keeping our options open.
<Banner type="warning">
Payload's Lexical rich text editor is currently in beta. It's stable enough to use as you build on Payload, so if you're up for helping us fine-tune it, you should use it. But if you're looking for stability, use Slate instead.
Payload's Lexical rich text editor is currently in beta. It's stable enough to use as you build on
Payload, so if you're up for helping us fine-tune it, you should use it. But if you're looking for
stability, use Slate instead.
</Banner>
Lexical is extremely impressive and trivializes a lot of the hard parts of building new elements into a rich text editor. It has a few distinct advantages over Slate, including the following:
@@ -38,7 +40,7 @@ export default buildConfig({
// your collections here
],
// Pass the Lexical editor to the root config
editor: lexicalEditor({})
editor: lexicalEditor({}),
})
```
@@ -46,9 +48,7 @@ You can also override Lexical settings on a field-by-field basis as follows:
```ts
import type { CollectionConfig } from 'payload/types'
import {
lexicalEditor
} from '@payloadcms/richtext-lexical'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
export const Pages: CollectionConfig = {
slug: 'pages',
@@ -57,9 +57,9 @@ export const Pages: CollectionConfig = {
name: 'content',
type: 'richText',
// Pass the Lexical editor here and override base settings as necessary
editor: lexicalEditor({})
}
]
editor: lexicalEditor({}),
},
],
}
```
@@ -82,7 +82,7 @@ import {
BlocksFeature,
LinkFeature,
UploadFeature,
lexicalEditor
lexicalEditor,
} from '@payloadcms/richtext-lexical'
import { Banner } from '../blocks/Banner'
import { CallToAction } from '../blocks/CallToAction'
@@ -126,12 +126,9 @@ import { CallToAction } from '../blocks/CallToAction'
// This is incredibly powerful. You can re-use your Payload blocks
// directly in the Lexical editor as follows:
BlocksFeature({
blocks: [
Banner,
CallToAction,
],
blocks: [Banner, CallToAction],
}),
]
],
})
}
```
@@ -141,7 +138,7 @@ import { CallToAction } from '../blocks/CallToAction'
Here's an overview of all the included features:
| Feature Name | Included by default | Description |
|--------------------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------------------ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`BoldTextFeature`** | Yes | Handles the bold text format |
| **`ItalicTextFeature`** | Yes | Handles the italic text format |
| **`UnderlineTextFeature`** | Yes | Handles the underline text format |
@@ -187,11 +184,7 @@ To add HTML generation directly within the collection, follow the example below:
```ts
import type { CollectionConfig } from 'payload/types'
import {
HTMLConverterFeature,
lexicalEditor,
lexicalHTML
} from '@payloadcms/richtext-lexical'
import { HTMLConverterFeature, lexicalEditor, lexicalHTML } from '@payloadcms/richtext-lexical'
const Pages: CollectionConfig = {
slug: 'pages',
@@ -211,6 +204,7 @@ const Pages: CollectionConfig = {
],
}
```
The `lexicalHTML()` function creates a new field that automatically converts the referenced lexical richText field into HTML through an afterRead hook.
#### Generating HTML in the Frontend:
@@ -225,13 +219,17 @@ import {
consolidateHTMLConverters,
} from '@payloadcms/richtext-lexical'
async function lexicalToHTML(editorData: SerializedEditorState, editorConfig: SanitizedEditorConfig) {
async function lexicalToHTML(
editorData: SerializedEditorState,
editorConfig: SanitizedEditorConfig,
) {
return await convertLexicalToHTML({
converters: consolidateHTMLConverters({ editorConfig }),
data: editorData,
})
}
```
This method employs `convertLexicalToHTML` from `@payloadcms/richtext-lexical`, which converts the serialized editor state into HTML.
Because every `Feature` is able to provide html converters, and because the `htmlFeature` can modify those or provide their own, we need to consolidate them with the default html Converters using the `consolidateHTMLConverters` function.
@@ -286,9 +284,13 @@ export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
//...
},
],
plugins: [/*...*/],
plugins: [
/*...*/
],
props: props,
slashMenu: {/*...*/},
slashMenu: {
/*...*/
},
}
},
key: 'upload',
@@ -299,6 +301,7 @@ export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
### Headless Editor
Lexical provides a seamless way to perform conversions between various other formats:
- HTML to Lexical (or, importing HTML into the lexical editor)
- Markdown to Lexical (or, importing Markdown into the lexical editor)
- Lexical to Markdown
@@ -307,12 +310,9 @@ A headless editor can perform such conversions outside of the main editor instan
```ts
import { createHeadlessEditor } from '@lexical/headless' // <= make sure this package is installed
import {
getEnabledNodes,
sanitizeEditorConfig,
} from '@payloadcms/richtext-lexical'
import { getEnabledNodes, sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
const yourEditorConfig; // <= your editor config here
const yourEditorConfig // <= your editor config here
const headlessEditor = createHeadlessEditor({
nodes: getEnabledNodes({
@@ -346,9 +346,10 @@ Once you have your headless editor instance, you can use it to convert HTML to L
```ts
import { $generateNodesFromDOM } from '@lexical/html'
import { $getRoot, $getSelection } from 'lexical'
import { JSDOM } from 'jsdom';
import { JSDOM } from 'jsdom'
headlessEditor.update(() => {
headlessEditor.update(
() => {
// In a headless environment you can use a package such as JSDom to parse the HTML string.
const dom = new JSDOM(htmlString)
@@ -361,7 +362,9 @@ headlessEditor.update(() => {
// Insert them at a selection.
const selection = $getSelection()
selection.insertNodes(nodes)
}, { discrete: true })
},
{ discrete: true },
)
// Do this if you then want to get the editor JSON
const editorJSON = headlessEditor.getEditorState().toJSON()
@@ -374,7 +377,8 @@ This has been taken from the [lexical serialization & deserialization docs](http
<Banner type="success">
<strong>Note:</strong>
<br />
Using the <code>discrete: true</code> flag ensures instant updates to the editor state. If immediate reading of the updated state isn't necessary, you can omit the flag.
Using the <code>discrete: true</code> flag ensures instant updates to the editor state. If
immediate reading of the updated state isn't necessary, you can omit the flag.
</Banner>
### Markdown => Lexical
@@ -388,7 +392,12 @@ import { sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
const yourSanitizedEditorConfig = sanitizeEditorConfig(yourEditorConfig) // <= your editor config here
const markdown = `# Hello World`
headlessEditor.update(() => { $convertFromMarkdownString(markdown, yourSanitizedEditorConfig.features.markdownTransformers) }, { discrete: true })
headlessEditor.update(
() => {
$convertFromMarkdownString(markdown, yourSanitizedEditorConfig.features.markdownTransformers)
},
{ discrete: true },
)
// Do this if you then want to get the editor JSON
const editorJSON = headlessEditor.getEditorState().toJSON()
@@ -406,7 +415,7 @@ Here's the code for it:
```ts
import { $convertToMarkdownString } from '@lexical/markdown'
import { sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
import type { SerializedEditorState } from "lexical"
import type { SerializedEditorState } from 'lexical'
const yourSanitizedEditorConfig = sanitizeEditorConfig(yourEditorConfig) // <= your editor config here
const yourEditorState: SerializedEditorState // <= your current editor state here
@@ -427,7 +436,6 @@ headlessEditor.getEditorState().read(() => {
The `.setEditorState()` function immediately updates your editor state. Thus, there's no need for the `discrete: true` flag when reading the state afterward.
### Lexical => Plain Text
Export content from the Lexical editor into plain text using these steps:
@@ -438,8 +446,8 @@ Export content from the Lexical editor into plain text using these steps:
Here's the code for it:
```ts
import type { SerializedEditorState } from "lexical"
import { $getRoot } from "lexical"
import type { SerializedEditorState } from 'lexical'
import { $getRoot } from 'lexical'
const yourEditorState: SerializedEditorState // <= your current editor state here
@@ -451,7 +459,8 @@ try {
}
// Export to plain text
const plainTextContent = headlessEditor.getEditorState().read(() => {
const plainTextContent =
headlessEditor.getEditorState().read(() => {
return $getRoot().getTextContent()
}) || ''
```
@@ -469,10 +478,7 @@ Simply add the `SlateToLexicalFeature` to your editor:
```ts
import type { CollectionConfig } from 'payload/types'
import {
SlateToLexicalFeature,
lexicalEditor,
} from '@payloadcms/richtext-lexical'
import { SlateToLexicalFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
const Pages: CollectionConfig = {
slug: 'pages',
@@ -481,10 +487,7 @@ const Pages: CollectionConfig = {
name: 'nameOfYourRichTextField',
type: 'richText',
editor: lexicalEditor({
features: ({ defaultFeatures }) => [
...defaultFeatures,
SlateToLexicalFeature({})
],
features: ({ defaultFeatures }) => [...defaultFeatures, SlateToLexicalFeature({})],
}),
},
],
@@ -494,6 +497,7 @@ const Pages: CollectionConfig = {
and done! Now, everytime this lexical editor is initialized, it converts the slate date to lexical on-the-fly. If the data is already in lexical format, it will just pass it through.
This is by far the easiest way to migrate from Slate to Lexical, although it does come with a few caveats:
- There is a performance hit when initializing the lexical editor
- The editor will still output the Slate data in the output JSON, as the on-the-fly converter only runs for the admin panel
@@ -535,7 +539,8 @@ export async function convertAll(payload: Payload, collectionName: string, field
const promises = batch.map(async (doc: YourDocumentType) => {
const richText = doc[fieldName]
if (richText && Array.isArray(richText) && !('root' in richText)) { // It's Slate data - skip already-converted data
if (richText && Array.isArray(richText) && !('root' in richText)) {
// It's Slate data - skip already-converted data
const converted = convertSlateToLexical({
converters: converters,
slateData: richText,
@@ -604,7 +609,7 @@ import type { CollectionConfig } from 'payload/types'
import {
SlateToLexicalFeature,
lexicalEditor,
defaultSlateConverters
defaultSlateConverters,
} from '@payloadcms/richtext-lexical'
import { YourCustomConverter } from '../converters/YourCustomConverter'
@@ -619,10 +624,7 @@ const Pages: CollectionConfig = {
features: ({ defaultFeatures }) => [
...defaultFeatures,
SlateToLexicalFeature({
converters: [
...defaultSlateConverters,
YourCustomConverter
]
converters: [...defaultSlateConverters, YourCustomConverter],
}),
],
}),

View File

@@ -16,7 +16,6 @@ To use the Slate editor, first you need to install it:
npm install --save @payloadcms/richtext-slate
```
After installation, you can pass it to your top-level Payload config:
```ts
@@ -28,7 +27,7 @@ export default buildConfig({
// your collections here
],
// Pass the Slate editor to the root config
editor: slateEditor({})
editor: slateEditor({}),
})
```
@@ -52,11 +51,11 @@ export const Pages: CollectionConfig = {
],
leaves: [
// customize leaves allowed in Slate editor here
]
}
})
}
]
],
},
}),
},
],
}
```

View File

@@ -41,7 +41,7 @@ Every Payload Collection can opt-in to supporting Uploads by specifying the `upl
### Collection Upload Options
| Option | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`staticURL`** \* | The URL path to use to access your uploads. Relative path like `/media` will be served by payload. Full path like `https://example.com/media` needs to be served by another web server. |
| **`staticDir`** \* | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. |
| **`adminThumbnail`** | Set the way that the Admin panel will display thumbnails for this Collection. [More](#admin-thumbnails) |
@@ -154,15 +154,13 @@ When an uploaded image is smaller than the defined image size, we have 3 options
`withoutEnlargement: undefined | false | true`
1.`undefined` [default]: uploading images with smaller width AND height than the image size will return null
2. `false`: always enlarge images to the image size
3. `true`: if the image is smaller than the image size, return the original image
1.`undefined` [default]: uploading images with smaller width AND height than the image size will return null 2. `false`: always enlarge images to the image size 3. `true`: if the image is smaller than the image size, return the original image
<Banner type="error">
<strong>Note:</strong>
<br />
By default, the image size will return NULL when the uploaded image is smaller than the defined image size.
Use the `withoutEnlargement` prop to change this.
By default, the image size will return NULL when the uploaded image is smaller than the defined
image size. Use the `withoutEnlargement` prop to change this.
</Banner>
### Crop and Focal Point Selector
@@ -209,8 +207,7 @@ export const Media: CollectionConfig = {
// ... image sizes here
],
// highlight-start
adminThumbnail: ({ doc }) =>
`https://google.com/custom-path-to-file/${doc.filename}`,
adminThumbnail: ({ doc }) => `https://google.com/custom-path-to-file/${doc.filename}`,
// highlight-end
},
}

View File

@@ -20,7 +20,7 @@ _If Autosave is enabled, drafts will be created automatically as the document is
Collections and Globals both support the same options for configuring autosave. You can either set `versions.drafts.autosave` to `true`, or pass an object to configure autosave properties.
| Drafts Autosave Options | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `interval` | Define an `interval` in milliseconds to automatically save progress while documents are edited. Document updates are "debounced" at this interval. Defaults to `800`. |
**Example config with versions, drafts, and autosave enabled:**

View File

@@ -1,8 +1,8 @@
module.exports = {
printWidth: 100,
parser: "typescript",
parser: 'typescript',
semi: false,
singleQuote: true,
trailingComma: "all",
arrowParens: "avoid",
};
trailingComma: 'all',
arrowParens: 'avoid',
}

View File

@@ -8,23 +8,23 @@
export interface Config {
collections: {
users: User;
};
globals: {};
users: User
}
globals: {}
}
export interface User {
id: string;
firstName?: string;
lastName?: string;
roles?: ('admin' | 'user')[];
updatedAt: string;
createdAt: string;
email: string;
resetPasswordToken?: string;
resetPasswordExpiration?: string;
salt?: string;
hash?: string;
loginAttempts?: number;
lockUntil?: string;
password?: string;
id: string
firstName?: string
lastName?: string
roles?: ('admin' | 'user')[]
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
}

View File

@@ -1,8 +1,8 @@
module.exports = {
printWidth: 100,
parser: "typescript",
parser: 'typescript',
semi: false,
singleQuote: true,
trailingComma: "all",
arrowParens: "avoid",
};
trailingComma: 'all',
arrowParens: 'avoid',
}

View File

@@ -8,23 +8,23 @@
export interface Config {
collections: {
users: User;
};
globals: {};
users: User
}
globals: {}
}
export interface User {
id: string;
firstName?: string;
lastName?: string;
roles?: ('admin' | 'user')[];
updatedAt: string;
createdAt: string;
email: string;
resetPasswordToken?: string;
resetPasswordExpiration?: string;
salt?: string;
hash?: string;
loginAttempts?: number;
lockUntil?: string;
password?: string;
id: string
firstName?: string
lastName?: string
roles?: ('admin' | 'user')[]
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
}

View File

@@ -1,5 +1,4 @@
build
dist
node_modules
package-lock.json
.env
package - lock.json.env

View File

@@ -1,8 +1,8 @@
module.exports = {
printWidth: 100,
parser: "typescript",
parser: 'typescript',
semi: false,
singleQuote: true,
trailingComma: "all",
arrowParens: "avoid",
};
trailingComma: 'all',
arrowParens: 'avoid',
}

View File

@@ -1,7 +1,4 @@
build
dist
node_modules
package-lock.json
.env
.next
.vercel
package - lock.json.env.next.vercel

View File

@@ -1,8 +1,8 @@
module.exports = {
printWidth: 100,
parser: "typescript",
parser: 'typescript',
semi: false,
singleQuote: true,
trailingComma: "all",
arrowParens: "avoid",
};
trailingComma: 'all',
arrowParens: 'avoid',
}

View File

@@ -23,8 +23,6 @@ export default buildConfig({
}),
// ...rest of config
})
```
More detailed usage can be found in the [Payload Docs](https://payloadcms.com/docs/configuration/overview).

View File

@@ -1,8 +1,9 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import type { ConnectOptions } from 'mongoose'
import mongoose from 'mongoose'
import type { Connect } from 'payload/database'
import mongoose from 'mongoose'
import type { MongooseAdapter } from './index.js'
export const connect: Connect = async function connect(
@@ -36,8 +37,6 @@ export const connect: Connect = async function connect(
const client = this.connection.getClient()
if (!client.options.replicaSet) {
this.transactionOptions = false
this.beginTransaction = undefined

View File

@@ -17,7 +17,7 @@ export const createGlobal: CreateGlobal = async function createGlobal(
}
const options = withSession(this, req.transactionID)
let [result] = (await Model.create([global], options)) as any
let [result] = await Model.create([global], options)
result = JSON.parse(JSON.stringify(result))

View File

@@ -10,7 +10,7 @@ import { withSession } from './withSession.js'
export const findGlobal: FindGlobal = async function findGlobal(
this: MongooseAdapter,
{ locale, req = {} as PayloadRequest, slug, where },
{ slug, locale, req = {} as PayloadRequest, where },
) {
const Model = this.globals
const options = {
@@ -25,7 +25,7 @@ export const findGlobal: FindGlobal = async function findGlobal(
where: combineQueries({ globalType: { equals: slug } }, where),
})
let doc = (await Model.findOne(query, {}, options)) as any
let doc = await Model.findOne(query, {}, options)
if (!doc) {
return null

View File

@@ -1,12 +1,12 @@
import type { TransactionOptions } from 'mongodb'
import type { ClientSession, Connection, ConnectOptions } from 'mongoose'
import mongoose from 'mongoose'
import type { ClientSession, ConnectOptions, Connection } from 'mongoose'
import type { Payload } from 'payload'
import type { BaseDatabaseAdapter, DatabaseAdapterObj } from 'payload/database'
import { createDatabaseAdapter } from 'payload/database'
import fs from 'fs'
import mongoose from 'mongoose'
import path from 'path'
import { createDatabaseAdapter } from 'payload/database'
import type { CollectionModel, GlobalModel } from './types.js'
@@ -46,13 +46,13 @@ export interface Args {
/** Set false to disable $facet aggregation in non-supporting databases, Defaults to true */
useFacet?: boolean
}
/** Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false */
disableIndexHints?: boolean
migrationDir?: string
/**
* typed as any to avoid dependency
*/
mongoMemoryServer?: any
/** Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false */
disableIndexHints?: boolean
migrationDir?: string
transactionOptions?: TransactionOptions | false
/** The URL to connect to MongoDB or false to start payload and prevent connecting */
url: false | string
@@ -94,8 +94,8 @@ export function mongooseAdapter({
autoPluralization = true,
connectOptions,
disableIndexHints = false,
mongoMemoryServer,
migrationDir: migrationDirArg,
mongoMemoryServer,
transactionOptions = {},
url,
}: Args): DatabaseAdapterObj {

View File

@@ -23,9 +23,9 @@ export async function migrateFresh(
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
type: 'confirm',
},
{
onCancel: () => {

View File

@@ -8,7 +8,7 @@ import { withSession } from './withSession.js'
export const updateGlobal: UpdateGlobal = async function updateGlobal(
this: MongooseAdapter,
{ data, req = {} as PayloadRequest, slug },
{ slug, data, req = {} as PayloadRequest },
) {
const Model = this.globals
const options = {

View File

@@ -21,12 +21,10 @@ export default buildConfig({
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URI,
}
},
}),
// ...rest of config
})
```
More detailed usage can be found in the [Payload Docs](https://payloadcms.com/docs/configuration/overview).

View File

@@ -19,8 +19,8 @@ export const create: Create = async function create(
db,
fields: collection.fields,
operation: 'create',
tableName: toSnakeCase(collectionSlug),
req,
tableName: toSnakeCase(collectionSlug),
})
return result

View File

@@ -9,7 +9,7 @@ import { upsertRow } from './upsertRow/index.js'
export async function createGlobal<T extends TypeWithID>(
this: PostgresAdapter,
{ data, req = {} as PayloadRequest, slug }: CreateGlobalArgs,
{ slug, data, req = {} as PayloadRequest }: CreateGlobalArgs,
): Promise<T> {
const db = this.sessions[req.transactionID]?.db || this.drizzle
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
@@ -20,8 +20,8 @@ export async function createGlobal<T extends TypeWithID>(
db,
fields: globalConfig.fields,
operation: 'create',
tableName: toSnakeCase(slug),
req,
tableName: toSnakeCase(slug),
})
return result

View File

@@ -1,8 +1,8 @@
import type { TypeWithVersion } from 'payload/database'
import { type CreateGlobalVersionArgs } from 'payload/database'
import type { PayloadRequest, TypeWithID } from 'payload/types'
import { sql } from 'drizzle-orm'
import { type CreateGlobalVersionArgs } from 'payload/database'
import { buildVersionGlobalFields } from 'payload/versions'
import toSnakeCase from 'to-snake-case'
@@ -29,8 +29,8 @@ export async function createGlobalVersion<T extends TypeWithID>(
db,
fields: buildVersionGlobalFields(global),
operation: 'create',
tableName,
req,
tableName,
})
const table = this.tables[tableName]

View File

@@ -35,8 +35,8 @@ export async function createVersion<T extends TypeWithID>(
db,
fields: buildVersionCollectionFields(collection),
operation: 'create',
tableName,
req,
tableName,
})
const table = this.tables[tableName]

View File

@@ -8,7 +8,7 @@ import { findMany } from './find/findMany.js'
export const findGlobal: FindGlobal = async function findGlobal(
this: PostgresAdapter,
{ locale, req, slug, where },
{ slug, locale, req, where },
) {
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
const tableName = toSnakeCase(slug)

View File

@@ -95,7 +95,7 @@ export const getTableColumnFromPath = ({
field: {
name: 'id',
type: adapter.idType === 'uuid' ? 'text' : 'number',
} as TextField | NumberField,
} as NumberField | TextField,
table: adapter.tables[newTableName],
}
}

View File

@@ -10,8 +10,8 @@ import type { GenericColumn, PostgresAdapter } from '../types.js'
import type { BuildQueryJoinAliases, BuildQueryJoins } from './buildQuery.js'
import { buildAndOrConditions } from './buildAndOrConditions.js'
import { createJSONQuery } from './createJSONQuery/index.js'
import { convertPathToJSONTraversal } from './createJSONQuery/convertPathToJSONTraversal.js'
import { createJSONQuery } from './createJSONQuery/index.js'
import { getTableColumnFromPath } from './getTableColumnFromPath.js'
import { operatorMap } from './operatorMap.js'
import { sanitizeQueryValue } from './sanitizeQueryValue.js'

View File

@@ -4,11 +4,11 @@ import type { TextField } from 'payload/types'
type Args = {
field: TextField
locale?: string
textRows: Record<string, unknown>[]
ref: Record<string, unknown>
textRows: Record<string, unknown>[]
}
export const transformHasManyText = ({ field, locale, textRows, ref }: Args) => {
export const transformHasManyText = ({ field, locale, ref, textRows }: Args) => {
const result = textRows.map(({ text }) => text)
if (locale) {

View File

@@ -48,11 +48,11 @@ export const transform = <T extends TypeWithID>({ config, data, fields }: Transf
deletions,
fieldPrefix: '',
fields,
texts,
numbers,
path: '',
relationships,
table: data,
texts,
})
deletions.forEach((deletion) => deletion())

View File

@@ -18,7 +18,6 @@ type Args = {
data: unknown
field: ArrayField
locale?: string
texts: Record<string, unknown>[]
numbers: Record<string, unknown>[]
path: string
relationships: Record<string, unknown>[]
@@ -26,6 +25,7 @@ type Args = {
selects: {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
}
export const transformArray = ({
@@ -37,12 +37,12 @@ export const transformArray = ({
data,
field,
locale,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
}: Args) => {
const newRows: ArrayRowToInsert[] = []
const hasUUID = adapter.tables[arrayTableName]._uuid
@@ -88,7 +88,6 @@ export const transformArray = ({
fieldPrefix: '',
fields: field.fields,
locales: newRow.locales,
texts,
numbers,
parentTableName: arrayTableName,
path: `${path || ''}${field.name}.${i}.`,
@@ -96,6 +95,7 @@ export const transformArray = ({
relationshipsToDelete,
row: newRow.row,
selects,
texts,
})
newRows.push(newRow)

View File

@@ -18,7 +18,6 @@ type Args = {
data: Record<string, unknown>[]
field: BlockField
locale?: string
texts: Record<string, unknown>[]
numbers: Record<string, unknown>[]
path: string
relationships: Record<string, unknown>[]
@@ -26,6 +25,7 @@ type Args = {
selects: {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
}
export const transformBlocks = ({
adapter,
@@ -35,12 +35,12 @@ export const transformBlocks = ({
data,
field,
locale,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
}: Args) => {
data.forEach((blockRow, i) => {
if (typeof blockRow.blockType !== 'string') return
@@ -86,7 +86,6 @@ export const transformBlocks = ({
fieldPrefix: '',
fields: matchedBlock.fields,
locales: newRow.locales,
texts,
numbers,
parentTableName: blockTableName,
path: `${path || ''}${field.name}.${i}.`,
@@ -94,6 +93,7 @@ export const transformBlocks = ({
relationshipsToDelete,
row: newRow.row,
selects,
texts,
})
blocks[blockType].push(newRow)

View File

@@ -27,12 +27,12 @@ export const transformForWrite = ({
blocks: {},
blocksToDelete: new Set(),
locales: {},
texts: [],
numbers: [],
relationships: [],
relationshipsToDelete: [],
row: {},
selects: {},
texts: [],
}
// This function is responsible for building up the
@@ -48,7 +48,6 @@ export const transformForWrite = ({
fieldPrefix: '',
fields,
locales: rowToInsert.locales,
texts: rowToInsert.texts,
numbers: rowToInsert.numbers,
parentTableName: tableName,
path,
@@ -56,6 +55,7 @@ export const transformForWrite = ({
relationshipsToDelete: rowToInsert.relationshipsToDelete,
row: rowToInsert.row,
selects: rowToInsert.selects,
texts: rowToInsert.texts,
})
return rowToInsert

View File

@@ -8,8 +8,8 @@ export const transformTexts = ({ baseRow, data, texts }: Args) => {
data.forEach((val, i) => {
texts.push({
...baseRow,
text: val,
order: i + 1,
text: val,
})
})
}

View File

@@ -45,7 +45,6 @@ type Args = {
locales: {
[locale: string]: Record<string, unknown>
}
texts: Record<string, unknown>[]
numbers: Record<string, unknown>[]
/**
* This is the name of the parent table
@@ -58,6 +57,7 @@ type Args = {
selects: {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
}
export const traverseFields = ({
@@ -73,7 +73,6 @@ export const traverseFields = ({
fields,
forcedLocale,
locales,
texts,
numbers,
parentTableName,
path,
@@ -81,6 +80,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
}: Args) => {
fields.forEach((field) => {
let columnName = ''
@@ -111,12 +111,12 @@ export const traverseFields = ({
data: localeData,
field,
locale: localeKey,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
})
arrays[arrayTableName] = arrays[arrayTableName].concat(newRows)
@@ -132,12 +132,12 @@ export const traverseFields = ({
blocksToDelete,
data: data[field.name],
field,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
})
arrays[arrayTableName] = arrays[arrayTableName].concat(newRows)
@@ -163,12 +163,12 @@ export const traverseFields = ({
data: localeData,
field,
locale: localeKey,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
})
}
})
@@ -181,12 +181,12 @@ export const traverseFields = ({
blocksToDelete,
data: fieldData,
field,
texts,
numbers,
path,
relationships,
relationshipsToDelete,
selects,
texts,
})
}
@@ -210,7 +210,6 @@ export const traverseFields = ({
fields: field.fields,
forcedLocale: localeKey,
locales,
texts,
numbers,
parentTableName,
path: `${path || ''}${field.name}.`,
@@ -218,6 +217,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
})
} else {
@@ -233,7 +233,6 @@ export const traverseFields = ({
fieldPrefix: `${fieldName}_`,
fields: field.fields,
locales,
texts,
numbers,
parentTableName,
path: `${path || ''}${field.name}.`,
@@ -241,6 +240,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
}
}
@@ -267,7 +267,6 @@ export const traverseFields = ({
fields: tab.fields,
forcedLocale: localeKey,
locales,
texts,
numbers,
parentTableName,
path: `${path || ''}${tab.name}.`,
@@ -275,6 +274,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
})
} else {
@@ -290,7 +290,6 @@ export const traverseFields = ({
fieldPrefix: `${fieldPrefix || ''}${tab.name}_`,
fields: tab.fields,
locales,
texts,
numbers,
parentTableName,
path: `${path || ''}${tab.name}.`,
@@ -298,6 +297,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
}
}
@@ -314,7 +314,6 @@ export const traverseFields = ({
fieldPrefix,
fields: tab.fields,
locales,
texts,
numbers,
parentTableName,
path,
@@ -322,6 +321,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
}
})
@@ -340,7 +340,6 @@ export const traverseFields = ({
fieldPrefix,
fields: field.fields,
locales,
texts,
numbers,
parentTableName,
path,
@@ -348,6 +347,7 @@ export const traverseFields = ({
relationshipsToDelete,
row,
selects,
texts,
})
}

View File

@@ -34,7 +34,6 @@ export type RowToInsert = {
locales: {
[locale: string]: Record<string, unknown>
}
texts: Record<string, unknown>[]
numbers: Record<string, unknown>[]
relationships: Record<string, unknown>[]
relationshipsToDelete: RelationshipToDelete[]
@@ -42,4 +41,5 @@ export type RowToInsert = {
selects: {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
}

View File

@@ -4,6 +4,7 @@ import toSnakeCase from 'to-snake-case'
import type { ChainedMethods } from './find/chainMethods.js'
import type { PostgresAdapter } from './types.js'
import { chainMethods } from './find/chainMethods.js'
import buildQuery from './queries/buildQuery.js'
import { upsertRow } from './upsertRow/index.js'
@@ -70,8 +71,8 @@ export const updateOne: UpdateOne = async function updateOne(
db,
fields: collection.fields,
operation: 'update',
tableName: toSnakeCase(collectionSlug),
req,
tableName: toSnakeCase(collectionSlug),
})
return result

View File

@@ -9,7 +9,7 @@ import { upsertRow } from './upsertRow/index.js'
export async function updateGlobal<T extends TypeWithID>(
this: PostgresAdapter,
{ data, req = {} as PayloadRequest, slug }: UpdateGlobalArgs,
{ slug, data, req = {} as PayloadRequest }: UpdateGlobalArgs,
): Promise<T> {
const db = this.sessions[req.transactionID]?.db || this.drizzle
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
@@ -23,8 +23,8 @@ export async function updateGlobal<T extends TypeWithID>(
data,
db,
fields: globalConfig.fields,
tableName,
req,
tableName,
})
return result

View File

@@ -43,9 +43,9 @@ export async function updateGlobalVersion<T extends TypeWithID>(
db,
fields,
operation: 'update',
req,
tableName,
where,
req,
})
return result

View File

@@ -41,9 +41,9 @@ export async function updateVersion<T extends TypeWithID>(
db,
fields,
operation: 'update',
req,
tableName,
where,
req,
})
return result

View File

@@ -9,8 +9,8 @@ type BaseArgs = {
db: DrizzleDB
fields: Field[]
path?: string
tableName: string
req: PayloadRequest
tableName: string
}
type CreateArgs = BaseArgs & {

View File

@@ -1,21 +1,21 @@
/* eslint-disable no-param-reassign */
import * as GraphQL from 'graphql'
import { OperationArgs } from 'graphql-http'
import {
fieldExtensionsEstimator,
simpleEstimator,
createComplexityRule,
} from 'graphql-query-complexity'
import type { OperationArgs } from 'graphql-http'
import type { GraphQLInfo } from 'payload/config'
import type { SanitizedConfig } from 'payload/types'
import * as GraphQL from 'graphql'
import {
createComplexityRule,
fieldExtensionsEstimator,
simpleEstimator,
} from 'graphql-query-complexity'
import accessResolver from './resolvers/auth/access.js'
import initCollections from './schema/initCollections.js'
import initGlobals from './schema/initGlobals.js'
import buildFallbackLocaleInputType from './schema/buildFallbackLocaleInputType.js'
import buildLocaleInputType from './schema/buildLocaleInputType.js'
import buildPoliciesType from './schema/buildPoliciesType.js'
import initCollections from './schema/initCollections.js'
import initGlobals from './schema/initGlobals.js'
import { wrapCustomFields } from './utilities/wrapCustomResolver.js'
export async function configToSchema(config: SanitizedConfig): Promise<{
@@ -34,7 +34,17 @@ export async function configToSchema(config: SanitizedConfig): Promise<{
config: config.globals,
}
let graphqlResult: GraphQLInfo = {
const graphqlResult: GraphQLInfo = {
Mutation: {
name: 'Mutation',
fields: {},
},
Query: {
name: 'Query',
fields: {},
},
collections,
globals,
types: {
arrayTypes: {},
blockInputTypes: {},
@@ -42,16 +52,6 @@ export async function configToSchema(config: SanitizedConfig): Promise<{
groupTypes: {},
tabTypes: {},
},
Query: {
name: 'Query',
fields: {},
},
Mutation: {
name: 'Mutation',
fields: {},
},
collections,
globals,
}
if (config.localization) {
@@ -65,8 +65,8 @@ export async function configToSchema(config: SanitizedConfig): Promise<{
initGlobals({ config, graphqlResult })
graphqlResult.Query.fields['Access'] = {
resolve: accessResolver(config),
type: buildPoliciesType(config),
resolve: accessResolver(config),
}
if (typeof config.graphQL.queries === 'function') {

View File

@@ -1,9 +1,11 @@
import { accessOperation } from 'payload/operations'
import type { SanitizedConfig } from 'payload/types'
import formatName from '../../utilities/formatName.js'
import { Context } from '../types.js'
import { accessOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
import formatName from '../../utilities/formatName.js'
const formatConfigNames = (results, configs) => {
const formattedResults = { ...results }

View File

@@ -1,7 +1,8 @@
import { forgotPasswordOperation } from 'payload/operations'
import type { Collection } from 'payload/types'
import { forgotPasswordOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function forgotPasswordResolver(collection: Collection): any {

View File

@@ -1,5 +1,6 @@
import { initOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function initResolver(collection: string) {

View File

@@ -1,8 +1,9 @@
import { loginOperation } from 'payload/operations'
import { generatePayloadCookie } from 'payload/auth'
import type { Collection } from 'payload/types'
import { generatePayloadCookie } from 'payload/auth'
import { loginOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function loginResolver(collection: Collection): any {
@@ -19,9 +20,9 @@ function loginResolver(collection: Collection): any {
const result = await loginOperation(options)
const cookie = generatePayloadCookie({
token: result.token,
payload: context.req.payload,
collectionConfig: collection.config,
payload: context.req.payload,
token: result.token,
})
context.headers['Set-Cookie'] = cookie

View File

@@ -1,8 +1,9 @@
import { logoutOperation } from 'payload/operations'
import { generateExpiredPayloadCookie } from 'payload/auth'
import type { Collection } from 'payload/types'
import { generateExpiredPayloadCookie } from 'payload/auth'
import { logoutOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function logoutResolver(collection: Collection): any {

View File

@@ -1,7 +1,8 @@
import { meOperation } from 'payload/operations'
import type { Collection } from 'payload/types'
import { meOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function meResolver(collection: Collection): any {

View File

@@ -1,8 +1,9 @@
import { refreshOperation } from 'payload/operations'
import { generatePayloadCookie, extractJWT } from 'payload/auth'
import type { Collection } from 'payload/types'
import { extractJWT, generatePayloadCookie } from 'payload/auth'
import { refreshOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function refreshResolver(collection: Collection): any {
@@ -24,9 +25,9 @@ function refreshResolver(collection: Collection): any {
const result = await refreshOperation(options)
const cookie = generatePayloadCookie({
token: result.refreshedToken,
payload: context.req.payload,
collectionConfig: collection.config,
payload: context.req.payload,
token: result.refreshedToken,
})
context.headers['Set-Cookie'] = cookie

View File

@@ -1,8 +1,9 @@
import { resetPasswordOperation } from 'payload/operations'
import { generatePayloadCookie } from 'payload/auth'
import type { Collection } from 'payload/types'
import { generatePayloadCookie } from 'payload/auth'
import { resetPasswordOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function resetPasswordResolver(collection: Collection): any {
@@ -20,9 +21,9 @@ function resetPasswordResolver(collection: Collection): any {
const result = await resetPasswordOperation(options)
const cookie = generatePayloadCookie({
token: result.token,
payload: context.req.payload,
collectionConfig: collection.config,
payload: context.req.payload,
token: result.token,
})
context.headers['Set-Cookie'] = cookie

View File

@@ -1,7 +1,8 @@
import { unlockOperation } from 'payload/operations'
import type { Collection } from 'payload/types'
import { unlockOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function unlockResolver(collection: Collection) {

View File

@@ -1,7 +1,8 @@
import { verifyEmailOperation } from 'payload/operations'
import type { Collection } from 'payload/types'
import { verifyEmailOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
function verifyEmailResolver(collection: Collection) {

View File

@@ -1,10 +1,11 @@
import { createOperation } from 'payload/operations'
import type { MarkOptional } from 'ts-essentials'
import type { GeneratedTypes } from 'payload'
import type { PayloadRequest } from 'payload/types'
import type { Collection } from 'payload/types'
import type { MarkOptional } from 'ts-essentials'
import { createOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
export type Resolver<TSlug extends keyof GeneratedTypes['collections']> = (

View File

@@ -1,9 +1,10 @@
import { deleteByIDOperation } from 'payload/operations'
import type { GeneratedTypes } from 'payload'
import type { PayloadRequest } from 'payload/types'
import type { Collection } from 'payload/types'
import { deleteByIDOperation } from 'payload/operations'
import { isolateObjectProperty } from 'payload/utilities'
import type { Context } from '../types.js'
export type Resolver<TSlug extends keyof GeneratedTypes['collections']> = (

Some files were not shown because too many files have changed in this diff Show More