Compare commits
30 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df023a52fd | ||
|
|
d267cad482 | ||
|
|
fa38dfc16c | ||
|
|
8e1a5c8dba | ||
|
|
a8c60c1c02 | ||
|
|
d44fb2db37 | ||
|
|
852f9fc1fd | ||
|
|
e2d803800d | ||
|
|
7fa68d17f5 | ||
|
|
9ec431a5bd | ||
|
|
cadf815ef6 | ||
|
|
638382e7fd | ||
|
|
08fdbcacc0 | ||
|
|
b27e42c484 | ||
|
|
32cc1a5761 | ||
|
|
38be69b7d3 | ||
|
|
6b82196f01 | ||
|
|
ead12c8a49 | ||
|
|
6253ec5d1a | ||
|
|
f9ae56ec88 | ||
|
|
0688c2b79d | ||
|
|
c6246618ba | ||
|
|
b69826a81e | ||
|
|
e80da7cb75 | ||
|
|
6f512b6ca8 | ||
|
|
22ee8bf383 | ||
|
|
308fad8a7a | ||
|
|
6427b7eb29 | ||
|
|
3a657847f2 | ||
|
|
8212c0d65f |
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@@ -31,8 +31,15 @@
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"editor.formatOnSaveMode": "file",
|
||||
// All ESLint rules to 'warn' to differentate from TypeScript's 'error' level
|
||||
"eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }],
|
||||
"eslint.rules.customizations": [
|
||||
// Defaultt all ESLint errors to 'warn' to differentate from TypeScript's 'error' level
|
||||
{ "rule": "*", "severity": "warn" },
|
||||
|
||||
// Silence some warnings that will get auto-fixed
|
||||
{ "rule": "perfectionist/*", "severity": "off", "fixable": true },
|
||||
{ "rule": "curly", "severity": "off", "fixable": true },
|
||||
{ "rule": "object-shorthand", "severity": "off", "fixable": true }
|
||||
],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
// Load .git-blame-ignore-revs file
|
||||
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"],
|
||||
|
||||
@@ -431,14 +431,14 @@ export const MyClientComponent: React.FC = () => {
|
||||
See [Using Hooks](#using-hooks) for more details.
|
||||
</Banner>
|
||||
|
||||
All [Field Components](./fields) automatically receive their respective Client Field Config through a common [`field`](./fields#the-field-prop) prop:
|
||||
All [Field Components](./fields) automatically receive their respective Field Config through a common [`field`](./fields#the-field-prop) prop:
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import type { TextFieldProps } from 'payload'
|
||||
import type { TextFieldClientComponent } from 'payload'
|
||||
|
||||
export const MyClientFieldComponent: TextFieldProps = ({ field: { name } }) => {
|
||||
export const MyClientFieldComponent: TextFieldClientComponent = ({ field: { name } }) => {
|
||||
return (
|
||||
<p>
|
||||
{`This field's name is ${name}`}
|
||||
|
||||
@@ -136,7 +136,7 @@ All Field Components receive the following props:
|
||||
| Property | Description |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`docPreferences`** | An object that contains the [Preferences](./preferences) for the document.
|
||||
| **`field`** | The sanitized, client-friendly version of the field's config. [More details](#the-field-prop) |
|
||||
| **`field`** | The field's config. [More details](#the-field-prop) |
|
||||
| **`locale`** | The locale of the field. [More details](../configuration/localization). |
|
||||
| **`readOnly`** | A boolean value that represents if the field is read-only or not. |
|
||||
| **`user`** | The currently authenticated user. [More details](../authentication/overview). |
|
||||
@@ -175,46 +175,46 @@ export const CustomTextField: React.FC = () => {
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Field Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview). The convention is to append `Props` to the type of field, i.e. `TextFieldProps`.
|
||||
When building Custom Field Components, you can import the component type to ensure type safety. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview) and for every client/server environment. The convention is to prepend the field type onto the target type, i.e. `TextFieldClientComponent`:
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldProps,
|
||||
BlocksFieldProps,
|
||||
CheckboxFieldProps,
|
||||
CodeFieldProps,
|
||||
CollapsibleFieldProps,
|
||||
DateFieldProps,
|
||||
EmailFieldProps,
|
||||
GroupFieldProps,
|
||||
HiddenFieldProps,
|
||||
JSONFieldProps,
|
||||
NumberFieldProps,
|
||||
PointFieldProps,
|
||||
RadioFieldProps,
|
||||
RelationshipFieldProps,
|
||||
RichTextFieldProps,
|
||||
RowFieldProps,
|
||||
SelectFieldProps,
|
||||
TabsFieldProps,
|
||||
TextFieldProps,
|
||||
TextareaFieldProps,
|
||||
UploadFieldProps
|
||||
TextFieldClientComponent,
|
||||
TextFieldServerComponent,
|
||||
TextFieldClientProps,
|
||||
TextFieldServerProps,
|
||||
// ...and so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
### The `field` Prop
|
||||
|
||||
All Field Components are passed a client-friendly version of their Field Config through a common `field` prop. Since the raw Field Config is [non-serializable](https://react.dev/reference/rsc/use-client#serializable-types), Payload sanitized it into a [Client Config](./components#accessing-the-payload-config) that is safe to pass into Client Components.
|
||||
All Field Components are passed their own Field Config through a common `field` prop. Within a Server Component, this is the raw Field Config. Within Client Components, however, the raw Field Config is [non-serializable](https://react.dev/reference/rsc/use-client#serializable-types). Instead, Client Components receives a [Client Config](./components#accessing-the-payload-config), which is a sanitizes version of the Field Config that is safe to pass into Client Components.
|
||||
|
||||
The exact shape of this prop is unique to the specific [Field Type](../fields/overview) being rendered, minus all non-serializable properties. Any [Custom Components](../components) are also resolved into a "mapped component" that is safe to pass.
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import type { TextFieldServerComponent } from 'payload'
|
||||
|
||||
export const MyServerTextField: TextFieldServerComponent = ({ payload, field: { name } }) => {
|
||||
const result = await payload.find({
|
||||
collection: 'myCollection',
|
||||
depth: 1,
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Client Component:
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import type { TextFieldProps } from 'payload'
|
||||
import type { TextFieldClientComponent } from 'payload'
|
||||
|
||||
export const MyClientFieldComponent: React.FC<TextFieldProps> = ({ field: { name } }) => {
|
||||
export const MyClientTextField: TextFieldClientComponent = ({ field: { name } }) => {
|
||||
return (
|
||||
<p>
|
||||
{`This field's name is ${name}`}
|
||||
@@ -238,40 +238,18 @@ The following additional properties are also provided to the `field` prop:
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Field Components, you can import the client field props to ensure type safety in your component. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview). The convention is to append `Client` to the type of field, i.e. `TextFieldClient`.
|
||||
When building Custom Field Components, you can import the client field props to ensure type safety in your component. There is an explicit type for the Field Component, one for every [Field Type](../fields/overview) and server/client environment. The convention is to prepend the field type onto the target type, i.e. `TextFieldClientComponent`:
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldClient,
|
||||
BlocksFieldClient,
|
||||
CheckboxFieldClient,
|
||||
CodeFieldClient,
|
||||
CollapsibleFieldClient,
|
||||
DateFieldClient,
|
||||
EmailFieldClient,
|
||||
GroupFieldClient,
|
||||
HiddenFieldClient,
|
||||
JSONFieldClient,
|
||||
NumberFieldClient,
|
||||
PointFieldClient,
|
||||
RadioFieldClient,
|
||||
RelationshipFieldClient,
|
||||
RichTextFieldClient,
|
||||
RowFieldClient,
|
||||
SelectFieldClient,
|
||||
TabsFieldClient,
|
||||
TextFieldClient,
|
||||
TextareaFieldClient,
|
||||
UploadFieldClient
|
||||
TextFieldClientComponent,
|
||||
TextFieldServerComponent,
|
||||
TextFieldClientProps,
|
||||
TextFieldServerProps,
|
||||
// ...and so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
When working on the client, you will never have access to objects of type `Field`. This is reserved for the server-side. Instead, you can use `ClientField` which is a union type of all the client fields:
|
||||
|
||||
```tsx
|
||||
import type { ClientField } from 'payload'
|
||||
```
|
||||
|
||||
### The Cell Component
|
||||
|
||||
The Cell Component is rendered in the table of the List View. It represents the value of the field when displayed in a table cell.
|
||||
@@ -353,7 +331,7 @@ When building Custom Label Components, you can import the component props to ens
|
||||
import type {
|
||||
TextFieldLabelServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
// And so on for each Field Type
|
||||
// ...and so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ The following options are available:
|
||||
| **`lockTime`** | Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
|
||||
| **`loginWithUsername`** | Ability to allow users to login with username/password. [More](/docs/authentication/overview#login-with-username) |
|
||||
| **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
|
||||
| **`removeTokenFromResponses`** | Set to true if you want to remove the token from the returned authentication API responses such as login or refresh. |
|
||||
| **`strategies`** | Advanced - an array of custom authentification strategies to extend this collection's authentication with. [More details](./custom-strategies). |
|
||||
| **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
|
||||
| **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More details](./api-keys). |
|
||||
|
||||
@@ -5,13 +5,13 @@ export const recordLastLoggedInTenant: AfterLoginHook = async ({ req, user }) =>
|
||||
const relatedOrg = await req.payload
|
||||
.find({
|
||||
collection: 'tenants',
|
||||
depth: 0,
|
||||
limit: 1,
|
||||
where: {
|
||||
'domains.domain': {
|
||||
in: [req.headers.host],
|
||||
},
|
||||
},
|
||||
depth: 0,
|
||||
limit: 1,
|
||||
})
|
||||
?.then((res) => res.docs?.[0])
|
||||
|
||||
@@ -24,7 +24,10 @@ export const recordLastLoggedInTenant: AfterLoginHook = async ({ req, user }) =>
|
||||
req,
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
req.payload.logger.error(`Error recording last logged in tenant for user ${user.id}: ${err}`)
|
||||
req.payload.logger.error({
|
||||
err,
|
||||
msg: `Error recording last logged in tenant for user ${user.id}`,
|
||||
})
|
||||
}
|
||||
|
||||
return user
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -37,6 +37,8 @@ async function installDeps(args: {
|
||||
installCmd = 'yarn'
|
||||
} else if (packageManager === 'pnpm') {
|
||||
installCmd = 'pnpm install'
|
||||
} else if (packageManager === 'bun') {
|
||||
installCmd = 'bun install'
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import execa from 'execa'
|
||||
import fse from 'fs-extra'
|
||||
|
||||
import type { CliArgs, PackageManager } from '../types.js'
|
||||
|
||||
export async function getPackageManager(args: {
|
||||
cliArgs?: CliArgs
|
||||
projectDir: string
|
||||
}): Promise<PackageManager> {
|
||||
export function getPackageManager(args: { cliArgs?: CliArgs; projectDir: string }): PackageManager {
|
||||
const { cliArgs, projectDir } = args
|
||||
|
||||
try {
|
||||
@@ -18,15 +14,11 @@ export async function getPackageManager(args: {
|
||||
detected = 'yarn'
|
||||
} else if (cliArgs?.['--use-npm'] || fse.existsSync(`${projectDir}/package-lock.json`)) {
|
||||
detected = 'npm'
|
||||
} else if (cliArgs?.['--use-bun'] || fse.existsSync(`${projectDir}/bun.lockb`)) {
|
||||
detected = 'bun'
|
||||
} else {
|
||||
// Otherwise check for existing commands
|
||||
if (await commandExists('pnpm')) {
|
||||
detected = 'pnpm'
|
||||
} else if (await commandExists('yarn')) {
|
||||
detected = 'yarn'
|
||||
} else {
|
||||
detected = 'npm'
|
||||
}
|
||||
// Otherwise check the execution environment
|
||||
detected = getEnvironmentPackageManager()
|
||||
}
|
||||
|
||||
return detected
|
||||
@@ -35,11 +27,20 @@ export async function getPackageManager(args: {
|
||||
}
|
||||
}
|
||||
|
||||
async function commandExists(command: string): Promise<boolean> {
|
||||
try {
|
||||
await execa.command(`command -v ${command}`)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
function getEnvironmentPackageManager(): PackageManager {
|
||||
const userAgent = process.env.npm_config_user_agent || ''
|
||||
|
||||
if (userAgent.startsWith('yarn')) {
|
||||
return 'yarn'
|
||||
}
|
||||
|
||||
if (userAgent.startsWith('pnpm')) {
|
||||
return 'pnpm'
|
||||
}
|
||||
|
||||
if (userAgent.startsWith('bun')) {
|
||||
return 'bun'
|
||||
}
|
||||
|
||||
return 'npm'
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ export class Main {
|
||||
|
||||
// Package manager
|
||||
'--no-deps': Boolean,
|
||||
'--use-bun': Boolean,
|
||||
'--use-npm': Boolean,
|
||||
'--use-pnpm': Boolean,
|
||||
'--use-yarn': Boolean,
|
||||
@@ -132,7 +133,7 @@ export class Main {
|
||||
? path.dirname(nextConfigPath)
|
||||
: path.resolve(process.cwd(), slugify(projectName))
|
||||
|
||||
const packageManager = await getPackageManager({ cliArgs: this.args, projectDir })
|
||||
const packageManager = getPackageManager({ cliArgs: this.args, projectDir })
|
||||
|
||||
if (nextConfigPath) {
|
||||
p.log.step(
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface Args extends arg.Spec {
|
||||
'--secret': StringConstructor
|
||||
'--template': StringConstructor
|
||||
'--template-branch': StringConstructor
|
||||
'--use-bun': BooleanConstructor
|
||||
'--use-npm': BooleanConstructor
|
||||
'--use-pnpm': BooleanConstructor
|
||||
'--use-yarn': BooleanConstructor
|
||||
|
||||
@@ -40,6 +40,7 @@ export function helpMessage(): void {
|
||||
--use-npm Use npm to install dependencies
|
||||
--use-yarn Use yarn to install dependencies
|
||||
--use-pnpm Use pnpm to install dependencies
|
||||
--use-bun Use bun to install dependencies (experimental)
|
||||
--no-deps Do not install any dependencies
|
||||
-h Show help
|
||||
`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -23,7 +23,7 @@ const connectWithReconnect = async function ({
|
||||
} else {
|
||||
try {
|
||||
result = await adapter.pool.connect()
|
||||
} catch (err) {
|
||||
} catch (ignore) {
|
||||
setTimeout(() => {
|
||||
payload.logger.info('Reconnecting to postgres')
|
||||
void connectWithReconnect({ adapter, payload, reconnect: true })
|
||||
@@ -38,7 +38,7 @@ const connectWithReconnect = async function ({
|
||||
if (err.code === 'ECONNRESET') {
|
||||
void connectWithReconnect({ adapter, payload, reconnect: true })
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (ignore) {
|
||||
// swallow error
|
||||
}
|
||||
})
|
||||
@@ -76,7 +76,7 @@ export const connect: Connect = async function connect(
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.payload.logger.error(`Error: cannot connect to Postgres. Details: ${err.message}`, err)
|
||||
this.payload.logger.error({ err, msg: `Error: cannot connect to Postgres: ${err.message}` })
|
||||
if (typeof this.rejectInitializing === 'function') {
|
||||
this.rejectInitializing()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-sqlite",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "The officially supported SQLite database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -37,7 +37,7 @@ export const connect: Connect = async function connect(
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.payload.logger.error(`Error: cannot connect to SQLite. Details: ${err.message}`, err)
|
||||
this.payload.logger.error({ err, msg: `Error: cannot connect to SQLite: ${err.message}` })
|
||||
if (typeof this.rejectInitializing === 'function') {
|
||||
this.rejectInitializing()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-vercel-postgres",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Vercel Postgres adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -39,7 +39,7 @@ export const connect: Connect = async function connect(
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.payload.logger.error(`Error: cannot connect to Postgres. Details: ${err.message}`, err)
|
||||
this.payload.logger.error({ err, msg: `Error: cannot connect to Postgres: ${err.message}` })
|
||||
if (typeof this.rejectInitializing === 'function') {
|
||||
this.rejectInitializing()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/drizzle",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "A library of shared functions used by different payload database adapters",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -80,6 +80,7 @@ export const buildFindManyArgs = ({
|
||||
depth,
|
||||
fields,
|
||||
path: '',
|
||||
tablePath: '',
|
||||
topLevelArgs: result,
|
||||
topLevelTableName: tableName,
|
||||
})
|
||||
|
||||
@@ -14,6 +14,7 @@ type TraverseFieldArgs = {
|
||||
depth?: number
|
||||
fields: Field[]
|
||||
path: string
|
||||
tablePath: string
|
||||
topLevelArgs: Record<string, unknown>
|
||||
topLevelTableName: string
|
||||
}
|
||||
@@ -26,6 +27,7 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields,
|
||||
path,
|
||||
tablePath,
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
}: TraverseFieldArgs) => {
|
||||
@@ -53,6 +55,7 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields: field.fields,
|
||||
path,
|
||||
tablePath,
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
})
|
||||
@@ -63,6 +66,7 @@ export const traverseFields = ({
|
||||
if (field.type === 'tabs') {
|
||||
field.tabs.forEach((tab) => {
|
||||
const tabPath = tabHasName(tab) ? `${path}${tab.name}_` : path
|
||||
const tabTablePath = tabHasName(tab) ? `${tablePath}${toSnakeCase(tab.name)}_` : tablePath
|
||||
|
||||
traverseFields({
|
||||
_locales,
|
||||
@@ -72,6 +76,7 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields: tab.fields,
|
||||
path: tabPath,
|
||||
tablePath: tabTablePath,
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
})
|
||||
@@ -92,7 +97,7 @@ export const traverseFields = ({
|
||||
}
|
||||
|
||||
const arrayTableName = adapter.tableNameMap.get(
|
||||
`${currentTableName}_${path}${toSnakeCase(field.name)}`,
|
||||
`${currentTableName}_${tablePath}${toSnakeCase(field.name)}`,
|
||||
)
|
||||
|
||||
const arrayTableNameWithLocales = `${arrayTableName}${adapter.localesSuffix}`
|
||||
@@ -116,6 +121,7 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields: field.fields,
|
||||
path: '',
|
||||
tablePath: '',
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
})
|
||||
@@ -172,6 +178,7 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields: block.fields,
|
||||
path: '',
|
||||
tablePath: '',
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
})
|
||||
@@ -180,7 +187,7 @@ export const traverseFields = ({
|
||||
|
||||
break
|
||||
|
||||
case 'group':
|
||||
case 'group': {
|
||||
traverseFields({
|
||||
_locales,
|
||||
adapter,
|
||||
@@ -189,11 +196,13 @@ export const traverseFields = ({
|
||||
depth,
|
||||
fields: field.fields,
|
||||
path: `${path}${field.name}_`,
|
||||
tablePath: `${tablePath}${toSnakeCase(field.name)}_`,
|
||||
topLevelArgs,
|
||||
topLevelTableName,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
default: {
|
||||
break
|
||||
|
||||
@@ -257,10 +257,10 @@ export const getTableColumnFromPath = ({
|
||||
tableType = 'numbers'
|
||||
columnName = 'number'
|
||||
}
|
||||
newTableName = `${tableName}_${tableType}`
|
||||
newTableName = `${rootTableName}_${tableType}`
|
||||
const joinConstraints = [
|
||||
eq(adapter.tables[tableName].id, adapter.tables[newTableName].parent),
|
||||
eq(adapter.tables[newTableName].path, `${constraintPath}${field.name}`),
|
||||
eq(adapter.tables[rootTableName].id, adapter.tables[newTableName].parent),
|
||||
like(adapter.tables[newTableName].path, `${constraintPath}${field.name}`),
|
||||
]
|
||||
|
||||
if (locale && field.localized && adapter.payload.config.localization) {
|
||||
|
||||
@@ -37,6 +37,7 @@ export const beginTransaction: BeginTransaction = async function beginTransactio
|
||||
return done
|
||||
}
|
||||
reject = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
||||
rej()
|
||||
return done
|
||||
}
|
||||
@@ -57,7 +58,7 @@ export const beginTransaction: BeginTransaction = async function beginTransactio
|
||||
resolve,
|
||||
}
|
||||
} catch (err) {
|
||||
this.payload.logger.error(`Error: cannot begin transaction: ${err.message}`, err)
|
||||
this.payload.logger.error({ err, msg: `Error: cannot begin transaction: ${err.message}` })
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-react",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
gap: base(0.8);
|
||||
padding: base(2);
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--base);
|
||||
gap: base(0.4);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
gap: base(0.4);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
&--width-normal {
|
||||
.template-minimal__wrap {
|
||||
max-width: 500px;
|
||||
max-width: base(24);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&--width-wide {
|
||||
.template-minimal__wrap {
|
||||
max-width: 1024px;
|
||||
max-width: base(48);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.create-first-user {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.4);
|
||||
|
||||
> form > .field-type {
|
||||
margin-bottom: var(--base);
|
||||
|
||||
& .form-submit {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
useListQuery,
|
||||
useModal,
|
||||
useRouteCache,
|
||||
useSearchParams,
|
||||
useStepNav,
|
||||
useTranslation,
|
||||
useWindowInfo,
|
||||
@@ -54,8 +53,7 @@ export const DefaultListView: React.FC = () => {
|
||||
newDocumentURL,
|
||||
} = useListInfo()
|
||||
|
||||
const { data, defaultLimit, handlePageChange, handlePerPageChange } = useListQuery()
|
||||
const { searchParams } = useSearchParams()
|
||||
const { data, defaultLimit, handlePageChange, handlePerPageChange, params } = useListQuery()
|
||||
const { openModal } = useModal()
|
||||
const { clearRouteCache } = useRouteCache()
|
||||
const { setCollectionSlug, setOnSuccess } = useBulkUpload()
|
||||
@@ -226,9 +224,7 @@ export const DefaultListView: React.FC = () => {
|
||||
</div>
|
||||
<PerPage
|
||||
handleChange={(limit) => void handlePerPageChange(limit)}
|
||||
limit={
|
||||
isNumber(searchParams?.limit) ? Number(searchParams.limit) : defaultLimit
|
||||
}
|
||||
limit={isNumber(params?.limit) ? Number(params.limit) : defaultLimit}
|
||||
limits={collectionConfig?.admin?.pagination?.limits}
|
||||
resetPage={data.totalDocs <= data.pagingCounter}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,10 @@ import { formatAdminURL } from '@payloadcms/ui/shared'
|
||||
import LinkImport from 'next/link.js'
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'logout'
|
||||
|
||||
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
||||
|
||||
export const LogoutClient: React.FC<{
|
||||
@@ -26,7 +30,7 @@ export const LogoutClient: React.FC<{
|
||||
|
||||
if (isLoggingOut) {
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
{inactivity && <h2>{t('authentication:loggedOutInactivity')}</h2>}
|
||||
{!inactivity && <h2>{t('authentication:loggedOutSuccessfully')}</h2>}
|
||||
<Button
|
||||
@@ -43,7 +47,7 @@ export const LogoutClient: React.FC<{
|
||||
>
|
||||
{t('authentication:logBackIn')}
|
||||
</Button>
|
||||
</Fragment>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.logout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
min-height: 100vh;
|
||||
|
||||
&__wrap {
|
||||
& > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: base(0.8);
|
||||
width: 100%;
|
||||
max-width: base(36);
|
||||
|
||||
& > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const LogoutView: React.FC<
|
||||
} = initPageResult
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<div className={`${baseClass}`}>
|
||||
<LogoutClient
|
||||
adminRoute={adminRoute}
|
||||
inactivity={inactivity}
|
||||
|
||||
@@ -38,8 +38,10 @@ export const NotFoundClient: React.FC<{
|
||||
.join(' ')}
|
||||
>
|
||||
<Gutter className={`${baseClass}__wrap`}>
|
||||
<h1>{t('general:nothingFound')}</h1>
|
||||
<p>{t('general:sorryNotFound')}</p>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<h1>{t('general:nothingFound')}</h1>
|
||||
<p>{t('general:sorryNotFound')}</p>
|
||||
</div>
|
||||
<Button
|
||||
className={`${baseClass}__button`}
|
||||
el="link"
|
||||
|
||||
@@ -13,6 +13,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: base(0.8);
|
||||
max-width: base(36);
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.4);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -75,21 +75,23 @@ export const ResetPasswordClient: React.FC<Args> = ({ token }) => {
|
||||
method="POST"
|
||||
onSuccess={onSuccess}
|
||||
>
|
||||
<PasswordField
|
||||
field={{
|
||||
name: 'password',
|
||||
label: i18n.t('authentication:newPassword'),
|
||||
required: true,
|
||||
}}
|
||||
/>
|
||||
<ConfirmPasswordField />
|
||||
<HiddenField
|
||||
field={{
|
||||
name: 'token',
|
||||
}}
|
||||
forceUsePathFromProps
|
||||
value={token}
|
||||
/>
|
||||
<div className={'inputWrap'}>
|
||||
<PasswordField
|
||||
field={{
|
||||
name: 'password',
|
||||
label: i18n.t('authentication:newPassword'),
|
||||
required: true,
|
||||
}}
|
||||
/>
|
||||
<ConfirmPasswordField />
|
||||
<HiddenField
|
||||
field={{
|
||||
name: 'token',
|
||||
}}
|
||||
forceUsePathFromProps
|
||||
value={token}
|
||||
/>
|
||||
</div>
|
||||
<FormSubmit size="large">{i18n.t('authentication:resetPassword')}</FormSubmit>
|
||||
</Form>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.reset-password {
|
||||
form > .field-type {
|
||||
margin-bottom: var(--base);
|
||||
&__wrap {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: base(0.8);
|
||||
max-width: base(36);
|
||||
|
||||
& > form {
|
||||
width: 100%;
|
||||
|
||||
& > .inputWrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.8);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { AdminViewProps } from 'payload'
|
||||
|
||||
import { Button, Translation } from '@payloadcms/ui'
|
||||
import { formatAdminURL } from '@payloadcms/ui/shared'
|
||||
import { Button } from '@payloadcms/ui'
|
||||
import { formatAdminURL, Translation } from '@payloadcms/ui/shared'
|
||||
import LinkImport from 'next/link.js'
|
||||
import React from 'react'
|
||||
|
||||
import { MinimalTemplate } from '../../templates/Minimal/index.js'
|
||||
import { ResetPasswordClient } from './index.client.js'
|
||||
import './index.scss'
|
||||
|
||||
@@ -37,42 +36,37 @@ export const ResetPassword: React.FC<AdminViewProps> = ({ initPageResult, params
|
||||
|
||||
if (user) {
|
||||
return (
|
||||
<MinimalTemplate className={resetPasswordBaseClass}>
|
||||
<div className={`${resetPasswordBaseClass}__wrap`}>
|
||||
<h1>{i18n.t('authentication:alreadyLoggedIn')}</h1>
|
||||
<p>
|
||||
<Translation
|
||||
elements={{
|
||||
'0': ({ children }) => (
|
||||
<Link
|
||||
href={formatAdminURL({
|
||||
adminRoute,
|
||||
path: accountRoute,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
i18nKey="authentication:loggedInChangePassword"
|
||||
t={i18n.t}
|
||||
/>
|
||||
</p>
|
||||
<br />
|
||||
<Button buttonStyle="secondary" el="link" Link={Link} to={adminRoute}>
|
||||
{i18n.t('general:backToDashboard')}
|
||||
</Button>
|
||||
</div>
|
||||
</MinimalTemplate>
|
||||
<div className={`${resetPasswordBaseClass}__wrap`}>
|
||||
<h1>{i18n.t('authentication:alreadyLoggedIn')}</h1>
|
||||
<p>
|
||||
<Translation
|
||||
elements={{
|
||||
'0': ({ children }) => (
|
||||
<Link
|
||||
href={formatAdminURL({
|
||||
adminRoute,
|
||||
path: accountRoute,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
i18nKey="authentication:loggedInChangePassword"
|
||||
t={i18n.t}
|
||||
/>
|
||||
</p>
|
||||
<Button buttonStyle="secondary" el="link" Link={Link} size="large" to={adminRoute}>
|
||||
{i18n.t('general:backToDashboard')}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<MinimalTemplate className={resetPasswordBaseClass}>
|
||||
<div className={`${resetPasswordBaseClass}__wrap`}>
|
||||
<h1>{i18n.t('authentication:resetPassword')}</h1>
|
||||
<ResetPasswordClient token={token} />
|
||||
</div>
|
||||
</MinimalTemplate>
|
||||
<div className={`${resetPasswordBaseClass}__wrap`}>
|
||||
<h1>{i18n.t('authentication:resetPassword')}</h1>
|
||||
<ResetPasswordClient token={token} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,24 +38,40 @@
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
&__toggle {
|
||||
@extend %btn-reset;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
[dir='ltr'] & {
|
||||
margin-right: var(--base);
|
||||
}
|
||||
[dir='rtl'] & {
|
||||
margin-left: var(--base);
|
||||
}
|
||||
&__wrapper {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.8);
|
||||
padding: base(2);
|
||||
max-width: base(36);
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(0.4);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__modal-template {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: base(0.4);
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import { toast } from 'sonner'
|
||||
|
||||
import type { Props } from './types.js'
|
||||
|
||||
import { MinimalTemplate } from '../../../templates/Minimal/index.js'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'restore-version'
|
||||
@@ -36,11 +35,14 @@ const Restore: React.FC<Props> = ({
|
||||
}) => {
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { admin: adminRoute, api: apiRoute },
|
||||
serverURL,
|
||||
},
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = collections.find((collection) => collection.slug === collectionSlug)
|
||||
|
||||
const { toggleModal } = useModal()
|
||||
const [processing, setProcessing] = useState(false)
|
||||
const router = useRouter()
|
||||
@@ -54,7 +56,8 @@ const Restore: React.FC<Props> = ({
|
||||
|
||||
let fetchURL = `${serverURL}${apiRoute}`
|
||||
let redirectURL: string
|
||||
const canRestoreAsDraft = status !== 'draft'
|
||||
|
||||
const canRestoreAsDraft = status !== 'draft' && collectionConfig?.versions?.drafts
|
||||
|
||||
if (collectionSlug) {
|
||||
fetchURL = `${fetchURL}/${collectionSlug}/versions/${versionID}?draft=${draft}`
|
||||
@@ -119,20 +122,25 @@ const Restore: React.FC<Props> = ({
|
||||
)}
|
||||
</div>
|
||||
<Modal className={`${baseClass}__modal`} slug={modalSlug}>
|
||||
<MinimalTemplate className={`${baseClass}__modal-template`}>
|
||||
<h1>{t('version:confirmVersionRestoration')}</h1>
|
||||
<p>{restoreMessage}</p>
|
||||
<Button
|
||||
buttonStyle="secondary"
|
||||
onClick={processing ? undefined : () => toggleModal(modalSlug)}
|
||||
type="button"
|
||||
>
|
||||
{t('general:cancel')}
|
||||
</Button>
|
||||
<Button onClick={processing ? undefined : () => void handleRestore()}>
|
||||
{processing ? t('version:restoring') : t('general:confirm')}
|
||||
</Button>
|
||||
</MinimalTemplate>
|
||||
<div className={`${baseClass}__wrapper`}>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<h1>{t('version:confirmVersionRestoration')}</h1>
|
||||
<p>{restoreMessage}</p>
|
||||
</div>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<Button
|
||||
buttonStyle="secondary"
|
||||
onClick={processing ? undefined : () => toggleModal(modalSlug)}
|
||||
size="large"
|
||||
type="button"
|
||||
>
|
||||
{t('general:cancel')}
|
||||
</Button>
|
||||
<Button onClick={processing ? undefined : () => void handleRestore()}>
|
||||
{processing ? t('version:restoring') : t('general:confirm')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
} from '../fields/config/types.js'
|
||||
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
|
||||
import type { JsonObject, Payload, PayloadRequest, RequestContext } from '../types/index.js'
|
||||
import type { RichTextFieldProps } from './fields/RichText.js'
|
||||
import type { RichTextFieldClientProps } from './fields/RichText.js'
|
||||
import type { CreateMappedComponent } from './types.js'
|
||||
|
||||
export type AfterReadRichTextHookArgs<
|
||||
@@ -261,7 +261,7 @@ export type RichTextAdapter<
|
||||
ExtraFieldProperties = any,
|
||||
> = {
|
||||
CellComponent: PayloadComponent<never>
|
||||
FieldComponent: PayloadComponent<never, RichTextFieldProps>
|
||||
FieldComponent: PayloadComponent<never, RichTextFieldClientProps>
|
||||
} & RichTextAdapterBase<Value, AdapterProps, ExtraFieldProperties>
|
||||
|
||||
export type RichTextAdapterProvider<
|
||||
|
||||
@@ -3,21 +3,38 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { ArrayField, ArrayFieldClient } from '../../fields/config/types.js'
|
||||
import type { ArrayFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
MappedComponent,
|
||||
} from '../types.js'
|
||||
|
||||
type ArrayFieldClientWithoutType = MarkOptional<ArrayFieldClient, 'type'>
|
||||
|
||||
export type ArrayFieldProps = {
|
||||
type ArrayFieldBaseClientProps = {
|
||||
readonly CustomRowLabel?: MappedComponent
|
||||
readonly validate?: ArrayFieldValidation
|
||||
} & Omit<FormFieldBase<ArrayFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type ArrayFieldClientProps = ArrayFieldBaseClientProps &
|
||||
ClientFieldBase<ArrayFieldClientWithoutType>
|
||||
|
||||
export type ArrayFieldServerProps = ServerFieldBase<ArrayField>
|
||||
|
||||
export type ArrayFieldServerComponent = FieldServerComponent<ArrayField>
|
||||
|
||||
export type ArrayFieldClientComponent = FieldClientComponent<
|
||||
ArrayFieldClientWithoutType,
|
||||
ArrayFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type ArrayFieldLabelServerComponent = FieldLabelServerComponent<ArrayField>
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { BlockField, BlockFieldClient } from '../../fields/config/types.js'
|
||||
import type { BlockFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type BlocksFieldClientWithoutType = MarkOptional<BlockFieldClient, 'type'>
|
||||
|
||||
export type BlockFieldProps = {
|
||||
type BlocksFieldBaseClientProps = {
|
||||
readonly validate?: BlockFieldValidation
|
||||
} & Omit<FormFieldBase<BlocksFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type BlocksFieldClientProps = BlocksFieldBaseClientProps &
|
||||
ClientFieldBase<BlocksFieldClientWithoutType>
|
||||
|
||||
export type BlocksFieldServerProps = ServerFieldBase<BlockField>
|
||||
|
||||
export type BlocksFieldServerComponent = FieldServerComponent<BlockField>
|
||||
|
||||
export type BlocksFieldClientComponent = FieldClientComponent<
|
||||
BlocksFieldClientWithoutType,
|
||||
BlocksFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type BlockFieldLabelServerComponent = FieldLabelServerComponent<BlockField>
|
||||
|
||||
|
||||
@@ -3,24 +3,41 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { CheckboxField, CheckboxFieldClient } from '../../fields/config/types.js'
|
||||
import type { CheckboxFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type CheckboxFieldClientWithoutType = MarkOptional<CheckboxFieldClient, 'type'>
|
||||
|
||||
export type CheckboxFieldProps = {
|
||||
type CheckboxFieldBaseClientProps = {
|
||||
readonly checked?: boolean
|
||||
readonly disableFormData?: boolean
|
||||
readonly id?: string
|
||||
readonly onChange?: (value: boolean) => void
|
||||
readonly partialChecked?: boolean
|
||||
readonly validate?: CheckboxFieldValidation
|
||||
} & Omit<FormFieldBase<CheckboxFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type CheckboxFieldClientProps = CheckboxFieldBaseClientProps &
|
||||
ClientFieldBase<CheckboxFieldClientWithoutType>
|
||||
|
||||
export type CheckboxFieldServerProps = ServerFieldBase<CheckboxField>
|
||||
|
||||
export type CheckboxFieldServerComponent = FieldServerComponent<CheckboxField>
|
||||
|
||||
export type CheckboxFieldClientComponent = FieldClientComponent<
|
||||
CheckboxFieldClientWithoutType,
|
||||
CheckboxFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type CheckboxFieldLabelServerComponent = FieldLabelServerComponent<CheckboxField>
|
||||
|
||||
|
||||
@@ -3,20 +3,37 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { CodeField, CodeFieldClient } from '../../fields/config/types.js'
|
||||
import type { CodeFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type CodeFieldClientWithoutType = MarkOptional<CodeFieldClient, 'type'>
|
||||
|
||||
export type CodeFieldProps = {
|
||||
type CodeFieldBaseClientProps = {
|
||||
readonly autoComplete?: string
|
||||
readonly validate?: CodeFieldValidation
|
||||
} & Omit<FormFieldBase<CodeFieldClientWithoutType>, 'validate'>
|
||||
readonly valiCode?: CodeFieldValidation
|
||||
}
|
||||
|
||||
export type CodeFieldClientProps = ClientFieldBase<CodeFieldClientWithoutType> &
|
||||
CodeFieldBaseClientProps
|
||||
|
||||
export type CodeFieldServerProps = ServerFieldBase<CodeField>
|
||||
|
||||
export type CodeFieldServerComponent = FieldServerComponent<CodeField>
|
||||
|
||||
export type CodeFieldClientComponent = FieldClientComponent<
|
||||
CodeFieldClientWithoutType,
|
||||
CodeFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type CodeFieldLabelServerComponent = FieldLabelServerComponent<CodeField>
|
||||
|
||||
|
||||
@@ -2,17 +2,29 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { CollapsibleField, CollapsibleFieldClient } from '../../fields/config/types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type CollapsibleFieldClientWithoutType = MarkOptional<CollapsibleFieldClient, 'type'>
|
||||
|
||||
export type CollapsibleFieldProps = FormFieldBase<CollapsibleFieldClientWithoutType>
|
||||
export type CollapsibleFieldClientProps = ClientFieldBase<CollapsibleFieldClientWithoutType>
|
||||
|
||||
export type CollapsibleFieldServerProps = ServerFieldBase<CollapsibleField>
|
||||
|
||||
export type CollapsibleFieldServerComponent = FieldServerComponent<CollapsibleField>
|
||||
|
||||
export type CollapsibleFieldClientComponent =
|
||||
FieldClientComponent<CollapsibleFieldClientWithoutType>
|
||||
|
||||
export type CollapsibleFieldLabelServerComponent = FieldLabelServerComponent<CollapsibleField>
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { DateField, DateFieldClient } from '../../fields/config/types.js'
|
||||
import type { DateFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type DateFieldClientWithoutType = MarkOptional<DateFieldClient, 'type'>
|
||||
|
||||
export type DateFieldProps = {
|
||||
type DateFieldBaseClientProps = {
|
||||
readonly validate?: DateFieldValidation
|
||||
} & Omit<FormFieldBase<DateFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type DateFieldClientProps = ClientFieldBase<DateFieldClientWithoutType> &
|
||||
DateFieldBaseClientProps
|
||||
|
||||
export type DateFieldServerProps = ServerFieldBase<DateField>
|
||||
|
||||
export type DateFieldServerComponent = FieldServerComponent<DateField>
|
||||
|
||||
export type DateFieldClientComponent = FieldClientComponent<
|
||||
DateFieldClientWithoutType,
|
||||
DateFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type DateFieldLabelServerComponent = FieldLabelServerComponent<DateField>
|
||||
|
||||
|
||||
@@ -3,20 +3,37 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { EmailField, EmailFieldClient } from '../../fields/config/types.js'
|
||||
import type { EmailFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type EmailFieldClientWithoutType = MarkOptional<EmailFieldClient, 'type'>
|
||||
|
||||
export type EmailFieldProps = {
|
||||
type EmailFieldBaseClientProps = {
|
||||
readonly autoComplete?: string
|
||||
readonly validate?: EmailFieldValidation
|
||||
} & Omit<FormFieldBase<EmailFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type EmailFieldClientProps = ClientFieldBase<EmailFieldClientWithoutType> &
|
||||
EmailFieldBaseClientProps
|
||||
|
||||
export type EmailFieldServerProps = ServerFieldBase<EmailField>
|
||||
|
||||
export type EmailFieldServerComponent = FieldServerComponent<EmailField>
|
||||
|
||||
export type EmailFieldClientComponent = FieldClientComponent<
|
||||
EmailFieldClientWithoutType,
|
||||
EmailFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type EmailFieldLabelServerComponent = FieldLabelServerComponent<EmailField>
|
||||
|
||||
|
||||
@@ -2,17 +2,28 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { GroupField, GroupFieldClient } from '../../fields/config/types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type GroupFieldClientWithoutType = MarkOptional<GroupFieldClient, 'type'>
|
||||
|
||||
export type GroupFieldProps = FormFieldBase<GroupFieldClientWithoutType>
|
||||
export type GroupFieldClientProps = ClientFieldBase<GroupFieldClientWithoutType>
|
||||
|
||||
export type GroupFieldServerProps = ServerFieldBase<GroupField>
|
||||
|
||||
export type GroupFieldServerComponent = FieldServerComponent<GroupField>
|
||||
|
||||
export type GroupFieldClientComponent = FieldClientComponent<GroupFieldClientWithoutType>
|
||||
|
||||
export type GroupFieldLabelServerComponent = FieldLabelServerComponent<GroupField>
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { JSONField, JSONFieldClient } from '../../fields/config/types.js'
|
||||
import type { JSONFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type JSONFieldClientWithoutType = MarkOptional<JSONFieldClient, 'type'>
|
||||
|
||||
export type JSONFieldProps = {
|
||||
type JSONFieldBaseClientProps = {
|
||||
readonly validate?: JSONFieldValidation
|
||||
} & Omit<FormFieldBase<JSONFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type JSONFieldClientProps = ClientFieldBase<JSONFieldClientWithoutType> &
|
||||
JSONFieldBaseClientProps
|
||||
|
||||
export type JSONFieldServerProps = ServerFieldBase<JSONField>
|
||||
|
||||
export type JSONFieldServerComponent = FieldServerComponent<JSONField>
|
||||
|
||||
export type JSONFieldClientComponent = FieldClientComponent<
|
||||
JSONFieldClientWithoutType,
|
||||
JSONFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type JSONFieldLabelServerComponent = FieldLabelServerComponent<JSONField>
|
||||
|
||||
|
||||
@@ -3,20 +3,37 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { NumberField, NumberFieldClient } from '../../fields/config/types.js'
|
||||
import type { NumberFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type NumberFieldClientWithoutType = MarkOptional<NumberFieldClient, 'type'>
|
||||
|
||||
export type NumberFieldProps = {
|
||||
type NumberFieldBaseClientProps = {
|
||||
readonly onChange?: (e: number) => void
|
||||
readonly validate?: NumberFieldValidation
|
||||
} & Omit<FormFieldBase<NumberFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type NumberFieldClientProps = ClientFieldBase<NumberFieldClientWithoutType> &
|
||||
NumberFieldBaseClientProps
|
||||
|
||||
export type NumberFieldServerProps = ServerFieldBase<NumberField>
|
||||
|
||||
export type NumberFieldServerComponent = FieldServerComponent<NumberField>
|
||||
|
||||
export type NumberFieldClientComponent = FieldClientComponent<
|
||||
NumberFieldClientWithoutType,
|
||||
NumberFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type NumberFieldLabelServerComponent = FieldLabelServerComponent<NumberField>
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { PointField, PointFieldClient } from '../../fields/config/types.js'
|
||||
import type { PointFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type PointFieldClientWithoutType = MarkOptional<PointFieldClient, 'type'>
|
||||
|
||||
export type PointFieldProps = {
|
||||
type PointFieldBaseClientProps = {
|
||||
readonly validate?: PointFieldValidation
|
||||
} & Omit<FormFieldBase<PointFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type PointFieldClientProps = ClientFieldBase<PointFieldClientWithoutType> &
|
||||
PointFieldBaseClientProps
|
||||
|
||||
export type PointFieldServerProps = ServerFieldBase<PointField>
|
||||
|
||||
export type PointFieldServerComponent = FieldServerComponent<PointField>
|
||||
|
||||
export type PointFieldClientComponent = FieldClientComponent<
|
||||
PointFieldClientWithoutType,
|
||||
PointFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type PointFieldLabelServerComponent = FieldLabelServerComponent<PointField>
|
||||
|
||||
|
||||
@@ -3,21 +3,38 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { RadioField, RadioFieldClient } from '../../fields/config/types.js'
|
||||
import type { RadioFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RadioFieldClientWithoutType = MarkOptional<RadioFieldClient, 'type'>
|
||||
|
||||
export type RadioFieldProps = {
|
||||
type RadioFieldBaseClientProps = {
|
||||
readonly onChange?: OnChange
|
||||
readonly validate?: RadioFieldValidation
|
||||
readonly value?: string
|
||||
} & Omit<FormFieldBase<RadioFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type RadioFieldClientProps = ClientFieldBase<RadioFieldClientWithoutType> &
|
||||
RadioFieldBaseClientProps
|
||||
|
||||
export type RadioFieldServerProps = ServerFieldBase<RadioField>
|
||||
|
||||
export type RadioFieldServerComponent = FieldServerComponent<RadioField>
|
||||
|
||||
export type RadioFieldClientComponent = FieldClientComponent<
|
||||
RadioFieldClientWithoutType,
|
||||
RadioFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type OnChange<T = string> = (value: T) => void
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { RelationshipField, RelationshipFieldClient } from '../../fields/config/types.js'
|
||||
import type { RelationshipFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RelationshipFieldClientWithoutType = MarkOptional<RelationshipFieldClient, 'type'>
|
||||
|
||||
export type RelationshipFieldProps = {
|
||||
type RelationshipFieldBaseClientProps = {
|
||||
readonly validate?: RelationshipFieldValidation
|
||||
} & Omit<FormFieldBase<RelationshipFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type RelationshipFieldClientProps = ClientFieldBase<RelationshipFieldClientWithoutType> &
|
||||
RelationshipFieldBaseClientProps
|
||||
|
||||
export type RelationshipFieldServerProps = ServerFieldBase<RelationshipField>
|
||||
|
||||
export type RelationshipFieldServerComponent = FieldServerComponent<RelationshipField>
|
||||
|
||||
export type RelationshipFieldClientComponent = FieldClientComponent<
|
||||
RelationshipFieldClientWithoutType,
|
||||
RelationshipFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type RelationshipFieldLabelServerComponent = FieldLabelServerComponent<RelationshipField>
|
||||
|
||||
|
||||
@@ -3,23 +3,44 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { RichTextField, RichTextFieldClient } from '../../fields/config/types.js'
|
||||
import type { RichTextFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RichTextFieldClientWithoutType = MarkOptional<RichTextFieldClient, 'type'>
|
||||
|
||||
export type RichTextFieldProps<
|
||||
type RichTextFieldBaseClientProps<
|
||||
TValue extends object = any,
|
||||
TAdapterProps = any,
|
||||
TExtraProperties = object,
|
||||
> = {
|
||||
readonly validate?: RichTextFieldValidation
|
||||
} & Omit<FormFieldBase<RichTextFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type RichTextFieldClientProps<
|
||||
TValue extends object = any,
|
||||
TAdapterProps = any,
|
||||
TExtraProperties = object,
|
||||
> = ClientFieldBase<RichTextFieldClientWithoutType> &
|
||||
RichTextFieldBaseClientProps<TValue, TAdapterProps, TExtraProperties>
|
||||
|
||||
export type RichTextFieldServerProps = ServerFieldBase<RichTextField>
|
||||
|
||||
export type RichTextFieldServerComponent = FieldServerComponent<RichTextField>
|
||||
|
||||
export type RichTextFieldClientComponent = FieldClientComponent<
|
||||
RichTextFieldClientWithoutType,
|
||||
RichTextFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type RichTextFieldLabelServerComponent = FieldLabelServerComponent<RichTextField>
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { RowField, RowFieldClient } from '../../fields/config/types.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
@@ -8,15 +14,26 @@ import type {
|
||||
FieldErrorServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RowFieldClientWithoutType = MarkOptional<RowFieldClient, 'type'>
|
||||
|
||||
export type RowFieldProps = {
|
||||
type RowFieldBaseClientProps = {
|
||||
readonly forceRender?: boolean
|
||||
readonly indexPath: string
|
||||
} & FormFieldBase<RowFieldClientWithoutType>
|
||||
}
|
||||
|
||||
export type RowFieldClientProps = ClientFieldBase<RowFieldClientWithoutType> &
|
||||
RowFieldBaseClientProps
|
||||
|
||||
export type RowFieldServerProps = ServerFieldBase<RowField>
|
||||
|
||||
export type RowFieldServerComponent = FieldServerComponent<RowField>
|
||||
|
||||
export type RowFieldClientComponent = FieldClientComponent<
|
||||
RowFieldClientWithoutType,
|
||||
RowFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type RowFieldLabelServerComponent = FieldLabelServerComponent<RowField>
|
||||
|
||||
|
||||
@@ -3,21 +3,38 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { SelectField, SelectFieldClient } from '../../fields/config/types.js'
|
||||
import type { SelectFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type SelectFieldClientWithoutType = MarkOptional<SelectFieldClient, 'type'>
|
||||
|
||||
export type SelectFieldProps = {
|
||||
type SelectFieldBaseClientProps = {
|
||||
readonly onChange?: (e: string | string[]) => void
|
||||
readonly validate?: SelectFieldValidation
|
||||
readonly value?: string
|
||||
} & Omit<FormFieldBase<SelectFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type SelectFieldClientProps = ClientFieldBase<SelectFieldClientWithoutType> &
|
||||
SelectFieldBaseClientProps
|
||||
|
||||
export type SelectFieldServerProps = ServerFieldBase<SelectField>
|
||||
|
||||
export type SelectFieldServerComponent = FieldServerComponent<SelectField>
|
||||
|
||||
export type SelectFieldClientComponent = FieldClientComponent<
|
||||
SelectFieldClientWithoutType,
|
||||
SelectFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type SelectFieldLabelServerComponent = FieldLabelServerComponent<SelectField>
|
||||
|
||||
|
||||
@@ -8,21 +8,32 @@ import type {
|
||||
UnnamedTab,
|
||||
} from '../../fields/config/types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
export type ClientTab =
|
||||
| ({ fields: ClientField[] } & Omit<NamedTab, 'fields'>)
|
||||
| ({ fields: ClientField[] } & Omit<UnnamedTab, 'fields'>)
|
||||
|
||||
export type TabsFieldClientWithoutType = MarkOptional<TabsFieldClient, 'type'>
|
||||
type TabsFieldClientWithoutType = MarkOptional<TabsFieldClient, 'type'>
|
||||
|
||||
export type TabsFieldProps = FormFieldBase<TabsFieldClientWithoutType>
|
||||
export type TabsFieldClientProps = ClientFieldBase<TabsFieldClientWithoutType>
|
||||
|
||||
export type TabsFieldServerProps = ServerFieldBase<TabsField>
|
||||
|
||||
export type TabsFieldServerComponent = FieldServerComponent<TabsField>
|
||||
|
||||
export type TabsFieldClientComponent = FieldClientComponent<TabsFieldClientWithoutType>
|
||||
|
||||
export type TabsFieldLabelServerComponent = FieldLabelServerComponent<TabsField>
|
||||
|
||||
|
||||
@@ -4,21 +4,38 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { TextField, TextFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type TextFieldClientWithoutType = MarkOptional<TextFieldClient, 'type'>
|
||||
|
||||
export type TextFieldProps = {
|
||||
type TextFieldBaseClientProps = {
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly validate?: TextFieldValidation
|
||||
} & Omit<FormFieldBase<TextFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type TextFieldClientProps = ClientFieldBase<TextFieldClientWithoutType> &
|
||||
TextFieldBaseClientProps
|
||||
|
||||
export type TextFieldServerProps = ServerFieldBase<TextField>
|
||||
|
||||
export type TextFieldServerComponent = FieldServerComponent<TextField>
|
||||
|
||||
export type TextFieldClientComponent = FieldClientComponent<
|
||||
TextFieldClientWithoutType,
|
||||
TextFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type TextFieldLabelServerComponent = FieldLabelServerComponent<TextField>
|
||||
|
||||
|
||||
@@ -4,21 +4,38 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { TextareaField, TextareaFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextareaFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type TextareaFieldClientWithoutType = MarkOptional<TextareaFieldClient, 'type'>
|
||||
|
||||
export type TextareaFieldProps = {
|
||||
type TextareaFieldBaseClientProps = {
|
||||
readonly inputRef?: React.Ref<HTMLInputElement>
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly validate?: TextareaFieldValidation
|
||||
} & Omit<FormFieldBase<TextareaFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type TextareaFieldClientProps = ClientFieldBase<TextareaFieldClientWithoutType> &
|
||||
TextareaFieldBaseClientProps
|
||||
|
||||
export type TextareaFieldServerProps = ServerFieldBase<TextareaField>
|
||||
|
||||
export type TextareaFieldServerComponent = FieldServerComponent<TextareaField>
|
||||
|
||||
export type TextareaFieldClientComponent = FieldClientComponent<
|
||||
TextareaFieldClientWithoutType,
|
||||
TextareaFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type TextareaFieldLabelServerComponent = FieldLabelServerComponent<TextareaField>
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type { UploadField, UploadFieldClient } from '../../fields/config/types.js'
|
||||
import type { UploadFieldValidation } from '../../fields/validations.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
ClientFieldBase,
|
||||
FieldClientComponent,
|
||||
FieldServerComponent,
|
||||
ServerFieldBase,
|
||||
} from '../forms/Field.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type UploadFieldClientWithoutType = MarkOptional<UploadFieldClient, 'type'>
|
||||
|
||||
export type UploadFieldProps = {
|
||||
type UploadFieldBaseClientProps = {
|
||||
readonly validate?: UploadFieldValidation
|
||||
} & Omit<FormFieldBase<UploadFieldClientWithoutType>, 'validate'>
|
||||
}
|
||||
|
||||
export type UploadFieldClientProps = ClientFieldBase<UploadFieldClientWithoutType> &
|
||||
UploadFieldBaseClientProps
|
||||
|
||||
export type UploadFieldServerProps = ServerFieldBase<UploadField>
|
||||
|
||||
export type UploadFieldServerComponent = FieldServerComponent<UploadField>
|
||||
|
||||
export type UploadFieldClientComponent = FieldClientComponent<
|
||||
UploadFieldClientWithoutType,
|
||||
UploadFieldBaseClientProps
|
||||
>
|
||||
|
||||
export type UploadFieldLabelServerComponent = FieldLabelServerComponent<UploadField>
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { LabelFunction, ServerProps } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
import type { ClientFieldWithOptionalType } from './Field.js'
|
||||
|
||||
export type DescriptionFunction = LabelFunction
|
||||
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldDescriptionClientComponent<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = React.ComponentType<FieldDescriptionClientProps<TFieldClient>>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { ServerProps } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
import type { ClientFieldWithOptionalType } from './Field.js'
|
||||
|
||||
export type GenericErrorProps = {
|
||||
readonly alignCaret?: 'center' | 'left' | 'right'
|
||||
@@ -12,8 +11,6 @@ export type GenericErrorProps = {
|
||||
readonly showError?: boolean
|
||||
}
|
||||
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldErrorClientProps<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
|
||||
@@ -2,24 +2,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { User } from '../../auth/types.js'
|
||||
import type { Locale } from '../../config/types.js'
|
||||
import type { ClientField, Validate } from '../../fields/config/types.js'
|
||||
import type { ClientField, Field, Validate } from '../../fields/config/types.js'
|
||||
import type { DocumentPreferences } from '../../preferences/types.js'
|
||||
import type { FieldDescriptionClientProps } from './Description.js'
|
||||
import type { FieldErrorClientProps } from './Error.js'
|
||||
import type { FieldLabelClientProps } from './Label.js'
|
||||
import type { FieldDescriptionClientProps, FieldDescriptionServerProps } from './Description.js'
|
||||
import type { FieldErrorClientProps, FieldErrorServerProps } from './Error.js'
|
||||
import type { FieldLabelClientProps, FieldLabelServerProps } from './Label.js'
|
||||
|
||||
export type FormFieldBase<
|
||||
TFieldClient extends MarkOptional<ClientField, 'type'> = MarkOptional<ClientField, 'type'>,
|
||||
export type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type ClientFieldBase<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
readonly descriptionProps?: FieldDescriptionClientProps<TFieldClient>
|
||||
readonly docPreferences?: DocumentPreferences
|
||||
readonly errorProps?: FieldErrorClientProps<TFieldClient>
|
||||
readonly field: TFieldClient
|
||||
readonly labelProps?: FieldLabelClientProps<TFieldClient>
|
||||
} & FormFieldBase
|
||||
|
||||
export type ServerFieldBase<TFieldServer extends Field = Field> = {
|
||||
readonly descriptionProps?: FieldDescriptionServerProps<TFieldServer>
|
||||
readonly errorProps?: FieldErrorServerProps<TFieldServer>
|
||||
readonly field: TFieldServer
|
||||
readonly labelProps?: FieldLabelServerProps<TFieldServer>
|
||||
} & FormFieldBase
|
||||
|
||||
export type FormFieldBase = {
|
||||
readonly docPreferences?: DocumentPreferences
|
||||
/**
|
||||
* `forceRender` is added by RenderField automatically.
|
||||
*/
|
||||
readonly forceRender?: boolean
|
||||
readonly labelProps?: FieldLabelClientProps<TFieldClient>
|
||||
readonly locale?: Locale
|
||||
/**
|
||||
* `readOnly` is added by RenderField automatically. This should be used instead of `field.admin.readOnly`.
|
||||
@@ -28,3 +40,13 @@ export type FormFieldBase<
|
||||
readonly user?: User
|
||||
readonly validate?: Validate
|
||||
}
|
||||
|
||||
export type FieldClientComponent<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
AdditionalProps extends Record<string, unknown> = Record<string, unknown>,
|
||||
> = React.ComponentType<AdditionalProps & ClientFieldBase<TFieldClient>>
|
||||
|
||||
export type FieldServerComponent<
|
||||
TFieldServer extends Field = Field,
|
||||
AdditionalProps extends Record<string, unknown> = Record<string, unknown>,
|
||||
> = React.ComponentType<AdditionalProps & ServerFieldBase<TFieldServer>>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { ServerProps, StaticLabel } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
import type { ClientFieldWithOptionalType } from './Field.js'
|
||||
|
||||
export type GenericLabelProps = {
|
||||
readonly as?: 'label' | 'span'
|
||||
@@ -13,8 +12,6 @@ export type GenericLabelProps = {
|
||||
readonly unstyled?: boolean
|
||||
}
|
||||
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldLabelClientProps<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
|
||||
@@ -24,13 +24,16 @@ export type {
|
||||
} from './elements/WithServerSideProps.js'
|
||||
|
||||
export type {
|
||||
ArrayFieldClientComponent,
|
||||
ArrayFieldClientProps,
|
||||
ArrayFieldDescriptionClientComponent,
|
||||
ArrayFieldDescriptionServerComponent,
|
||||
ArrayFieldErrorClientComponent,
|
||||
ArrayFieldErrorServerComponent,
|
||||
ArrayFieldLabelClientComponent,
|
||||
ArrayFieldLabelServerComponent,
|
||||
ArrayFieldProps,
|
||||
ArrayFieldServerComponent,
|
||||
ArrayFieldServerProps,
|
||||
} from './fields/Array.js'
|
||||
|
||||
export type {
|
||||
@@ -40,190 +43,247 @@ export type {
|
||||
BlockFieldErrorServerComponent,
|
||||
BlockFieldLabelClientComponent,
|
||||
BlockFieldLabelServerComponent,
|
||||
BlockFieldProps,
|
||||
BlocksFieldClientComponent,
|
||||
BlocksFieldClientProps,
|
||||
BlocksFieldServerComponent,
|
||||
BlocksFieldServerProps,
|
||||
} from './fields/Blocks.js'
|
||||
|
||||
export type {
|
||||
CheckboxFieldClientComponent,
|
||||
CheckboxFieldClientProps,
|
||||
CheckboxFieldDescriptionClientComponent,
|
||||
CheckboxFieldDescriptionServerComponent,
|
||||
CheckboxFieldErrorClientComponent,
|
||||
CheckboxFieldErrorServerComponent,
|
||||
CheckboxFieldLabelClientComponent,
|
||||
CheckboxFieldLabelServerComponent,
|
||||
CheckboxFieldProps,
|
||||
CheckboxFieldServerComponent,
|
||||
CheckboxFieldServerProps,
|
||||
} from './fields/Checkbox.js'
|
||||
|
||||
export type {
|
||||
CodeFieldClientComponent,
|
||||
CodeFieldClientProps,
|
||||
CodeFieldDescriptionClientComponent,
|
||||
CodeFieldDescriptionServerComponent,
|
||||
CodeFieldErrorClientComponent,
|
||||
CodeFieldErrorServerComponent,
|
||||
CodeFieldLabelClientComponent,
|
||||
CodeFieldLabelServerComponent,
|
||||
CodeFieldProps,
|
||||
CodeFieldServerComponent,
|
||||
CodeFieldServerProps,
|
||||
} from './fields/Code.js'
|
||||
|
||||
export type {
|
||||
CollapsibleFieldClientComponent,
|
||||
CollapsibleFieldClientProps,
|
||||
CollapsibleFieldDescriptionClientComponent,
|
||||
CollapsibleFieldDescriptionServerComponent,
|
||||
CollapsibleFieldErrorClientComponent,
|
||||
CollapsibleFieldErrorServerComponent,
|
||||
CollapsibleFieldLabelClientComponent,
|
||||
CollapsibleFieldLabelServerComponent,
|
||||
CollapsibleFieldProps,
|
||||
CollapsibleFieldServerComponent,
|
||||
CollapsibleFieldServerProps,
|
||||
} from './fields/Collapsible.js'
|
||||
|
||||
export type {
|
||||
DateFieldClientComponent,
|
||||
DateFieldClientProps,
|
||||
DateFieldDescriptionClientComponent,
|
||||
DateFieldDescriptionServerComponent,
|
||||
DateFieldErrorClientComponent,
|
||||
DateFieldErrorServerComponent,
|
||||
DateFieldLabelClientComponent,
|
||||
DateFieldLabelServerComponent,
|
||||
DateFieldProps,
|
||||
DateFieldServerComponent,
|
||||
DateFieldServerProps,
|
||||
} from './fields/Date.js'
|
||||
|
||||
export type {
|
||||
EmailFieldClientComponent,
|
||||
EmailFieldClientProps,
|
||||
EmailFieldDescriptionClientComponent,
|
||||
EmailFieldDescriptionServerComponent,
|
||||
EmailFieldErrorClientComponent,
|
||||
EmailFieldErrorServerComponent,
|
||||
EmailFieldLabelClientComponent,
|
||||
EmailFieldLabelServerComponent,
|
||||
EmailFieldProps,
|
||||
EmailFieldServerComponent,
|
||||
EmailFieldServerProps,
|
||||
} from './fields/Email.js'
|
||||
|
||||
export type {
|
||||
GroupFieldClientComponent,
|
||||
GroupFieldClientProps,
|
||||
GroupFieldDescriptionClientComponent,
|
||||
GroupFieldDescriptionServerComponent,
|
||||
GroupFieldErrorClientComponent,
|
||||
GroupFieldErrorServerComponent,
|
||||
GroupFieldLabelClientComponent,
|
||||
GroupFieldLabelServerComponent,
|
||||
GroupFieldProps,
|
||||
GroupFieldServerComponent,
|
||||
GroupFieldServerProps,
|
||||
} from './fields/Group.js'
|
||||
|
||||
export type { HiddenFieldProps } from './fields/Hidden.js'
|
||||
|
||||
export type {
|
||||
JSONFieldClientComponent,
|
||||
JSONFieldClientProps,
|
||||
JSONFieldDescriptionClientComponent,
|
||||
JSONFieldDescriptionServerComponent,
|
||||
JSONFieldErrorClientComponent,
|
||||
JSONFieldErrorServerComponent,
|
||||
JSONFieldLabelClientComponent,
|
||||
JSONFieldLabelServerComponent,
|
||||
JSONFieldProps,
|
||||
JSONFieldServerComponent,
|
||||
JSONFieldServerProps,
|
||||
} from './fields/JSON.js'
|
||||
|
||||
export type {
|
||||
NumberFieldClientComponent,
|
||||
NumberFieldClientProps,
|
||||
NumberFieldDescriptionClientComponent,
|
||||
NumberFieldDescriptionServerComponent,
|
||||
NumberFieldErrorClientComponent,
|
||||
NumberFieldErrorServerComponent,
|
||||
NumberFieldLabelClientComponent,
|
||||
NumberFieldLabelServerComponent,
|
||||
NumberFieldProps,
|
||||
NumberFieldServerComponent,
|
||||
NumberFieldServerProps,
|
||||
} from './fields/Number.js'
|
||||
|
||||
export type {
|
||||
PointFieldClientComponent,
|
||||
PointFieldClientProps,
|
||||
PointFieldDescriptionClientComponent,
|
||||
PointFieldDescriptionServerComponent,
|
||||
PointFieldErrorClientComponent,
|
||||
PointFieldErrorServerComponent,
|
||||
PointFieldLabelClientComponent,
|
||||
PointFieldLabelServerComponent,
|
||||
PointFieldProps,
|
||||
PointFieldServerComponent,
|
||||
PointFieldServerProps,
|
||||
} from './fields/Point.js'
|
||||
|
||||
export type {
|
||||
RadioFieldClientComponent,
|
||||
RadioFieldClientProps,
|
||||
RadioFieldDescriptionClientComponent,
|
||||
RadioFieldDescriptionServerComponent,
|
||||
RadioFieldErrorClientComponent,
|
||||
RadioFieldErrorServerComponent,
|
||||
RadioFieldLabelClientComponent,
|
||||
RadioFieldLabelServerComponent,
|
||||
RadioFieldProps,
|
||||
RadioFieldServerComponent,
|
||||
RadioFieldServerProps,
|
||||
} from './fields/Radio.js'
|
||||
|
||||
export type {
|
||||
RelationshipFieldClientComponent,
|
||||
RelationshipFieldClientProps,
|
||||
RelationshipFieldDescriptionClientComponent,
|
||||
RelationshipFieldDescriptionServerComponent,
|
||||
RelationshipFieldErrorClientComponent,
|
||||
RelationshipFieldErrorServerComponent,
|
||||
RelationshipFieldLabelClientComponent,
|
||||
RelationshipFieldLabelServerComponent,
|
||||
RelationshipFieldProps,
|
||||
RelationshipFieldServerComponent,
|
||||
RelationshipFieldServerProps,
|
||||
} from './fields/Relationship.js'
|
||||
|
||||
export type {
|
||||
RichTextFieldClientComponent,
|
||||
RichTextFieldClientProps,
|
||||
RichTextFieldDescriptionClientComponent,
|
||||
RichTextFieldDescriptionServerComponent,
|
||||
RichTextFieldErrorClientComponent,
|
||||
RichTextFieldErrorServerComponent,
|
||||
RichTextFieldLabelClientComponent,
|
||||
RichTextFieldLabelServerComponent,
|
||||
RichTextFieldProps,
|
||||
RichTextFieldServerComponent,
|
||||
RichTextFieldServerProps,
|
||||
} from './fields/RichText.js'
|
||||
|
||||
export type {
|
||||
RowFieldClientComponent,
|
||||
RowFieldClientProps,
|
||||
RowFieldDescriptionClientComponent,
|
||||
RowFieldDescriptionServerComponent,
|
||||
RowFieldErrorClientComponent,
|
||||
RowFieldErrorServerComponent,
|
||||
RowFieldLabelClientComponent,
|
||||
RowFieldLabelServerComponent,
|
||||
RowFieldProps,
|
||||
RowFieldServerComponent,
|
||||
RowFieldServerProps,
|
||||
} from './fields/Row.js'
|
||||
|
||||
export type {
|
||||
SelectFieldClientComponent,
|
||||
SelectFieldClientProps,
|
||||
SelectFieldDescriptionClientComponent,
|
||||
SelectFieldDescriptionServerComponent,
|
||||
SelectFieldErrorClientComponent,
|
||||
SelectFieldErrorServerComponent,
|
||||
SelectFieldLabelClientComponent,
|
||||
SelectFieldLabelServerComponent,
|
||||
SelectFieldProps,
|
||||
SelectFieldServerComponent,
|
||||
SelectFieldServerProps,
|
||||
} from './fields/Select.js'
|
||||
|
||||
export type {
|
||||
ClientTab,
|
||||
TabsFieldClientComponent,
|
||||
TabsFieldClientProps,
|
||||
TabsFieldDescriptionClientComponent,
|
||||
TabsFieldDescriptionServerComponent,
|
||||
TabsFieldErrorClientComponent,
|
||||
TabsFieldErrorServerComponent,
|
||||
TabsFieldLabelClientComponent,
|
||||
TabsFieldLabelServerComponent,
|
||||
TabsFieldProps,
|
||||
TabsFieldServerComponent,
|
||||
TabsFieldServerProps,
|
||||
} from './fields/Tabs.js'
|
||||
|
||||
export type {
|
||||
TextFieldClientComponent,
|
||||
TextFieldClientProps,
|
||||
TextFieldDescriptionClientComponent,
|
||||
TextFieldDescriptionServerComponent,
|
||||
TextFieldErrorClientComponent,
|
||||
TextFieldErrorServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
TextFieldLabelServerComponent,
|
||||
TextFieldProps,
|
||||
TextFieldServerComponent,
|
||||
TextFieldServerProps,
|
||||
} from './fields/Text.js'
|
||||
|
||||
export type {
|
||||
TextareaFieldClientComponent,
|
||||
TextareaFieldClientProps,
|
||||
TextareaFieldDescriptionClientComponent,
|
||||
TextareaFieldDescriptionServerComponent,
|
||||
TextareaFieldErrorClientComponent,
|
||||
TextareaFieldErrorServerComponent,
|
||||
TextareaFieldLabelClientComponent,
|
||||
TextareaFieldLabelServerComponent,
|
||||
TextareaFieldProps,
|
||||
TextareaFieldServerComponent,
|
||||
TextareaFieldServerProps,
|
||||
} from './fields/Textarea.js'
|
||||
|
||||
export type {
|
||||
UploadFieldClientComponent,
|
||||
UploadFieldClientProps,
|
||||
UploadFieldDescriptionClientComponent,
|
||||
UploadFieldDescriptionServerComponent,
|
||||
UploadFieldErrorClientComponent,
|
||||
UploadFieldErrorServerComponent,
|
||||
UploadFieldLabelClientComponent,
|
||||
UploadFieldLabelServerComponent,
|
||||
UploadFieldProps,
|
||||
UploadFieldServerComponent,
|
||||
UploadFieldServerProps,
|
||||
} from './fields/Upload.js'
|
||||
|
||||
export type {
|
||||
|
||||
@@ -2,8 +2,6 @@ import type { TypedUser } from '../../index.js'
|
||||
import type { PayloadRequest } from '../../types/index.js'
|
||||
import type { Permissions } from '../types.js'
|
||||
|
||||
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
||||
import { initTransaction } from '../../utilities/initTransaction.js'
|
||||
import { killTransaction } from '../../utilities/killTransaction.js'
|
||||
import { executeAuthStrategies } from '../executeAuthStrategies.js'
|
||||
import { getAccessResults } from '../getAccessResults.js'
|
||||
@@ -25,8 +23,6 @@ export const auth = async (args: Required<AuthArgs>): Promise<AuthResult> => {
|
||||
const { payload } = req
|
||||
|
||||
try {
|
||||
const shouldCommit = await initTransaction(req)
|
||||
|
||||
const { responseHeaders, user } = await executeAuthStrategies({
|
||||
headers,
|
||||
payload,
|
||||
@@ -39,10 +35,6 @@ export const auth = async (args: Required<AuthArgs>): Promise<AuthResult> => {
|
||||
req,
|
||||
})
|
||||
|
||||
if (shouldCommit) {
|
||||
await commitTransaction(req)
|
||||
}
|
||||
|
||||
return {
|
||||
permissions,
|
||||
responseHeaders,
|
||||
|
||||
@@ -12,8 +12,6 @@ import type { User } from '../types.js'
|
||||
import { buildAfterOperation } from '../../collections/operations/utils.js'
|
||||
import { AuthenticationError, LockedAuth, ValidationError } from '../../errors/index.js'
|
||||
import { afterRead } from '../../fields/hooks/afterRead/index.js'
|
||||
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
||||
import { initTransaction } from '../../utilities/initTransaction.js'
|
||||
import { killTransaction } from '../../utilities/killTransaction.js'
|
||||
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields.js'
|
||||
import { getFieldsToSign } from '../getFieldsToSign.js'
|
||||
@@ -43,8 +41,6 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
let args = incomingArgs
|
||||
|
||||
try {
|
||||
const shouldCommit = await initTransaction(args.req)
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeOperation - Collection
|
||||
// /////////////////////////////////////
|
||||
@@ -202,10 +198,6 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
})
|
||||
}
|
||||
|
||||
if (shouldCommit) {
|
||||
await commitTransaction(req)
|
||||
}
|
||||
|
||||
throw new AuthenticationError(req.t)
|
||||
}
|
||||
|
||||
@@ -334,10 +326,6 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
|
||||
// Return results
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (shouldCommit) {
|
||||
await commitTransaction(req)
|
||||
}
|
||||
|
||||
return result
|
||||
} catch (error: unknown) {
|
||||
await killTransaction(args.req)
|
||||
|
||||
@@ -132,24 +132,70 @@ export type LoginWithUsernameOptions =
|
||||
}
|
||||
|
||||
export interface IncomingAuthType {
|
||||
/**
|
||||
* Set cookie options, including secure, sameSite, and domain. For advanced users.
|
||||
*/
|
||||
cookies?: {
|
||||
domain?: string
|
||||
sameSite?: 'Lax' | 'None' | 'Strict' | boolean
|
||||
secure?: boolean
|
||||
}
|
||||
/**
|
||||
* How many levels deep a user document should be populated when creating the JWT and binding the user to the req. Defaults to 0 and should only be modified if absolutely necessary, as this will affect performance.
|
||||
* @default 0
|
||||
*/
|
||||
depth?: number
|
||||
/**
|
||||
* Advanced - disable Payload's built-in local auth strategy. Only use this property if you have replaced Payload's auth mechanisms with your own.
|
||||
*/
|
||||
disableLocalStrategy?: true
|
||||
/**
|
||||
* Customize the way that the forgotPassword operation functions.
|
||||
* @link https://payloadcms.com/docs/beta/authentication/email#forgot-password
|
||||
*/
|
||||
forgotPassword?: {
|
||||
generateEmailHTML?: GenerateForgotPasswordEmailHTML
|
||||
generateEmailSubject?: GenerateForgotPasswordEmailSubject
|
||||
}
|
||||
/**
|
||||
* Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than maxLoginAttempts allows for.
|
||||
*/
|
||||
lockTime?: number
|
||||
/**
|
||||
* Ability to allow users to login with username/password.
|
||||
*
|
||||
* @link https://payloadcms.com/docs/beta/authentication/overview#login-with-username
|
||||
*/
|
||||
loginWithUsername?: boolean | LoginWithUsernameOptions
|
||||
/**
|
||||
* Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to 0 to disable.
|
||||
*/
|
||||
maxLoginAttempts?: number
|
||||
/***
|
||||
* Set to true if you want to remove the token from the returned authentication API responses such as login or refresh.
|
||||
*/
|
||||
removeTokenFromResponses?: true
|
||||
/**
|
||||
* Advanced - an array of custom authentification strategies to extend this collection's authentication with.
|
||||
* @link https://payloadcms.com/docs/beta/authentication/custom-strategies
|
||||
*/
|
||||
strategies?: AuthStrategy[]
|
||||
/**
|
||||
* Controls how many seconds the token will be valid for. Default is 2 hours.
|
||||
* @default 7200
|
||||
* @link https://payloadcms.com/docs/beta/authentication/overview#config-options
|
||||
*/
|
||||
tokenExpiration?: number
|
||||
/**
|
||||
* Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection.
|
||||
* @default false
|
||||
* @link https://payloadcms.com/docs/beta/authentication/api-keys
|
||||
*/
|
||||
useAPIKey?: boolean
|
||||
/**
|
||||
* Set to true or pass an object with verification options to require users to verify by email before they are allowed to log into your app.
|
||||
* @link https://payloadcms.com/docs/beta/authentication/email#email-verification
|
||||
*/
|
||||
verify?:
|
||||
| {
|
||||
generateEmailHTML?: GenerateVerifyEmailHTML
|
||||
|
||||
@@ -14,6 +14,7 @@ import baseVersionFields from '../../versions/baseFields.js'
|
||||
import { versionDefaults } from '../../versions/defaults.js'
|
||||
import { authDefaults, defaults, loginWithUsernameDefaults } from './defaults.js'
|
||||
import { sanitizeAuthFields, sanitizeUploadFields } from './reservedFieldNames.js'
|
||||
import { validateUseAsTitle } from './useAsTitle.js'
|
||||
|
||||
export const sanitizeCollection = async (
|
||||
config: Config,
|
||||
@@ -44,6 +45,8 @@ export const sanitizeCollection = async (
|
||||
validRelationships,
|
||||
})
|
||||
|
||||
validateUseAsTitle(sanitized)
|
||||
|
||||
if (sanitized.timestamps !== false) {
|
||||
// add default timestamps fields only as needed
|
||||
let hasUpdatedAt = null
|
||||
|
||||
204
packages/payload/src/collections/config/useAsTitle.spec.ts
Normal file
204
packages/payload/src/collections/config/useAsTitle.spec.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
import type { Config } from '../../config/types.js'
|
||||
import type { CollectionConfig } from '../../index.js'
|
||||
|
||||
import { InvalidConfiguration } from '../../errors/InvalidConfiguration.js'
|
||||
import { sanitizeCollection } from './sanitize.js'
|
||||
|
||||
describe('sanitize - collections -', () => {
|
||||
const config = {
|
||||
collections: [],
|
||||
globals: [],
|
||||
} as Partial<Config>
|
||||
|
||||
describe('validate useAsTitle -', () => {
|
||||
const defaultCollection: CollectionConfig = {
|
||||
slug: 'collection-with-defaults',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
it('should throw on invalid field', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'invalidField',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).rejects.toThrow(InvalidConfiguration)
|
||||
})
|
||||
|
||||
it('should not throw on valid field', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it('should not throw on valid field inside tabs', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
label: 'General',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it('should not throw on valid field inside collapsibles', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
type: 'collapsible',
|
||||
label: 'Collapsible',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it('should throw on nested useAsTitle', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'content.title',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).rejects.toThrow(InvalidConfiguration)
|
||||
})
|
||||
|
||||
it('should not throw on default field: id', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'id',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it('should not throw on default field: email if auth is enabled', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
auth: true,
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).not.toThrow()
|
||||
})
|
||||
it('should throw on default field: email if auth is not enabled', async () => {
|
||||
const collectionConfig: CollectionConfig = {
|
||||
...defaultCollection,
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
}
|
||||
await expect(async () => {
|
||||
await sanitizeCollection(
|
||||
// @ts-expect-error
|
||||
{
|
||||
...config,
|
||||
collections: [collectionConfig],
|
||||
},
|
||||
collectionConfig,
|
||||
)
|
||||
}).rejects.toThrow(InvalidConfiguration)
|
||||
})
|
||||
})
|
||||
})
|
||||
43
packages/payload/src/collections/config/useAsTitle.ts
Normal file
43
packages/payload/src/collections/config/useAsTitle.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { CollectionConfig } from '../../index.js'
|
||||
|
||||
import { InvalidConfiguration } from '../../errors/InvalidConfiguration.js'
|
||||
import { fieldAffectsData } from '../../fields/config/types.js'
|
||||
import flattenFields from '../../utilities/flattenTopLevelFields.js'
|
||||
|
||||
/**
|
||||
* Validate useAsTitle for collections.
|
||||
*/
|
||||
export const validateUseAsTitle = (config: CollectionConfig) => {
|
||||
if (config.admin.useAsTitle.includes('.')) {
|
||||
throw new InvalidConfiguration(
|
||||
`"useAsTitle" cannot be a nested field. Please specify a top-level field in the collection "${config.slug}"`,
|
||||
)
|
||||
}
|
||||
|
||||
if (config?.admin && config.admin?.useAsTitle && config.admin.useAsTitle !== 'id') {
|
||||
const fields = flattenFields(config.fields)
|
||||
const useAsTitleField = fields.find((field) => {
|
||||
if (fieldAffectsData(field) && config.admin) {
|
||||
return field.name === config.admin.useAsTitle
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// If auth is enabled then we don't need to
|
||||
if (config.auth) {
|
||||
if (config.admin.useAsTitle !== 'email') {
|
||||
if (!useAsTitleField) {
|
||||
throw new InvalidConfiguration(
|
||||
`The field "${config.admin.useAsTitle}" specified in "admin.useAsTitle" does not exist in the collection "${config.slug}"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!useAsTitleField) {
|
||||
throw new InvalidConfiguration(
|
||||
`The field "${config.admin.useAsTitle}" specified in "admin.useAsTitle" does not exist in the collection "${config.slug}"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,8 +136,8 @@ const batchAndLoadDocs =
|
||||
depth,
|
||||
docID: doc.id,
|
||||
draft,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
locale: req.locale,
|
||||
fallbackLocale,
|
||||
locale,
|
||||
overrideAccess,
|
||||
showHiddenFields,
|
||||
transactionID: req.transactionID,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import ObjectIdImport from 'bson-objectid'
|
||||
|
||||
import type { FieldHook } from '../config/types.js'
|
||||
|
||||
const ObjectId = (ObjectIdImport.default ||
|
||||
ObjectIdImport) as unknown as typeof ObjectIdImport.default
|
||||
/**
|
||||
* Arrays and Blocks need to clear ids beforeDuplicate
|
||||
*/
|
||||
export const baseBeforeDuplicateArrays: FieldHook = ({ value }) => {
|
||||
if (value) {
|
||||
value = value.map((item) => {
|
||||
item.id = new ObjectId().toHexString()
|
||||
return item
|
||||
})
|
||||
return value
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from '../../errors/index.js'
|
||||
import { MissingEditorProp } from '../../errors/MissingEditorProp.js'
|
||||
import { formatLabels, toWords } from '../../utilities/formatLabels.js'
|
||||
import { baseBeforeDuplicateArrays } from '../baseFields/baseBeforeDuplicateArrays.js'
|
||||
import { baseBlockFields } from '../baseFields/baseBlockFields.js'
|
||||
import { baseIDField } from '../baseFields/baseIDField.js'
|
||||
import { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'
|
||||
@@ -130,6 +131,15 @@ export const sanitizeFields = async ({
|
||||
|
||||
if (field.type === 'array' && field.fields) {
|
||||
field.fields.push(baseIDField)
|
||||
if (field.localized) {
|
||||
if (!field.hooks) {
|
||||
field.hooks = {}
|
||||
}
|
||||
if (!field.hooks.beforeDuplicate) {
|
||||
field.hooks.beforeDuplicate = []
|
||||
}
|
||||
field.hooks.beforeDuplicate.push(baseBeforeDuplicateArrays)
|
||||
}
|
||||
}
|
||||
|
||||
if ((field.type === 'blocks' || field.type === 'array') && field.label) {
|
||||
@@ -210,6 +220,15 @@ export const sanitizeFields = async ({
|
||||
}
|
||||
|
||||
if (field.type === 'blocks' && field.blocks) {
|
||||
if (field.localized) {
|
||||
if (!field.hooks) {
|
||||
field.hooks = {}
|
||||
}
|
||||
if (!field.hooks.beforeDuplicate) {
|
||||
field.hooks.beforeDuplicate = []
|
||||
}
|
||||
field.hooks.beforeDuplicate.push(baseBeforeDuplicateArrays)
|
||||
}
|
||||
for (const block of field.blocks) {
|
||||
if (block._sanitized === true) {
|
||||
continue
|
||||
|
||||
@@ -7,92 +7,92 @@ import type { DeepUndefinable } from 'ts-essentials'
|
||||
|
||||
import type { RichTextAdapter, RichTextAdapterProvider } from '../../admin/RichText.js'
|
||||
import type {
|
||||
ArrayFieldClientProps,
|
||||
ArrayFieldErrorClientComponent,
|
||||
ArrayFieldErrorServerComponent,
|
||||
ArrayFieldLabelClientComponent,
|
||||
ArrayFieldLabelServerComponent,
|
||||
ArrayFieldProps,
|
||||
BlockFieldErrorClientComponent,
|
||||
BlockFieldErrorServerComponent,
|
||||
BlockFieldProps,
|
||||
BlocksFieldClientProps,
|
||||
CheckboxFieldClientProps,
|
||||
CheckboxFieldErrorClientComponent,
|
||||
CheckboxFieldErrorServerComponent,
|
||||
CheckboxFieldLabelClientComponent,
|
||||
CheckboxFieldLabelServerComponent,
|
||||
CheckboxFieldProps,
|
||||
ClientTab,
|
||||
CodeFieldClientProps,
|
||||
CodeFieldErrorClientComponent,
|
||||
CodeFieldErrorServerComponent,
|
||||
CodeFieldLabelClientComponent,
|
||||
CodeFieldLabelServerComponent,
|
||||
CodeFieldProps,
|
||||
CollapsibleFieldClientProps,
|
||||
CollapsibleFieldLabelClientComponent,
|
||||
CollapsibleFieldLabelServerComponent,
|
||||
CollapsibleFieldProps,
|
||||
ConditionalDateProps,
|
||||
DateFieldClientProps,
|
||||
DateFieldErrorClientComponent,
|
||||
DateFieldErrorServerComponent,
|
||||
DateFieldLabelClientComponent,
|
||||
DateFieldLabelServerComponent,
|
||||
DateFieldProps,
|
||||
Description,
|
||||
EmailFieldClientProps,
|
||||
EmailFieldErrorClientComponent,
|
||||
EmailFieldErrorServerComponent,
|
||||
EmailFieldLabelClientComponent,
|
||||
EmailFieldLabelServerComponent,
|
||||
EmailFieldProps,
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
GroupFieldClientProps,
|
||||
GroupFieldLabelClientComponent,
|
||||
GroupFieldLabelServerComponent,
|
||||
GroupFieldProps,
|
||||
HiddenFieldProps,
|
||||
JSONFieldClientProps,
|
||||
JSONFieldErrorClientComponent,
|
||||
JSONFieldErrorServerComponent,
|
||||
JSONFieldLabelClientComponent,
|
||||
JSONFieldLabelServerComponent,
|
||||
JSONFieldProps,
|
||||
MappedComponent,
|
||||
NumberFieldClientProps,
|
||||
NumberFieldErrorClientComponent,
|
||||
NumberFieldErrorServerComponent,
|
||||
NumberFieldLabelClientComponent,
|
||||
NumberFieldLabelServerComponent,
|
||||
NumberFieldProps,
|
||||
PointFieldClientProps,
|
||||
PointFieldErrorClientComponent,
|
||||
PointFieldErrorServerComponent,
|
||||
PointFieldLabelClientComponent,
|
||||
PointFieldLabelServerComponent,
|
||||
PointFieldProps,
|
||||
RadioFieldClientProps,
|
||||
RadioFieldErrorClientComponent,
|
||||
RadioFieldErrorServerComponent,
|
||||
RadioFieldLabelClientComponent,
|
||||
RadioFieldLabelServerComponent,
|
||||
RadioFieldProps,
|
||||
RelationshipFieldClientProps,
|
||||
RelationshipFieldErrorClientComponent,
|
||||
RelationshipFieldErrorServerComponent,
|
||||
RelationshipFieldLabelClientComponent,
|
||||
RelationshipFieldLabelServerComponent,
|
||||
RelationshipFieldProps,
|
||||
RichTextFieldProps,
|
||||
RowFieldProps,
|
||||
RichTextFieldClientProps,
|
||||
RowFieldClientProps,
|
||||
RowLabelComponent,
|
||||
SelectFieldClientProps,
|
||||
SelectFieldErrorClientComponent,
|
||||
SelectFieldErrorServerComponent,
|
||||
SelectFieldLabelClientComponent,
|
||||
SelectFieldLabelServerComponent,
|
||||
SelectFieldProps,
|
||||
StaticDescription,
|
||||
TabsFieldProps,
|
||||
TabsFieldClientProps,
|
||||
TextareaFieldClientProps,
|
||||
TextareaFieldErrorClientComponent,
|
||||
TextareaFieldErrorServerComponent,
|
||||
TextareaFieldLabelClientComponent,
|
||||
TextareaFieldLabelServerComponent,
|
||||
TextareaFieldProps,
|
||||
TextFieldErrorClientComponent,
|
||||
TextFieldErrorServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
TextFieldLabelServerComponent,
|
||||
UploadFieldProps,
|
||||
UploadFieldClientProps,
|
||||
} from '../../admin/types.js'
|
||||
import type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js'
|
||||
import type {
|
||||
@@ -1425,26 +1425,26 @@ export type ClientField =
|
||||
| UploadFieldClient
|
||||
|
||||
export type ClientFieldProps =
|
||||
| ArrayFieldProps
|
||||
| BlockFieldProps
|
||||
| CheckboxFieldProps
|
||||
| CodeFieldProps
|
||||
| CollapsibleFieldProps
|
||||
| DateFieldProps
|
||||
| EmailFieldProps
|
||||
| GroupFieldProps
|
||||
| ArrayFieldClientProps
|
||||
| BlocksFieldClientProps
|
||||
| CheckboxFieldClientProps
|
||||
| CodeFieldClientProps
|
||||
| CollapsibleFieldClientProps
|
||||
| DateFieldClientProps
|
||||
| EmailFieldClientProps
|
||||
| GroupFieldClientProps
|
||||
| HiddenFieldProps
|
||||
| JSONFieldProps
|
||||
| NumberFieldProps
|
||||
| PointFieldProps
|
||||
| RadioFieldProps
|
||||
| RelationshipFieldProps
|
||||
| RichTextFieldProps
|
||||
| RowFieldProps
|
||||
| SelectFieldProps
|
||||
| TabsFieldProps
|
||||
| TextareaFieldProps
|
||||
| UploadFieldProps
|
||||
| JSONFieldClientProps
|
||||
| NumberFieldClientProps
|
||||
| PointFieldClientProps
|
||||
| RadioFieldClientProps
|
||||
| RelationshipFieldClientProps
|
||||
| RichTextFieldClientProps
|
||||
| RowFieldClientProps
|
||||
| SelectFieldClientProps
|
||||
| TabsFieldClientProps
|
||||
| TextareaFieldClientProps
|
||||
| UploadFieldClientProps
|
||||
|
||||
type ExtractFieldTypes<T> = T extends { type: infer U } ? U : never
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import type { Document, Where } from '../../types/index.js'
|
||||
import type { PreferenceRequest } from '../types.js'
|
||||
|
||||
import defaultAccess from '../../auth/defaultAccess.js'
|
||||
import executeAccess from '../../auth/executeAccess.js'
|
||||
import { NotFound } from '../../errors/NotFound.js'
|
||||
import { UnauthorizedError } from '../../errors/UnathorizedError.js'
|
||||
|
||||
async function deleteOperation(args: PreferenceRequest): Promise<Document> {
|
||||
export async function deleteOperation(args: PreferenceRequest): Promise<Document> {
|
||||
const {
|
||||
key,
|
||||
overrideAccess,
|
||||
req: { payload },
|
||||
req,
|
||||
user,
|
||||
@@ -19,10 +16,6 @@ async function deleteOperation(args: PreferenceRequest): Promise<Document> {
|
||||
throw new UnauthorizedError(req.t)
|
||||
}
|
||||
|
||||
if (!overrideAccess) {
|
||||
await executeAccess({ req }, defaultAccess)
|
||||
}
|
||||
|
||||
const where: Where = {
|
||||
and: [
|
||||
{ key: { equals: key } },
|
||||
@@ -42,5 +35,3 @@ async function deleteOperation(args: PreferenceRequest): Promise<Document> {
|
||||
}
|
||||
throw new NotFound(req.t)
|
||||
}
|
||||
|
||||
export default deleteOperation
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { TypedCollection } from '../../index.js'
|
||||
import type { Where } from '../../types/index.js'
|
||||
import type { PreferenceRequest } from '../types.js'
|
||||
|
||||
async function findOne(args: PreferenceRequest): Promise<TypedCollection['_preference']> {
|
||||
export async function findOne(args: PreferenceRequest): Promise<TypedCollection['_preference']> {
|
||||
const {
|
||||
key,
|
||||
req: { payload },
|
||||
@@ -22,11 +22,14 @@ async function findOne(args: PreferenceRequest): Promise<TypedCollection['_prefe
|
||||
],
|
||||
}
|
||||
|
||||
return await payload.db.findOne({
|
||||
const { docs } = await payload.db.find({
|
||||
collection: 'payload-preferences',
|
||||
limit: 1,
|
||||
pagination: false,
|
||||
req,
|
||||
sort: '-updatedAt',
|
||||
where,
|
||||
})
|
||||
}
|
||||
|
||||
export default findOne
|
||||
return docs?.[0] || null
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import type { Where } from '../../types/index.js'
|
||||
import type { PreferenceUpdateRequest } from '../types.js'
|
||||
|
||||
import defaultAccess from '../../auth/defaultAccess.js'
|
||||
import executeAccess from '../../auth/executeAccess.js'
|
||||
import { UnauthorizedError } from '../../errors/UnathorizedError.js'
|
||||
|
||||
async function update(args: PreferenceUpdateRequest) {
|
||||
export async function update(args: PreferenceUpdateRequest) {
|
||||
const {
|
||||
key,
|
||||
overrideAccess,
|
||||
req: { payload },
|
||||
req,
|
||||
user,
|
||||
@@ -20,10 +18,12 @@ async function update(args: PreferenceUpdateRequest) {
|
||||
|
||||
const collection = 'payload-preferences'
|
||||
|
||||
const filter = {
|
||||
key: { equals: key },
|
||||
'user.relationTo': { equals: user.collection },
|
||||
'user.value': { equals: user.id },
|
||||
const where: Where = {
|
||||
and: [
|
||||
{ key: { equals: key } },
|
||||
{ 'user.value': { equals: user.id } },
|
||||
{ 'user.relationTo': { equals: user.collection } },
|
||||
],
|
||||
}
|
||||
|
||||
const preference = {
|
||||
@@ -35,27 +35,23 @@ async function update(args: PreferenceUpdateRequest) {
|
||||
value,
|
||||
}
|
||||
|
||||
if (!overrideAccess) {
|
||||
await executeAccess({ req }, defaultAccess)
|
||||
}
|
||||
let result
|
||||
|
||||
try {
|
||||
// try/catch because we attempt to update without first reading to check if it exists first to save on db calls
|
||||
await payload.db.updateOne({
|
||||
result = await payload.db.updateOne({
|
||||
collection,
|
||||
data: preference,
|
||||
req,
|
||||
where: filter,
|
||||
where,
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
await payload.db.create({
|
||||
result = await payload.db.create({
|
||||
collection,
|
||||
data: preference,
|
||||
req,
|
||||
})
|
||||
}
|
||||
|
||||
return preference
|
||||
return result
|
||||
}
|
||||
|
||||
export default update
|
||||
|
||||
@@ -3,7 +3,7 @@ import httpStatus from 'http-status'
|
||||
import type { PayloadHandler } from '../../config/types.js'
|
||||
import type { PayloadRequest } from '../../types/index.js'
|
||||
|
||||
import deleteOperation from '../operations/delete.js'
|
||||
import { deleteOperation } from '../operations/delete.js'
|
||||
|
||||
export const deleteHandler: PayloadHandler = async (incomingReq): Promise<Response> => {
|
||||
// We cannot import the addDataAndFileToRequest utility here from the 'next' package because of dependency issues
|
||||
|
||||
@@ -3,7 +3,7 @@ import httpStatus from 'http-status'
|
||||
import type { PayloadHandler } from '../../config/types.js'
|
||||
import type { PayloadRequest } from '../../types/index.js'
|
||||
|
||||
import findOne from '../operations/findOne.js'
|
||||
import { findOne } from '../operations/findOne.js'
|
||||
|
||||
export const findByIDHandler: PayloadHandler = async (incomingReq): Promise<Response> => {
|
||||
// We cannot import the addDataAndFileToRequest utility here from the 'next' package because of dependency issues
|
||||
|
||||
@@ -3,7 +3,7 @@ import httpStatus from 'http-status'
|
||||
import type { PayloadHandler } from '../../config/types.js'
|
||||
import type { PayloadRequest } from '../../types/index.js'
|
||||
|
||||
import update from '../operations/update.js'
|
||||
import { update } from '../operations/update.js'
|
||||
|
||||
export const updateHandler: PayloadHandler = async (incomingReq) => {
|
||||
// We cannot import the addDataAndFileToRequest utility here from the 'next' package because of dependency issues
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { SelectFieldProps, SelectFieldValidation } from 'payload'
|
||||
import type { SelectFieldClientProps, SelectFieldValidation } from 'payload'
|
||||
|
||||
import { SelectField, useForm } from '@payloadcms/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
@@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'
|
||||
import type { SelectFieldOption } from '../../types.js'
|
||||
|
||||
export const DynamicFieldSelector: React.FC<
|
||||
{ validate: SelectFieldValidation } & SelectFieldProps
|
||||
{ validate: SelectFieldValidation } & SelectFieldClientProps
|
||||
> = (props) => {
|
||||
const { fields, getDataByPath } = useForm()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { Data, TextFieldProps } from 'payload'
|
||||
import type { Data, TextFieldClientComponent } from 'payload'
|
||||
|
||||
import { TextField, useLocale, useWatchForm } from '@payloadcms/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
@@ -10,7 +10,7 @@ type FieldWithID = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export const DynamicPriceSelector: React.FC<TextFieldProps> = (props) => {
|
||||
export const DynamicPriceSelector: TextFieldClientComponent = (props) => {
|
||||
const { field } = props
|
||||
|
||||
const { fields, getData, getDataByPath } = useWatchForm()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"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.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Redirects plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-relationship-object-ids",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "A Payload plugin to store all relationship IDs as ObjectIDs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-search",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "Search plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-seo",
|
||||
"version": "3.0.0-beta.98",
|
||||
"version": "3.0.0-beta.102",
|
||||
"description": "SEO plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import type { FieldType, Options } from '@payloadcms/ui'
|
||||
import type { TextareaFieldProps } from 'payload'
|
||||
import type { TextareaFieldClientProps } from 'payload'
|
||||
|
||||
import {
|
||||
FieldLabel,
|
||||
@@ -25,7 +25,7 @@ const { maxLength, minLength } = defaults.description
|
||||
|
||||
type MetaDescriptionProps = {
|
||||
readonly hasGenerateDescriptionFn: boolean
|
||||
} & TextareaFieldProps
|
||||
} & TextareaFieldClientProps
|
||||
|
||||
export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props) => {
|
||||
const {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import type { FieldType, Options } from '@payloadcms/ui'
|
||||
import type { UploadFieldProps } from 'payload'
|
||||
import type { UploadFieldClientProps } from 'payload'
|
||||
|
||||
import {
|
||||
FieldLabel,
|
||||
@@ -23,7 +23,7 @@ import { Pill } from '../../ui/Pill.js'
|
||||
|
||||
type MetaImageProps = {
|
||||
readonly hasGenerateImageFn: boolean
|
||||
} & UploadFieldProps
|
||||
} & UploadFieldClientProps
|
||||
|
||||
export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
const {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user