Compare commits
13 Commits
main
...
fix/config
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4eb75d9db | ||
|
|
e5eed336ff | ||
|
|
73a8a1836d | ||
|
|
a9d0b31f3f | ||
|
|
c82d130fd7 | ||
|
|
7a815f7e51 | ||
|
|
f212870f82 | ||
|
|
1d07fba5cb | ||
|
|
a5c995445b | ||
|
|
9bac0398d7 | ||
|
|
7af16bd1a7 | ||
|
|
00f27bba16 | ||
|
|
ceda0ad028 |
@@ -99,6 +99,7 @@
|
||||
"get-tsconfig": "4.8.1",
|
||||
"http-status": "2.1.0",
|
||||
"image-size": "2.0.2",
|
||||
"immer": "10.1.1",
|
||||
"jose": "5.9.6",
|
||||
"json-schema-to-typescript": "15.0.3",
|
||||
"minimist": "1.2.8",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { createDraft, finishDraft, isDraft, setAutoFreeze } from 'immer'
|
||||
|
||||
import type { Config, SanitizedConfig } from './types.js'
|
||||
|
||||
import { sanitizeConfig } from './sanitize.js'
|
||||
@@ -9,10 +11,27 @@ import { sanitizeConfig } from './sanitize.js'
|
||||
*/
|
||||
export async function buildConfig(config: Config): Promise<SanitizedConfig> {
|
||||
if (Array.isArray(config.plugins)) {
|
||||
let configAfterPlugins = config
|
||||
// Not freezing objects is faster
|
||||
setAutoFreeze(false)
|
||||
|
||||
// Use Immer to ensure config modifications by plugins are immutable and do not affect the original config / shared references
|
||||
let mutableConfig: Config = createDraft(config) as Config
|
||||
|
||||
for (const plugin of config.plugins) {
|
||||
configAfterPlugins = await plugin(configAfterPlugins)
|
||||
const newConfig = await plugin(mutableConfig)
|
||||
if (isDraft(newConfig)) {
|
||||
mutableConfig = newConfig
|
||||
} else {
|
||||
// If the plugin returns a new config object that is no longer a draft, we need to merge it into the mutable config
|
||||
for (const key of Object.keys(newConfig)) {
|
||||
// @ts-expect-error - We know this is safe - not worth fixing
|
||||
mutableConfig[key as keyof Config] = newConfig[key as keyof Config]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const configAfterPlugins = finishDraft(mutableConfig)
|
||||
|
||||
return await sanitizeConfig(configAfterPlugins)
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,12 @@ export const getFields = ({
|
||||
...(existingURLField || {}),
|
||||
hooks: {
|
||||
afterRead: [
|
||||
getAfterReadHook({ adapter, collection, disablePayloadAccessControl, generateFileURL }),
|
||||
getAfterReadHook({
|
||||
adapter,
|
||||
collectionSlug: collection.slug,
|
||||
disablePayloadAccessControl,
|
||||
generateFileURL,
|
||||
}),
|
||||
...(existingURLField?.hooks?.afterRead || []),
|
||||
],
|
||||
},
|
||||
@@ -114,7 +119,7 @@ export const getFields = ({
|
||||
afterRead: [
|
||||
getAfterReadHook({
|
||||
adapter,
|
||||
collection,
|
||||
collectionSlug: collection.slug,
|
||||
disablePayloadAccessControl,
|
||||
generateFileURL,
|
||||
size,
|
||||
|
||||
@@ -4,14 +4,15 @@ import type { GeneratedAdapter, TypeWithPrefix } from '../types.js'
|
||||
|
||||
interface Args {
|
||||
adapter: GeneratedAdapter
|
||||
collection: CollectionConfig
|
||||
collectionSlug: string
|
||||
}
|
||||
|
||||
export const getAfterDeleteHook = ({
|
||||
adapter,
|
||||
collection,
|
||||
collectionSlug,
|
||||
}: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {
|
||||
return async ({ doc, req }) => {
|
||||
const collection = req.payload.collections[collectionSlug]?.config as CollectionConfig
|
||||
try {
|
||||
const filesToDelete: string[] = [
|
||||
doc.filename,
|
||||
|
||||
@@ -4,15 +4,23 @@ import type { GeneratedAdapter, GenerateFileURL } from '../types.js'
|
||||
|
||||
interface Args {
|
||||
adapter: GeneratedAdapter
|
||||
collection: CollectionConfig
|
||||
collectionSlug: string
|
||||
disablePayloadAccessControl?: boolean
|
||||
generateFileURL?: GenerateFileURL
|
||||
size?: ImageSize
|
||||
}
|
||||
|
||||
export const getAfterReadHook =
|
||||
({ adapter, collection, disablePayloadAccessControl, generateFileURL, size }: Args): FieldHook =>
|
||||
async ({ data, value }) => {
|
||||
({
|
||||
adapter,
|
||||
collectionSlug,
|
||||
disablePayloadAccessControl,
|
||||
generateFileURL,
|
||||
size,
|
||||
}: Args): FieldHook =>
|
||||
async ({ data, req, value }) => {
|
||||
const collection = req.payload.collections[collectionSlug]?.config as CollectionConfig
|
||||
|
||||
const filename = size ? data?.sizes?.[size.name]?.filename : data?.filename
|
||||
const prefix = data?.prefix
|
||||
let url = value
|
||||
|
||||
@@ -6,12 +6,14 @@ import { getIncomingFiles } from '../utilities/getIncomingFiles.js'
|
||||
|
||||
interface Args {
|
||||
adapter: GeneratedAdapter
|
||||
collection: CollectionConfig
|
||||
collectionSlug: string
|
||||
}
|
||||
|
||||
export const getBeforeChangeHook =
|
||||
({ adapter, collection }: Args): CollectionBeforeChangeHook<FileData & TypeWithID> =>
|
||||
({ adapter, collectionSlug }: Args): CollectionBeforeChangeHook<FileData & TypeWithID> =>
|
||||
async ({ data, originalDoc, req }) => {
|
||||
const collection = req.payload.collections[collectionSlug]?.config as CollectionConfig
|
||||
|
||||
try {
|
||||
const files = getIncomingFiles({ data, req })
|
||||
|
||||
|
||||
@@ -17,15 +17,16 @@ import { getBeforeChangeHook } from './hooks/beforeChange.js'
|
||||
|
||||
export const cloudStoragePlugin =
|
||||
(pluginOptions: PluginOptions) =>
|
||||
(incomingConfig: Config): Config => {
|
||||
(config: Config): Config => {
|
||||
const { collections: allCollectionOptions, enabled } = pluginOptions
|
||||
const config = { ...incomingConfig }
|
||||
|
||||
// Return early if disabled. Only webpack config mods are applied.
|
||||
if (enabled === false) {
|
||||
return config
|
||||
}
|
||||
|
||||
const onInit = config.onInit
|
||||
|
||||
const initFunctions: Array<() => void> = []
|
||||
|
||||
return {
|
||||
@@ -77,11 +78,11 @@ export const cloudStoragePlugin =
|
||||
...(existingCollection.hooks || {}),
|
||||
afterDelete: [
|
||||
...(existingCollection.hooks?.afterDelete || []),
|
||||
getAfterDeleteHook({ adapter, collection: existingCollection }),
|
||||
getAfterDeleteHook({ adapter, collectionSlug: existingCollection.slug }),
|
||||
],
|
||||
beforeChange: [
|
||||
...(existingCollection.hooks?.beforeChange || []),
|
||||
getBeforeChangeHook({ adapter, collection: existingCollection }),
|
||||
getBeforeChangeHook({ adapter, collectionSlug: existingCollection.slug }),
|
||||
],
|
||||
},
|
||||
upload: {
|
||||
@@ -100,8 +101,8 @@ export const cloudStoragePlugin =
|
||||
}),
|
||||
onInit: async (payload) => {
|
||||
initFunctions.forEach((fn) => fn())
|
||||
if (config.onInit) {
|
||||
await config.onInit(payload)
|
||||
if (onInit) {
|
||||
await onInit(payload)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -110,8 +110,12 @@ const resave = async ({ collection, doc, draft, pluginConfig, req }: ResaveArgs)
|
||||
}
|
||||
|
||||
export const resaveChildren =
|
||||
(pluginConfig: NestedDocsPluginConfig, collection: CollectionConfig): CollectionAfterChangeHook =>
|
||||
(pluginConfig: NestedDocsPluginConfig, collectionSlug: string): CollectionAfterChangeHook =>
|
||||
async ({ doc, req }) => {
|
||||
const collection = req.payload.collections[collectionSlug]?.config
|
||||
if (!collection) {
|
||||
throw new Error(`Collection ${collectionSlug} not found`)
|
||||
}
|
||||
await resave({
|
||||
collection,
|
||||
doc,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CollectionAfterChangeHook, CollectionConfig } from 'payload'
|
||||
import type { CollectionAfterChangeHook } from 'payload'
|
||||
|
||||
import type { Breadcrumb, NestedDocsPluginConfig } from '../types.js'
|
||||
|
||||
@@ -6,12 +6,17 @@ import type { Breadcrumb, NestedDocsPluginConfig } from '../types.js'
|
||||
// so that we can build its breadcrumbs with the newly created document's ID.
|
||||
|
||||
export const resaveSelfAfterCreate =
|
||||
(pluginConfig: NestedDocsPluginConfig, collection: CollectionConfig): CollectionAfterChangeHook =>
|
||||
(pluginConfig: NestedDocsPluginConfig, collectionSlug: string): CollectionAfterChangeHook =>
|
||||
async ({ doc, operation, req }) => {
|
||||
if (operation !== 'create') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const collection = req.payload.collections[collectionSlug]?.config
|
||||
if (!collection) {
|
||||
throw new Error(`Collection ${collectionSlug} not found`)
|
||||
}
|
||||
|
||||
const { locale, payload } = req
|
||||
const breadcrumbSlug = pluginConfig.breadcrumbsFieldSlug || 'breadcrumbs'
|
||||
const breadcrumbs = doc[breadcrumbSlug] as unknown as Breadcrumb[]
|
||||
|
||||
@@ -47,19 +47,28 @@ export const nestedDocsPlugin =
|
||||
fields.push(createBreadcrumbsField(collection.slug))
|
||||
}
|
||||
|
||||
const collectionSlug = collection.slug
|
||||
|
||||
return {
|
||||
...collection,
|
||||
fields,
|
||||
hooks: {
|
||||
...(collection.hooks || {}),
|
||||
afterChange: [
|
||||
resaveChildren(pluginConfig, collection),
|
||||
resaveSelfAfterCreate(pluginConfig, collection),
|
||||
resaveChildren(pluginConfig, collection.slug),
|
||||
resaveSelfAfterCreate(pluginConfig, collection.slug),
|
||||
...(collection?.hooks?.afterChange || []),
|
||||
],
|
||||
beforeChange: [
|
||||
async ({ data, originalDoc, req }) =>
|
||||
populateBreadcrumbs(req, pluginConfig, collection, data, originalDoc),
|
||||
async ({ data, originalDoc, req }) => {
|
||||
const collectionConfig = req.payload.collections[collectionSlug]?.config
|
||||
if (!collectionConfig) {
|
||||
throw new Error(`Collection ${collectionSlug} not found`)
|
||||
}
|
||||
|
||||
return populateBreadcrumbs(req, pluginConfig, collectionConfig, data, originalDoc)
|
||||
},
|
||||
|
||||
...(collection?.hooks?.beforeChange || []),
|
||||
],
|
||||
},
|
||||
|
||||
@@ -144,10 +144,11 @@ export const seoPlugin =
|
||||
const result = pluginConfig.generateTitle
|
||||
? await pluginConfig.generateTitle({
|
||||
...data,
|
||||
collectionConfig: config.collections?.find(
|
||||
(c) => c.slug === reqData.collectionSlug,
|
||||
collectionConfig:
|
||||
req.payload.collections[reqData.collectionSlug as string]?.config,
|
||||
globalConfig: req.payload.config.globals?.find(
|
||||
(g) => g.slug === reqData.globalSlug,
|
||||
),
|
||||
globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),
|
||||
req,
|
||||
} satisfies Parameters<GenerateTitle>[0])
|
||||
: ''
|
||||
@@ -168,10 +169,12 @@ export const seoPlugin =
|
||||
const result = pluginConfig.generateDescription
|
||||
? await pluginConfig.generateDescription({
|
||||
...data,
|
||||
collectionConfig: config.collections?.find(
|
||||
(c) => c.slug === reqData.collectionSlug,
|
||||
collectionConfig:
|
||||
req.payload.collections[reqData.collectionSlug as string]?.config,
|
||||
|
||||
globalConfig: req.payload.config.globals?.find(
|
||||
(g) => g.slug === reqData.globalSlug,
|
||||
),
|
||||
globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),
|
||||
req,
|
||||
} satisfies Parameters<GenerateDescription>[0])
|
||||
: ''
|
||||
@@ -192,10 +195,12 @@ export const seoPlugin =
|
||||
const result = pluginConfig.generateURL
|
||||
? await pluginConfig.generateURL({
|
||||
...data,
|
||||
collectionConfig: config.collections?.find(
|
||||
(c) => c.slug === reqData.collectionSlug,
|
||||
collectionConfig:
|
||||
req.payload.collections[reqData.collectionSlug as string]?.config,
|
||||
|
||||
globalConfig: req.payload.config.globals?.find(
|
||||
(g) => g.slug === reqData.globalSlug,
|
||||
),
|
||||
globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),
|
||||
req,
|
||||
} satisfies Parameters<GenerateURL>[0])
|
||||
: ''
|
||||
@@ -216,10 +221,12 @@ export const seoPlugin =
|
||||
const result = pluginConfig.generateImage
|
||||
? await pluginConfig.generateImage({
|
||||
...data,
|
||||
collectionConfig: config.collections?.find(
|
||||
(c) => c.slug === reqData.collectionSlug,
|
||||
collectionConfig:
|
||||
req.payload.collections[reqData.collectionSlug as string]?.config,
|
||||
|
||||
globalConfig: req.payload.config.globals?.find(
|
||||
(g) => g.slug === reqData.globalSlug,
|
||||
),
|
||||
globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),
|
||||
req,
|
||||
} satisfies Parameters<GenerateImage>[0])
|
||||
: ''
|
||||
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -847,6 +847,9 @@ importers:
|
||||
image-size:
|
||||
specifier: 2.0.2
|
||||
version: 2.0.2
|
||||
immer:
|
||||
specifier: 10.1.1
|
||||
version: 10.1.1
|
||||
jose:
|
||||
specifier: 5.9.6
|
||||
version: 5.9.6
|
||||
@@ -7570,6 +7573,9 @@ packages:
|
||||
immediate@3.0.6:
|
||||
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||
|
||||
immer@10.1.1:
|
||||
resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==}
|
||||
|
||||
immer@9.0.21:
|
||||
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
|
||||
|
||||
@@ -8581,6 +8587,7 @@ packages:
|
||||
node-domexception@1.0.0:
|
||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||
engines: {node: '>=10.5.0'}
|
||||
deprecated: Use your platform's native DOMException instead
|
||||
|
||||
node-fetch-native@1.6.4:
|
||||
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
|
||||
@@ -17451,6 +17458,8 @@ snapshots:
|
||||
|
||||
immediate@3.0.6: {}
|
||||
|
||||
immer@10.1.1: {}
|
||||
|
||||
immer@9.0.21: {}
|
||||
|
||||
immutable@4.3.7: {}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import type { SanitizedConfig } from 'payload'
|
||||
import type { CollectionConfig, SanitizedConfig } from 'payload'
|
||||
|
||||
import { APIError } from 'payload'
|
||||
|
||||
@@ -22,6 +22,17 @@ import Users, { seedHooksUsers } from './collections/Users/index.js'
|
||||
import { ValueCollection } from './collections/Value/index.js'
|
||||
import { DataHooksGlobal } from './globals/Data/index.js'
|
||||
|
||||
const sharedHooks: CollectionConfig['hooks'] = {
|
||||
afterRead: [
|
||||
({ doc }) => {
|
||||
return {
|
||||
...doc,
|
||||
afterRead1: true,
|
||||
}
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
admin: {
|
||||
importMap: {
|
||||
@@ -42,6 +53,43 @@ export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
DataHooks,
|
||||
FieldPaths,
|
||||
ValueCollection,
|
||||
{
|
||||
slug: 'sharedHooks1',
|
||||
hooks: sharedHooks,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'sharedHooks2',
|
||||
hooks: sharedHooks,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
(config) => {
|
||||
const sharedHooks1 = config?.collections?.find((c) => c.slug === 'sharedHooks1')
|
||||
|
||||
if (!sharedHooks1) {
|
||||
return config
|
||||
}
|
||||
|
||||
;((sharedHooks1.hooks ??= {}).afterRead ??= []).push(({ doc }) => {
|
||||
return {
|
||||
...doc,
|
||||
afterRead2: true,
|
||||
}
|
||||
})
|
||||
return config
|
||||
},
|
||||
],
|
||||
globals: [DataHooksGlobal],
|
||||
endpoints: [
|
||||
|
||||
@@ -665,4 +665,20 @@ describe('Hooks', () => {
|
||||
expect(updateResult).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
it('plugins adding hooks should only affect targetted collection, regardless of hooks object reference', async () => {
|
||||
const sharedHooks1: any = await payload.create({
|
||||
collection: 'sharedHooks1',
|
||||
data: {},
|
||||
})
|
||||
const sharedHooks2: any = await payload.create({
|
||||
collection: 'sharedHooks2',
|
||||
data: {},
|
||||
})
|
||||
|
||||
expect(sharedHooks1.afterRead1).toBeTruthy()
|
||||
expect(sharedHooks1.afterRead2).toBeTruthy()
|
||||
expect(sharedHooks2.afterRead1).toBeTruthy()
|
||||
expect(sharedHooks2.afterRead2).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -80,6 +80,8 @@ export interface Config {
|
||||
'data-hooks': DataHook;
|
||||
'field-paths': FieldPath;
|
||||
'value-hooks': ValueHook;
|
||||
sharedHooks1: SharedHooks1;
|
||||
sharedHooks2: SharedHooks2;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
@@ -99,6 +101,8 @@ export interface Config {
|
||||
'data-hooks': DataHooksSelect<false> | DataHooksSelect<true>;
|
||||
'field-paths': FieldPathsSelect<false> | FieldPathsSelect<true>;
|
||||
'value-hooks': ValueHooksSelect<false> | ValueHooksSelect<true>;
|
||||
sharedHooks1: SharedHooks1Select<false> | SharedHooks1Select<true>;
|
||||
sharedHooks2: SharedHooks2Select<false> | SharedHooks2Select<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
@@ -625,6 +629,26 @@ export interface ValueHook {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "sharedHooks1".
|
||||
*/
|
||||
export interface SharedHooks1 {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "sharedHooks2".
|
||||
*/
|
||||
export interface SharedHooks2 {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
@@ -683,6 +707,14 @@ export interface PayloadLockedDocument {
|
||||
| ({
|
||||
relationTo: 'value-hooks';
|
||||
value: string | ValueHook;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'sharedHooks1';
|
||||
value: string | SharedHooks1;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'sharedHooks2';
|
||||
value: string | SharedHooks2;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
@@ -940,6 +972,24 @@ export interface ValueHooksSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "sharedHooks1_select".
|
||||
*/
|
||||
export interface SharedHooks1Select<T extends boolean = true> {
|
||||
text?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "sharedHooks2_select".
|
||||
*/
|
||||
export interface SharedHooks2Select<T extends boolean = true> {
|
||||
text?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
|
||||
@@ -3,8 +3,9 @@ import type { ArrayField, Payload, RelationshipField } from 'payload'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Page } from './payload-types.js'
|
||||
|
||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
import { Page } from './payload-types.js'
|
||||
|
||||
let payload: Payload
|
||||
|
||||
@@ -98,8 +99,8 @@ describe('@payloadcms/plugin-nested-docs', () => {
|
||||
},
|
||||
})
|
||||
|
||||
const firstUpdatedChildBreadcrumbs = docs[0]?.breadcrumbs as Page['breadcrumbs']
|
||||
const lastUpdatedChildBreadcrumbs = docs[10]?.breadcrumbs as Page['breadcrumbs']
|
||||
const firstUpdatedChildBreadcrumbs = docs[0]?.breadcrumbs
|
||||
const lastUpdatedChildBreadcrumbs = docs[10]?.breadcrumbs
|
||||
|
||||
expect(firstUpdatedChildBreadcrumbs).toHaveLength(2)
|
||||
// @ts-ignore
|
||||
|
||||
Reference in New Issue
Block a user