diff --git a/packages/payload/src/fields/hooks/afterRead/promise.ts b/packages/payload/src/fields/hooks/afterRead/promise.ts index 1a2d9d33f0..c6e43ae95d 100644 --- a/packages/payload/src/fields/hooks/afterRead/promise.ts +++ b/packages/payload/src/fields/hooks/afterRead/promise.ts @@ -6,6 +6,7 @@ import type { SanitizedGlobalConfig } from '../../../globals/config/types' import type { Field, TabAsField } from '../../config/types' import { fieldAffectsData, tabHasName } from '../../config/types' +import getValueWithDefault from '../../getDefaultValue' import relationshipPopulationPromise from './relationshipPopulationPromise' import { traverseFields } from './traverseFields' @@ -265,6 +266,20 @@ export const promise = async ({ } } + // Set defaultValue on the field for globals being returned without being first created + // or collection documents created prior to having a default + if ( + typeof siblingDoc[field.name] === 'undefined' && + typeof field.defaultValue !== 'undefined' + ) { + siblingDoc[field.name] = await getValueWithDefault({ + defaultValue: field.defaultValue, + locale: req.locale, + user: req.user, + value: siblingDoc[field.name], + }) + } + if (field.type === 'relationship' || field.type === 'upload') { populationPromises.push( relationshipPopulationPromise({ diff --git a/test/globals/config.ts b/test/globals/config.ts index 00686f4be3..443e4b2832 100644 --- a/test/globals/config.ts +++ b/test/globals/config.ts @@ -6,6 +6,8 @@ export const arraySlug = 'array' export const accessControlSlug = 'access-control' +export const defaultValueSlug = 'default-value' + export const englishLocale = 'en' export const spanishLocale = 'es' @@ -17,13 +19,8 @@ const access = { } export default buildConfigWithDefaults({ - localization: { - locales: [englishLocale, spanishLocale], - defaultLocale: englishLocale, - }, globals: [ { - slug, access, fields: [ { @@ -35,26 +32,47 @@ export default buildConfigWithDefaults({ type: 'text', }, ], + slug, }, { - slug: arraySlug, access, fields: [ { name: 'array', - type: 'array', - localized: true, fields: [ { name: 'text', type: 'text', }, ], + localized: true, + type: 'array', }, ], + slug: arraySlug, + }, + { + fields: [ + { + name: 'text', + defaultValue: 'test', + type: 'text', + }, + { + name: 'group', + fields: [ + { + name: 'text', + defaultValue: 'test', + type: 'text', + }, + ], + type: 'group', + }, + ], + slug: defaultValueSlug, }, { - slug: accessControlSlug, access: { read: ({ req: { user } }) => { if (user) { @@ -71,22 +89,27 @@ export default buildConfigWithDefaults({ fields: [ { name: 'title', - type: 'text', required: true, + type: 'text', }, { name: 'enabled', type: 'checkbox', }, ], + slug: accessControlSlug, }, { - slug: 'without-graphql', access, - graphQL: false, fields: [], + graphQL: false, + slug: 'without-graphql', }, ], + localization: { + defaultLocale: englishLocale, + locales: [englishLocale, spanishLocale], + }, onInit: async (payload) => { await payload.create({ collection: 'users', @@ -97,10 +120,10 @@ export default buildConfigWithDefaults({ }) await payload.updateGlobal({ - slug: accessControlSlug, data: { title: 'hello', }, + slug: accessControlSlug, }) }, }) diff --git a/test/globals/int.spec.ts b/test/globals/int.spec.ts index 5650d9e47b..07d7db9dc9 100644 --- a/test/globals/int.spec.ts +++ b/test/globals/int.spec.ts @@ -6,6 +6,7 @@ import { RESTClient } from '../helpers/rest' import configPromise, { accessControlSlug, arraySlug, + defaultValueSlug, englishLocale, slug, spanishLocale, @@ -21,14 +22,14 @@ describe('globals', () => { let client: RESTClient beforeAll(async () => { const config = await configPromise - client = new RESTClient(config, { serverURL, defaultSlug: slug }) + client = new RESTClient(config, { defaultSlug: slug, serverURL }) }) it('should create', async () => { const title = 'update' const data = { title, } - const { status, doc } = await client.updateGlobal({ data }) + const { doc, status } = await client.updateGlobal({ data }) expect(status).toEqual(200) expect(doc).toMatchObject(data) @@ -40,7 +41,7 @@ describe('globals', () => { title, } await client.updateGlobal({ data }) - const { status, doc } = await client.findGlobal() + const { doc, status } = await client.findGlobal() expect(status).toEqual(200) expect(doc.globalType).toEqual(slug) @@ -54,11 +55,11 @@ describe('globals', () => { }, ] - const { status, doc } = await client.updateGlobal({ - slug: arraySlug, + const { doc, status } = await client.updateGlobal({ data: { array, }, + slug: arraySlug, }) expect(status).toBe(200) @@ -71,12 +72,12 @@ describe('globals', () => { describe('local', () => { it('should save empty json objects', async () => { const createdJSON: any = await payload.updateGlobal({ - slug, data: { json: { state: {}, }, }, + slug, }) expect(createdJSON.json.state).toEqual({}) @@ -87,8 +88,8 @@ describe('globals', () => { title: 'title', } const doc = await payload.updateGlobal({ - slug, data, + slug, }) expect(doc).toMatchObject(data) }) @@ -99,8 +100,8 @@ describe('globals', () => { title, } await payload.updateGlobal({ - slug, data, + slug, }) const doc = await payload.findGlobal({ slug, @@ -129,19 +130,19 @@ describe('globals', () => { } await payload.updateGlobal({ - slug: arraySlug, - locale: englishLocale, data: { array: localized.en.array, }, + locale: englishLocale, + slug: arraySlug, }) await payload.updateGlobal({ - slug: arraySlug, - locale: spanishLocale, data: { array: localized.es.array, }, + locale: spanishLocale, + slug: arraySlug, }) const en = await payload.findGlobal({ @@ -160,26 +161,36 @@ describe('globals', () => { it('should respect valid access query constraint', async () => { const emptyGlobal = await payload.findGlobal({ - slug: accessControlSlug, overrideAccess: false, + slug: accessControlSlug, }) expect(Object.keys(emptyGlobal)).toHaveLength(0) await payload.updateGlobal({ - slug: accessControlSlug, data: { enabled: true, }, + slug: accessControlSlug, }) const hasAccess = await payload.findGlobal({ - slug: accessControlSlug, overrideAccess: false, + slug: accessControlSlug, }) expect(hasAccess.title).toBeDefined() }) + + it('should get globals with defaultValues populated before first creation', async () => { + const defaultValueGlobal = await payload.findGlobal({ + slug: defaultValueSlug, + }) + + expect(defaultValueGlobal.text).toStrictEqual('test') + // @ts-ignore + expect(defaultValueGlobal.group.text).toStrictEqual('test') + }) }) describe('graphql', () => { @@ -209,8 +220,8 @@ describe('globals', () => { title: 'updated graphql', } await payload.updateGlobal({ - slug, data, + slug, }) const query = `query {