Compare commits
9 Commits
chore/driz
...
feat/forma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2cd6bbaec | ||
|
|
b2657ed12b | ||
|
|
0851ef99da | ||
|
|
3c483ab57a | ||
|
|
9bdbbb674f | ||
|
|
eb191f335b | ||
|
|
02bb176890 | ||
|
|
082c6ef44a | ||
|
|
f93cdf9364 |
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -196,7 +196,6 @@ jobs:
|
||||
- postgres-custom-schema
|
||||
- postgres-uuid
|
||||
- supabase
|
||||
- sqlite
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
|
||||
1
.github/workflows/pr-title.yml
vendored
1
.github/workflows/pr-title.yml
vendored
@@ -38,7 +38,6 @@ jobs:
|
||||
db-\*
|
||||
db-mongodb
|
||||
db-postgres
|
||||
db-sqlite
|
||||
email-nodemailer
|
||||
eslint
|
||||
graphql
|
||||
|
||||
@@ -266,10 +266,12 @@ export const myField: Field = {
|
||||
|
||||
_For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._
|
||||
|
||||
Custom Label Components receive all [Field Component](#the-field-component) props, plus the following props:
|
||||
All Label Components receive the following props:
|
||||
|
||||
| Property | Description |
|
||||
| -------------- | ---------------------------------------------------------------- |
|
||||
| **`label`** | Label value provided in field, it can be used with i18n. |
|
||||
| **`required`** | The `admin.required` property defined in the [Field Config](../fields/overview). |
|
||||
| **`schemaPath`** | The path to the field in the schema. Similar to `path`, but without dynamic indices. |
|
||||
|
||||
<Banner type="success">
|
||||
@@ -277,36 +279,6 @@ Custom Label Components receive all [Field Component](#the-field-component) prop
|
||||
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
|
||||
</Banner>
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Error Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Error Component, one for every [Field Type](../fields/overview). The convention is to append `ErrorComponent` to the type of field, i.e. `TextFieldErrorComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldLabelComponent,
|
||||
BlocksFieldLabelComponent,
|
||||
CheckboxFieldLabelComponent,
|
||||
CodeFieldLabelComponent,
|
||||
CollapsibleFieldLabelComponent,
|
||||
DateFieldLabelComponent,
|
||||
EmailFieldLabelComponent,
|
||||
GroupFieldLabelComponent,
|
||||
HiddenFieldLabelComponent,
|
||||
JSONFieldLabelComponent,
|
||||
NumberFieldLabelComponent,
|
||||
PointFieldLabelComponent,
|
||||
RadioFieldLabelComponent,
|
||||
RelationshipFieldLabelComponent,
|
||||
RichTextFieldLabelComponent,
|
||||
RowFieldLabelComponent,
|
||||
SelectFieldLabelComponent,
|
||||
TabsFieldLabelComponent,
|
||||
TextFieldLabelComponent,
|
||||
TextareaFieldLabelComponent,
|
||||
UploadFieldLabelComponent
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
### The Error Component
|
||||
|
||||
The Error Component is rendered when a field fails validation. It is typically displayed beneath the field input in a visually-compelling style.
|
||||
@@ -329,7 +301,7 @@ export const myField: Field = {
|
||||
|
||||
_For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._
|
||||
|
||||
Custom Error Components receive all [Field Component](#the-field-component) props, plus the following props:
|
||||
All Error Components receive the following props:
|
||||
|
||||
| Property | Description |
|
||||
| --------------- | ------------------------------------------------------------- |
|
||||
@@ -340,36 +312,6 @@ Custom Error Components receive all [Field Component](#the-field-component) prop
|
||||
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
|
||||
</Banner>
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Error Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Error Component, one for every [Field Type](../fields/overview). The convention is to append `ErrorComponent` to the type of field, i.e. `TextFieldErrorComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldErrorComponent,
|
||||
BlocksFieldErrorComponent,
|
||||
CheckboxFieldErrorComponent,
|
||||
CodeFieldErrorComponent,
|
||||
CollapsibleFieldErrorComponent,
|
||||
DateFieldErrorComponent,
|
||||
EmailFieldErrorComponent,
|
||||
GroupFieldErrorComponent,
|
||||
HiddenFieldErrorComponent,
|
||||
JSONFieldErrorComponent,
|
||||
NumberFieldErrorComponent,
|
||||
PointFieldErrorComponent,
|
||||
RadioFieldErrorComponent,
|
||||
RelationshipFieldErrorComponent,
|
||||
RichTextFieldErrorComponent,
|
||||
RowFieldErrorComponent,
|
||||
SelectFieldErrorComponent,
|
||||
TabsFieldErrorComponent,
|
||||
TextFieldErrorComponent,
|
||||
TextareaFieldErrorComponent,
|
||||
UploadFieldErrorComponent
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
### The Description Property
|
||||
|
||||
Field Descriptions are used to provide additional information to the editor about a field, such as special instructions. Their placement varies from field to field, but typically are displayed with subtle style differences beneath the field inputs.
|
||||
@@ -464,7 +406,7 @@ export const MyCollectionConfig: SanitizedCollectionConfig = {
|
||||
|
||||
_For details on how to build a Custom Description, see [Building Custom Components](./components#building-custom-components)._
|
||||
|
||||
Custom Description Components receive all [Field Component](#the-field-component) props, plus the following props:
|
||||
All Description Components receive the following props:
|
||||
|
||||
| Property | Description |
|
||||
| -------------- | ---------------------------------------------------------------- |
|
||||
@@ -475,36 +417,6 @@ Custom Description Components receive all [Field Component](#the-field-component
|
||||
All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details.
|
||||
</Banner>
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Description Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Description Component, one for every [Field Type](../fields/overview). The convention is to append `DescriptionComponent` to the type of field, i.e. `TextFieldDescriptionComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldDescriptionComponent,
|
||||
BlocksFieldDescriptionComponent,
|
||||
CheckboxFieldDescriptionComponent,
|
||||
CodeFieldDescriptionComponent,
|
||||
CollapsibleFieldDescriptionComponent,
|
||||
DateFieldDescriptionComponent,
|
||||
EmailFieldDescriptionComponent,
|
||||
GroupFieldDescriptionComponent,
|
||||
HiddenFieldDescriptionComponent,
|
||||
JSONFieldDescriptionComponent,
|
||||
NumberFieldDescriptionComponent,
|
||||
PointFieldDescriptionComponent,
|
||||
RadioFieldDescriptionComponent,
|
||||
RelationshipFieldDescriptionComponent,
|
||||
RichTextFieldDescriptionComponent,
|
||||
RowFieldDescriptionComponent,
|
||||
SelectFieldDescriptionComponent,
|
||||
TabsFieldDescriptionComponent,
|
||||
TextFieldDescriptionComponent,
|
||||
TextareaFieldDescriptionComponent,
|
||||
UploadFieldDescriptionComponent
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
### afterInput and beforeInput
|
||||
|
||||
With these properties you can add multiple components _before_ and _after_ the input element, as their name suggests. This is useful when you need to render additional elements alongside the field without replacing the entire field component.
|
||||
|
||||
@@ -294,7 +294,7 @@ When using custom validation functions, Payload will use yours in place of the d
|
||||
To reuse default field validations, call them from within your custom validation function:
|
||||
|
||||
```ts
|
||||
import { text } from 'payload/shared'
|
||||
import { text } from 'payload/fields/validations'
|
||||
|
||||
const field: Field = {
|
||||
name: 'notBad',
|
||||
|
||||
@@ -193,7 +193,7 @@ You can learn more about writing queries [here](/docs/queries/overview).
|
||||
When a relationship field has both <strong>filterOptions</strong> and a custom{' '}
|
||||
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
|
||||
unless you call the default relationship field validation function imported from{' '}
|
||||
<strong>payload/shared</strong> in your validate function.
|
||||
<strong>payload/fields/validations</strong> in your validate function.
|
||||
</Banner>
|
||||
|
||||
## How the data is saved
|
||||
|
||||
@@ -123,5 +123,5 @@ You can learn more about writing queries [here](/docs/queries/overview).
|
||||
When an upload field has both <strong>filterOptions</strong> and a custom{' '}
|
||||
<strong>validate</strong> function, the api will not validate <strong>filterOptions</strong>{' '}
|
||||
unless you call the default upload field validation function imported from{' '}
|
||||
<strong>payload/shared</strong> in your validate function.
|
||||
<strong>payload/fields/validations</strong> in your validate function.
|
||||
</Banner>
|
||||
|
||||
@@ -335,6 +335,7 @@ import {
|
||||
FieldMap,
|
||||
File,
|
||||
Form,
|
||||
FormFieldBase,
|
||||
FormLoadingOverlayToggle,
|
||||
FormSubmit,
|
||||
GenerateConfirmation,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -119,7 +119,7 @@
|
||||
"create-payload-app": "workspace:*",
|
||||
"cross-env": "7.0.3",
|
||||
"dotenv": "16.4.5",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-orm": "0.29.4",
|
||||
"escape-html": "^1.0.3",
|
||||
"execa": "5.1.1",
|
||||
"form-data": "3.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -50,7 +50,6 @@
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.7.0",
|
||||
"@sindresorhus/slugify": "^1.1.0",
|
||||
"@swc/core": "^1.6.13",
|
||||
"arg": "^5.0.0",
|
||||
"chalk": "^4.1.0",
|
||||
"comment-json": "^4.2.3",
|
||||
|
||||
@@ -79,7 +79,7 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
|
||||
const installSpinner = p.spinner()
|
||||
installSpinner.start('Installing Payload and dependencies...')
|
||||
|
||||
const configurationResult = await installAndConfigurePayload({
|
||||
const configurationResult = installAndConfigurePayload({
|
||||
...args,
|
||||
nextAppDetails,
|
||||
nextConfigType,
|
||||
@@ -143,16 +143,15 @@ async function addPayloadConfigToTsConfig(projectDir: string, isSrcDir: boolean)
|
||||
}
|
||||
}
|
||||
|
||||
async function installAndConfigurePayload(
|
||||
function installAndConfigurePayload(
|
||||
args: {
|
||||
nextAppDetails: NextAppDetails
|
||||
nextConfigType: NextConfigType
|
||||
useDistFiles?: boolean
|
||||
} & InitNextArgs,
|
||||
): Promise<
|
||||
):
|
||||
| { payloadConfigPath: string; success: true }
|
||||
| { payloadConfigPath?: string; reason: string; success: false }
|
||||
> {
|
||||
| { payloadConfigPath?: string; reason: string; success: false } {
|
||||
const {
|
||||
'--debug': debug,
|
||||
nextAppDetails: { isSrcDir, nextAppDir, nextConfigPath } = {},
|
||||
@@ -213,7 +212,7 @@ async function installAndConfigurePayload(
|
||||
copyRecursiveSync(templateSrcDir, path.dirname(nextConfigPath), debug)
|
||||
|
||||
// Wrap next.config.js with withPayload
|
||||
await wrapNextConfig({ nextConfigPath, nextConfigType })
|
||||
wrapNextConfig({ nextConfigPath, nextConfigType })
|
||||
|
||||
return {
|
||||
payloadConfigPath: path.resolve(nextAppDir, '../payload.config.ts'),
|
||||
@@ -241,7 +240,7 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
const isSrcDir = fs.existsSync(path.resolve(projectDir, 'src'))
|
||||
|
||||
const nextConfigPath: string | undefined = (
|
||||
await globby('next.config.*(t|j)s', { absolute: true, cwd: projectDir })
|
||||
await globby('next.config.*js', { absolute: true, cwd: projectDir })
|
||||
)?.[0]
|
||||
|
||||
if (!nextConfigPath || nextConfigPath.length === 0) {
|
||||
@@ -287,13 +286,8 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
function getProjectType(args: {
|
||||
nextConfigPath: string
|
||||
packageObj: Record<string, unknown>
|
||||
}): NextConfigType {
|
||||
}): 'cjs' | 'esm' {
|
||||
const { nextConfigPath, packageObj } = args
|
||||
|
||||
if (nextConfigPath.endsWith('.ts')) {
|
||||
return 'ts'
|
||||
}
|
||||
|
||||
if (nextConfigPath.endsWith('.mjs')) {
|
||||
return 'esm'
|
||||
}
|
||||
|
||||
@@ -3,35 +3,6 @@ import { jest } from '@jest/globals'
|
||||
|
||||
import { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js'
|
||||
|
||||
const tsConfigs = {
|
||||
defaultNextConfig: `import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {};
|
||||
export default nextConfig;`,
|
||||
|
||||
nextConfigExportNamedDefault: `import type { NextConfig } from "next";
|
||||
const nextConfig: NextConfig = {};
|
||||
const wrapped = someFunc(asdf);
|
||||
export { wrapped as default };
|
||||
`,
|
||||
nextConfigWithFunc: `import type { NextConfig } from "next";
|
||||
const nextConfig: NextConfig = {};
|
||||
export default someFunc(nextConfig);
|
||||
`,
|
||||
nextConfigWithFuncMultiline: `import type { NextConfig } from "next";
|
||||
const nextConfig: NextConfig = {};
|
||||
export default someFunc(
|
||||
nextConfig
|
||||
);
|
||||
`,
|
||||
nextConfigWithSpread: `import type { NextConfig } from "next";
|
||||
const nextConfig: NextConfig = {
|
||||
...someConfig,
|
||||
};
|
||||
export default nextConfig;
|
||||
`,
|
||||
}
|
||||
|
||||
const esmConfigs = {
|
||||
defaultNextConfig: `/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
@@ -81,66 +52,27 @@ module.exports = nextConfig;
|
||||
}
|
||||
|
||||
describe('parseAndInsertWithPayload', () => {
|
||||
describe('ts', () => {
|
||||
const configType = 'ts'
|
||||
const importStatement = withPayloadStatement[configType]
|
||||
|
||||
it('should parse the default next config', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
tsConfigs.defaultNextConfig,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(importStatement)
|
||||
expect(modifiedConfigContent).toContain('withPayload(nextConfig)')
|
||||
})
|
||||
|
||||
it('should parse the config with a function', async () => {
|
||||
const { modifiedConfigContent: modifiedConfigContent2 } = await parseAndModifyConfigContent(
|
||||
tsConfigs.nextConfigWithFunc,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent2).toContain('withPayload(someFunc(nextConfig))')
|
||||
})
|
||||
|
||||
it('should parse the config with a multi-lined function', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
tsConfigs.nextConfigWithFuncMultiline,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(importStatement)
|
||||
expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/)
|
||||
})
|
||||
|
||||
it('should parse the config with a spread', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
tsConfigs.nextConfigWithSpread,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(importStatement)
|
||||
expect(modifiedConfigContent).toContain('withPayload(nextConfig)')
|
||||
})
|
||||
})
|
||||
describe('esm', () => {
|
||||
const configType = 'esm'
|
||||
const importStatement = withPayloadStatement[configType]
|
||||
it('should parse the default next config', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the default next config', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
esmConfigs.defaultNextConfig,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(importStatement)
|
||||
expect(modifiedConfigContent).toContain('withPayload(nextConfig)')
|
||||
})
|
||||
it('should parse the config with a function', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a function', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
esmConfigs.nextConfigWithFunc,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')
|
||||
})
|
||||
|
||||
it('should parse the config with a multi-lined function', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a function on a new line', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
esmConfigs.nextConfigWithFuncMultiline,
|
||||
configType,
|
||||
)
|
||||
@@ -148,8 +80,8 @@ describe('parseAndInsertWithPayload', () => {
|
||||
expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/)
|
||||
})
|
||||
|
||||
it('should parse the config with a spread', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a spread', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
esmConfigs.nextConfigWithSpread,
|
||||
configType,
|
||||
)
|
||||
@@ -158,10 +90,10 @@ describe('parseAndInsertWithPayload', () => {
|
||||
})
|
||||
|
||||
// Unsupported: export { wrapped as default }
|
||||
it('should give warning with a named export as default', async () => {
|
||||
it('should give warning with a named export as default', () => {
|
||||
const warnLogSpy = jest.spyOn(p.log, 'warn').mockImplementation(() => {})
|
||||
|
||||
const { modifiedConfigContent, success } = await parseAndModifyConfigContent(
|
||||
const { modifiedConfigContent, success } = parseAndModifyConfigContent(
|
||||
esmConfigs.nextConfigExportNamedDefault,
|
||||
configType,
|
||||
)
|
||||
@@ -177,39 +109,39 @@ describe('parseAndInsertWithPayload', () => {
|
||||
describe('cjs', () => {
|
||||
const configType = 'cjs'
|
||||
const requireStatement = withPayloadStatement[configType]
|
||||
it('should parse the default next config', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the default next config', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.defaultNextConfig,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(requireStatement)
|
||||
expect(modifiedConfigContent).toContain('withPayload(nextConfig)')
|
||||
})
|
||||
it('should parse anonymous default config', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse anonymous default config', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.anonConfig,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(requireStatement)
|
||||
expect(modifiedConfigContent).toContain('withPayload({})')
|
||||
})
|
||||
it('should parse the config with a function', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a function', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.nextConfigWithFunc,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')
|
||||
})
|
||||
it('should parse the config with a multi-lined function', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a function on a new line', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.nextConfigWithFuncMultiline,
|
||||
configType,
|
||||
)
|
||||
expect(modifiedConfigContent).toContain(requireStatement)
|
||||
expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/)
|
||||
})
|
||||
it('should parse the config with a named export as default', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a named export as default', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.nextConfigExportNamedDefault,
|
||||
configType,
|
||||
)
|
||||
@@ -217,8 +149,8 @@ describe('parseAndInsertWithPayload', () => {
|
||||
expect(modifiedConfigContent).toContain('withPayload(wrapped)')
|
||||
})
|
||||
|
||||
it('should parse the config with a spread', async () => {
|
||||
const { modifiedConfigContent } = await parseAndModifyConfigContent(
|
||||
it('should parse the config with a spread', () => {
|
||||
const { modifiedConfigContent } = parseAndModifyConfigContent(
|
||||
cjsConfigs.nextConfigWithSpread,
|
||||
configType,
|
||||
)
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import type { ExportDefaultExpression, ModuleItem } from '@swc/core'
|
||||
import type { Program } from 'esprima-next'
|
||||
|
||||
import swc from '@swc/core'
|
||||
import chalk from 'chalk'
|
||||
import { Syntax, parseModule } from 'esprima-next'
|
||||
import fs from 'fs'
|
||||
|
||||
import type { NextConfigType } from '../types.js'
|
||||
|
||||
import { log, warning } from '../utils/log.js'
|
||||
|
||||
export const withPayloadStatement = {
|
||||
cjs: `const { withPayload } = require("@payloadcms/next/withPayload");`,
|
||||
esm: `import { withPayload } from "@payloadcms/next/withPayload";`,
|
||||
ts: `import { withPayload } from "@payloadcms/next/withPayload";`,
|
||||
cjs: `const { withPayload } = require('@payloadcms/next/withPayload')\n`,
|
||||
esm: `import { withPayload } from '@payloadcms/next/withPayload'\n`,
|
||||
}
|
||||
|
||||
export const wrapNextConfig = async (args: {
|
||||
type NextConfigType = 'cjs' | 'esm'
|
||||
|
||||
export const wrapNextConfig = (args: {
|
||||
nextConfigPath: string
|
||||
nextConfigType: NextConfigType
|
||||
}) => {
|
||||
const { nextConfigPath, nextConfigType: configType } = args
|
||||
const configContent = fs.readFileSync(nextConfigPath, 'utf8')
|
||||
const { modifiedConfigContent: newConfig, success } = await parseAndModifyConfigContent(
|
||||
const { modifiedConfigContent: newConfig, success } = parseAndModifyConfigContent(
|
||||
configContent,
|
||||
configType,
|
||||
)
|
||||
@@ -36,142 +34,113 @@ export const wrapNextConfig = async (args: {
|
||||
/**
|
||||
* Parses config content with AST and wraps it with withPayload function
|
||||
*/
|
||||
export async function parseAndModifyConfigContent(
|
||||
export function parseAndModifyConfigContent(
|
||||
content: string,
|
||||
configType: NextConfigType,
|
||||
): Promise<{ modifiedConfigContent: string; success: boolean }> {
|
||||
content = withPayloadStatement[configType] + '\n' + content
|
||||
): { modifiedConfigContent: string; success: boolean } {
|
||||
content = withPayloadStatement[configType] + content
|
||||
|
||||
console.log({ configType, content })
|
||||
|
||||
if (configType === 'cjs' || configType === 'esm') {
|
||||
try {
|
||||
const ast = parseModule(content, { loc: true })
|
||||
|
||||
if (configType === 'cjs') {
|
||||
// Find `module.exports = X`
|
||||
const moduleExports = ast.body.find(
|
||||
(p) =>
|
||||
p.type === Syntax.ExpressionStatement &&
|
||||
p.expression?.type === Syntax.AssignmentExpression &&
|
||||
p.expression.left?.type === Syntax.MemberExpression &&
|
||||
p.expression.left.object?.type === Syntax.Identifier &&
|
||||
p.expression.left.object.name === 'module' &&
|
||||
p.expression.left.property?.type === Syntax.Identifier &&
|
||||
p.expression.left.property.name === 'exports',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
) as any
|
||||
|
||||
if (moduleExports && moduleExports.expression.right?.loc) {
|
||||
const modifiedConfigContent = insertBeforeAndAfter(
|
||||
content,
|
||||
moduleExports.expression.right.loc,
|
||||
)
|
||||
return { modifiedConfigContent, success: true }
|
||||
}
|
||||
|
||||
return Promise.resolve({
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
})
|
||||
} else if (configType === 'esm') {
|
||||
const exportDefaultDeclaration = ast.body.find(
|
||||
(p) => p.type === Syntax.ExportDefaultDeclaration,
|
||||
) as Directive | undefined
|
||||
|
||||
const exportNamedDeclaration = ast.body.find(
|
||||
(p) => p.type === Syntax.ExportNamedDeclaration,
|
||||
) as ExportNamedDeclaration | undefined
|
||||
|
||||
if (!exportDefaultDeclaration && !exportNamedDeclaration) {
|
||||
throw new Error('Could not find ExportDefaultDeclaration in next.config.js')
|
||||
}
|
||||
|
||||
if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
|
||||
const modifiedConfigContent = insertBeforeAndAfter(
|
||||
content,
|
||||
exportDefaultDeclaration.declaration.loc,
|
||||
)
|
||||
return { modifiedConfigContent, success: true }
|
||||
} else if (exportNamedDeclaration) {
|
||||
const exportSpecifier = exportNamedDeclaration.specifiers.find(
|
||||
(s) =>
|
||||
s.type === 'ExportSpecifier' &&
|
||||
s.exported?.name === 'default' &&
|
||||
s.local?.type === 'Identifier' &&
|
||||
s.local?.name,
|
||||
)
|
||||
|
||||
if (exportSpecifier) {
|
||||
warning('Could not automatically wrap next.config.js with withPayload.')
|
||||
warning('Automatic wrapping of named exports as default not supported yet.')
|
||||
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warning('Could not automatically wrap Next config with withPayload.')
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return Promise.resolve({
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
})
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
warning(`Unable to parse Next config. Error: ${error.message} `)
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
}
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
let ast: Program | undefined
|
||||
try {
|
||||
ast = parseModule(content, { loc: true })
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
warning(`Unable to parse Next config. Error: ${error.message} `)
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
}
|
||||
} else if (configType === 'ts') {
|
||||
const { moduleItems, parseOffset } = await compileTypeScriptFileToAST(content)
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
|
||||
const exportDefaultDeclaration = moduleItems.find(
|
||||
(m) =>
|
||||
m.type === 'ExportDefaultExpression' &&
|
||||
(m.expression.type === 'Identifier' || m.expression.type === 'CallExpression'),
|
||||
) as ExportDefaultExpression | undefined
|
||||
if (configType === 'esm') {
|
||||
const exportDefaultDeclaration = ast.body.find(
|
||||
(p) => p.type === Syntax.ExportDefaultDeclaration,
|
||||
) as Directive | undefined
|
||||
|
||||
if (exportDefaultDeclaration) {
|
||||
if (!('span' in exportDefaultDeclaration.expression)) {
|
||||
warning('Could not automatically wrap Next config with withPayload.')
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return Promise.resolve({
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
})
|
||||
}
|
||||
const exportNamedDeclaration = ast.body.find(
|
||||
(p) => p.type === Syntax.ExportNamedDeclaration,
|
||||
) as ExportNamedDeclaration | undefined
|
||||
|
||||
const modifiedConfigContent = insertBeforeAndAfterSWC(
|
||||
if (!exportDefaultDeclaration && !exportNamedDeclaration) {
|
||||
throw new Error('Could not find ExportDefaultDeclaration in next.config.js')
|
||||
}
|
||||
|
||||
if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
|
||||
const modifiedConfigContent = insertBeforeAndAfter(
|
||||
content,
|
||||
exportDefaultDeclaration.expression.span,
|
||||
parseOffset,
|
||||
exportDefaultDeclaration.declaration.loc,
|
||||
)
|
||||
return { modifiedConfigContent, success: true }
|
||||
} else if (exportNamedDeclaration) {
|
||||
const exportSpecifier = exportNamedDeclaration.specifiers.find(
|
||||
(s) =>
|
||||
s.type === 'ExportSpecifier' &&
|
||||
s.exported?.name === 'default' &&
|
||||
s.local?.type === 'Identifier' &&
|
||||
s.local?.name,
|
||||
)
|
||||
|
||||
if (exportSpecifier) {
|
||||
warning('Could not automatically wrap next.config.js with withPayload.')
|
||||
warning('Automatic wrapping of named exports as default not supported yet.')
|
||||
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warning('Could not automatically wrap Next config with withPayload.')
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
} else if (configType === 'cjs') {
|
||||
// Find `module.exports = X`
|
||||
const moduleExports = ast.body.find(
|
||||
(p) =>
|
||||
p.type === Syntax.ExpressionStatement &&
|
||||
p.expression?.type === Syntax.AssignmentExpression &&
|
||||
p.expression.left?.type === Syntax.MemberExpression &&
|
||||
p.expression.left.object?.type === Syntax.Identifier &&
|
||||
p.expression.left.object.name === 'module' &&
|
||||
p.expression.left.property?.type === Syntax.Identifier &&
|
||||
p.expression.left.property.name === 'exports',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
) as any
|
||||
|
||||
if (moduleExports && moduleExports.expression.right?.loc) {
|
||||
const modifiedConfigContent = insertBeforeAndAfter(
|
||||
content,
|
||||
moduleExports.expression.right.loc,
|
||||
)
|
||||
return { modifiedConfigContent, success: true }
|
||||
}
|
||||
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
|
||||
warning('Could not automatically wrap Next config with withPayload.')
|
||||
warnUserWrapNotSuccessful(configType)
|
||||
return Promise.resolve({
|
||||
return {
|
||||
modifiedConfigContent: content,
|
||||
success: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function warnUserWrapNotSuccessful(configType: NextConfigType) {
|
||||
// Output directions for user to update next.config.js
|
||||
const withPayloadMessage = `
|
||||
|
||||
${chalk.bold(`Please manually wrap your existing Next config with the withPayload function. Here is an example:`)}
|
||||
${chalk.bold(`Please manually wrap your existing next.config.js with the withPayload function. Here is an example:`)}
|
||||
|
||||
${withPayloadStatement[configType]}
|
||||
|
||||
@@ -179,7 +148,7 @@ function warnUserWrapNotSuccessful(configType: NextConfigType) {
|
||||
// Your Next.js config here
|
||||
}
|
||||
|
||||
${configType === 'cjs' ? 'module.exports = withPayload(nextConfig)' : 'export default withPayload(nextConfig)'}
|
||||
${configType === 'esm' ? 'export default withPayload(nextConfig)' : 'module.exports = withPayload(nextConfig)'}
|
||||
|
||||
`
|
||||
|
||||
@@ -217,7 +186,7 @@ type Loc = {
|
||||
start: { column: number; line: number }
|
||||
}
|
||||
|
||||
function insertBeforeAndAfter(content: string, loc: Loc): string {
|
||||
function insertBeforeAndAfter(content: string, loc: Loc) {
|
||||
const { end, start } = loc
|
||||
const lines = content.split('\n')
|
||||
|
||||
@@ -236,57 +205,3 @@ function insertBeforeAndAfter(content: string, loc: Loc): string {
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
function insertBeforeAndAfterSWC(
|
||||
content: string,
|
||||
span: ModuleItem['span'],
|
||||
/**
|
||||
* WARNING: This is ONLY for unit tests. Defaults to 0 otherwise.
|
||||
*
|
||||
* @see compileTypeScriptFileToAST
|
||||
*/
|
||||
parseOffset: number,
|
||||
): string {
|
||||
const { end: preOffsetEnd, start: preOffsetStart } = span
|
||||
|
||||
const start = preOffsetStart - parseOffset
|
||||
const end = preOffsetEnd - parseOffset
|
||||
|
||||
const insert = (pos: number, text: string): string => {
|
||||
return content.slice(0, pos) + text + content.slice(pos)
|
||||
}
|
||||
|
||||
// insert ) after end
|
||||
content = insert(end - 1, ')')
|
||||
// insert withPayload before start
|
||||
content = insert(start - 1, 'withPayload(')
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile typescript to AST using the swc compiler
|
||||
*/
|
||||
async function compileTypeScriptFileToAST(
|
||||
fileContent: string,
|
||||
): Promise<{ moduleItems: ModuleItem[]; parseOffset: number }> {
|
||||
let parseOffset = 0
|
||||
|
||||
/**
|
||||
* WARNING: This is ONLY for unit tests.
|
||||
*
|
||||
* Multiple instances of swc DO NOT reset the .span.end value.
|
||||
* During unit tests, the .spawn.end value is read and accounted for.
|
||||
*
|
||||
* https://github.com/swc-project/swc/issues/1366
|
||||
*/
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
parseOffset = (await swc.parse('')).span.end
|
||||
}
|
||||
|
||||
const module = await swc.parse(fileContent, {
|
||||
syntax: 'typescript',
|
||||
})
|
||||
|
||||
return { moduleItems: module.body, parseOffset }
|
||||
}
|
||||
|
||||
@@ -75,6 +75,6 @@ export type NextAppDetails = {
|
||||
nextConfigType?: NextConfigType
|
||||
}
|
||||
|
||||
export type NextConfigType = 'cjs' | 'esm' | 'ts'
|
||||
export type NextConfigType = 'cjs' | 'esm'
|
||||
|
||||
export type StorageAdapterType = 'localDisk' | 'payloadCloud' | 'vercelBlobStorage'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The officially supported MongoDB database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-postgres",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -47,8 +47,8 @@
|
||||
"dependencies": {
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-kit": "0.23.0-eb2ca29",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.20.14-1f2c838",
|
||||
"drizzle-orm": "0.29.4",
|
||||
"pg": "8.11.3",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
|
||||
@@ -65,7 +65,7 @@ export const createMigration: CreateMigration = async function createMigration(
|
||||
|
||||
const sqlStatementsUp = await generateMigration(drizzleJsonBefore, drizzleJsonAfter)
|
||||
const sqlStatementsDown = await generateMigration(drizzleJsonAfter, drizzleJsonBefore)
|
||||
const sqlExecute = 'await payload.db.drizzle.execute(sql`'
|
||||
const sqlExecute = 'await db.execute(sql`'
|
||||
|
||||
if (sqlStatementsUp?.length) {
|
||||
upSQL = `${sqlExecute}\n ${sqlStatementsUp?.join('\n')}\`)`
|
||||
|
||||
@@ -7,11 +7,10 @@ export const defaultDrizzleSnapshot: DrizzleSnapshotJSON = {
|
||||
schemas: {},
|
||||
tables: {},
|
||||
},
|
||||
dialect: 'postgresql',
|
||||
dialect: 'pg',
|
||||
enums: {},
|
||||
prevId: '00000000-0000-0000-0000-00000000000',
|
||||
schemas: {},
|
||||
sequences: {},
|
||||
tables: {},
|
||||
version: '7',
|
||||
version: '5',
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ export const getMigrationTemplate = ({
|
||||
upSQL,
|
||||
}: MigrationTemplateArgs): string => `import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||
${imports ? `${imports}\n` : ''}
|
||||
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
${upSQL}
|
||||
}
|
||||
|
||||
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
${downSQL}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import type { Init, SanitizedCollectionConfig } from 'payload'
|
||||
/* eslint-disable no-param-reassign */
|
||||
import type { SanitizedCollectionConfig } from 'payload'
|
||||
import type { Init } from 'payload'
|
||||
|
||||
import { createTableName } from '@payloadcms/drizzle'
|
||||
import { pgEnum, pgSchema, pgTable } from 'drizzle-orm/pg-core'
|
||||
import { buildVersionCollectionFields, buildVersionGlobalFields } from 'payload'
|
||||
import toSnakeCase from 'to-snake-case'
|
||||
|
||||
import type { PostgresAdapter } from './types.js'
|
||||
|
||||
import { createTableName } from '../../drizzle/src/createTableName.js'
|
||||
import { buildTable } from './schema/build.js'
|
||||
|
||||
export const init: Init = function init(this: PostgresAdapter) {
|
||||
|
||||
@@ -156,7 +156,6 @@ declare module 'payload' {
|
||||
export interface DatabaseAdapter
|
||||
extends Omit<Args, 'idType' | 'logger' | 'migrationDir' | 'pool'>,
|
||||
DrizzleAdapter {
|
||||
drizzle: PostgresDB
|
||||
enums: Record<string, GenericEnum>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-sqlite",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.36",
|
||||
"description": "The officially supported SQLite database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -46,8 +46,8 @@
|
||||
"@libsql/client": "^0.6.2",
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-kit": "0.23.0-eb2ca29",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-kit": "0.20.14-1f2c838",
|
||||
"drizzle-orm": "0.29.4",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
"uuid": "9.0.0"
|
||||
|
||||
@@ -66,7 +66,7 @@ export const createMigration: CreateMigration = async function createMigration(
|
||||
const sqlStatementsUp = await generateSQLiteMigration(drizzleJsonBefore, drizzleJsonAfter)
|
||||
const sqlStatementsDown = await generateSQLiteMigration(drizzleJsonAfter, drizzleJsonBefore)
|
||||
// need to create tables as separate statements
|
||||
const sqlExecute = 'await payload.db.drizzle.run(sql`'
|
||||
const sqlExecute = 'await db.run(sql`'
|
||||
|
||||
if (sqlStatementsUp?.length) {
|
||||
upSQL = sqlStatementsUp
|
||||
|
||||
@@ -10,5 +10,5 @@ export const defaultDrizzleSnapshot: DrizzleSQLiteSnapshotJSON = {
|
||||
enums: {},
|
||||
prevId: '00000000-0000-0000-0000-00000000000',
|
||||
tables: {},
|
||||
version: '6',
|
||||
version: '3',
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ export const getMigrationTemplate = ({
|
||||
upSQL,
|
||||
}: MigrationTemplateArgs): string => `import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-sqlite'
|
||||
${imports ? `${imports}\n` : ''}
|
||||
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
${upSQL}
|
||||
}
|
||||
|
||||
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
${downSQL}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { Relation } from 'drizzle-orm'
|
||||
/* eslint-disable no-param-reassign */
|
||||
import type { ColumnDataType, Relation } from 'drizzle-orm'
|
||||
import type {
|
||||
AnySQLiteColumn,
|
||||
ForeignKeyBuilder,
|
||||
IndexBuilder,
|
||||
SQLiteColumn,
|
||||
SQLiteColumnBuilder,
|
||||
SQLiteTableWithColumns,
|
||||
UniqueConstraintBuilder,
|
||||
@@ -31,7 +32,18 @@ import { traverseFields } from './traverseFields.js'
|
||||
export type BaseExtraConfig = Record<
|
||||
string,
|
||||
(cols: {
|
||||
[x: string]: AnySQLiteColumn
|
||||
[x: string]: SQLiteColumn<{
|
||||
baseColumn: never
|
||||
columnType: string
|
||||
data: unknown
|
||||
dataType: ColumnDataType
|
||||
driverParam: unknown
|
||||
enumValues: string[]
|
||||
hasDefault: false
|
||||
name: string
|
||||
notNull: false
|
||||
tableName: string
|
||||
}>
|
||||
}) => ForeignKeyBuilder | IndexBuilder | UniqueConstraintBuilder
|
||||
>
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { AnySQLiteColumn} from 'drizzle-orm/sqlite-core';
|
||||
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { index, uniqueIndex } from 'drizzle-orm/sqlite-core'
|
||||
|
||||
import type { GenericColumn } from '../types.js'
|
||||
|
||||
type CreateIndexArgs = {
|
||||
columnName: string
|
||||
name: string | string[]
|
||||
@@ -10,7 +11,7 @@ type CreateIndexArgs = {
|
||||
}
|
||||
|
||||
export const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {
|
||||
return (table: { [x: string]: AnySQLiteColumn }) => {
|
||||
return (table: { [x: string]: GenericColumn }) => {
|
||||
let columns
|
||||
if (Array.isArray(name)) {
|
||||
columns = name
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Client, Config, ResultSet } from '@libsql/client'
|
||||
import type { Operators } from '@payloadcms/drizzle'
|
||||
import type { BuildQueryJoinAliases, DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { DrizzleConfig, Relation, Relations, SQL } from 'drizzle-orm'
|
||||
import type { ColumnDataType, DrizzleConfig, Relation, Relations, SQL } from 'drizzle-orm'
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||
import type {
|
||||
AnySQLiteColumn,
|
||||
SQLiteColumn,
|
||||
SQLiteInsertOnConflictDoUpdateConfig,
|
||||
SQLiteTableWithColumns,
|
||||
SQLiteTransactionConfig,
|
||||
@@ -25,8 +25,24 @@ export type Args = {
|
||||
versionsSuffix?: string
|
||||
}
|
||||
|
||||
export type GenericColumn = SQLiteColumn<
|
||||
{
|
||||
baseColumn: never
|
||||
columnType: string
|
||||
data: unknown
|
||||
dataType: ColumnDataType
|
||||
driverParam: unknown
|
||||
enumValues: string[]
|
||||
hasDefault: false
|
||||
name: string
|
||||
notNull: false
|
||||
tableName: string
|
||||
},
|
||||
object
|
||||
>
|
||||
|
||||
export type GenericColumns = {
|
||||
[x: string]: AnySQLiteColumn
|
||||
[x: string]: GenericColumn
|
||||
}
|
||||
|
||||
export type GenericTable = SQLiteTableWithColumns<{
|
||||
@@ -116,10 +132,12 @@ export type SQLiteAdapter = {
|
||||
export type IDType = 'integer' | 'numeric' | 'text'
|
||||
|
||||
export type MigrateUpArgs = {
|
||||
db: LibSQLDatabase
|
||||
payload: Payload
|
||||
req?: Partial<PayloadRequest>
|
||||
}
|
||||
export type MigrateDownArgs = {
|
||||
db: LibSQLDatabase
|
||||
payload: Payload
|
||||
req?: Partial<PayloadRequest>
|
||||
}
|
||||
@@ -128,7 +146,6 @@ declare module 'payload' {
|
||||
export interface DatabaseAdapter
|
||||
extends Omit<Args, 'idType' | 'logger' | 'migrationDir' | 'pool'>,
|
||||
DrizzleAdapter {
|
||||
drizzle: LibSQLDatabase
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
* Used for returning properly formed errors from unique fields
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/drizzle",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.36",
|
||||
"description": "A library of shared functions used by different payload database adapters",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -39,7 +39,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"console-table-printer": "2.11.2",
|
||||
"drizzle-orm": "0.32.1",
|
||||
"drizzle-orm": "0.29.4",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
"uuid": "9.0.0"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Field, SanitizedConfig, TabAsField } from 'payload'
|
||||
|
||||
import type { Field, SanitizedConfig , TabAsField } from 'payload'
|
||||
|
||||
import { fieldAffectsData } from 'payload/shared'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -39,7 +39,7 @@ export const index = deepMerge(
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/rules-of-hooks': 'warn',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-react",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official React SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-vue",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official Vue SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official live preview JavaScript SDK for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/next",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -134,8 +134,12 @@ export const POST =
|
||||
resHeaders.append(key, headers[key])
|
||||
}
|
||||
|
||||
if (req.responseHeaders) {
|
||||
mergeHeaders(req.responseHeaders, resHeaders)
|
||||
}
|
||||
|
||||
return new Response(apiResponse.body, {
|
||||
headers: req.responseHeaders ? mergeHeaders(req.responseHeaders, resHeaders) : resHeaders,
|
||||
headers: resHeaders,
|
||||
status: apiResponse.status,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -167,13 +167,7 @@ const handleCustomEndpoints = async ({
|
||||
|
||||
if (res instanceof Response) {
|
||||
if (req.responseHeaders) {
|
||||
const mergedResponse = new Response(res.body, {
|
||||
headers: mergeHeaders(req.responseHeaders, res.headers),
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
})
|
||||
|
||||
return mergedResponse
|
||||
mergeHeaders(req.responseHeaders, res.headers)
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -385,13 +379,7 @@ export const GET =
|
||||
|
||||
if (res instanceof Response) {
|
||||
if (req.responseHeaders) {
|
||||
const mergedResponse = new Response(res.body, {
|
||||
headers: mergeHeaders(req.responseHeaders, res.headers),
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
})
|
||||
|
||||
return mergedResponse
|
||||
mergeHeaders(req.responseHeaders, res.headers)
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -567,13 +555,7 @@ export const POST =
|
||||
|
||||
if (res instanceof Response) {
|
||||
if (req.responseHeaders) {
|
||||
const mergedResponse = new Response(res.body, {
|
||||
headers: mergeHeaders(req.responseHeaders, res.headers),
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
})
|
||||
|
||||
return mergedResponse
|
||||
mergeHeaders(req.responseHeaders, res.headers)
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -661,13 +643,7 @@ export const DELETE =
|
||||
|
||||
if (res instanceof Response) {
|
||||
if (req.responseHeaders) {
|
||||
const mergedResponse = new Response(res.body, {
|
||||
headers: mergeHeaders(req.responseHeaders, res.headers),
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
})
|
||||
|
||||
return mergedResponse
|
||||
mergeHeaders(req.responseHeaders, res.headers)
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -756,13 +732,7 @@ export const PATCH =
|
||||
|
||||
if (res instanceof Response) {
|
||||
if (req.responseHeaders) {
|
||||
const mergedResponse = new Response(res.body, {
|
||||
headers: mergeHeaders(req.responseHeaders, res.headers),
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
})
|
||||
|
||||
return mergedResponse
|
||||
mergeHeaders(req.responseHeaders, res.headers)
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
@@ -1,11 +1,33 @@
|
||||
export const mergeHeaders = (sourceHeaders: Headers, destinationHeaders: Headers): Headers => {
|
||||
// Create a new Headers object
|
||||
const combinedHeaders = new Headers(destinationHeaders)
|
||||
const headersToJoin = ['set-cookie', 'warning', 'www-authenticate', 'proxy-authenticate', 'vary']
|
||||
|
||||
// Append sourceHeaders to combinedHeaders
|
||||
sourceHeaders.forEach((value, key) => {
|
||||
combinedHeaders.append(key, value)
|
||||
export function mergeHeaders(sourceHeaders: Headers, destinationHeaders: Headers): void {
|
||||
// Create a map to store combined headers
|
||||
const combinedHeaders = new Headers()
|
||||
|
||||
// Add existing destination headers to the combined map
|
||||
destinationHeaders.forEach((value, key) => {
|
||||
combinedHeaders.set(key, value)
|
||||
})
|
||||
|
||||
return combinedHeaders
|
||||
// Add source headers to the combined map, joining specific headers
|
||||
sourceHeaders.forEach((value, key) => {
|
||||
const lowerKey = key.toLowerCase()
|
||||
if (headersToJoin.includes(lowerKey)) {
|
||||
if (combinedHeaders.has(key)) {
|
||||
combinedHeaders.set(key, `${combinedHeaders.get(key)}, ${value}`)
|
||||
} else {
|
||||
combinedHeaders.set(key, value)
|
||||
}
|
||||
} else {
|
||||
combinedHeaders.set(key, value)
|
||||
}
|
||||
})
|
||||
|
||||
// Clear the destination headers and set the combined headers
|
||||
destinationHeaders.forEach((_, key) => {
|
||||
destinationHeaders.delete(key)
|
||||
})
|
||||
combinedHeaders.forEach((value, key) => {
|
||||
destinationHeaders.append(key, value)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
import type { FormProps } from '@payloadcms/ui'
|
||||
import type { FieldMap } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
ClientConfig,
|
||||
ClientGlobalConfig,
|
||||
Data,
|
||||
FieldMap,
|
||||
LivePreviewConfig,
|
||||
} from 'payload'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { StepNavItem } from '@payloadcms/ui'
|
||||
import type { ClientCollectionConfig, ClientGlobalConfig, FieldMap } from 'payload'
|
||||
import type { FieldMap } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
import type { ClientCollectionConfig, ClientGlobalConfig } from 'payload'
|
||||
import type React from 'react'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MappedField } from 'payload'
|
||||
import type { MappedField } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { getUniqueListBy } from 'payload/shared'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client'
|
||||
import type { ClientCollectionConfig, MappedField } from 'payload'
|
||||
import type { ClientCollectionConfig } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { useConfig } from '@payloadcms/ui'
|
||||
import { type MappedField, useConfig } from '@payloadcms/ui'
|
||||
import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/shared'
|
||||
import React from 'react'
|
||||
import ReactDiffViewerImport from 'react-diff-viewer-continued'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { I18nClient } from '@payloadcms/translations'
|
||||
import type { MappedField, OptionObject, SelectField, SelectFieldProps } from 'payload'
|
||||
import type { SelectFieldProps } from '@payloadcms/ui'
|
||||
import type { MappedField } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
import type { OptionObject, SelectField } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MappedField, TabsFieldProps } from 'payload'
|
||||
import type { MappedField, TabsFieldProps } from '@payloadcms/ui'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { I18nClient } from '@payloadcms/translations'
|
||||
import type { FieldMap, FieldPermissions, MappedField } from 'payload'
|
||||
import type { FieldMap, MappedField } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
import type { FieldPermissions } from 'payload'
|
||||
import type React from 'react'
|
||||
import type { DiffMethod } from 'react-diff-viewer-continued'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { I18nClient } from '@payloadcms/translations'
|
||||
import type { FieldMap, FieldPermissions, MappedField } from 'payload'
|
||||
import type { FieldMap, MappedField } from '@payloadcms/ui/utilities/buildComponentMap'
|
||||
import type { FieldPermissions } from 'payload'
|
||||
import type { DiffMethod } from 'react-diff-viewer-continued'
|
||||
|
||||
import type { DiffComponents } from './fields/types.js'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
|
||||
@@ -8,7 +8,6 @@ import type {
|
||||
RelationshipField,
|
||||
SelectField,
|
||||
} from '../../fields/config/types.js'
|
||||
import type { FormFieldBase } from '../types.js'
|
||||
|
||||
export type RowData = Record<string, any>
|
||||
|
||||
@@ -21,7 +20,7 @@ export type CellComponentProps = {
|
||||
dateDisplayFormat?: DateField['admin']['date']['displayFormat']
|
||||
fieldType?: Field['type']
|
||||
isFieldAffectingData?: boolean
|
||||
label?: FormFieldBase['label']
|
||||
label?: Record<string, string> | string
|
||||
labels?: Labels
|
||||
link?: boolean
|
||||
name: FieldBase['name']
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { ArrayField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type ArrayFieldProps = {
|
||||
CustomRowLabel?: React.ReactNode
|
||||
fieldMap: FieldMap
|
||||
forceRender?: boolean
|
||||
isSortable?: boolean
|
||||
labels?: ArrayField['labels']
|
||||
maxRows?: ArrayField['maxRows']
|
||||
minRows?: ArrayField['minRows']
|
||||
name?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type ArrayFieldLabelComponent = LabelComponent<'array'>
|
||||
|
||||
export type ArrayFieldDescriptionComponent = DescriptionComponent<'array'>
|
||||
|
||||
export type ArrayFieldErrorComponent = ErrorComponent<'array'>
|
||||
@@ -1,32 +0,0 @@
|
||||
import type { Block, BlockField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type BlocksFieldProps = {
|
||||
blocks?: ReducedBlock[]
|
||||
forceRender?: boolean
|
||||
isSortable?: boolean
|
||||
labels?: BlockField['labels']
|
||||
maxRows?: number
|
||||
minRows?: number
|
||||
name?: string
|
||||
slug?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type ReducedBlock = {
|
||||
LabelComponent: Block['admin']['components']['Label']
|
||||
custom?: Record<any, string>
|
||||
fieldMap: FieldMap
|
||||
imageAltText?: string
|
||||
imageURL?: string
|
||||
labels: BlockField['labels']
|
||||
slug: string
|
||||
}
|
||||
|
||||
export type BlocksFieldLabelComponent = LabelComponent<'blocks'>
|
||||
|
||||
export type BlocksFieldDescriptionComponent = DescriptionComponent<'blocks'>
|
||||
|
||||
export type BlocksFieldErrorComponent = ErrorComponent<'blocks'>
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type CheckboxFieldProps = {
|
||||
checked?: boolean
|
||||
disableFormData?: boolean
|
||||
id?: string
|
||||
name?: string
|
||||
onChange?: (val: boolean) => void
|
||||
partialChecked?: boolean
|
||||
path?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type CheckboxFieldLabelComponent = LabelComponent<'checkbox'>
|
||||
|
||||
export type CheckboxFieldDescriptionComponent = DescriptionComponent<'checkbox'>
|
||||
|
||||
export type CheckboxFieldErrorComponent = ErrorComponent<'checkbox'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { CodeField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type CodeFieldProps = {
|
||||
editorOptions?: CodeField['admin']['editorOptions']
|
||||
language?: CodeField['admin']['language']
|
||||
name?: string
|
||||
path?: string
|
||||
width: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type CodeFieldLabelComponent = LabelComponent<'code'>
|
||||
|
||||
export type CodeFieldDescriptionComponent = DescriptionComponent<'code'>
|
||||
|
||||
export type CodeFieldErrorComponent = ErrorComponent<'code'>
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type CollapsibleFieldProps = {
|
||||
fieldMap: FieldMap
|
||||
initCollapsed?: boolean
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type CollapsibleFieldLabelComponent = LabelComponent<'collapsible'>
|
||||
|
||||
export type CollapsibleFieldDescriptionComponent = DescriptionComponent<'collapsible'>
|
||||
|
||||
export type CollapsibleFieldErrorComponent = ErrorComponent<'collapsible'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { DateField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type DateFieldProps = {
|
||||
date?: DateField['admin']['date']
|
||||
name?: string
|
||||
path?: string
|
||||
placeholder?: DateField['admin']['placeholder'] | string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type DateFieldLabelComponent = LabelComponent<'date'>
|
||||
|
||||
export type DateFieldDescriptionComponent = DescriptionComponent<'date'>
|
||||
|
||||
export type DateFieldErrorComponent = ErrorComponent<'date'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { EmailField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type EmailFieldProps = {
|
||||
autoComplete?: string
|
||||
name?: string
|
||||
path?: string
|
||||
placeholder?: EmailField['admin']['placeholder']
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type EmailFieldLabelComponent = LabelComponent<'email'>
|
||||
|
||||
export type EmailFieldDescriptionComponent = DescriptionComponent<'email'>
|
||||
|
||||
export type EmailFieldErrorComponent = ErrorComponent<'email'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type GroupFieldProps = {
|
||||
fieldMap: FieldMap
|
||||
forceRender?: boolean
|
||||
hideGutter?: boolean
|
||||
name?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type GroupFieldLabelComponent = LabelComponent<'group'>
|
||||
|
||||
export type GroupFieldDescriptionComponent = DescriptionComponent<'group'>
|
||||
|
||||
export type GroupFieldErrorComponent = ErrorComponent<'group'>
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type HiddenFieldProps = {
|
||||
disableModifyingForm?: false
|
||||
forceUsePathFromProps?: boolean
|
||||
name?: string
|
||||
path?: string
|
||||
value?: unknown
|
||||
} & FormFieldBase
|
||||
|
||||
export type HiddenFieldLabelComponent = LabelComponent<'hidden'>
|
||||
|
||||
export type HiddenFieldDescriptionComponent = DescriptionComponent<'hidden'>
|
||||
|
||||
export type HiddenFieldErrorComponent = ErrorComponent<'hidden'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { JSONField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type JSONFieldProps = {
|
||||
editorOptions?: JSONField['admin']['editorOptions']
|
||||
jsonSchema?: Record<string, unknown>
|
||||
name?: string
|
||||
path?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type JSONFieldLabelComponent = LabelComponent<'json'>
|
||||
|
||||
export type JSONFieldDescriptionComponent = DescriptionComponent<'json'>
|
||||
|
||||
export type JSONFieldErrorComponent = ErrorComponent<'json'>
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { NumberField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type NumberFieldProps = {
|
||||
hasMany?: boolean
|
||||
max?: number
|
||||
maxRows?: number
|
||||
min?: number
|
||||
name?: string
|
||||
onChange?: (e: number) => void
|
||||
path?: string
|
||||
placeholder?: NumberField['admin']['placeholder']
|
||||
step?: number
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type NumberFieldLabelComponent = LabelComponent<'number'>
|
||||
|
||||
export type NumberFieldDescriptionComponent = DescriptionComponent<'number'>
|
||||
|
||||
export type NumberFieldErrorComponent = ErrorComponent<'number'>
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type PointFieldProps = {
|
||||
name?: string
|
||||
path?: string
|
||||
placeholder?: string
|
||||
step?: number
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type PointFieldLabelComponent = LabelComponent<'point'>
|
||||
|
||||
export type PointFieldDescriptionComponent = DescriptionComponent<'point'>
|
||||
|
||||
export type PointFieldErrorComponent = ErrorComponent<'point'>
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Option } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type RadioFieldProps = {
|
||||
layout?: 'horizontal' | 'vertical'
|
||||
name?: string
|
||||
onChange?: OnChange
|
||||
options?: Option[]
|
||||
path?: string
|
||||
value?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type OnChange<T = string> = (value: T) => void
|
||||
|
||||
export type RadioFieldLabelComponent = LabelComponent<'radio'>
|
||||
|
||||
export type RadioFieldDescriptionComponent = DescriptionComponent<'radio'>
|
||||
|
||||
export type RadioFieldErrorComponent = ErrorComponent<'radio'>
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { RelationshipField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type RelationshipFieldProps = {
|
||||
allowCreate?: RelationshipField['admin']['allowCreate']
|
||||
hasMany?: boolean
|
||||
isSortable?: boolean
|
||||
name: string
|
||||
relationTo?: RelationshipField['relationTo']
|
||||
sortOptions?: RelationshipField['admin']['sortOptions']
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type RelationshipFieldLabelComponent = LabelComponent<'relationship'>
|
||||
|
||||
export type RelationshipFieldDescriptionComponent = DescriptionComponent<'relationship'>
|
||||
|
||||
export type RelationshipFieldErrorComponent = ErrorComponent<'relationship'>
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { MappedField } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type RichTextComponentProps = {
|
||||
name: string
|
||||
richTextComponentMap?: Map<string, MappedField[] | React.ReactNode>
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type RichTextFieldLabelComponent = LabelComponent<'richText'>
|
||||
|
||||
export type RichTextFieldDescriptionComponent = DescriptionComponent<'richText'>
|
||||
|
||||
export type RichTextFieldErrorComponent = ErrorComponent<'richText'>
|
||||
@@ -1,18 +0,0 @@
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from 'payload'
|
||||
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
|
||||
export type RowFieldProps = {
|
||||
fieldMap: FieldMap
|
||||
forceRender?: boolean
|
||||
indexPath: string
|
||||
path?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type RowFieldLabelComponent = LabelComponent<'row'>
|
||||
|
||||
export type RowFieldDescriptionComponent = DescriptionComponent<'row'>
|
||||
|
||||
export type RowFieldErrorComponent = ErrorComponent<'row'>
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Option } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type SelectFieldProps = {
|
||||
hasMany?: boolean
|
||||
isClearable?: boolean
|
||||
isSortable?: boolean
|
||||
name?: string
|
||||
onChange?: (e: string | string[]) => void
|
||||
options?: Option[]
|
||||
path?: string
|
||||
value?: string
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type SelectFieldLabelComponent = LabelComponent<'select'>
|
||||
|
||||
export type SelectFieldDescriptionComponent = DescriptionComponent<'select'>
|
||||
|
||||
export type SelectFieldErrorComponent = ErrorComponent<'select'>
|
||||
@@ -1,24 +0,0 @@
|
||||
import type { TabsField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldMap } from '../forms/FieldMap.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type TabsFieldProps = {
|
||||
forceRender?: boolean
|
||||
name?: string
|
||||
path?: string
|
||||
tabs?: MappedTab[]
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type MappedTab = {
|
||||
fieldMap?: FieldMap
|
||||
label: TabsField['tabs'][0]['label']
|
||||
name?: string
|
||||
}
|
||||
|
||||
export type TabsFieldLabelComponent = LabelComponent<'tabs'>
|
||||
|
||||
export type TabsFieldDescriptionComponent = DescriptionComponent<'tabs'>
|
||||
|
||||
export type TabsFieldErrorComponent = ErrorComponent<'tabs'>
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { TextField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type TextFieldProps = {
|
||||
hasMany?: boolean
|
||||
inputRef?: React.MutableRefObject<HTMLInputElement>
|
||||
maxLength?: number
|
||||
maxRows?: number
|
||||
minLength?: number
|
||||
minRows?: number
|
||||
name?: string
|
||||
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
path?: string
|
||||
placeholder?: TextField['admin']['placeholder']
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type TextFieldLabelComponent = LabelComponent<'text'>
|
||||
|
||||
export type TextFieldDescriptionComponent = DescriptionComponent<'text'>
|
||||
|
||||
export type TextFieldErrorComponent = ErrorComponent<'text'>
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { TextareaField } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
|
||||
export type TextareaFieldProps = {
|
||||
maxLength?: number
|
||||
minLength?: number
|
||||
name?: string
|
||||
path?: string
|
||||
placeholder?: TextareaField['admin']['placeholder']
|
||||
rows?: number
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type TextareaFieldLabelComponent = LabelComponent<'textarea'>
|
||||
|
||||
export type TextareaFieldDescriptionComponent = DescriptionComponent<'textarea'>
|
||||
|
||||
export type TextareaFieldErrorComponent = ErrorComponent<'textarea'>
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent, UploadField } from 'payload'
|
||||
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
|
||||
export type UploadFieldProps = {
|
||||
filterOptions?: UploadField['filterOptions']
|
||||
name?: string
|
||||
path?: string
|
||||
relationTo?: UploadField['relationTo']
|
||||
width?: string
|
||||
} & FormFieldBase
|
||||
|
||||
export type UploadFieldLabelComponent = LabelComponent<'upload'>
|
||||
|
||||
export type UploadFieldDescriptionComponent = DescriptionComponent<'upload'>
|
||||
|
||||
export type UploadFieldErrorComponent = ErrorComponent<'upload'>
|
||||
@@ -1,86 +0,0 @@
|
||||
import type { ArrayFieldProps } from './Array.js'
|
||||
import type { BlocksFieldProps } from './Blocks.js'
|
||||
import type { CheckboxFieldProps } from './Checkbox.js'
|
||||
import type { CodeFieldProps } from './Code.js'
|
||||
import type { CollapsibleFieldProps } from './Collapsible.js'
|
||||
import type { DateFieldProps } from './Date.js'
|
||||
import type { EmailFieldProps } from './Email.js'
|
||||
import type { GroupFieldProps } from './Group.js'
|
||||
import type { HiddenFieldProps } from './Hidden.js'
|
||||
import type { JSONFieldProps } from './JSON.js'
|
||||
import type { NumberFieldProps } from './Number.js'
|
||||
import type { PointFieldProps } from './Point.js'
|
||||
import type { RadioFieldProps } from './Radio.js'
|
||||
import type { RelationshipFieldProps } from './Relationship.js'
|
||||
import type { RichTextComponentProps } from './RichText.js'
|
||||
import type { RowFieldProps } from './Row.js'
|
||||
import type { SelectFieldProps } from './Select.js'
|
||||
import type { TabsFieldProps } from './Tabs.js'
|
||||
import type { TextFieldProps } from './Text.js'
|
||||
import type { TextareaFieldProps } from './Textarea.js'
|
||||
import type { UploadFieldProps } from './Upload.js'
|
||||
|
||||
export type FieldComponentProps =
|
||||
| ({
|
||||
type: 'array'
|
||||
} & ArrayFieldProps)
|
||||
| ({
|
||||
type: 'blocks'
|
||||
} & BlocksFieldProps)
|
||||
| ({
|
||||
type: 'checkbox'
|
||||
} & CheckboxFieldProps)
|
||||
| ({
|
||||
type: 'code'
|
||||
} & CodeFieldProps)
|
||||
| ({
|
||||
type: 'collapsible'
|
||||
} & CollapsibleFieldProps)
|
||||
| ({
|
||||
type: 'date'
|
||||
} & DateFieldProps)
|
||||
| ({
|
||||
type: 'email'
|
||||
} & EmailFieldProps)
|
||||
| ({
|
||||
type: 'group'
|
||||
} & GroupFieldProps)
|
||||
| ({
|
||||
type: 'hidden'
|
||||
} & HiddenFieldProps)
|
||||
| ({
|
||||
type: 'json'
|
||||
} & JSONFieldProps)
|
||||
| ({
|
||||
type: 'number'
|
||||
} & NumberFieldProps)
|
||||
| ({
|
||||
type: 'point'
|
||||
} & PointFieldProps)
|
||||
| ({
|
||||
type: 'radio'
|
||||
} & RadioFieldProps)
|
||||
| ({
|
||||
type: 'relationship'
|
||||
} & RelationshipFieldProps)
|
||||
| ({
|
||||
type: 'richText'
|
||||
} & RichTextComponentProps)
|
||||
| ({
|
||||
type: 'row'
|
||||
} & RowFieldProps)
|
||||
| ({
|
||||
type: 'select'
|
||||
} & SelectFieldProps)
|
||||
| ({
|
||||
type: 'tabs'
|
||||
} & TabsFieldProps)
|
||||
| ({
|
||||
type: 'text'
|
||||
} & TextFieldProps)
|
||||
| ({
|
||||
type: 'textarea'
|
||||
} & TextareaFieldProps)
|
||||
| ({
|
||||
type: 'upload'
|
||||
} & UploadFieldProps)
|
||||
@@ -1,19 +1,7 @@
|
||||
import type { CustomComponent, ServerProps } from '../../config/types.js'
|
||||
import type { FieldComponentProps } from '../types.js'
|
||||
import type { FieldTypes } from './FieldTypes.js'
|
||||
|
||||
export type GenericErrorProps = {
|
||||
export type ErrorProps = {
|
||||
CustomError?: React.ReactNode
|
||||
alignCaret?: 'center' | 'left' | 'right'
|
||||
message?: string
|
||||
path?: string
|
||||
showError?: boolean
|
||||
}
|
||||
|
||||
export type ErrorProps<T extends keyof FieldTypes = any> = {
|
||||
type: T
|
||||
} & FieldComponentProps &
|
||||
GenericErrorProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
export type ErrorComponent<T extends keyof FieldTypes = any> = CustomComponent<ErrorProps<T>>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import type { User } from '../../auth/types.js'
|
||||
import type { LabelStatic, Locale } from '../../config/types.js'
|
||||
import type { Validate } from '../../fields/config/types.js'
|
||||
import type { DocumentPreferences } from '../../preferences/types.js'
|
||||
import type { ErrorProps } from './Error.js'
|
||||
import type { FieldDescriptionProps } from './FieldDescription.js'
|
||||
import type { SanitizedLabelProps } from './Label.js'
|
||||
|
||||
export type FormFieldBase = {
|
||||
AfterInput?: React.ReactNode
|
||||
BeforeInput?: React.ReactNode
|
||||
CustomDescription?: React.ReactNode
|
||||
CustomError?: React.ReactNode
|
||||
CustomLabel?: React.ReactNode
|
||||
className?: string
|
||||
custom?: Record<string, any>
|
||||
descriptionProps?: Omit<FieldDescriptionProps, 'type'>
|
||||
disabled?: boolean
|
||||
docPreferences?: DocumentPreferences
|
||||
errorProps?: Omit<ErrorProps, 'type'>
|
||||
label?: LabelStatic | false
|
||||
labelProps?: SanitizedLabelProps
|
||||
locale?: Locale
|
||||
localized?: boolean
|
||||
path?: string
|
||||
readOnly?: boolean
|
||||
required?: boolean
|
||||
rtl?: boolean
|
||||
style?: React.CSSProperties
|
||||
user?: User
|
||||
validate?: Validate
|
||||
}
|
||||
@@ -1,24 +1,18 @@
|
||||
import type React from 'react'
|
||||
|
||||
import type { CustomComponent, LabelFunction, ServerProps } from '../../config/types.js'
|
||||
import type { FieldComponentProps } from '../types.js'
|
||||
import type { FieldTypes } from './FieldTypes.js'
|
||||
import type { CustomComponent, LabelFunction } from '../../config/types.js'
|
||||
import type { Payload } from '../../index.js'
|
||||
|
||||
export type DescriptionFunction = LabelFunction
|
||||
|
||||
export type DescriptionComponent<T extends keyof FieldTypes = any> = CustomComponent<
|
||||
FieldDescriptionProps<T>
|
||||
>
|
||||
export type DescriptionComponent = CustomComponent<FieldDescriptionProps>
|
||||
|
||||
export type Description = DescriptionFunction | Record<string, string> | string
|
||||
export type GenericDescriptionProps = {
|
||||
|
||||
export type FieldDescriptionProps = {
|
||||
CustomDescription?: React.ReactNode
|
||||
className?: string
|
||||
description?: Record<string, string> | string
|
||||
marginPlacement?: 'bottom' | 'top'
|
||||
payload?: Payload
|
||||
}
|
||||
export type FieldDescriptionProps<T extends keyof FieldTypes = any> = {
|
||||
type: T
|
||||
} & FieldComponentProps &
|
||||
GenericDescriptionProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import type { CellComponentProps, FieldComponentProps } from '../types.js'
|
||||
import type { FieldTypes } from './FieldTypes.js'
|
||||
|
||||
export type MappedField = {
|
||||
CustomCell?: React.ReactNode
|
||||
CustomField?: React.ReactNode
|
||||
cellComponentProps: CellComponentProps
|
||||
custom?: Record<any, string>
|
||||
disableBulkEdit?: boolean
|
||||
disableListColumn?: boolean
|
||||
disableListFilter?: boolean
|
||||
disabled?: boolean
|
||||
fieldComponentProps: FieldComponentProps
|
||||
fieldIsPresentational: boolean
|
||||
isFieldAffectingData: boolean
|
||||
isHidden?: boolean
|
||||
isSidebar?: boolean
|
||||
localized: boolean
|
||||
name?: string
|
||||
type: keyof FieldTypes
|
||||
unique?: boolean
|
||||
}
|
||||
|
||||
export type FieldMap = MappedField[]
|
||||
@@ -1,24 +1,11 @@
|
||||
import type { CustomComponent, ServerProps } from '../../config/types.js'
|
||||
import type { FieldComponentProps } from '../fields/index.js'
|
||||
import type { FormFieldBase } from './Field.js'
|
||||
import type { FieldTypes } from './FieldTypes.js'
|
||||
|
||||
export type GenericLabelProps = {
|
||||
export type LabelProps = {
|
||||
CustomLabel?: React.ReactNode
|
||||
as?: 'label' | 'span'
|
||||
htmlFor?: string
|
||||
label?: Record<string, string> | string
|
||||
required?: boolean
|
||||
schemaPath?: string
|
||||
unstyled?: boolean
|
||||
} & FormFieldBase
|
||||
}
|
||||
|
||||
export type LabelProps<T extends keyof FieldTypes = any> = {
|
||||
type: T
|
||||
} & FieldComponentProps &
|
||||
GenericLabelProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
export type SanitizedLabelProps<T extends keyof FieldTypes = any> = Omit<
|
||||
LabelProps<T>,
|
||||
'label' | 'required'
|
||||
>
|
||||
|
||||
export type LabelComponent<T extends keyof FieldTypes = any> = CustomComponent<LabelProps<T>>
|
||||
export type SanitizedLabelProps = Omit<LabelProps, 'label' | 'required'>
|
||||
|
||||
@@ -7,7 +7,6 @@ export type { CustomPreviewButton } from './elements/PreviewButton.js'
|
||||
export type { CustomPublishButton } from './elements/PublishButton.js'
|
||||
export type { CustomSaveButton } from './elements/SaveButton.js'
|
||||
export type { CustomSaveDraftButton } from './elements/SaveDraftButton.js'
|
||||
|
||||
export type {
|
||||
DocumentTab,
|
||||
DocumentTabComponent,
|
||||
@@ -15,191 +14,20 @@ export type {
|
||||
DocumentTabConfig,
|
||||
DocumentTabProps,
|
||||
} from './elements/Tab.js'
|
||||
|
||||
export type { CustomUpload } from './elements/Upload.js'
|
||||
|
||||
export type {
|
||||
WithServerSidePropsComponent,
|
||||
WithServerSidePropsComponentProps,
|
||||
} from './elements/WithServerSideProps.js'
|
||||
|
||||
export type {
|
||||
ArrayFieldDescriptionComponent,
|
||||
ArrayFieldErrorComponent,
|
||||
ArrayFieldLabelComponent,
|
||||
ArrayFieldProps,
|
||||
} from './fields/Array.js'
|
||||
|
||||
export type { ReducedBlock } from './fields/Blocks.js'
|
||||
|
||||
export type {
|
||||
BlocksFieldDescriptionComponent,
|
||||
BlocksFieldErrorComponent,
|
||||
BlocksFieldLabelComponent,
|
||||
BlocksFieldProps,
|
||||
} from './fields/Blocks.js'
|
||||
|
||||
export type {
|
||||
CheckboxFieldDescriptionComponent,
|
||||
CheckboxFieldErrorComponent,
|
||||
CheckboxFieldLabelComponent,
|
||||
CheckboxFieldProps,
|
||||
} from './fields/Checkbox.js'
|
||||
|
||||
export type {
|
||||
CodeFieldDescriptionComponent,
|
||||
CodeFieldErrorComponent,
|
||||
CodeFieldLabelComponent,
|
||||
CodeFieldProps,
|
||||
} from './fields/Code.js'
|
||||
|
||||
export type {
|
||||
CollapsibleFieldDescriptionComponent,
|
||||
CollapsibleFieldErrorComponent,
|
||||
CollapsibleFieldLabelComponent,
|
||||
CollapsibleFieldProps,
|
||||
} from './fields/Collapsible.js'
|
||||
|
||||
export type {
|
||||
DateFieldDescriptionComponent,
|
||||
DateFieldErrorComponent,
|
||||
DateFieldLabelComponent,
|
||||
DateFieldProps,
|
||||
} from './fields/Date.js'
|
||||
|
||||
export type {
|
||||
EmailFieldDescriptionComponent,
|
||||
EmailFieldErrorComponent,
|
||||
EmailFieldLabelComponent,
|
||||
EmailFieldProps,
|
||||
} from './fields/Email.js'
|
||||
|
||||
export type {
|
||||
GroupFieldDescriptionComponent,
|
||||
GroupFieldErrorComponent,
|
||||
GroupFieldLabelComponent,
|
||||
GroupFieldProps,
|
||||
} from './fields/Group.js'
|
||||
|
||||
export type {
|
||||
HiddenFieldDescriptionComponent,
|
||||
HiddenFieldErrorComponent,
|
||||
HiddenFieldLabelComponent,
|
||||
HiddenFieldProps,
|
||||
} from './fields/Hidden.js'
|
||||
|
||||
export type {
|
||||
JSONFieldDescriptionComponent,
|
||||
JSONFieldErrorComponent,
|
||||
JSONFieldLabelComponent,
|
||||
JSONFieldProps,
|
||||
} from './fields/JSON.js'
|
||||
|
||||
export type {
|
||||
NumberFieldDescriptionComponent,
|
||||
NumberFieldErrorComponent,
|
||||
NumberFieldLabelComponent,
|
||||
NumberFieldProps,
|
||||
} from './fields/Number.js'
|
||||
|
||||
export type {
|
||||
PointFieldDescriptionComponent,
|
||||
PointFieldErrorComponent,
|
||||
PointFieldLabelComponent,
|
||||
PointFieldProps,
|
||||
} from './fields/Point.js'
|
||||
|
||||
export type {
|
||||
RadioFieldDescriptionComponent,
|
||||
RadioFieldErrorComponent,
|
||||
RadioFieldLabelComponent,
|
||||
RadioFieldProps,
|
||||
} from './fields/Radio.js'
|
||||
|
||||
export type {
|
||||
RelationshipFieldDescriptionComponent,
|
||||
RelationshipFieldErrorComponent,
|
||||
RelationshipFieldLabelComponent,
|
||||
RelationshipFieldProps,
|
||||
} from './fields/Relationship.js'
|
||||
|
||||
export type {
|
||||
RichTextComponentProps,
|
||||
RichTextFieldDescriptionComponent,
|
||||
RichTextFieldErrorComponent,
|
||||
RichTextFieldLabelComponent,
|
||||
} from './fields/RichText.js'
|
||||
|
||||
export type {
|
||||
RowFieldDescriptionComponent,
|
||||
RowFieldErrorComponent,
|
||||
RowFieldLabelComponent,
|
||||
RowFieldProps,
|
||||
} from './fields/Row.js'
|
||||
|
||||
export type {
|
||||
SelectFieldDescriptionComponent,
|
||||
SelectFieldErrorComponent,
|
||||
SelectFieldLabelComponent,
|
||||
SelectFieldProps,
|
||||
} from './fields/Select.js'
|
||||
|
||||
export type { MappedTab } from './fields/Tabs.js'
|
||||
|
||||
export type {
|
||||
TabsFieldDescriptionComponent,
|
||||
TabsFieldErrorComponent,
|
||||
TabsFieldLabelComponent,
|
||||
TabsFieldProps,
|
||||
} from './fields/Tabs.js'
|
||||
|
||||
export type {
|
||||
TextFieldDescriptionComponent,
|
||||
TextFieldErrorComponent,
|
||||
TextFieldLabelComponent,
|
||||
TextFieldProps,
|
||||
} from './fields/Text.js'
|
||||
|
||||
export type {
|
||||
TextareaFieldDescriptionComponent,
|
||||
TextareaFieldErrorComponent,
|
||||
TextareaFieldLabelComponent,
|
||||
TextareaFieldProps,
|
||||
} from './fields/Textarea.js'
|
||||
|
||||
export type {
|
||||
UploadFieldDescriptionComponent,
|
||||
UploadFieldErrorComponent,
|
||||
UploadFieldLabelComponent,
|
||||
UploadFieldProps,
|
||||
} from './fields/Upload.js'
|
||||
|
||||
export type { FieldComponentProps } from './fields/index.js'
|
||||
|
||||
export type { ErrorComponent, ErrorProps, GenericErrorProps } from './forms/Error.js'
|
||||
|
||||
export type { FormFieldBase } from './forms/Field.js'
|
||||
|
||||
export type { ErrorProps } from './forms/Error.js'
|
||||
export type {
|
||||
Description,
|
||||
DescriptionComponent,
|
||||
DescriptionFunction,
|
||||
FieldDescriptionProps,
|
||||
GenericDescriptionProps,
|
||||
} from './forms/FieldDescription.js'
|
||||
|
||||
export type { MappedField } from './forms/FieldMap.js'
|
||||
|
||||
export type { FieldMap } from './forms/FieldMap.js'
|
||||
|
||||
export type { Data, FilterOptionsResult, FormField, FormState, Row } from './forms/Form.js'
|
||||
|
||||
export type {
|
||||
GenericLabelProps,
|
||||
LabelComponent,
|
||||
LabelProps,
|
||||
SanitizedLabelProps,
|
||||
} from './forms/Label.js'
|
||||
export type { LabelProps, SanitizedLabelProps } from './forms/Label.js'
|
||||
|
||||
export type { RowLabel, RowLabelComponent } from './forms/RowLabel.js'
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import type {
|
||||
EntityDescriptionComponent,
|
||||
GeneratePreviewURL,
|
||||
LabelFunction,
|
||||
LabelStatic,
|
||||
LivePreviewConfig,
|
||||
OpenGraphConfig,
|
||||
} from '../../config/types.js'
|
||||
@@ -439,8 +438,8 @@ export type CollectionConfig<TSlug extends CollectionSlug = any> = {
|
||||
* Label configuration
|
||||
*/
|
||||
labels?: {
|
||||
plural?: LabelFunction | LabelStatic
|
||||
singular?: LabelFunction | LabelStatic
|
||||
plural?: LabelFunction | Record<string, string> | string
|
||||
singular?: LabelFunction | Record<string, string> | string
|
||||
}
|
||||
slug: string
|
||||
/**
|
||||
|
||||
@@ -423,8 +423,6 @@ export type LocalizationConfig = Prettify<
|
||||
|
||||
export type LabelFunction = ({ t }: { t: TFunction }) => string
|
||||
|
||||
export type LabelStatic = Record<string, string> | string
|
||||
|
||||
export type SharpDependency = (
|
||||
input?:
|
||||
| ArrayBuffer
|
||||
|
||||
@@ -9,19 +9,19 @@ import type { JSONSchema4 } from 'json-schema'
|
||||
import type React from 'react'
|
||||
|
||||
import type { RichTextAdapter, RichTextAdapterProvider } from '../../admin/RichText.js'
|
||||
import type { ErrorComponent } from '../../admin/forms/Error.js'
|
||||
import type {
|
||||
ConditionalDateProps,
|
||||
Description,
|
||||
DescriptionComponent,
|
||||
LabelComponent,
|
||||
ErrorProps,
|
||||
LabelProps,
|
||||
RowLabelComponent,
|
||||
} from '../../admin/types.js'
|
||||
import type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js'
|
||||
import type { CustomComponent, LabelFunction, LabelStatic } from '../../config/types.js'
|
||||
import type { CustomComponent, LabelFunction } from '../../config/types.js'
|
||||
import type { DBIdentifierName } from '../../database/types.js'
|
||||
import type { SanitizedGlobalConfig } from '../../globals/config/types.js'
|
||||
import type { CollectionSlug } from '../../index.js'
|
||||
import type { CollectionSlug, GeneratedTypes } from '../../index.js'
|
||||
import type { DocumentPreferences } from '../../preferences/types.js'
|
||||
import type { Operation, PayloadRequest, RequestContext, Where } from '../../types/index.js'
|
||||
import type { ClientFieldConfig } from './client.js'
|
||||
@@ -123,10 +123,6 @@ export type FilterOptionsProps<TData = any> = {
|
||||
user: Partial<PayloadRequest['user']>
|
||||
}
|
||||
|
||||
export type FilterOptionsFunc<TData = any> = (
|
||||
options: FilterOptionsProps<TData>,
|
||||
) => Promise<Where | boolean> | Where | boolean
|
||||
|
||||
export type FilterOptions<TData = any> =
|
||||
| ((options: FilterOptionsProps<TData>) => Promise<Where | boolean> | Where | boolean)
|
||||
| Where
|
||||
@@ -171,8 +167,8 @@ type Admin = {
|
||||
}
|
||||
|
||||
export type Labels = {
|
||||
plural: LabelFunction | LabelStatic
|
||||
singular: LabelFunction | LabelStatic
|
||||
plural: LabelFunction | Record<string, string> | string
|
||||
singular: LabelFunction | Record<string, string> | string
|
||||
}
|
||||
|
||||
export type BaseValidateOptions<TData, TSiblingData> = {
|
||||
@@ -203,7 +199,7 @@ export type Validate<
|
||||
export type ClientValidate = Omit<Validate, 'req'>
|
||||
|
||||
export type OptionObject = {
|
||||
label: LabelFunction | LabelStatic
|
||||
label: LabelFunction | Record<string, string> | string
|
||||
value: string
|
||||
}
|
||||
|
||||
@@ -231,7 +227,7 @@ export interface FieldBase {
|
||||
beforeValidate?: FieldHook[]
|
||||
}
|
||||
index?: boolean
|
||||
label?: LabelFunction | LabelStatic | false
|
||||
label?: LabelFunction | Record<string, string> | false | string
|
||||
localized?: boolean
|
||||
/**
|
||||
* The name of the field. Must be alphanumeric and cannot contain ' . '
|
||||
@@ -256,8 +252,8 @@ export type NumberField = {
|
||||
/** Set this property to a string that will be used for browser autocomplete. */
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -295,8 +291,8 @@ export type TextField = {
|
||||
admin?: {
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -330,8 +326,8 @@ export type EmailField = {
|
||||
admin?: {
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -343,8 +339,8 @@ export type EmailField = {
|
||||
export type TextareaField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -360,8 +356,8 @@ export type TextareaField = {
|
||||
export type CheckboxField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -372,8 +368,8 @@ export type CheckboxField = {
|
||||
export type DateField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
}
|
||||
@@ -508,8 +504,8 @@ export type UIField = {
|
||||
export type UploadField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
}
|
||||
filterOptions?: FilterOptions
|
||||
@@ -525,8 +521,8 @@ export type UploadField = {
|
||||
|
||||
type CodeAdmin = {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
editorOptions?: EditorProps['options']
|
||||
language?: string
|
||||
@@ -541,8 +537,8 @@ export type CodeField = {
|
||||
|
||||
type JSONAdmin = {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
editorOptions?: EditorProps['options']
|
||||
} & Admin
|
||||
@@ -560,8 +556,8 @@ export type JSONField = {
|
||||
export type SelectField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
isClearable?: boolean
|
||||
isSortable?: boolean
|
||||
@@ -622,8 +618,8 @@ type SharedRelationshipProperties = {
|
||||
type RelationshipAdmin = {
|
||||
allowCreate?: boolean
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
isSortable?: boolean
|
||||
} & Admin
|
||||
@@ -663,8 +659,8 @@ export type RichTextField<
|
||||
> = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
} & Admin
|
||||
editor?:
|
||||
@@ -712,8 +708,8 @@ export type ArrayField = {
|
||||
export type RadioField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ErrorProps>
|
||||
Label?: CustomComponent<LabelProps>
|
||||
}
|
||||
layout?: 'horizontal' | 'vertical'
|
||||
} & Admin
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { Field, FieldHookArgs, TabAsField, ValidateOptions } from '../../co
|
||||
|
||||
import { MissingEditorProp } from '../../../errors/index.js'
|
||||
import { deepMergeWithSourceArrays } from '../../../utilities/deepMerge.js'
|
||||
import { formatErrorLabels } from '../../../utilities/formatLabels.js'
|
||||
import { fieldAffectsData, tabHasName } from '../../config/types.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { beforeDuplicate } from './beforeDuplicate.js'
|
||||
@@ -146,7 +147,7 @@ export const promise = async ({
|
||||
|
||||
if (typeof validationResult === 'string') {
|
||||
errors.push({
|
||||
field: fieldPath.join('.'),
|
||||
field: formatErrorLabels(fieldPath),
|
||||
message: validationResult,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -981,7 +981,7 @@ export {
|
||||
deepMergeWithSourceArrays,
|
||||
} from './utilities/deepMerge.js'
|
||||
export { default as flattenTopLevelFields } from './utilities/flattenTopLevelFields.js'
|
||||
export { formatLabels, formatNames, toWords } from './utilities/formatLabels.js'
|
||||
export { formatErrorLabels, formatLabels, formatNames, toWords } from './utilities/formatLabels.js'
|
||||
export { getCollectionIDFieldTypes } from './utilities/getCollectionIDFieldTypes.js'
|
||||
export { getObjectDotNotation } from './utilities/getObjectDotNotation.js'
|
||||
export { initTransaction } from './utilities/initTransaction.js'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { formatLabels, toWords } from './formatLabels'
|
||||
import { formatErrorLabels, formatLabels, toWords } from './formatLabels'
|
||||
|
||||
describe('formatLabels', () => {
|
||||
it('should format singular slug', () => {
|
||||
@@ -39,3 +39,11 @@ describe('formatLabels', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatErrorLabels', () => {
|
||||
it('should format array', () => {
|
||||
expect(formatErrorLabels(['test', 1, 'field', 'array', 3, 'final'])).toBe(
|
||||
'Test (1) > Field > Array (3) > Final',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,7 +9,8 @@ const toWords = (inputString: string, joinWords = false): string => {
|
||||
const trimmedString = notNullString.trim()
|
||||
const arrayOfStrings = trimmedString.split(/[\s-]/)
|
||||
|
||||
const splitStringsArray = []
|
||||
const splitStringsArray: string[] = []
|
||||
|
||||
arrayOfStrings.forEach((tempString) => {
|
||||
if (tempString !== '') {
|
||||
const splitWords = tempString.split(/(?=[A-Z])/).join(' ')
|
||||
@@ -46,4 +47,23 @@ const formatNames = (slug: string): { plural: string; singular: string } => {
|
||||
}
|
||||
}
|
||||
|
||||
export { formatLabels, formatNames, toWords }
|
||||
/**
|
||||
* Formats labels for error field schema array.
|
||||
* @param fieldSchema - Array of strings and numbers.
|
||||
* @returns Formatted string.
|
||||
*
|
||||
* @example
|
||||
* formatErrorLabels(['test', 1, 'test2']) // => 'Test (1) > Test2'
|
||||
*/
|
||||
const formatErrorLabels = (fieldSchema: (number | string)[]): string => {
|
||||
return fieldSchema.reduce((acc: string, current, index) => {
|
||||
if (typeof current === 'number') {
|
||||
return index === 0 ? `(${current})` : `${acc} (${current})`
|
||||
} else {
|
||||
const formattedLabel = current.charAt(0).toUpperCase() + current.slice(1)
|
||||
return index === 0 ? `${acc}${formattedLabel}` : `${acc} > ${formattedLabel}`
|
||||
}
|
||||
}, '') as string
|
||||
}
|
||||
|
||||
export { formatErrorLabels, formatLabels, formatNames, toWords }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official cloud storage plugin for Payload CMS",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official Payload Cloud plugin",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-form-builder",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { TextFieldProps } from 'payload'
|
||||
import type { TextFieldProps } from '@payloadcms/ui'
|
||||
|
||||
import { SelectField, useForm } from '@payloadcms/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
@@ -34,5 +34,7 @@ export const DynamicFieldSelector: React.FC<TextFieldProps> = (props) => {
|
||||
}
|
||||
}, [fields, getDataByPath])
|
||||
|
||||
// TODO: label from config is Record<string, string> | false | string
|
||||
// but the FormFieldBase type has only label?: string, changing FormFieldBase breaks other ui components
|
||||
return <SelectField {...props} options={options} />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import type { Data, TextFieldProps } from 'payload'
|
||||
import type { TextFieldProps } from '@payloadcms/ui'
|
||||
import type { Data } from 'payload'
|
||||
|
||||
import { TextField, useLocale, useWatchForm } from '@payloadcms/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Block, CollectionConfig, Field } from 'payload'
|
||||
|
||||
import { deepMergeWithSourceArrays } from 'payload'
|
||||
|
||||
import type { FormBuilderPluginConfig } from '../../types.js'
|
||||
import type { FieldConfig, FormBuilderPluginConfig } from '../../types.js'
|
||||
|
||||
import { fields } from './fields.js'
|
||||
|
||||
@@ -157,9 +157,7 @@ export const generateFormCollection = (formConfig: FormBuilderPluginConfig): Col
|
||||
name: 'cc',
|
||||
type: 'text',
|
||||
admin: {
|
||||
style: {
|
||||
maxWidth: '50%',
|
||||
},
|
||||
width: '50%',
|
||||
},
|
||||
label: 'CC',
|
||||
},
|
||||
@@ -167,9 +165,7 @@ export const generateFormCollection = (formConfig: FormBuilderPluginConfig): Col
|
||||
name: 'bcc',
|
||||
type: 'text',
|
||||
admin: {
|
||||
style: {
|
||||
maxWidth: '50%',
|
||||
},
|
||||
width: '50%',
|
||||
},
|
||||
label: 'BCC',
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "The official Nested Docs plugin for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-redirects",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Redirects plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -8,8 +8,6 @@ Minimum required version of Payload: `1.9.5`
|
||||
|
||||
It injects a `beforeChange` field hook into each `relationship` and `upload` field, which converts string-based IDs to `ObjectID`s immediately prior to storage.
|
||||
|
||||
By default, it also injects an `afterRead` field hook into the above fields, which ensures that the values are re-formatted back to strings after having been read from the database.
|
||||
|
||||
#### Usage
|
||||
|
||||
Simply import and install the plugin to make it work:
|
||||
@@ -22,11 +20,7 @@ export default buildConfig({
|
||||
// your config here
|
||||
plugins: [
|
||||
// Call the plugin within your `plugins` array
|
||||
relationshipsAsObjectID({
|
||||
// Optionally keep relationship values as ObjectID
|
||||
// when they are retrieved from the database.
|
||||
keepAfterRead: true,
|
||||
}),
|
||||
relationshipsAsObjectID(),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-relationship-object-ids",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "A Payload plugin to store all relationship IDs as ObjectIDs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import type { CollectionConfig, Config, FieldHook, RelationshipField, UploadField } from 'payload'
|
||||
|
||||
import mongoose from 'mongoose'
|
||||
import { fieldAffectsData } from 'payload/shared'
|
||||
|
||||
const convertValue = ({
|
||||
relatedCollection,
|
||||
value,
|
||||
}: {
|
||||
relatedCollection: CollectionConfig
|
||||
value: number | string
|
||||
}): mongoose.Types.ObjectId | number | string => {
|
||||
const customIDField = relatedCollection.fields.find(
|
||||
(field) => fieldAffectsData(field) && field.name === 'id',
|
||||
)
|
||||
|
||||
if (!customIDField && mongoose.Types.ObjectId.isValid(value)) {
|
||||
return value.toString()
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
interface RelationObject {
|
||||
relationTo: string
|
||||
value: number | string
|
||||
}
|
||||
|
||||
function isValidRelationObject(value: unknown): value is RelationObject {
|
||||
return typeof value === 'object' && value !== null && 'relationTo' in value && 'value' in value
|
||||
}
|
||||
|
||||
interface Args {
|
||||
config: Config
|
||||
field: RelationshipField | UploadField
|
||||
}
|
||||
|
||||
export const getAfterReadHook =
|
||||
({ config, field }: Args): FieldHook =>
|
||||
({ value }) => {
|
||||
let relatedCollection: CollectionConfig | undefined
|
||||
|
||||
const hasManyRelations = typeof field.relationTo !== 'string'
|
||||
|
||||
if (!hasManyRelations) {
|
||||
relatedCollection = config.collections?.find(({ slug }) => slug === field.relationTo)
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((val) => {
|
||||
// Handle has many
|
||||
if (relatedCollection && val) {
|
||||
return convertValue({
|
||||
relatedCollection,
|
||||
value: val,
|
||||
})
|
||||
}
|
||||
|
||||
// Handle has many - polymorphic
|
||||
if (isValidRelationObject(val)) {
|
||||
const relatedCollectionForSingleValue = config.collections?.find(
|
||||
({ slug }) => slug === val.relationTo,
|
||||
)
|
||||
|
||||
if (relatedCollectionForSingleValue) {
|
||||
return {
|
||||
relationTo: val.relationTo,
|
||||
value: convertValue({
|
||||
relatedCollection: relatedCollectionForSingleValue,
|
||||
value: val.value,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val
|
||||
})
|
||||
}
|
||||
|
||||
// Handle has one - polymorphic
|
||||
if (isValidRelationObject(value)) {
|
||||
relatedCollection = config.collections?.find(({ slug }) => slug === value.relationTo)
|
||||
|
||||
if (relatedCollection) {
|
||||
return {
|
||||
relationTo: value.relationTo,
|
||||
value: convertValue({ relatedCollection, value: value.value }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle has one
|
||||
if (relatedCollection && value) {
|
||||
return convertValue({
|
||||
relatedCollection,
|
||||
value,
|
||||
})
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
@@ -1,28 +1,14 @@
|
||||
import type { Config, Field, FieldHook } from 'payload'
|
||||
import type { Config, Field } from 'payload'
|
||||
|
||||
import { getAfterReadHook } from './hooks/afterRead.js'
|
||||
import { getBeforeChangeHook } from './hooks/beforeChange.js'
|
||||
|
||||
interface TraverseFieldsArgs {
|
||||
config: Config
|
||||
fields: Field[]
|
||||
keepAfterRead: boolean
|
||||
}
|
||||
|
||||
const traverseFields = ({ config, fields, keepAfterRead }: TraverseFieldsArgs): Field[] => {
|
||||
const traverseFields = ({ config, fields }: { config: Config; fields: Field[] }): Field[] => {
|
||||
return fields.map((field) => {
|
||||
if (field.type === 'relationship' || field.type === 'upload') {
|
||||
const afterRead: FieldHook[] = [...(field.hooks?.afterRead || [])]
|
||||
|
||||
if (!keepAfterRead) {
|
||||
afterRead.unshift(getAfterReadHook({ config, field }))
|
||||
}
|
||||
|
||||
return {
|
||||
...field,
|
||||
hooks: {
|
||||
...(field.hooks || {}),
|
||||
afterRead,
|
||||
beforeChange: [
|
||||
...(field.hooks?.beforeChange || []),
|
||||
getBeforeChangeHook({ config, field }),
|
||||
@@ -34,7 +20,7 @@ const traverseFields = ({ config, fields, keepAfterRead }: TraverseFieldsArgs):
|
||||
if ('fields' in field) {
|
||||
return {
|
||||
...field,
|
||||
fields: traverseFields({ config, fields: field.fields, keepAfterRead }),
|
||||
fields: traverseFields({ config, fields: field.fields }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +30,7 @@ const traverseFields = ({ config, fields, keepAfterRead }: TraverseFieldsArgs):
|
||||
tabs: field.tabs.map((tab) => {
|
||||
return {
|
||||
...tab,
|
||||
fields: traverseFields({ config, fields: tab.fields, keepAfterRead }),
|
||||
fields: traverseFields({ config, fields: tab.fields }),
|
||||
}
|
||||
}),
|
||||
}
|
||||
@@ -56,7 +42,7 @@ const traverseFields = ({ config, fields, keepAfterRead }: TraverseFieldsArgs):
|
||||
blocks: field.blocks.map((block) => {
|
||||
return {
|
||||
...block,
|
||||
fields: traverseFields({ config, fields: block.fields, keepAfterRead }),
|
||||
fields: traverseFields({ config, fields: block.fields }),
|
||||
}
|
||||
}),
|
||||
}
|
||||
@@ -66,19 +52,9 @@ const traverseFields = ({ config, fields, keepAfterRead }: TraverseFieldsArgs):
|
||||
})
|
||||
}
|
||||
|
||||
interface Args {
|
||||
/*
|
||||
If you want to keep ObjectIDs as ObjectIDs after read, you can enable this flag.
|
||||
By default, all relationship ObjectIDs are stringified within the AfterRead hook.
|
||||
*/
|
||||
keepAfterRead?: boolean
|
||||
}
|
||||
|
||||
export const relationshipsAsObjectID =
|
||||
(args?: Args) =>
|
||||
(/** Possible args in the future */) =>
|
||||
(config: Config): Config => {
|
||||
const keepAfterRead = typeof args?.keepAfterRead === 'boolean' ? args.keepAfterRead : false
|
||||
|
||||
return {
|
||||
...config,
|
||||
collections: (config.collections || []).map((collection) => {
|
||||
@@ -87,7 +63,6 @@ export const relationshipsAsObjectID =
|
||||
fields: traverseFields({
|
||||
config,
|
||||
fields: collection.fields,
|
||||
keepAfterRead,
|
||||
}),
|
||||
}
|
||||
}),
|
||||
@@ -97,7 +72,6 @@ export const relationshipsAsObjectID =
|
||||
fields: traverseFields({
|
||||
config,
|
||||
fields: global.fields,
|
||||
keepAfterRead,
|
||||
}),
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-search",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "Search plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-seo",
|
||||
"version": "3.0.0-beta.71",
|
||||
"version": "3.0.0-beta.68",
|
||||
"description": "SEO plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { FieldType, Options } from '@payloadcms/ui'
|
||||
import type { FormFieldBase } from 'payload'
|
||||
import type { FieldType, FormFieldBase, Options } from '@payloadcms/ui'
|
||||
|
||||
import {
|
||||
FieldLabel,
|
||||
@@ -83,9 +82,7 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
|
||||
<React.Fragment>
|
||||
—
|
||||
<button
|
||||
onClick={() => {
|
||||
void regenerateDescription()
|
||||
}}
|
||||
onClick={regenerateDescription}
|
||||
style={{
|
||||
background: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user