chore: separate Lexical tests into dedicated suite (#12047)
Lexical tests comprise almost half of the collections in the fields suite, and are starting to become complex to manage. They are sometimes related to other auxiliary collections, so refactoring one test sometimes breaks another, seemingly unrelated one. In addition, the fields suite is very large, taking a long time to compile. This will make it faster. Some ideas for future refactorings: - 3 main collections: defaultFeatures, fully featured, and legacy. Legacy is the current one that has multiple editors and could later be migrated to the first two. - Avoid collections with more than 1 editor. - Create reseed buttons to restore the editor to certain states, to avoid a proliferation of collections and documents. - Reduce the complexity of the three auxiliary collections (text, array, upload), which are rarely or never used and have many fields designed for tests in the fields suite.
This commit is contained in:
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
@@ -294,14 +294,10 @@ jobs:
|
||||
- fields__collections__Email
|
||||
- fields__collections__Indexed
|
||||
- fields__collections__JSON
|
||||
- fields__collections__Lexical__e2e__main
|
||||
- fields__collections__Lexical__e2e__blocks
|
||||
- fields__collections__Lexical__e2e__blocks#config.blockreferences.ts
|
||||
- fields__collections__Number
|
||||
- fields__collections__Point
|
||||
- fields__collections__Radio
|
||||
- fields__collections__Relationship
|
||||
- fields__collections__RichText
|
||||
- fields__collections__Row
|
||||
- fields__collections__Select
|
||||
- fields__collections__Tabs
|
||||
@@ -310,6 +306,10 @@ jobs:
|
||||
- fields__collections__UI
|
||||
- fields__collections__Upload
|
||||
- hooks
|
||||
- lexical__collections__Lexical__e2e__main
|
||||
- lexical__collections__Lexical__e2e__blocks
|
||||
- lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts
|
||||
- lexical__collections__RichText
|
||||
- query-presets
|
||||
- form-state
|
||||
- live-preview
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Config, User } from './payload-types.js'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { devUser } from '../credentials.js'
|
||||
import { textToLexicalJSON } from '../fields/collections/LexicalLocalized/textToLexicalJSON.js'
|
||||
import { textToLexicalJSON } from '../lexical/collections/LexicalLocalized/textToLexicalJSON.js'
|
||||
import { Disabled } from './collections/Disabled/index.js'
|
||||
import { Hooks } from './collections/hooks/index.js'
|
||||
import { Regression1 } from './collections/Regression-1/index.js'
|
||||
|
||||
@@ -20,22 +20,10 @@ import EmailFields from './collections/Email/index.js'
|
||||
import GroupFields from './collections/Group/index.js'
|
||||
import IndexedFields from './collections/Indexed/index.js'
|
||||
import JSONFields from './collections/JSON/index.js'
|
||||
import {
|
||||
getLexicalFieldsCollection,
|
||||
lexicalBlocks,
|
||||
lexicalInlineBlocks,
|
||||
} from './collections/Lexical/index.js'
|
||||
import { LexicalAccessControl } from './collections/LexicalAccessControl/index.js'
|
||||
import { LexicalInBlock } from './collections/LexicalInBlock/index.js'
|
||||
import { LexicalLocalizedFields } from './collections/LexicalLocalized/index.js'
|
||||
import { LexicalMigrateFields } from './collections/LexicalMigrate/index.js'
|
||||
import { LexicalObjectReferenceBugCollection } from './collections/LexicalObjectReferenceBug/index.js'
|
||||
import { LexicalRelationshipsFields } from './collections/LexicalRelationships/index.js'
|
||||
import NumberFields from './collections/Number/index.js'
|
||||
import PointFields from './collections/Point/index.js'
|
||||
import RadioFields from './collections/Radio/index.js'
|
||||
import RelationshipFields from './collections/Relationship/index.js'
|
||||
import RichTextFields from './collections/RichText/index.js'
|
||||
import RowFields from './collections/Row/index.js'
|
||||
import SelectFields from './collections/Select/index.js'
|
||||
import SelectVersionsFields from './collections/SelectVersions/index.js'
|
||||
@@ -50,17 +38,9 @@ import UploadsMultiPoly from './collections/UploadMultiPoly/index.js'
|
||||
import UploadsPoly from './collections/UploadPoly/index.js'
|
||||
import UploadRestricted from './collections/UploadRestricted/index.js'
|
||||
import Uploads3 from './collections/Uploads3/index.js'
|
||||
import TabsWithRichText from './globals/TabsWithRichText.js'
|
||||
import { clearAndSeedEverything } from './seed.js'
|
||||
|
||||
export const collectionSlugs: CollectionConfig[] = [
|
||||
getLexicalFieldsCollection({
|
||||
blocks: lexicalBlocks,
|
||||
inlineBlocks: lexicalInlineBlocks,
|
||||
}),
|
||||
LexicalMigrateFields,
|
||||
LexicalLocalizedFields,
|
||||
LexicalObjectReferenceBugCollection,
|
||||
{
|
||||
slug: 'users',
|
||||
admin: {
|
||||
@@ -75,8 +55,6 @@ export const collectionSlugs: CollectionConfig[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
LexicalInBlock,
|
||||
LexicalAccessControl,
|
||||
SelectVersionsFields,
|
||||
ArrayFields,
|
||||
BlockFields,
|
||||
@@ -97,8 +75,6 @@ export const collectionSlugs: CollectionConfig[] = [
|
||||
NumberFields,
|
||||
PointFields,
|
||||
RelationshipFields,
|
||||
LexicalRelationshipsFields,
|
||||
RichTextFields,
|
||||
SelectFields,
|
||||
TabsFields2,
|
||||
TabsFields,
|
||||
@@ -115,7 +91,6 @@ export const collectionSlugs: CollectionConfig[] = [
|
||||
|
||||
export const baseConfig: Partial<Config> = {
|
||||
collections: collectionSlugs,
|
||||
globals: [TabsWithRichText],
|
||||
blocks: [
|
||||
{
|
||||
slug: 'ConfigBlockTest',
|
||||
|
||||
@@ -1,35 +1,10 @@
|
||||
/* eslint-disable no-restricted-exports */
|
||||
import type { BlockSlug } from 'payload'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { autoDedupeBlocksPlugin } from '../helpers/autoDedupeBlocksPlugin/index.js'
|
||||
import { baseConfig } from './baseConfig.js'
|
||||
import {
|
||||
getLexicalFieldsCollection,
|
||||
lexicalBlocks,
|
||||
lexicalInlineBlocks,
|
||||
} from './collections/Lexical/index.js'
|
||||
import { lexicalFieldsSlug } from './slugs.js'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
...baseConfig,
|
||||
blocks: [
|
||||
...(baseConfig.blocks ?? []),
|
||||
...lexicalBlocks.filter((block) => typeof block !== 'string'),
|
||||
...lexicalInlineBlocks.filter((block) => typeof block !== 'string'),
|
||||
],
|
||||
collections: baseConfig.collections?.map((collection) => {
|
||||
if (collection.slug === lexicalFieldsSlug) {
|
||||
return getLexicalFieldsCollection({
|
||||
blocks: lexicalBlocks.map((block) =>
|
||||
typeof block === 'string' ? block : block.slug,
|
||||
) as BlockSlug[],
|
||||
inlineBlocks: lexicalInlineBlocks.map((block) =>
|
||||
typeof block === 'string' ? block : block.slug,
|
||||
) as BlockSlug[],
|
||||
})
|
||||
}
|
||||
return collection
|
||||
}),
|
||||
plugins: [autoDedupeBlocksPlugin({ silent: true })],
|
||||
})
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { MongooseAdapter } from '@payloadcms/db-mongodb'
|
||||
import type { IndexDirection, IndexOptions } from 'mongoose'
|
||||
|
||||
import path from 'path'
|
||||
import { type PaginatedDocs, type Payload, reload } from 'payload'
|
||||
import { type Payload, reload } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { NextRESTClient } from '../helpers/NextRESTClient.js'
|
||||
import type { BlockField, GroupField, RichTextField } from './payload-types.js'
|
||||
import type { BlockField, GroupField } from './payload-types.js'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
@@ -3023,91 +3023,6 @@ describe('Fields', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('richText', () => {
|
||||
it('should allow querying on rich text content', async () => {
|
||||
const emptyRichTextQuery = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'doesnt exist',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(emptyRichTextQuery.docs).toHaveLength(0)
|
||||
|
||||
const workingRichTextQuery = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'hello',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(workingRichTextQuery.docs).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should show center alignment', async () => {
|
||||
const query = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'hello',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(query.docs[0].richText[0].textAlign).toEqual('center')
|
||||
})
|
||||
|
||||
it('should populate link relationship', async () => {
|
||||
const query = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.linkType': {
|
||||
equals: 'internal',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const nodes = query.docs[0].richText
|
||||
expect(nodes).toBeDefined()
|
||||
const child = nodes.flatMap((n) => n.children).find((c) => c.doc)
|
||||
expect(child).toMatchObject({
|
||||
type: 'link',
|
||||
linkType: 'internal',
|
||||
})
|
||||
expect(child.doc.relationTo).toEqual('array-fields')
|
||||
|
||||
if (payload.db.defaultIDType === 'number') {
|
||||
expect(typeof child.doc.value.id).toBe('number')
|
||||
} else {
|
||||
expect(typeof child.doc.value.id).toBe('string')
|
||||
}
|
||||
|
||||
expect(child.doc.value.items).toHaveLength(6)
|
||||
})
|
||||
|
||||
it('should respect rich text depth parameter', async () => {
|
||||
const query = `query {
|
||||
RichTextFields {
|
||||
docs {
|
||||
richText(depth: 2)
|
||||
}
|
||||
}
|
||||
}`
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
const { docs }: PaginatedDocs<RichTextField> = data.RichTextFields
|
||||
const uploadElement = docs[0].richText.find((el) => el.type === 'upload') as any
|
||||
expect(uploadElement.value.media.filename).toStrictEqual('payload.png')
|
||||
})
|
||||
})
|
||||
|
||||
describe('relationships', () => {
|
||||
it('should not crash if querying with empty in operator', async () => {
|
||||
const query = await payload.find({
|
||||
|
||||
@@ -61,22 +61,6 @@ export type SupportedTimezones =
|
||||
| 'Pacific/Auckland'
|
||||
| 'Pacific/Fiji'
|
||||
| 'America/Monterrey';
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "BlockColumns".
|
||||
*/
|
||||
export type BlockColumns =
|
||||
| {
|
||||
text?: string | null;
|
||||
subArray?:
|
||||
| {
|
||||
requiredText: string;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
|
||||
export interface Config {
|
||||
auth: {
|
||||
@@ -88,13 +72,7 @@ export interface Config {
|
||||
localizedTextReference2: LocalizedTextReference2;
|
||||
};
|
||||
collections: {
|
||||
'lexical-fields': LexicalField;
|
||||
'lexical-migrate-fields': LexicalMigrateField;
|
||||
'lexical-localized-fields': LexicalLocalizedField;
|
||||
lexicalObjectReferenceBug: LexicalObjectReferenceBug;
|
||||
users: User;
|
||||
LexicalInBlock: LexicalInBlock;
|
||||
'lexical-access-control': LexicalAccessControl;
|
||||
'select-versions-fields': SelectVersionsField;
|
||||
'array-fields': ArrayField;
|
||||
'block-fields': BlockField;
|
||||
@@ -115,8 +93,6 @@ export interface Config {
|
||||
'number-fields': NumberField;
|
||||
'point-fields': PointField;
|
||||
'relationship-fields': RelationshipField;
|
||||
'lexical-relationship-fields': LexicalRelationshipField;
|
||||
'rich-text-fields': RichTextField;
|
||||
'select-fields': SelectField;
|
||||
'tabs-fields-2': TabsFields2;
|
||||
'tabs-fields': TabsField;
|
||||
@@ -135,13 +111,7 @@ export interface Config {
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
'lexical-fields': LexicalFieldsSelect<false> | LexicalFieldsSelect<true>;
|
||||
'lexical-migrate-fields': LexicalMigrateFieldsSelect<false> | LexicalMigrateFieldsSelect<true>;
|
||||
'lexical-localized-fields': LexicalLocalizedFieldsSelect<false> | LexicalLocalizedFieldsSelect<true>;
|
||||
lexicalObjectReferenceBug: LexicalObjectReferenceBugSelect<false> | LexicalObjectReferenceBugSelect<true>;
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
LexicalInBlock: LexicalInBlockSelect<false> | LexicalInBlockSelect<true>;
|
||||
'lexical-access-control': LexicalAccessControlSelect<false> | LexicalAccessControlSelect<true>;
|
||||
'select-versions-fields': SelectVersionsFieldsSelect<false> | SelectVersionsFieldsSelect<true>;
|
||||
'array-fields': ArrayFieldsSelect<false> | ArrayFieldsSelect<true>;
|
||||
'block-fields': BlockFieldsSelect<false> | BlockFieldsSelect<true>;
|
||||
@@ -162,8 +132,6 @@ export interface Config {
|
||||
'number-fields': NumberFieldsSelect<false> | NumberFieldsSelect<true>;
|
||||
'point-fields': PointFieldsSelect<false> | PointFieldsSelect<true>;
|
||||
'relationship-fields': RelationshipFieldsSelect<false> | RelationshipFieldsSelect<true>;
|
||||
'lexical-relationship-fields': LexicalRelationshipFieldsSelect<false> | LexicalRelationshipFieldsSelect<true>;
|
||||
'rich-text-fields': RichTextFieldsSelect<false> | RichTextFieldsSelect<true>;
|
||||
'select-fields': SelectFieldsSelect<false> | SelectFieldsSelect<true>;
|
||||
'tabs-fields-2': TabsFields2Select<false> | TabsFields2Select<true>;
|
||||
'tabs-fields': TabsFieldsSelect<false> | TabsFieldsSelect<true>;
|
||||
@@ -183,12 +151,8 @@ export interface Config {
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {
|
||||
tabsWithRichText: TabsWithRichText;
|
||||
};
|
||||
globalsSelect: {
|
||||
tabsWithRichText: TabsWithRichTextSelect<false> | TabsWithRichTextSelect<true>;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: 'en' | 'es';
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
@@ -246,242 +210,6 @@ export interface LocalizedTextReference2 {
|
||||
blockName?: string | null;
|
||||
blockType: 'localizedTextReference2';
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-fields".
|
||||
*/
|
||||
export interface LexicalField {
|
||||
id: string;
|
||||
title: string;
|
||||
lexicalRootEditor?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalSimple?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalWithBlocks: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
lexicalWithBlocks_markdown?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-migrate-fields".
|
||||
*/
|
||||
export interface LexicalMigrateField {
|
||||
id: string;
|
||||
title: string;
|
||||
lexicalWithLexicalPluginData?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalWithSlateData?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalSimple?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalSimple_html?: string | null;
|
||||
groupWithLexicalField?: {
|
||||
lexicalInGroupField?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalInGroupField_html?: string | null;
|
||||
};
|
||||
arrayWithLexicalField?:
|
||||
| {
|
||||
lexicalInArrayField?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalInArrayField_html?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-localized-fields".
|
||||
*/
|
||||
export interface LexicalLocalizedField {
|
||||
id: string;
|
||||
title: string;
|
||||
/**
|
||||
* Non-localized field with localized block subfields
|
||||
*/
|
||||
lexicalBlocksSubLocalized?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* Localized field with localized block subfields
|
||||
*/
|
||||
lexicalBlocksLocalized?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexicalObjectReferenceBug".
|
||||
*/
|
||||
export interface LexicalObjectReferenceBug {
|
||||
id: string;
|
||||
lexicalDefault?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
lexicalEditor?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
@@ -500,77 +228,6 @@ export interface User {
|
||||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "LexicalInBlock".
|
||||
*/
|
||||
export interface LexicalInBlock {
|
||||
id: string;
|
||||
content?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
blocks?:
|
||||
| {
|
||||
lexical?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'lexicalInBlock2';
|
||||
}[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-access-control".
|
||||
*/
|
||||
export interface LexicalAccessControl {
|
||||
id: string;
|
||||
title?: string | null;
|
||||
richText?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "select-versions-fields".
|
||||
@@ -1658,126 +1315,6 @@ export interface RelationshipField {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-relationship-fields".
|
||||
*/
|
||||
export interface LexicalRelationshipField {
|
||||
id: string;
|
||||
richText?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
richText2?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "rich-text-fields".
|
||||
*/
|
||||
export interface RichTextField {
|
||||
id: string;
|
||||
title: string;
|
||||
lexicalCustomFields: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
lexicalCustomFields_html?: string | null;
|
||||
/**
|
||||
* This rich text field uses the lexical editor.
|
||||
*/
|
||||
lexical?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* This select field is rendered here to ensure its options dropdown renders above the rich text toolbar.
|
||||
*/
|
||||
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null;
|
||||
richText: {
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
richTextCustomFields?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}[]
|
||||
| null;
|
||||
richTextReadOnly?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}[]
|
||||
| null;
|
||||
blocks?:
|
||||
| (
|
||||
| {
|
||||
text?: string | null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'textBlock';
|
||||
}
|
||||
| {
|
||||
text?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'richTextBlockSlate';
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "select-fields".
|
||||
@@ -2067,34 +1604,10 @@ export interface UiField {
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'lexical-fields';
|
||||
value: string | LexicalField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'lexical-migrate-fields';
|
||||
value: string | LexicalMigrateField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'lexical-localized-fields';
|
||||
value: string | LexicalLocalizedField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'lexicalObjectReferenceBug';
|
||||
value: string | LexicalObjectReferenceBug;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'LexicalInBlock';
|
||||
value: string | LexicalInBlock;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'lexical-access-control';
|
||||
value: string | LexicalAccessControl;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'select-versions-fields';
|
||||
value: string | SelectVersionsField;
|
||||
@@ -2175,14 +1688,6 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'relationship-fields';
|
||||
value: string | RelationshipField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'lexical-relationship-fields';
|
||||
value: string | LexicalRelationshipField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'rich-text-fields';
|
||||
value: string | RichTextField;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'select-fields';
|
||||
value: string | SelectField;
|
||||
@@ -2273,66 +1778,6 @@ export interface PayloadMigration {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-fields_select".
|
||||
*/
|
||||
export interface LexicalFieldsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
lexicalRootEditor?: T;
|
||||
lexicalSimple?: T;
|
||||
lexicalWithBlocks?: T;
|
||||
lexicalWithBlocks_markdown?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-migrate-fields_select".
|
||||
*/
|
||||
export interface LexicalMigrateFieldsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
lexicalWithLexicalPluginData?: T;
|
||||
lexicalWithSlateData?: T;
|
||||
lexicalSimple?: T;
|
||||
lexicalSimple_html?: T;
|
||||
groupWithLexicalField?:
|
||||
| T
|
||||
| {
|
||||
lexicalInGroupField?: T;
|
||||
lexicalInGroupField_html?: T;
|
||||
};
|
||||
arrayWithLexicalField?:
|
||||
| T
|
||||
| {
|
||||
lexicalInArrayField?: T;
|
||||
lexicalInArrayField_html?: T;
|
||||
id?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-localized-fields_select".
|
||||
*/
|
||||
export interface LexicalLocalizedFieldsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
lexicalBlocksSubLocalized?: T;
|
||||
lexicalBlocksLocalized?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexicalObjectReferenceBug_select".
|
||||
*/
|
||||
export interface LexicalObjectReferenceBugSelect<T extends boolean = true> {
|
||||
lexicalDefault?: T;
|
||||
lexicalEditor?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
@@ -2349,36 +1794,6 @@ export interface UsersSelect<T extends boolean = true> {
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "LexicalInBlock_select".
|
||||
*/
|
||||
export interface LexicalInBlockSelect<T extends boolean = true> {
|
||||
content?: T;
|
||||
blocks?:
|
||||
| T
|
||||
| {
|
||||
lexicalInBlock2?:
|
||||
| T
|
||||
| {
|
||||
lexical?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-access-control_select".
|
||||
*/
|
||||
export interface LexicalAccessControlSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
richText?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "select-versions-fields_select".
|
||||
@@ -3374,50 +2789,6 @@ export interface RelationshipFieldsSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "lexical-relationship-fields_select".
|
||||
*/
|
||||
export interface LexicalRelationshipFieldsSelect<T extends boolean = true> {
|
||||
richText?: T;
|
||||
richText2?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "rich-text-fields_select".
|
||||
*/
|
||||
export interface RichTextFieldsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
lexicalCustomFields?: T;
|
||||
lexicalCustomFields_html?: T;
|
||||
lexical?: T;
|
||||
selectHasMany?: T;
|
||||
richText?: T;
|
||||
richTextCustomFields?: T;
|
||||
richTextReadOnly?: T;
|
||||
blocks?:
|
||||
| T
|
||||
| {
|
||||
textBlock?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
richTextBlockSlate?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "select-fields_select".
|
||||
@@ -3766,93 +3137,6 @@ export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "tabsWithRichText".
|
||||
*/
|
||||
export interface TabsWithRichText {
|
||||
id: string;
|
||||
tab1?: {
|
||||
rt1?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
tab2?: {
|
||||
rt2?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
updatedAt?: string | null;
|
||||
createdAt?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "tabsWithRichText_select".
|
||||
*/
|
||||
export interface TabsWithRichTextSelect<T extends boolean = true> {
|
||||
tab1?:
|
||||
| T
|
||||
| {
|
||||
rt1?: T;
|
||||
};
|
||||
tab2?:
|
||||
| T
|
||||
| {
|
||||
rt2?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
globalType?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "LexicalBlocksRadioButtonsBlock".
|
||||
*/
|
||||
export interface LexicalBlocksRadioButtonsBlock {
|
||||
radioButtons?: ('option1' | 'option2' | 'option3') | null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'radioButtons';
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "AvatarGroupBlock".
|
||||
*/
|
||||
export interface AvatarGroupBlock {
|
||||
avatars?:
|
||||
| {
|
||||
image?: (string | null) | Upload;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'AvatarGroup';
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
|
||||
@@ -6,7 +6,9 @@ import { fileURLToPath } from 'url'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { seedDB } from '../helpers/seed.js'
|
||||
import { anotherArrayDoc, arrayDoc } from './collections/Array/shared.js'
|
||||
// TODO: decouple blocks from both test suites
|
||||
import { richTextDocData } from '../lexical/collections/RichText/data.js'
|
||||
import { arrayDoc } from './collections/Array/shared.js'
|
||||
import { blocksDoc } from './collections/Blocks/shared.js'
|
||||
import { codeDoc } from './collections/Code/shared.js'
|
||||
import { collapsibleDoc } from './collections/Collapsible/shared.js'
|
||||
@@ -16,14 +18,9 @@ import { dateDoc } from './collections/Date/shared.js'
|
||||
import { anotherEmailDoc, emailDoc } from './collections/Email/shared.js'
|
||||
import { groupDoc } from './collections/Group/shared.js'
|
||||
import { jsonDoc } from './collections/JSON/shared.js'
|
||||
import { lexicalDocData } from './collections/Lexical/data.js'
|
||||
import { generateLexicalLocalizedRichText } from './collections/LexicalLocalized/generateLexicalRichText.js'
|
||||
import { textToLexicalJSON } from './collections/LexicalLocalized/textToLexicalJSON.js'
|
||||
import { lexicalMigrateDocData } from './collections/LexicalMigrate/data.js'
|
||||
import { numberDoc } from './collections/Number/shared.js'
|
||||
import { pointDoc } from './collections/Point/shared.js'
|
||||
import { radiosDoc } from './collections/Radio/shared.js'
|
||||
import { richTextBulletsDocData, richTextDocData } from './collections/RichText/data.js'
|
||||
import { selectsDoc } from './collections/Select/shared.js'
|
||||
import { tabsDoc } from './collections/Tabs/shared.js'
|
||||
import { anotherTextDoc, textDoc } from './collections/Text/shared.js'
|
||||
@@ -43,22 +40,15 @@ import {
|
||||
emailFieldsSlug,
|
||||
groupFieldsSlug,
|
||||
jsonFieldsSlug,
|
||||
lexicalFieldsSlug,
|
||||
lexicalLocalizedFieldsSlug,
|
||||
lexicalMigrateFieldsSlug,
|
||||
lexicalRelationshipFieldsSlug,
|
||||
numberFieldsSlug,
|
||||
pointFieldsSlug,
|
||||
radioFieldsSlug,
|
||||
relationshipFieldsSlug,
|
||||
richTextFieldsSlug,
|
||||
selectFieldsSlug,
|
||||
tabsFieldsSlug,
|
||||
textFieldsSlug,
|
||||
uiSlug,
|
||||
uploads2Slug,
|
||||
uploadsMulti,
|
||||
uploadsMultiPoly,
|
||||
uploadsPoly,
|
||||
uploadsSlug,
|
||||
usersSlug,
|
||||
@@ -86,13 +76,6 @@ export const seed = async (_payload: Payload) => {
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdAnotherArrayDoc = await _payload.create({
|
||||
collection: arrayFieldsSlug,
|
||||
data: anotherArrayDoc,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdTextDoc = await _payload.create({
|
||||
collection: textFieldsSlug,
|
||||
data: textDoc,
|
||||
@@ -177,7 +160,6 @@ export const seed = async (_payload: Payload) => {
|
||||
// media: { value: createdJPGDocSlug2.id, relationTo: uploads2Slug },
|
||||
// },
|
||||
// })
|
||||
|
||||
const formattedID =
|
||||
_payload.db.defaultIDType === 'number' ? createdArrayDoc.id : `"${createdArrayDoc.id}"`
|
||||
|
||||
@@ -193,29 +175,14 @@ export const seed = async (_payload: Payload) => {
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`),
|
||||
)
|
||||
const richTextBulletsDocWithRelId = JSON.parse(
|
||||
JSON.stringify(richTextBulletsDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`),
|
||||
)
|
||||
|
||||
const richTextDocWithRelationship = { ...richTextDocWithRelId }
|
||||
|
||||
const blocksDocWithRichText = {
|
||||
...(blocksDoc as any),
|
||||
}
|
||||
const richTextDocWithRelationship = { ...richTextDocWithRelId }
|
||||
|
||||
blocksDocWithRichText.blocks[0].richText = richTextDocWithRelationship.richText
|
||||
blocksDocWithRichText.localizedBlocks[0].richText = richTextDocWithRelationship.richText
|
||||
|
||||
await _payload.create({
|
||||
collection: richTextFieldsSlug,
|
||||
data: richTextBulletsDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: emailFieldsSlug,
|
||||
data: emailDoc,
|
||||
@@ -230,32 +197,6 @@ export const seed = async (_payload: Payload) => {
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdRichTextDoc = await _payload.create({
|
||||
collection: richTextFieldsSlug,
|
||||
data: richTextDocWithRelationship,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const formattedRichTextDocID =
|
||||
_payload.db.defaultIDType === 'number' ? createdRichTextDoc.id : `"${createdRichTextDoc.id}"`
|
||||
|
||||
const lexicalDocWithRelId = JSON.parse(
|
||||
JSON.stringify(lexicalDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`)
|
||||
.replace(/"\{\{RICH_TEXT_DOC_ID\}\}"/g, `${formattedRichTextDocID}`),
|
||||
)
|
||||
|
||||
const lexicalMigrateDocWithRelId = JSON.parse(
|
||||
JSON.stringify(lexicalMigrateDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`)
|
||||
.replace(/"\{\{RICH_TEXT_DOC_ID\}\}"/g, `${formattedRichTextDocID}`),
|
||||
)
|
||||
|
||||
await _payload.create({
|
||||
collection: usersSlug,
|
||||
depth: 0,
|
||||
@@ -392,96 +333,6 @@ export const seed = async (_payload: Payload) => {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalFieldsSlug,
|
||||
data: lexicalDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const lexicalLocalizedDoc1 = await _payload.create({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
data: {
|
||||
title: 'Localized Lexical en',
|
||||
lexicalBlocksLocalized: textToLexicalJSON({ text: 'English text' }),
|
||||
lexicalBlocksSubLocalized: generateLexicalLocalizedRichText(
|
||||
'Shared text',
|
||||
'English text in block',
|
||||
) as any,
|
||||
},
|
||||
locale: 'en',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalRelationshipFieldsSlug,
|
||||
data: {
|
||||
richText: textToLexicalJSON({ text: 'English text' }),
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.update({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
id: lexicalLocalizedDoc1.id,
|
||||
data: {
|
||||
title: 'Localized Lexical es',
|
||||
lexicalBlocksLocalized: textToLexicalJSON({ text: 'Spanish text' }),
|
||||
lexicalBlocksSubLocalized: generateLexicalLocalizedRichText(
|
||||
'Shared text',
|
||||
'Spanish text in block',
|
||||
(lexicalLocalizedDoc1.lexicalBlocksSubLocalized.root.children[1].fields as any).id,
|
||||
) as any,
|
||||
},
|
||||
locale: 'es',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const lexicalLocalizedDoc2 = await _payload.create({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
data: {
|
||||
title: 'Localized Lexical en 2',
|
||||
|
||||
lexicalBlocksLocalized: textToLexicalJSON({
|
||||
text: 'English text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
lexicalBlocksSubLocalized: textToLexicalJSON({
|
||||
text: 'English text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
},
|
||||
locale: 'en',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.update({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
id: lexicalLocalizedDoc2.id,
|
||||
data: {
|
||||
title: 'Localized Lexical es 2',
|
||||
|
||||
lexicalBlocksLocalized: textToLexicalJSON({
|
||||
text: 'Spanish text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
},
|
||||
locale: 'es',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalMigrateFieldsSlug,
|
||||
data: lexicalMigrateDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: numberFieldsSlug,
|
||||
data: { number: 2 },
|
||||
@@ -511,152 +362,6 @@ export const seed = async (_payload: Payload) => {
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
const getInlineBlock = () => ({
|
||||
type: 'inlineBlock',
|
||||
fields: {
|
||||
id: Math.random().toString(36).substring(2, 15),
|
||||
text: 'text',
|
||||
blockType: 'inlineBlockInLexical',
|
||||
},
|
||||
version: 1,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: 'LexicalInBlock',
|
||||
depth: 0,
|
||||
data: {
|
||||
content: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
format: '',
|
||||
type: 'block',
|
||||
version: 2,
|
||||
fields: {
|
||||
id: '6773773284be8978db7a498d',
|
||||
lexicalInBlock: textToLexicalJSON({ text: 'text' }),
|
||||
blockName: '',
|
||||
blockType: 'blockInLexical',
|
||||
},
|
||||
},
|
||||
],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
blockName: '1',
|
||||
lexical: textToLexicalJSON({ text: '1' }),
|
||||
},
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
blockName: '2',
|
||||
lexical: textToLexicalJSON({ text: '2' }),
|
||||
},
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
lexical: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
children: [...Array.from({ length: 20 }, () => getInlineBlock())],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'paragraph',
|
||||
version: 1,
|
||||
textFormat: 0,
|
||||
textStyle: '',
|
||||
},
|
||||
],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
id: '67e1af0b78de3228e23ef1d5',
|
||||
blockName: '1',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: 'lexical-access-control',
|
||||
data: {
|
||||
richText: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'text ',
|
||||
type: 'text',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
children: [
|
||||
{
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'link',
|
||||
type: 'text',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'link',
|
||||
version: 3,
|
||||
fields: {
|
||||
url: 'https://',
|
||||
newTab: false,
|
||||
linkType: 'custom',
|
||||
blocks: [
|
||||
{
|
||||
id: '67e45673cbd5181ca8cbeef7',
|
||||
blockType: 'block',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: '67e4566fcbd5181ca8cbeef5',
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'paragraph',
|
||||
version: 1,
|
||||
textFormat: 0,
|
||||
textStyle: '',
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
title: 'title',
|
||||
},
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
await Promise.all([
|
||||
_payload.create({
|
||||
collection: customIDSlug,
|
||||
|
||||
@@ -13,18 +13,11 @@ export const emailFieldsSlug = 'email-fields'
|
||||
export const groupFieldsSlug = 'group-fields'
|
||||
export const indexedFieldsSlug = 'indexed-fields'
|
||||
export const jsonFieldsSlug = 'json-fields'
|
||||
export const lexicalFieldsSlug = 'lexical-fields'
|
||||
export const lexicalLocalizedFieldsSlug = 'lexical-localized-fields'
|
||||
export const lexicalMigrateFieldsSlug = 'lexical-migrate-fields'
|
||||
export const lexicalRelationshipFieldsSlug = 'lexical-relationship-fields'
|
||||
|
||||
export const lexicalAccessControlSlug = 'lexical-access-control'
|
||||
|
||||
export const numberFieldsSlug = 'number-fields'
|
||||
export const pointFieldsSlug = 'point-fields'
|
||||
export const radioFieldsSlug = 'radio-fields'
|
||||
export const relationshipFieldsSlug = 'relationship-fields'
|
||||
export const richTextFieldsSlug = 'rich-text-fields'
|
||||
export const rowFieldsSlug = 'row-fields'
|
||||
export const selectFieldsSlug = 'select-fields'
|
||||
export const selectVersionsFieldsSlug = 'select-versions-fields'
|
||||
@@ -52,15 +45,10 @@ export const collectionSlugs = [
|
||||
groupFieldsSlug,
|
||||
indexedFieldsSlug,
|
||||
jsonFieldsSlug,
|
||||
lexicalFieldsSlug,
|
||||
lexicalMigrateFieldsSlug,
|
||||
lexicalRelationshipFieldsSlug,
|
||||
lexicalAccessControlSlug,
|
||||
numberFieldsSlug,
|
||||
pointFieldsSlug,
|
||||
radioFieldsSlug,
|
||||
relationshipFieldsSlug,
|
||||
richTextFieldsSlug,
|
||||
rowFieldsSlug,
|
||||
selectFieldsSlug,
|
||||
tabsFieldsSlug,
|
||||
|
||||
63
test/lexical/baseConfig.ts
Normal file
63
test/lexical/baseConfig.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
import { type Config } from 'payload'
|
||||
|
||||
import ArrayFields from './collections/Array/index.js'
|
||||
import {
|
||||
getLexicalFieldsCollection,
|
||||
lexicalBlocks,
|
||||
lexicalInlineBlocks,
|
||||
} from './collections/Lexical/index.js'
|
||||
import { LexicalAccessControl } from './collections/LexicalAccessControl/index.js'
|
||||
import { LexicalInBlock } from './collections/LexicalInBlock/index.js'
|
||||
import { LexicalLocalizedFields } from './collections/LexicalLocalized/index.js'
|
||||
import { LexicalMigrateFields } from './collections/LexicalMigrate/index.js'
|
||||
import { LexicalObjectReferenceBugCollection } from './collections/LexicalObjectReferenceBug/index.js'
|
||||
import { LexicalRelationshipsFields } from './collections/LexicalRelationships/index.js'
|
||||
import RichTextFields from './collections/RichText/index.js'
|
||||
import TextFields from './collections/Text/index.js'
|
||||
import Uploads from './collections/Upload/index.js'
|
||||
import TabsWithRichText from './globals/TabsWithRichText.js'
|
||||
import { clearAndSeedEverything } from './seed.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
export const baseConfig: Partial<Config> = {
|
||||
// ...extend config here
|
||||
collections: [
|
||||
getLexicalFieldsCollection({
|
||||
blocks: lexicalBlocks,
|
||||
inlineBlocks: lexicalInlineBlocks,
|
||||
}),
|
||||
LexicalMigrateFields,
|
||||
LexicalLocalizedFields,
|
||||
LexicalObjectReferenceBugCollection,
|
||||
LexicalInBlock,
|
||||
LexicalAccessControl,
|
||||
LexicalRelationshipsFields,
|
||||
RichTextFields,
|
||||
TextFields,
|
||||
Uploads,
|
||||
ArrayFields,
|
||||
],
|
||||
globals: [TabsWithRichText],
|
||||
admin: {
|
||||
importMap: {
|
||||
baseDir: path.resolve(dirname),
|
||||
},
|
||||
},
|
||||
onInit: async (payload) => {
|
||||
if (process.env.SEED_IN_CONFIG_ONINIT !== 'false') {
|
||||
await clearAndSeedEverything(payload)
|
||||
}
|
||||
},
|
||||
localization: {
|
||||
defaultLocale: 'en',
|
||||
fallback: true,
|
||||
locales: ['en', 'es'],
|
||||
},
|
||||
typescript: {
|
||||
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||
},
|
||||
}
|
||||
29
test/lexical/collections/Array/AddRowButton.tsx
Normal file
29
test/lexical/collections/Array/AddRowButton.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
|
||||
import { useForm } from '@payloadcms/ui'
|
||||
|
||||
const AddRowButton = () => {
|
||||
const { addFieldRow } = useForm()
|
||||
|
||||
const handleClick = () => {
|
||||
addFieldRow({
|
||||
path: 'externallyUpdatedArray',
|
||||
schemaPath: 'externallyUpdatedArray',
|
||||
subFieldState: {
|
||||
text: {
|
||||
initialValue: 'Hello, world!',
|
||||
valid: true,
|
||||
value: 'Hello, world!',
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<button id="updateArrayExternally" onClick={handleClick} type="button">
|
||||
Add Row
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddRowButton
|
||||
12
test/lexical/collections/Array/CustomArrayField.tsx
Normal file
12
test/lexical/collections/Array/CustomArrayField.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
'use client'
|
||||
import type { ArrayFieldClientComponent } from 'payload'
|
||||
|
||||
import { ArrayField } from '@payloadcms/ui'
|
||||
|
||||
export const CustomArrayField: ArrayFieldClientComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-array-field">
|
||||
<ArrayField {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
11
test/lexical/collections/Array/CustomTextField.tsx
Normal file
11
test/lexical/collections/Array/CustomTextField.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { TextFieldServerComponent } from 'payload'
|
||||
|
||||
import { TextField } from '@payloadcms/ui'
|
||||
|
||||
export const CustomTextField: TextFieldServerComponent = ({ clientField, path }) => {
|
||||
return (
|
||||
<div id="custom-text-field">
|
||||
<TextField field={clientField} path={path} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
15
test/lexical/collections/Array/LabelComponent.tsx
Normal file
15
test/lexical/collections/Array/LabelComponent.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import type { PayloadClientReactComponent, RowLabelComponent } from 'payload'
|
||||
|
||||
import { useRowLabel } from '@payloadcms/ui'
|
||||
import React from 'react'
|
||||
|
||||
export const ArrayRowLabel: PayloadClientReactComponent<RowLabelComponent> = () => {
|
||||
const { data } = useRowLabel<{ title: string }>()
|
||||
return (
|
||||
<div id="custom-array-row-label" style={{ color: 'coral', textTransform: 'uppercase' }}>
|
||||
{data.title || 'Untitled'}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
268
test/lexical/collections/Array/index.ts
Normal file
268
test/lexical/collections/Array/index.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { arrayFieldsSlug } from '../../slugs.js'
|
||||
|
||||
export const arrayDefaultValue = [{ text: 'row one' }, { text: 'row two' }]
|
||||
|
||||
const ArrayFields: CollectionConfig = {
|
||||
admin: {
|
||||
enableRichTextLink: false,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'items',
|
||||
defaultValue: arrayDefaultValue,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'anotherText',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'uiField',
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: './collections/Array/LabelComponent.js#ArrayRowLabel',
|
||||
serverProps: {
|
||||
// While this doesn't do anything, this will reproduce a bug where having server-only props in here will throw a "Functions cannot be passed directly to Client Components" error
|
||||
someFn: () => 'Hello',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'localizedText',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'subArray',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'textTwo',
|
||||
label: 'Second text field',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: 'default',
|
||||
},
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
name: 'textInRow',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: 'default',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
],
|
||||
required: true,
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'collapsedArray',
|
||||
admin: {
|
||||
initCollapsed: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
required: true,
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'localized',
|
||||
defaultValue: arrayDefaultValue,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
required: true,
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
localized: true,
|
||||
required: true,
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'readOnly',
|
||||
admin: {
|
||||
readOnly: true,
|
||||
},
|
||||
defaultValue: [
|
||||
{
|
||||
text: 'defaultValue',
|
||||
},
|
||||
{
|
||||
text: 'defaultValue2',
|
||||
},
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'potentiallyEmptyArray',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'groupInRow',
|
||||
fields: [
|
||||
{
|
||||
name: 'textInGroupInRow',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'group',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'rowLabelAsComponent',
|
||||
admin: {
|
||||
components: {
|
||||
RowLabel: '/collections/Array/LabelComponent.js#ArrayRowLabel',
|
||||
},
|
||||
description: 'Row labels rendered as react components.',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'arrayWithMinRows',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
minRows: 2,
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'disableSort',
|
||||
defaultValue: arrayDefaultValue,
|
||||
admin: {
|
||||
isSortable: false,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
required: true,
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
{
|
||||
name: 'nestedArrayLocalized',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'externallyUpdatedArray',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'customTextField',
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '/collections/Array/CustomTextField.js#CustomTextField',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'customArrayField',
|
||||
type: 'array',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '/collections/Array/CustomArrayField.js#CustomArrayField',
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'ui',
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '/collections/Array/AddRowButton.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'arrayWithLabels',
|
||||
type: 'array',
|
||||
labels: {
|
||||
singular: ({ t }) => t('authentication:account'),
|
||||
plural: ({ t }) => t('authentication:generate'),
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
slug: arrayFieldsSlug,
|
||||
versions: true,
|
||||
}
|
||||
|
||||
export default ArrayFields
|
||||
68
test/lexical/collections/Array/shared.ts
Normal file
68
test/lexical/collections/Array/shared.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import type { RequiredDataFromCollection } from 'payload/types'
|
||||
|
||||
import type { ArrayField } from '../../payload-types.js'
|
||||
|
||||
export const arrayDoc: RequiredDataFromCollection<ArrayField> = {
|
||||
arrayWithMinRows: [
|
||||
{
|
||||
text: 'first row',
|
||||
},
|
||||
{
|
||||
text: 'second row',
|
||||
},
|
||||
],
|
||||
collapsedArray: [
|
||||
{
|
||||
text: 'initialize collapsed',
|
||||
},
|
||||
],
|
||||
items: [
|
||||
{
|
||||
text: 'first row',
|
||||
},
|
||||
{
|
||||
text: 'second row',
|
||||
},
|
||||
{
|
||||
text: 'third row',
|
||||
},
|
||||
{
|
||||
text: 'fourth row',
|
||||
},
|
||||
{
|
||||
text: 'fifth row',
|
||||
},
|
||||
{
|
||||
text: 'sixth row',
|
||||
},
|
||||
],
|
||||
title: 'array doc 1',
|
||||
}
|
||||
|
||||
export const anotherArrayDoc: RequiredDataFromCollection<ArrayField> = {
|
||||
arrayWithMinRows: [
|
||||
{
|
||||
text: 'first row',
|
||||
},
|
||||
{
|
||||
text: 'second row',
|
||||
},
|
||||
],
|
||||
collapsedArray: [
|
||||
{
|
||||
text: 'initialize collapsed',
|
||||
},
|
||||
],
|
||||
items: [
|
||||
{
|
||||
text: 'first row',
|
||||
},
|
||||
{
|
||||
text: 'second row',
|
||||
},
|
||||
{
|
||||
text: 'third row',
|
||||
},
|
||||
],
|
||||
title: 'array doc 2',
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import type { ArrayField, Block, TextFieldSingleValidation } from 'payload'
|
||||
|
||||
import { BlocksFeature, FixedToolbarFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||
|
||||
import { textFieldsSlug } from '../Text/shared.js'
|
||||
import { textFieldsSlug } from '../../slugs.js'
|
||||
|
||||
async function asyncFunction(param: string) {
|
||||
return new Promise((resolve) => {
|
||||
@@ -514,21 +514,8 @@ describe('lexicalMain', () => {
|
||||
await wait(500)
|
||||
await expect(page.locator('.shimmer-effect')).toHaveCount(0)
|
||||
|
||||
await uploadListDrawer.locator('.rs__control .value-container').first().click()
|
||||
await wait(500)
|
||||
await expect(uploadListDrawer.locator('.rs__option').nth(1)).toBeVisible()
|
||||
await expect(uploadListDrawer.locator('.rs__option').nth(1)).toContainText('Upload 2')
|
||||
await uploadListDrawer.locator('.rs__option').nth(1).click()
|
||||
|
||||
// wait till the text appears in uploadListDrawer: "No Uploads 2 found. Either no Uploads 2 exist yet or none match the filters you've specified above."
|
||||
await expect(
|
||||
uploadListDrawer.getByText(
|
||||
"No Uploads 2 found. Either no Uploads 2 exist yet or none match the filters you've specified above.",
|
||||
),
|
||||
).toBeVisible()
|
||||
|
||||
await uploadListDrawer.getByText('Create New').first().click()
|
||||
const createUploadDrawer = page.locator('dialog[id^=doc-drawer_uploads2_]').first() // IDs starting with list-drawer_1_ (there's some other symbol after the underscore)
|
||||
await page.getByRole('dialog').getByLabel('Add new Upload').first().click()
|
||||
const createUploadDrawer = page.locator('dialog[id^=doc-drawer_uploads_]').first() // IDs starting with list-drawer_1_ (there's some other symbol after the underscore)
|
||||
await expect(createUploadDrawer).toBeVisible()
|
||||
await wait(500)
|
||||
|
||||
@@ -555,10 +542,10 @@ describe('lexicalMain', () => {
|
||||
await expect(secondUploadNode).toBeVisible()
|
||||
|
||||
await expect(secondUploadNode.locator('.lexical-upload__bottomRow')).toContainText(
|
||||
'payload.jpg',
|
||||
'payload-1.jpg',
|
||||
)
|
||||
await expect(secondUploadNode.locator('.lexical-upload__collectionLabel')).toContainText(
|
||||
'Upload 2',
|
||||
'Upload',
|
||||
)
|
||||
})
|
||||
|
||||
@@ -182,27 +182,6 @@ describe('Rich Text', () => {
|
||||
await expect(modalTrigger).toBeDisabled()
|
||||
})
|
||||
|
||||
test('should only list RTE enabled upload collections in drawer', async () => {
|
||||
await navigateToRichTextFields()
|
||||
await wait(1000)
|
||||
|
||||
// Open link drawer
|
||||
await page
|
||||
.locator('.rich-text__toolbar button:not([disabled]) .upload-rich-text-button')
|
||||
.first()
|
||||
.click()
|
||||
|
||||
const drawer = page.locator('[id^=list-drawer_1_]')
|
||||
await expect(drawer).toBeVisible()
|
||||
|
||||
// open the list select menu
|
||||
await page.locator('.list-drawer__select-collection-wrap .rs__control').click()
|
||||
|
||||
const menu = page.locator('.list-drawer__select-collection-wrap .rs__menu')
|
||||
// `uploads-3` has enableRichTextRelationship set to false
|
||||
await expect(menu).not.toContainText('Uploads3')
|
||||
})
|
||||
|
||||
// TODO: this test can't find the selector for the search filter, but functionality works.
|
||||
// Need to debug
|
||||
test.skip('should search correct useAsTitle field after toggling collection in list drawer', async () => {
|
||||
5
test/lexical/collections/Text/CustomDescription.tsx
Normal file
5
test/lexical/collections/Text/CustomDescription.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function CustomDescription() {
|
||||
return <div>Custom Description</div>
|
||||
}
|
||||
200
test/lexical/collections/Text/index.ts
Normal file
200
test/lexical/collections/Text/index.ts
Normal file
@@ -0,0 +1,200 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { defaultText, textFieldsSlug } from './shared.js'
|
||||
|
||||
const TextFields: CollectionConfig = {
|
||||
slug: textFieldsSlug,
|
||||
admin: {
|
||||
useAsTitle: 'text',
|
||||
},
|
||||
defaultSort: 'id',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
required: true,
|
||||
hooks: {
|
||||
beforeDuplicate: [({ value }) => `${value} - duplicate`],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'hiddenTextField',
|
||||
type: 'text',
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'adminHiddenTextField',
|
||||
type: 'text',
|
||||
admin: {
|
||||
hidden: true,
|
||||
description: 'This field should be hidden',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'disabledTextField',
|
||||
type: 'text',
|
||||
admin: {
|
||||
disabled: true,
|
||||
description: 'This field should be disabled',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'row',
|
||||
admin: {
|
||||
components: {
|
||||
Field: './components/CustomField.tsx#CustomField',
|
||||
},
|
||||
},
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
name: 'localizedText',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'i18nText',
|
||||
type: 'text',
|
||||
admin: {
|
||||
description: {
|
||||
en: 'en description',
|
||||
es: 'es description',
|
||||
},
|
||||
placeholder: {
|
||||
en: 'en placeholder',
|
||||
es: 'es placeholder',
|
||||
},
|
||||
},
|
||||
label: {
|
||||
en: 'Text en',
|
||||
es: 'Text es',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'defaultString',
|
||||
type: 'text',
|
||||
defaultValue: defaultText,
|
||||
},
|
||||
{
|
||||
name: 'defaultEmptyString',
|
||||
type: 'text',
|
||||
defaultValue: '',
|
||||
},
|
||||
{
|
||||
name: 'defaultFunction',
|
||||
type: 'text',
|
||||
defaultValue: () => defaultText,
|
||||
},
|
||||
{
|
||||
name: 'defaultAsync',
|
||||
type: 'text',
|
||||
defaultValue: async (): Promise<string> => {
|
||||
return new Promise((resolve) =>
|
||||
setTimeout(() => {
|
||||
resolve(defaultText)
|
||||
}, 1),
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'overrideLength',
|
||||
type: 'text',
|
||||
label: 'Override the 40k text length default',
|
||||
maxLength: 50000,
|
||||
},
|
||||
{
|
||||
name: 'fieldWithDefaultValue',
|
||||
type: 'text',
|
||||
defaultValue: async () => {
|
||||
const defaultValue = new Promise((resolve) => setTimeout(() => resolve('some-value'), 1000))
|
||||
|
||||
return defaultValue
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dependentOnFieldWithDefaultValue',
|
||||
type: 'text',
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
({ data }) => {
|
||||
return data?.fieldWithDefaultValue || ''
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'hasMany',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: 'readOnlyHasMany',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
admin: {
|
||||
readOnly: true,
|
||||
},
|
||||
defaultValue: ['default'],
|
||||
},
|
||||
{
|
||||
name: 'validatesHasMany',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
minLength: 3,
|
||||
},
|
||||
{
|
||||
name: 'localizedHasMany',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'withMinRows',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
minRows: 2,
|
||||
},
|
||||
{
|
||||
name: 'withMaxRows',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
maxRows: 4,
|
||||
},
|
||||
{
|
||||
name: 'defaultValueFromReq',
|
||||
type: 'text',
|
||||
defaultValue: async ({ req }) => {
|
||||
return Promise.resolve(req.context.defaultValue)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'array',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'texts',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'blocks',
|
||||
type: 'blocks',
|
||||
blocks: [
|
||||
{
|
||||
slug: 'blockWithText',
|
||||
fields: [
|
||||
{
|
||||
name: 'texts',
|
||||
type: 'text',
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default TextFields
|
||||
15
test/lexical/collections/Text/shared.ts
Normal file
15
test/lexical/collections/Text/shared.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { RequiredDataFromCollection } from 'payload/types'
|
||||
|
||||
import type { TextField } from '../../payload-types.js'
|
||||
|
||||
export const defaultText = 'default-text'
|
||||
export const textFieldsSlug = 'text-fields'
|
||||
|
||||
export const textDoc: RequiredDataFromCollection<TextField> = {
|
||||
text: 'Seeded text document',
|
||||
localizedText: 'Localized text',
|
||||
}
|
||||
|
||||
export const anotherTextDoc: RequiredDataFromCollection<TextField> = {
|
||||
text: 'Another text document',
|
||||
}
|
||||
1
test/lexical/collections/Upload/.gitignore
vendored
Normal file
1
test/lexical/collections/Upload/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
uploads
|
||||
37
test/lexical/collections/Upload/index.ts
Normal file
37
test/lexical/collections/Upload/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { uploadsSlug } from '../../slugs.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
const Uploads: CollectionConfig = {
|
||||
slug: uploadsSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'media',
|
||||
type: 'upload',
|
||||
filterOptions: {
|
||||
mimeType: {
|
||||
equals: 'image/png',
|
||||
},
|
||||
},
|
||||
relationTo: uploadsSlug,
|
||||
},
|
||||
// {
|
||||
// name: 'richText',
|
||||
// type: 'richText',
|
||||
// },
|
||||
],
|
||||
upload: {
|
||||
staticDir: path.resolve(dirname, './uploads'),
|
||||
},
|
||||
}
|
||||
|
||||
export default Uploads
|
||||
BIN
test/lexical/collections/Upload/payload.jpg
Normal file
BIN
test/lexical/collections/Upload/payload.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 119 KiB |
5
test/lexical/collections/Upload/shared.ts
Normal file
5
test/lexical/collections/Upload/shared.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Upload } from '../../payload-types.js'
|
||||
|
||||
export const uploadsDoc: Partial<Upload> = {
|
||||
text: 'An upload here',
|
||||
}
|
||||
9
test/lexical/components/CustomField.tsx
Normal file
9
test/lexical/components/CustomField.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
'use client'
|
||||
|
||||
import type { TextFieldClientComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomField: TextFieldClientComponent = ({ schemaPath }) => {
|
||||
return <div id="custom-field-schema-path">{schemaPath}</div>
|
||||
}
|
||||
36
test/lexical/config.blockreferences.ts
Normal file
36
test/lexical/config.blockreferences.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/* eslint-disable no-restricted-exports */
|
||||
|
||||
import type { BlockSlug } from 'payload'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { autoDedupeBlocksPlugin } from '../helpers/autoDedupeBlocksPlugin/index.js'
|
||||
import { baseConfig } from './baseConfig.js'
|
||||
import {
|
||||
getLexicalFieldsCollection,
|
||||
lexicalBlocks,
|
||||
lexicalInlineBlocks,
|
||||
} from './collections/Lexical/index.js'
|
||||
import { lexicalFieldsSlug } from './slugs.js'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
...baseConfig,
|
||||
blocks: [
|
||||
...(baseConfig.blocks ?? []),
|
||||
...lexicalBlocks.filter((block) => typeof block !== 'string'),
|
||||
...lexicalInlineBlocks.filter((block) => typeof block !== 'string'),
|
||||
],
|
||||
collections: baseConfig.collections?.map((collection) => {
|
||||
if (collection.slug === lexicalFieldsSlug) {
|
||||
return getLexicalFieldsCollection({
|
||||
blocks: lexicalBlocks.map((block) =>
|
||||
typeof block === 'string' ? block : block.slug,
|
||||
) as BlockSlug[],
|
||||
inlineBlocks: lexicalInlineBlocks.map((block) =>
|
||||
typeof block === 'string' ? block : block.slug,
|
||||
) as BlockSlug[],
|
||||
})
|
||||
}
|
||||
return collection
|
||||
}),
|
||||
plugins: [autoDedupeBlocksPlugin({ silent: false })],
|
||||
})
|
||||
5
test/lexical/config.ts
Normal file
5
test/lexical/config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
/* eslint-disable no-restricted-exports */
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { baseConfig } from './baseConfig.js'
|
||||
|
||||
export default buildConfigWithDefaults(baseConfig)
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable jest/no-conditional-in-test */
|
||||
import type {
|
||||
SerializedBlockNode,
|
||||
SerializedLinkNode,
|
||||
@@ -679,4 +680,71 @@ describe('Lexical', () => {
|
||||
).toEqual(210) // Initial: 20. BeforeChange: +1 (21). AfterRead: *10 (210)
|
||||
})
|
||||
})
|
||||
|
||||
describe('richText', () => {
|
||||
it('should allow querying on rich text content', async () => {
|
||||
const emptyRichTextQuery = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'doesnt exist',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(emptyRichTextQuery.docs).toHaveLength(0)
|
||||
|
||||
const workingRichTextQuery = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'hello',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(workingRichTextQuery.docs).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should show center alignment', async () => {
|
||||
const query = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.text': {
|
||||
like: 'hello',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(query.docs[0]?.richText[0]?.textAlign).toEqual('center')
|
||||
})
|
||||
|
||||
it('should populate link relationship', async () => {
|
||||
const query = await payload.find({
|
||||
collection: 'rich-text-fields',
|
||||
where: {
|
||||
'richText.children.linkType': {
|
||||
equals: 'internal',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const nodes = query.docs[0]?.richText
|
||||
expect(nodes).toBeDefined()
|
||||
const child = nodes?.flatMap((n) => n.children).find((c) => c?.doc)
|
||||
expect(child).toMatchObject({
|
||||
type: 'link',
|
||||
linkType: 'internal',
|
||||
})
|
||||
expect(child.doc.relationTo).toEqual('array-fields')
|
||||
|
||||
if (payload.db.defaultIDType === 'number') {
|
||||
expect(typeof child.doc.value.id).toBe('number')
|
||||
} else {
|
||||
expect(typeof child.doc.value.id).toBe('string')
|
||||
}
|
||||
|
||||
expect(child.doc.value.items).toHaveLength(6)
|
||||
})
|
||||
})
|
||||
})
|
||||
1311
test/lexical/payload-types.ts
Normal file
1311
test/lexical/payload-types.ts
Normal file
File diff suppressed because it is too large
Load Diff
452
test/lexical/seed.ts
Normal file
452
test/lexical/seed.ts
Normal file
@@ -0,0 +1,452 @@
|
||||
import type { Payload } from 'payload'
|
||||
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { lexicalDocData } from './collections/Lexical/data.js'
|
||||
import { generateLexicalLocalizedRichText } from './collections/LexicalLocalized/generateLexicalRichText.js'
|
||||
import { textToLexicalJSON } from './collections/LexicalLocalized/textToLexicalJSON.js'
|
||||
import { lexicalMigrateDocData } from './collections/LexicalMigrate/data.js'
|
||||
import { richTextBulletsDocData, richTextDocData } from './collections/RichText/data.js'
|
||||
import {
|
||||
arrayFieldsSlug,
|
||||
collectionSlugs,
|
||||
lexicalFieldsSlug,
|
||||
lexicalLocalizedFieldsSlug,
|
||||
lexicalMigrateFieldsSlug,
|
||||
lexicalRelationshipFieldsSlug,
|
||||
richTextFieldsSlug,
|
||||
textFieldsSlug,
|
||||
uploadsSlug,
|
||||
usersSlug,
|
||||
} from './slugs.js'
|
||||
|
||||
// import type { Payload } from 'payload'
|
||||
|
||||
import { getFileByPath } from 'payload'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { seedDB } from '../helpers/seed.js'
|
||||
import { arrayDoc } from './collections/Array/shared.js'
|
||||
import { anotherTextDoc, textDoc } from './collections/Text/shared.js'
|
||||
import { uploadsDoc } from './collections/Upload/shared.js'
|
||||
// import { blocksDoc } from './collections/Blocks/shared.js'
|
||||
// import { codeDoc } from './collections/Code/shared.js'
|
||||
// import { collapsibleDoc } from './collections/Collapsible/shared.js'
|
||||
// import { conditionalLogicDoc } from './collections/ConditionalLogic/shared.js'
|
||||
// import { customRowID, customTabID, nonStandardID } from './collections/CustomID/shared.js'
|
||||
// import { dateDoc } from './collections/Date/shared.js'
|
||||
// import { anotherEmailDoc, emailDoc } from './collections/Email/shared.js'
|
||||
// import { groupDoc } from './collections/Group/shared.js'
|
||||
// import { jsonDoc } from './collections/JSON/shared.js'
|
||||
// import { lexicalDocData } from './collections/Lexical/data.js'
|
||||
// import { generateLexicalLocalizedRichText } from './collections/LexicalLocalized/generateLexicalRichText.js'
|
||||
// import { textToLexicalJSON } from './collections/LexicalLocalized/textToLexicalJSON.js'
|
||||
// import { lexicalMigrateDocData } from './collections/LexicalMigrate/data.js'
|
||||
// import { numberDoc } from './collections/Number/shared.js'
|
||||
// import { pointDoc } from './collections/Point/shared.js'
|
||||
// import { radiosDoc } from './collections/Radio/shared.js'
|
||||
// import { richTextBulletsDocData, richTextDocData } from './collections/RichText/data.js'
|
||||
// import { selectsDoc } from './collections/Select/shared.js'
|
||||
// import { tabsDoc } from './collections/Tabs/shared.js'
|
||||
// import { anotherTextDoc, textDoc } from './collections/Text/shared.js'
|
||||
// import { uploadsDoc } from './collections/Upload/shared.js'
|
||||
// import {
|
||||
// arrayFieldsSlug,
|
||||
// blockFieldsSlug,
|
||||
// checkboxFieldsSlug,
|
||||
// codeFieldsSlug,
|
||||
// collapsibleFieldsSlug,
|
||||
// collectionSlugs,
|
||||
// conditionalLogicSlug,
|
||||
// customIDSlug,
|
||||
// customRowIDSlug,
|
||||
// customTabIDSlug,
|
||||
// dateFieldsSlug,
|
||||
// emailFieldsSlug,
|
||||
// groupFieldsSlug,
|
||||
// jsonFieldsSlug,
|
||||
// lexicalFieldsSlug,
|
||||
// lexicalLocalizedFieldsSlug,
|
||||
// lexicalMigrateFieldsSlug,
|
||||
// lexicalRelationshipFieldsSlug,
|
||||
// numberFieldsSlug,
|
||||
// pointFieldsSlug,
|
||||
// radioFieldsSlug,
|
||||
// relationshipFieldsSlug,
|
||||
// richTextFieldsSlug,
|
||||
// selectFieldsSlug,
|
||||
// tabsFieldsSlug,
|
||||
// textFieldsSlug,
|
||||
// uiSlug,
|
||||
// uploads2Slug,
|
||||
// uploadsMulti,
|
||||
// uploadsMultiPoly,
|
||||
// uploadsPoly,
|
||||
// uploadsSlug,
|
||||
// usersSlug,
|
||||
// } from './slugs.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
export const seed = async (_payload: Payload) => {
|
||||
const jpgPath = path.resolve(dirname, './collections/Upload/payload.jpg')
|
||||
const pngPath = path.resolve(dirname, './uploads/payload.png')
|
||||
|
||||
// Get both files in parallel
|
||||
const [jpgFile, pngFile] = await Promise.all([getFileByPath(jpgPath), getFileByPath(pngPath)])
|
||||
|
||||
const createdArrayDoc = await _payload.create({
|
||||
collection: arrayFieldsSlug,
|
||||
data: arrayDoc,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdTextDoc = await _payload.create({
|
||||
collection: textFieldsSlug,
|
||||
data: textDoc,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: textFieldsSlug,
|
||||
data: anotherTextDoc,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdPNGDoc = await _payload.create({
|
||||
collection: uploadsSlug,
|
||||
data: {},
|
||||
file: pngFile,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdJPGDoc = await _payload.create({
|
||||
collection: uploadsSlug,
|
||||
data: {
|
||||
...uploadsDoc,
|
||||
media: createdPNGDoc.id,
|
||||
},
|
||||
file: jpgFile,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const formattedID =
|
||||
_payload.db.defaultIDType === 'number' ? createdArrayDoc.id : `"${createdArrayDoc.id}"`
|
||||
|
||||
const formattedJPGID =
|
||||
_payload.db.defaultIDType === 'number' ? createdJPGDoc.id : `"${createdJPGDoc.id}"`
|
||||
|
||||
const formattedTextID =
|
||||
_payload.db.defaultIDType === 'number' ? createdTextDoc.id : `"${createdTextDoc.id}"`
|
||||
|
||||
const richTextDocWithRelId = JSON.parse(
|
||||
JSON.stringify(richTextDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`),
|
||||
)
|
||||
const richTextBulletsDocWithRelId = JSON.parse(
|
||||
JSON.stringify(richTextBulletsDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`),
|
||||
)
|
||||
|
||||
const richTextDocWithRelationship = { ...richTextDocWithRelId }
|
||||
|
||||
await _payload.create({
|
||||
collection: richTextFieldsSlug,
|
||||
data: richTextBulletsDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const createdRichTextDoc = await _payload.create({
|
||||
collection: richTextFieldsSlug,
|
||||
data: richTextDocWithRelationship,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const formattedRichTextDocID =
|
||||
_payload.db.defaultIDType === 'number' ? createdRichTextDoc.id : `"${createdRichTextDoc.id}"`
|
||||
|
||||
const lexicalDocWithRelId = JSON.parse(
|
||||
JSON.stringify(lexicalDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`)
|
||||
.replace(/"\{\{RICH_TEXT_DOC_ID\}\}"/g, `${formattedRichTextDocID}`),
|
||||
)
|
||||
|
||||
const lexicalMigrateDocWithRelId = JSON.parse(
|
||||
JSON.stringify(lexicalMigrateDocData)
|
||||
.replace(/"\{\{ARRAY_DOC_ID\}\}"/g, `${formattedID}`)
|
||||
.replace(/"\{\{UPLOAD_DOC_ID\}\}"/g, `${formattedJPGID}`)
|
||||
.replace(/"\{\{TEXT_DOC_ID\}\}"/g, `${formattedTextID}`)
|
||||
.replace(/"\{\{RICH_TEXT_DOC_ID\}\}"/g, `${formattedRichTextDocID}`),
|
||||
)
|
||||
|
||||
await _payload.create({
|
||||
collection: usersSlug,
|
||||
depth: 0,
|
||||
data: {
|
||||
email: devUser.email,
|
||||
password: devUser.password,
|
||||
},
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalFieldsSlug,
|
||||
data: lexicalDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const lexicalLocalizedDoc1 = await _payload.create({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
data: {
|
||||
title: 'Localized Lexical en',
|
||||
lexicalBlocksLocalized: textToLexicalJSON({ text: 'English text' }),
|
||||
lexicalBlocksSubLocalized: generateLexicalLocalizedRichText(
|
||||
'Shared text',
|
||||
'English text in block',
|
||||
) as any,
|
||||
},
|
||||
locale: 'en',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalRelationshipFieldsSlug,
|
||||
data: {
|
||||
richText: textToLexicalJSON({ text: 'English text' }),
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.update({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
id: lexicalLocalizedDoc1.id,
|
||||
data: {
|
||||
title: 'Localized Lexical es',
|
||||
lexicalBlocksLocalized: textToLexicalJSON({ text: 'Spanish text' }),
|
||||
lexicalBlocksSubLocalized: generateLexicalLocalizedRichText(
|
||||
'Shared text',
|
||||
'Spanish text in block',
|
||||
(lexicalLocalizedDoc1.lexicalBlocksSubLocalized.root.children[1].fields as any).id,
|
||||
) as any,
|
||||
},
|
||||
locale: 'es',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const lexicalLocalizedDoc2 = await _payload.create({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
data: {
|
||||
title: 'Localized Lexical en 2',
|
||||
|
||||
lexicalBlocksLocalized: textToLexicalJSON({
|
||||
text: 'English text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
lexicalBlocksSubLocalized: textToLexicalJSON({
|
||||
text: 'English text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
},
|
||||
locale: 'en',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.update({
|
||||
collection: lexicalLocalizedFieldsSlug,
|
||||
id: lexicalLocalizedDoc2.id,
|
||||
data: {
|
||||
title: 'Localized Lexical es 2',
|
||||
|
||||
lexicalBlocksLocalized: textToLexicalJSON({
|
||||
text: 'Spanish text 2',
|
||||
lexicalLocalizedRelID: lexicalLocalizedDoc1.id,
|
||||
}),
|
||||
},
|
||||
locale: 'es',
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: lexicalMigrateFieldsSlug,
|
||||
data: lexicalMigrateDocWithRelId,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const getInlineBlock = () => ({
|
||||
type: 'inlineBlock',
|
||||
fields: {
|
||||
id: Math.random().toString(36).substring(2, 15),
|
||||
text: 'text',
|
||||
blockType: 'inlineBlockInLexical',
|
||||
},
|
||||
version: 1,
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: 'LexicalInBlock',
|
||||
depth: 0,
|
||||
data: {
|
||||
content: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
format: '',
|
||||
type: 'block',
|
||||
version: 2,
|
||||
fields: {
|
||||
id: '6773773284be8978db7a498d',
|
||||
lexicalInBlock: textToLexicalJSON({ text: 'text' }),
|
||||
blockName: '',
|
||||
blockType: 'blockInLexical',
|
||||
},
|
||||
},
|
||||
],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
blocks: [
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
blockName: '1',
|
||||
lexical: textToLexicalJSON({ text: '1' }),
|
||||
},
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
blockName: '2',
|
||||
lexical: textToLexicalJSON({ text: '2' }),
|
||||
},
|
||||
{
|
||||
blockType: 'lexicalInBlock2',
|
||||
lexical: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
children: [...Array.from({ length: 20 }, () => getInlineBlock())],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'paragraph',
|
||||
version: 1,
|
||||
textFormat: 0,
|
||||
textStyle: '',
|
||||
},
|
||||
],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
id: '67e1af0b78de3228e23ef1d5',
|
||||
blockName: '1',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: 'lexical-access-control',
|
||||
data: {
|
||||
richText: {
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'text ',
|
||||
type: 'text',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
children: [
|
||||
{
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'link',
|
||||
type: 'text',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'link',
|
||||
version: 3,
|
||||
fields: {
|
||||
url: 'https://',
|
||||
newTab: false,
|
||||
linkType: 'custom',
|
||||
blocks: [
|
||||
{
|
||||
id: '67e45673cbd5181ca8cbeef7',
|
||||
blockType: 'block',
|
||||
},
|
||||
],
|
||||
},
|
||||
id: '67e4566fcbd5181ca8cbeef5',
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'paragraph',
|
||||
version: 1,
|
||||
textFormat: 0,
|
||||
textStyle: '',
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
title: 'title',
|
||||
},
|
||||
depth: 0,
|
||||
})
|
||||
}
|
||||
|
||||
export async function clearAndSeedEverything(_payload: Payload) {
|
||||
return await seedDB({
|
||||
_payload,
|
||||
collectionSlugs,
|
||||
seedFunction: seed,
|
||||
snapshotKey: 'fieldsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
}
|
||||
24
test/lexical/slugs.ts
Normal file
24
test/lexical/slugs.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export const usersSlug = 'users'
|
||||
|
||||
export const lexicalFieldsSlug = 'lexical-fields'
|
||||
export const lexicalLocalizedFieldsSlug = 'lexical-localized-fields'
|
||||
export const lexicalMigrateFieldsSlug = 'lexical-migrate-fields'
|
||||
export const lexicalRelationshipFieldsSlug = 'lexical-relationship-fields'
|
||||
export const lexicalAccessControlSlug = 'lexical-access-control'
|
||||
export const richTextFieldsSlug = 'rich-text-fields'
|
||||
|
||||
// Auxiliary slugs
|
||||
export const textFieldsSlug = 'text-fields'
|
||||
export const uploadsSlug = 'uploads'
|
||||
export const arrayFieldsSlug = 'array-fields'
|
||||
|
||||
export const collectionSlugs = [
|
||||
lexicalFieldsSlug,
|
||||
lexicalLocalizedFieldsSlug,
|
||||
lexicalMigrateFieldsSlug,
|
||||
lexicalRelationshipFieldsSlug,
|
||||
lexicalAccessControlSlug,
|
||||
richTextFieldsSlug,
|
||||
textFieldsSlug,
|
||||
uploadsSlug,
|
||||
]
|
||||
13
test/lexical/tsconfig.eslint.json
Normal file
13
test/lexical/tsconfig.eslint.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// extend your base config to share compilerOptions, etc
|
||||
//"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// ensure that nobody can accidentally use this config for a build
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
// whatever paths you intend to lint
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx"
|
||||
]
|
||||
}
|
||||
3
test/lexical/tsconfig.json
Normal file
3
test/lexical/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../tsconfig.json"
|
||||
}
|
||||
BIN
test/lexical/uploads/payload.png
Normal file
BIN
test/lexical/uploads/payload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 341 KiB |
Reference in New Issue
Block a user