Compare commits
9 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46924f6745 | ||
|
|
1cf7d4db32 | ||
|
|
f39701401e | ||
|
|
b6d85f6efc | ||
|
|
187813ef63 | ||
|
|
ad5e8444ba | ||
|
|
16c1d949cd | ||
|
|
6a3386c3a0 | ||
|
|
674ef3dc9c |
@@ -218,7 +218,7 @@ export default buildConfig({
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
pnpm add @paylaodcms/storage-uploadthing
|
||||
pnpm add @payloadcms/storage-uploadthing
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -130,7 +130,7 @@
|
||||
"lint-staged": "^14.0.1",
|
||||
"minimist": "1.2.8",
|
||||
"mongodb-memory-server": "^9.0",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"open": "^10.1.0",
|
||||
"p-limit": "^5.0.0",
|
||||
"pino": "8.15.0",
|
||||
@@ -152,7 +152,7 @@
|
||||
"ts-node": "10.9.1",
|
||||
"tsx": "^4.7.1",
|
||||
"turbo": "^1.13.3",
|
||||
"typescript": "5.5.2",
|
||||
"typescript": "5.5.3",
|
||||
"uuid": "10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -66,7 +66,6 @@
|
||||
"@types/esprima": "^4.0.6",
|
||||
"@types/fs-extra": "^9.0.12",
|
||||
"@types/jest": "29.5.12",
|
||||
"@types/node": "20.12.5",
|
||||
"temp-dir": "2.0.0"
|
||||
"@types/node": "20.12.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import { dbReplacements } from './replacements.js'
|
||||
import { getValidTemplates } from './templates.js'
|
||||
import globby from 'globby'
|
||||
import { jest } from '@jest/globals'
|
||||
|
||||
import tempDirectory from 'temp-dir'
|
||||
import fs from 'fs'
|
||||
import * as os from 'node:os'
|
||||
|
||||
describe('createProject', () => {
|
||||
let projectDir: string
|
||||
@@ -16,6 +16,7 @@ describe('createProject', () => {
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
const tempDirectory = fs.realpathSync(os.tmpdir())
|
||||
projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -2,7 +2,7 @@ const baseRules = {
|
||||
// This rule makes no sense when overriding class methods. This is used a lot in richtext-lexical.
|
||||
'class-methods-use-this': 'off',
|
||||
'arrow-body-style': 0,
|
||||
'import/prefer-default-export': 'off',
|
||||
'import-x/prefer-default-export': 'off',
|
||||
'no-restricted-exports': ['warn', { restrictDefaultExports: { direct: true } }],
|
||||
'no-console': 'warn',
|
||||
'no-sparse-arrays': 'off',
|
||||
@@ -10,7 +10,7 @@ const baseRules = {
|
||||
'no-use-before-define': 'off',
|
||||
'object-shorthand': 'warn',
|
||||
'no-useless-escape': 'warn',
|
||||
'import/no-duplicates': 'warn',
|
||||
'import-x/no-duplicates': 'warn',
|
||||
'perfectionist/sort-objects': [
|
||||
'error',
|
||||
{
|
||||
@@ -124,7 +124,7 @@ module.exports = {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['import'], // Plugins are defined in the overrides to be more specific and only target the files they are meant for.
|
||||
plugins: ['import-x'], // Plugins are defined in the overrides to be more specific and only target the files they are meant for.
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
@@ -195,7 +195,7 @@ module.exports = {
|
||||
],
|
||||
rules: {}, // Rules are defined in the overrides to be more specific and only target the files they are meant for.
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'import-x/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx'],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
"@typescript-eslint/parser": "7.3.1",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-import": "2.25.2",
|
||||
"eslint-plugin-import-x": "0.5.3",
|
||||
"eslint-plugin-jest": "27.9.0",
|
||||
"eslint-plugin-jest-dom": "5.1.0",
|
||||
"eslint-plugin-jsx-a11y": "6.8.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-payload": "workspace:*",
|
||||
"eslint-plugin-perfectionist": "2.7.0",
|
||||
"eslint-plugin-react": "7.34.1",
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
"eslint-plugin-jest": "27.9.0",
|
||||
"eslint-plugin-jest-dom": "5.1.0",
|
||||
"eslint-plugin-jsx-a11y": "6.8.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-perfectionist": "2.7.0",
|
||||
"eslint-plugin-react": "7.34.1",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-react",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "The official live preview React SDK for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -100,7 +100,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^16.8.1",
|
||||
"next": "^15.0.0-rc.0",
|
||||
"next": "^15.0.0-canary.53",
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { GeneratedTypes, InitOptions, Payload, SanitizedConfig } from 'payload'
|
||||
import type { InitOptions, Payload, SanitizedConfig } from 'payload'
|
||||
|
||||
import { BasePayload } from 'payload'
|
||||
import WebSocket from 'ws'
|
||||
@@ -6,7 +6,7 @@ import WebSocket from 'ws'
|
||||
let cached: {
|
||||
payload: Payload | null
|
||||
promise: Promise<Payload> | null
|
||||
reload: Promise<boolean> | boolean
|
||||
reload: Promise<void> | boolean
|
||||
} = global._payload
|
||||
|
||||
if (!cached) {
|
||||
@@ -53,17 +53,18 @@ export const reload = async (config: SanitizedConfig, payload: Payload): Promise
|
||||
|
||||
export const getPayloadHMR = async (options: InitOptions): Promise<Payload> => {
|
||||
if (!options?.config) {
|
||||
throw new Error('Error: the payload config is required for getPayload to work.')
|
||||
throw new Error('Error: the payload config is required for getPayloadHMR to work.')
|
||||
}
|
||||
|
||||
if (cached.payload) {
|
||||
const config = await options.config // TODO: check if we can move this inside the cached.reload === true condition
|
||||
|
||||
if (cached.reload === true) {
|
||||
let resolve
|
||||
let resolve: () => void
|
||||
|
||||
// getPayloadHMR is called multiple times, in parallel. However, we only want to run `await reload` once. By immediately setting cached.reload to a promise,
|
||||
// we can ensure that all subsequent calls will wait for the first reload to finish. So if we set it here, the 2nd call of getPayloadHMR
|
||||
// will reach `if (cached.reload instanceof Promise) {` which then waits for the first reload to finish.
|
||||
cached.reload = new Promise((res) => (resolve = res))
|
||||
|
||||
const config = await options.config
|
||||
await reload(config, cached.payload)
|
||||
|
||||
resolve()
|
||||
@@ -77,6 +78,7 @@ export const getPayloadHMR = async (options: InitOptions): Promise<Payload> => {
|
||||
}
|
||||
|
||||
if (!cached.promise) {
|
||||
// no need to await options.config here, as it's already awaited in the BasePayload.init
|
||||
cached.promise = new BasePayload().init(options)
|
||||
}
|
||||
|
||||
|
||||
@@ -196,13 +196,6 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const viewComponentProps: ServerSideEditViewProps = {
|
||||
initPageResult,
|
||||
params,
|
||||
routeSegments: segments,
|
||||
searchParams,
|
||||
}
|
||||
|
||||
return (
|
||||
<DocumentInfoProvider
|
||||
action={action}
|
||||
@@ -246,13 +239,14 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
<RenderCustomComponent
|
||||
CustomComponent={ViewOverride || CustomView}
|
||||
DefaultComponent={DefaultView}
|
||||
componentProps={viewComponentProps}
|
||||
serverOnlyProps={{
|
||||
i18n,
|
||||
initPageResult,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
routeSegments: segments,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
@@ -104,7 +104,6 @@
|
||||
"json-schema-to-typescript": "11.0.3",
|
||||
"jsonwebtoken": "9.0.1",
|
||||
"minimist": "1.2.8",
|
||||
"mkdirp": "1.0.4",
|
||||
"monaco-editor": "0.38.0",
|
||||
"pino": "8.15.0",
|
||||
"pino-pretty": "10.2.0",
|
||||
@@ -123,11 +122,10 @@
|
||||
"@types/json-schema": "7.0.12",
|
||||
"@types/jsonwebtoken": "8.5.9",
|
||||
"@types/minimist": "1.2.2",
|
||||
"@types/mkdirp": "1.0.2",
|
||||
"@types/nodemailer": "6.4.14",
|
||||
"@types/pluralize": "0.0.33",
|
||||
"@types/react-datepicker": "6.2.0",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/uuid": "10.0.0",
|
||||
"copyfiles": "2.4.1",
|
||||
"cross-env": "7.0.3",
|
||||
"esbuild": "^0.21.4",
|
||||
|
||||
@@ -459,7 +459,9 @@ export type CollectionConfig<TSlug extends CollectionSlug = any> = {
|
||||
*/
|
||||
upload?: UploadConfig | boolean
|
||||
/**
|
||||
* Customize the handling of incoming file uploads
|
||||
* Enable versioning. Set it to true to enable default versions settings,
|
||||
* or customize versions options by setting the property equal to an object
|
||||
* containing the version options.
|
||||
*
|
||||
* @default false // disable versioning
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { OutputInfo, Sharp, SharpOptions } from 'sharp'
|
||||
|
||||
import { fileTypeFromBuffer } from 'file-type'
|
||||
import fs from 'fs'
|
||||
import mkdirp from 'mkdirp'
|
||||
import { mkdirSync } from 'node:fs'
|
||||
import sanitize from 'sanitize-filename'
|
||||
|
||||
import type { Collection } from '../collections/config/types.js'
|
||||
@@ -107,7 +107,7 @@ export const generateFileData = async <T>({
|
||||
}
|
||||
|
||||
if (!disableLocalStorage) {
|
||||
mkdirp.sync(staticPath)
|
||||
mkdirSync(staticPath, { recursive: true })
|
||||
}
|
||||
|
||||
let newData = data
|
||||
|
||||
@@ -1,47 +1,31 @@
|
||||
import type React from 'react'
|
||||
|
||||
import { isPlainObject } from './isPlainObject.js'
|
||||
|
||||
/*
|
||||
For reference: console.log output of [ClientComponent, RSC] array, tested in Turbo and Webpack (14.3.0-canary.37)
|
||||
|
||||
Both component functions async:
|
||||
|
||||
Turbo: [ [Function (anonymous)], [AsyncFunction: ExampleServer] ]
|
||||
Webpack: [ {}, [AsyncFunction: ExampleServer] ]
|
||||
|
||||
|
||||
Both component functions non-async:
|
||||
|
||||
Turbo: [ [Function (anonymous)], [Function: ExampleServer] ]
|
||||
Webpack: [ {}, [Function: ExampleServer] ]
|
||||
|
||||
*/
|
||||
const clientRefSymbol = Symbol.for('react.client.reference')
|
||||
|
||||
export function isReactServerComponentOrFunction<T extends any>(
|
||||
component: React.ComponentType | any,
|
||||
): component is T {
|
||||
const isClassComponent =
|
||||
typeof component === 'function' &&
|
||||
component.prototype &&
|
||||
typeof component.prototype.render === 'function'
|
||||
|
||||
const isFunctionalComponent =
|
||||
typeof component === 'function' && (!component.prototype || !component.prototype.render)
|
||||
if (component === null || component === undefined) {
|
||||
return false
|
||||
}
|
||||
const hasClientComponentSymbol = component.$$typeof == clientRefSymbol
|
||||
|
||||
const isFunctionalComponent = typeof component === 'function'
|
||||
// Anonymous functions are Client Components in Turbopack. RSCs should have a name
|
||||
const isAnonymousFunction = typeof component === 'function' && component.name === ''
|
||||
|
||||
return (isClassComponent || isFunctionalComponent) && !isAnonymousFunction
|
||||
const isRSC = isFunctionalComponent && !isAnonymousFunction && !hasClientComponentSymbol
|
||||
|
||||
return isRSC
|
||||
}
|
||||
|
||||
export function isReactClientComponent<T extends any>(
|
||||
component: React.ComponentType | any,
|
||||
): component is T {
|
||||
const isClientComponentWebpack = typeof component === 'object' && !isPlainObject(component) // In Webpack, client components are {}
|
||||
const isClientComponentTurbo = typeof component === 'function' && component.name === '' // Anonymous functions are Client Components in Turbopack
|
||||
|
||||
return isClientComponentWebpack || isClientComponentTurbo
|
||||
if (component === null || component === undefined) {
|
||||
return false
|
||||
}
|
||||
return !isReactServerComponentOrFunction(component) && component.$$typeof == clientRefSymbol
|
||||
}
|
||||
|
||||
export function isReactComponentOrFunction<T extends any>(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Redirects plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-relationship-object-ids",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"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.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Search plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-seo",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "SEO plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-stripe",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Stripe plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
@@ -63,7 +63,7 @@
|
||||
"@types/lodash.get": "^4.4.7",
|
||||
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/uuid": "10.0.0",
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-lexical",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "The officially supported Lexical richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
@@ -50,7 +50,7 @@
|
||||
"@lexical/rich-text": "0.16.1",
|
||||
"@lexical/selection": "0.16.1",
|
||||
"@lexical/utils": "0.16.1",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/uuid": "10.0.0",
|
||||
"bson-objectid": "2.0.4",
|
||||
"dequal": "2.0.3",
|
||||
"json-schema": "^0.4.0",
|
||||
@@ -59,7 +59,7 @@
|
||||
"uuid": "10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lexical/eslint-plugin": "0.15.0",
|
||||
"@lexical/eslint-plugin": " 0.16.1",
|
||||
"@payloadcms/eslint-config": "workspace:*",
|
||||
"@payloadcms/next": "workspace:*",
|
||||
"@payloadcms/translations": "workspace:*",
|
||||
|
||||
@@ -62,7 +62,7 @@ export const RichTextCell: React.FC<
|
||||
|
||||
Object.entries(clientFunctions).forEach(([key, plugin]) => {
|
||||
if (key.startsWith(`lexicalFeature.${schemaPath}.`)) {
|
||||
if (!key.includes('.components.')) {
|
||||
if (!key.includes('.lexical_internal_components.')) {
|
||||
featureProvidersLocal.push(plugin)
|
||||
}
|
||||
featureProvidersAndComponentsLoaded++
|
||||
@@ -167,7 +167,9 @@ export const RichTextCell: React.FC<
|
||||
featureProviderComponents.map((featureProvider) => {
|
||||
// get all components starting with key feature.${FeatureProvider.key}.components.{featureComponentKey}
|
||||
const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>
|
||||
key.startsWith(`feature.${featureProvider.key}.components.`),
|
||||
key.startsWith(
|
||||
`lexical_internal_feature.${featureProvider.key}.lexical_internal_components.`,
|
||||
),
|
||||
)
|
||||
|
||||
const featureComponents: React.ReactNode[] = featureComponentKeys.map((key) => {
|
||||
|
||||
@@ -56,8 +56,8 @@ export const BlockComponent: React.FC<Props> = (props) => {
|
||||
field: { richTextComponentMap },
|
||||
} = useEditorConfigContext()
|
||||
|
||||
const componentMapRenderedFieldsPath = `feature.blocks.fields.${formData?.blockType}`
|
||||
const schemaFieldsPath = `${schemaPath}.feature.blocks.${formData?.blockType}`
|
||||
const componentMapRenderedFieldsPath = `lexical_internal_feature.blocks.fields.${formData?.blockType}`
|
||||
const schemaFieldsPath = `${schemaPath}.lexical_internal_feature.blocks.${formData?.blockType}`
|
||||
|
||||
const reducedBlock: ReducedBlock = (
|
||||
editorConfig?.resolvedFeatureMap?.get('blocks')
|
||||
@@ -145,7 +145,7 @@ export const BlockComponent: React.FC<Props> = (props) => {
|
||||
formData={formData}
|
||||
formSchema={Array.isArray(fieldMap) ? fieldMap : []}
|
||||
nodeKey={nodeKey}
|
||||
path={`${path}.feature.blocks.${formData.blockType}`}
|
||||
path={`${path}.lexical_internal_feature.blocks.${formData.blockType}`}
|
||||
reducedBlock={reducedBlock}
|
||||
schemaPath={schemaFieldsPath}
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@ const useLexicalFeatureProp = <T,>(featureKey: string, componentKey: string, pro
|
||||
const schemaPath = schemaPathFromCellProps || schemaPathFromFieldProps // schemaPathFromCellProps needs to have priority, as there can be cells within fields (e.g. list drawers) and the cell schemaPath needs to be used there - not the parent field schemaPath. There cannot be fields within cells.
|
||||
|
||||
useAddClientFunction(
|
||||
`lexicalFeature.${schemaPath}.${featureKey}.components.${componentKey}`,
|
||||
`lexicalFeature.${schemaPath}.${featureKey}.lexical_internal_components.${componentKey}`,
|
||||
prop,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,7 +46,9 @@ export const RichTextField: React.FC<
|
||||
let featureProvidersAndComponentsToLoad = 0 // feature providers and components
|
||||
for (const featureProvider of featureProviderComponents) {
|
||||
const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>
|
||||
key.startsWith(`feature.${featureProvider.key}.components.`),
|
||||
key.startsWith(
|
||||
`lexical_internal_feature.${featureProvider.key}.lexical_internal_components.`,
|
||||
),
|
||||
)
|
||||
|
||||
featureProvidersAndComponentsToLoad += 1
|
||||
@@ -60,9 +62,10 @@ export const RichTextField: React.FC<
|
||||
|
||||
Object.entries(clientFunctions).forEach(([key, plugin]) => {
|
||||
if (key.startsWith(`lexicalFeature.${schemaPath}.`)) {
|
||||
if (!key.includes('.components.')) {
|
||||
if (!key.includes('.lexical_internal_components.')) {
|
||||
featureProvidersLocal.push(plugin)
|
||||
}
|
||||
|
||||
featureProvidersAndComponentsLoaded++
|
||||
}
|
||||
})
|
||||
@@ -112,7 +115,9 @@ export const RichTextField: React.FC<
|
||||
featureProviderComponents.map((featureProvider) => {
|
||||
// get all components starting with key feature.${FeatureProvider.key}.components.{featureComponentKey}
|
||||
const featureComponentKeys = Array.from(richTextComponentMap.keys()).filter((key) =>
|
||||
key.startsWith(`feature.${featureProvider.key}.components.`),
|
||||
key.startsWith(
|
||||
`lexical_internal_feature.${featureProvider.key}.lexical_internal_components.`,
|
||||
),
|
||||
)
|
||||
const featureComponents: React.ReactNode[] = featureComponentKeys.map((key) => {
|
||||
return richTextComponentMap.get(key)
|
||||
|
||||
@@ -34,8 +34,8 @@ export const DrawerContent: React.FC<Omit<FieldsDrawerProps, 'drawerSlug' | 'dra
|
||||
field: { richTextComponentMap },
|
||||
} = useEditorConfigContext()
|
||||
|
||||
const componentMapRenderedFieldsPath = `feature.${featureKey}.fields${schemaPathSuffix ? `.${schemaPathSuffix}` : ''}`
|
||||
const schemaFieldsPath = `${schemaPath}.feature.${featureKey}${schemaPathSuffix ? `.${schemaPathSuffix}` : ''}`
|
||||
const componentMapRenderedFieldsPath = `lexical_internal_feature.${featureKey}.fields${schemaPathSuffix ? `.${schemaPathSuffix}` : ''}`
|
||||
const schemaFieldsPath = `${schemaPath}.lexical_internal_feature.${featureKey}${schemaPathSuffix ? `.${schemaPathSuffix}` : ''}`
|
||||
|
||||
const fieldMap = richTextComponentMap.get(componentMapRenderedFieldsPath) // Field Schema
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export const getGenerateComponentMap =
|
||||
|
||||
if (Component) {
|
||||
componentMap.set(
|
||||
`feature.${featureKey}.components.${componentKey}`,
|
||||
`lexical_internal_feature.${featureKey}.lexical_internal_components.${componentKey}`,
|
||||
<WithServerSideProps
|
||||
Component={Component}
|
||||
componentKey={componentKey}
|
||||
@@ -79,11 +79,14 @@ export const getGenerateComponentMap =
|
||||
disableAddingID: true,
|
||||
fieldSchema: fields,
|
||||
i18n,
|
||||
parentPath: `${schemaPath}.feature.${featureKey}.fields.${schemaKey}`,
|
||||
parentPath: `${schemaPath}.lexical_internal_feature.${featureKey}.fields.${schemaKey}`,
|
||||
readOnly: false,
|
||||
})
|
||||
|
||||
componentMap.set(`feature.${featureKey}.fields.${schemaKey}`, mappedFields)
|
||||
componentMap.set(
|
||||
`lexical_internal_feature.${featureKey}.fields.${schemaKey}`,
|
||||
mappedFields,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export const getGenerateSchemaMap =
|
||||
schemaPath: schemaKey,
|
||||
})
|
||||
|
||||
schemaMap.set(`${schemaPath}.feature.${featureKey}.${schemaKey}`, fields)
|
||||
schemaMap.set(`${schemaPath}.lexical_internal_feature.${featureKey}.${schemaKey}`, fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-slate",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "The officially supported Slate richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-azure",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload storage adapter for Azure Blob Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-gcs",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload storage adapter for Google Cloud Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-s3",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload storage adapter for Amazon S3",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-uploadthing",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload storage adapter for uploadthing",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-vercel-blob",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"description": "Payload storage adapter for Vercel Blob Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/translations",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -47,7 +47,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"dotenv": "16.4.5",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"exports": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/ui",
|
||||
"version": "3.0.0-beta.58",
|
||||
"version": "3.0.0-beta.59",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -108,7 +108,7 @@
|
||||
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||
"@types/react-datepicker": "6.2.0",
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/uuid": "10.0.0",
|
||||
"babel-plugin-react-compiler": "0.0.0-experimental-592953e-20240517",
|
||||
"css-loader": "^6.10.0",
|
||||
"esbuild": "^0.21.4",
|
||||
@@ -122,7 +122,7 @@
|
||||
"turbopack": "^0.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^15.0.0-rc.0",
|
||||
"next": "^15.0.0-canary.53",
|
||||
"payload": "workspace:*",
|
||||
"react": "^19.0.0 || ^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0 || ^19.0.0-rc-f994737d14-20240522"
|
||||
|
||||
@@ -30,11 +30,11 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
||||
const { i18n, t } = useTranslation()
|
||||
const { code: currentLocale } = useLocale()
|
||||
|
||||
const [reducedFields, setReducedColumns] = useState(() => reduceFieldMap(fieldMap, i18n))
|
||||
const [reducedFields, setReducedColumns] = useState(() => reduceFieldMap({ fieldMap, i18n }))
|
||||
|
||||
useEffect(() => {
|
||||
setReducedColumns(reduceFieldMap(fieldMap, i18n, undefined, undefined, currentLocale))
|
||||
}, [fieldMap, i18n, currentLocale])
|
||||
setReducedColumns(reduceFieldMap({ fieldMap, i18n }))
|
||||
}, [fieldMap, i18n])
|
||||
|
||||
const { searchParams } = useSearchParams()
|
||||
const { handleWhereChange } = useListQuery()
|
||||
|
||||
@@ -1,38 +1,113 @@
|
||||
'use client'
|
||||
import type { ClientTranslationKeys, I18nClient } from '@payloadcms/translations'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations';
|
||||
|
||||
import type { FieldMap } from '../../utilities/buildComponentMap.js'
|
||||
|
||||
import { createNestedClientFieldPath } from '../../forms/Form/createNestedFieldPath.js'
|
||||
import { combineLabel } from '../FieldSelect/index.js'
|
||||
import fieldTypes from './field-types.js'
|
||||
|
||||
export const reduceFieldMap = (
|
||||
fieldMap: FieldMap,
|
||||
i18n,
|
||||
labelPrefix?: string,
|
||||
pathPrefix?: string,
|
||||
locale?: string,
|
||||
) => {
|
||||
export type ReduceFieldMapArgs = {
|
||||
fieldMap: FieldMap
|
||||
i18n: I18nClient
|
||||
labelPrefix?: string
|
||||
pathPrefix?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces a field map to a flat array of fields with labels and values.
|
||||
* Used in the WhereBuilder component to render the fields in the dropdown.
|
||||
*/
|
||||
export const reduceFieldMap = ({ fieldMap, i18n, labelPrefix, pathPrefix }: ReduceFieldMapArgs) => {
|
||||
return fieldMap.reduce((reduced, field) => {
|
||||
if (field.disableListFilter) return reduced
|
||||
|
||||
if (field.type === 'tabs' && 'tabs' in field.fieldComponentProps) {
|
||||
const tabs = field.fieldComponentProps.tabs
|
||||
tabs.forEach((tab) => {
|
||||
if (tab.name && typeof tab.label === 'string' && tab.fieldMap) {
|
||||
reduced.push(...reduceFieldMap(tab.fieldMap, i18n, tab.label, tab.name))
|
||||
if (typeof tab.label !== 'boolean') {
|
||||
const localizedTabLabel = getTranslation(tab.label, i18n)
|
||||
const labelWithPrefix = labelPrefix
|
||||
? labelPrefix + ' > ' + localizedTabLabel
|
||||
: localizedTabLabel
|
||||
|
||||
// Make sure we handle nested tabs
|
||||
const tabPathPrefix = tab.name
|
||||
? pathPrefix
|
||||
? pathPrefix + '.' + tab.name
|
||||
: tab.name
|
||||
: pathPrefix
|
||||
|
||||
if (typeof localizedTabLabel === 'string') {
|
||||
reduced.push(
|
||||
...reduceFieldMap({
|
||||
fieldMap: tab.fieldMap,
|
||||
i18n,
|
||||
labelPrefix: labelWithPrefix,
|
||||
pathPrefix: tabPathPrefix,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
return reduced
|
||||
}
|
||||
|
||||
if (field.type === 'group' && 'fieldMap' in field.fieldComponentProps) {
|
||||
// Rows cant have labels, so we need to handle them differently
|
||||
if (field.type === 'row' && 'fieldMap' in field.fieldComponentProps) {
|
||||
reduced.push(
|
||||
...reduceFieldMap(
|
||||
field.fieldComponentProps.fieldMap,
|
||||
...reduceFieldMap({
|
||||
fieldMap: field.fieldComponentProps.fieldMap,
|
||||
i18n,
|
||||
field.fieldComponentProps.label as string,
|
||||
field.name,
|
||||
),
|
||||
labelPrefix,
|
||||
pathPrefix,
|
||||
}),
|
||||
)
|
||||
return reduced
|
||||
}
|
||||
|
||||
if (field.type === 'collapsible' && 'fieldMap' in field.fieldComponentProps) {
|
||||
const localizedTabLabel = getTranslation(field.fieldComponentProps.label, i18n)
|
||||
const labelWithPrefix = labelPrefix
|
||||
? labelPrefix + ' > ' + localizedTabLabel
|
||||
: localizedTabLabel
|
||||
|
||||
reduced.push(
|
||||
...reduceFieldMap({
|
||||
fieldMap: field.fieldComponentProps.fieldMap,
|
||||
i18n,
|
||||
labelPrefix: labelWithPrefix,
|
||||
pathPrefix,
|
||||
}),
|
||||
)
|
||||
return reduced
|
||||
}
|
||||
|
||||
if (field.type === 'group' && 'fieldMap' in field.fieldComponentProps) {
|
||||
const translatedLabel = getTranslation(field.fieldComponentProps.label, i18n)
|
||||
|
||||
const labelWithPrefix = labelPrefix
|
||||
? translatedLabel
|
||||
? labelPrefix + ' > ' + translatedLabel
|
||||
: labelPrefix
|
||||
: translatedLabel
|
||||
|
||||
// Make sure we handle deeply nested groups
|
||||
const pathWithPrefix = field.name
|
||||
? pathPrefix
|
||||
? pathPrefix + '.' + field.name
|
||||
: field.name
|
||||
: pathPrefix
|
||||
|
||||
reduced.push(
|
||||
...reduceFieldMap({
|
||||
fieldMap: field.fieldComponentProps.fieldMap,
|
||||
i18n,
|
||||
labelPrefix: labelWithPrefix,
|
||||
pathPrefix: pathWithPrefix,
|
||||
}),
|
||||
)
|
||||
return reduced
|
||||
}
|
||||
@@ -42,18 +117,16 @@ export const reduceFieldMap = (
|
||||
const operators = fieldTypes[field.type].operators.reduce((acc, operator) => {
|
||||
if (!operatorKeys.has(operator.value)) {
|
||||
operatorKeys.add(operator.value)
|
||||
const operatorKey = `operators:${operator.label}` as ClientTranslationKeys
|
||||
acc.push({
|
||||
...operator,
|
||||
label: i18n.t(`operators:${operator.label}`),
|
||||
label: i18n.t(operatorKey),
|
||||
})
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
const localizedLabel =
|
||||
locale && typeof field.fieldComponentProps.label === 'object'
|
||||
? field.fieldComponentProps.label[locale]
|
||||
: field.fieldComponentProps.label
|
||||
const localizedLabel = getTranslation(field.fieldComponentProps.label, i18n)
|
||||
|
||||
const formattedLabel = labelPrefix
|
||||
? combineLabel({
|
||||
|
||||
543
pnpm-lock.yaml
generated
543
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
"@payloadcms/richtext-lexical": "beta",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"payload": "beta",
|
||||
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||
@@ -32,7 +32,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.0.0-rc.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@payloadcms/richtext-lexical": "beta",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"payload": "beta",
|
||||
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||
@@ -32,7 +32,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.0.0-rc.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@payloadcms/richtext-lexical": "beta",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"payload": "beta",
|
||||
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||
@@ -32,7 +32,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.0.0-rc.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@payloadcms/storage-vercel-blob": "beta",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"payload": "beta",
|
||||
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0-rc-f994737d14-20240522"
|
||||
@@ -32,7 +32,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.0.0-rc.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@payloadcms/storage-vercel-blob": "beta",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.0.0-rc.0",
|
||||
"next": "15.0.0-canary.53",
|
||||
"payload": "beta",
|
||||
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||
"react-dom": "^19.0.0-rc-f994737d14-20240522"
|
||||
@@ -32,7 +32,7 @@
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.0.0-rc.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
|
||||
@@ -738,7 +738,8 @@ describe('admin2', () => {
|
||||
await page.locator('.where-builder__add-first-filter').click()
|
||||
await page.locator('.condition__field .rs__control').click()
|
||||
const options = page.locator('.rs__option')
|
||||
await expect(options.locator('text=Title')).toHaveText('Title')
|
||||
|
||||
await expect(options.locator('text=Tab 1 > Title')).toHaveText('Tab 1 > Title')
|
||||
|
||||
// list columns
|
||||
await expect(page.locator('#heading-title .sort-column__label')).toHaveText('Title')
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"slate": "0.91.4",
|
||||
"tempy": "^1.0.1",
|
||||
"ts-essentials": "7.0.3",
|
||||
"typescript": "5.5.2",
|
||||
"typescript": "5.5.3",
|
||||
"uploadthing": "^6.10.1"
|
||||
},
|
||||
"overrides": {
|
||||
|
||||
Reference in New Issue
Block a user