fix: incorrect value inside beforeValidate field hooks (#11433)
### What? `value` within the beforeValidate field hook was not correctly falling back to the document value when no value was passed inside the request for the field. ### Why? The fallback logic was running after the beforeValidate field hooks are called. ### How? Run the fallback logic before running the beforeValidate field hooks. Fixes https://github.com/payloadcms/payload/issues/10923
This commit is contained in:
34
test/hooks/collections/Value/index.ts
Normal file
34
test/hooks/collections/Value/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const valueHooksSlug = 'value-hooks'
|
||||
export const ValueCollection: CollectionConfig = {
|
||||
slug: valueHooksSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'slug',
|
||||
type: 'text',
|
||||
hooks: {
|
||||
beforeValidate: [
|
||||
({ value, siblingData }) => {
|
||||
siblingData.beforeValidate_value = String(value)
|
||||
return value
|
||||
},
|
||||
],
|
||||
beforeChange: [
|
||||
({ value, siblingData }) => {
|
||||
siblingData.beforeChange_value = String(value)
|
||||
return value
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'beforeValidate_value',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'beforeChange_value',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import NestedAfterReadHooks from './collections/NestedAfterReadHooks/index.js'
|
||||
import Relations from './collections/Relations/index.js'
|
||||
import TransformHooks from './collections/Transform/index.js'
|
||||
import Users, { seedHooksUsers } from './collections/Users/index.js'
|
||||
import { ValueCollection } from './collections/Value/index.js'
|
||||
import { DataHooksGlobal } from './globals/Data/index.js'
|
||||
|
||||
export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
@@ -40,6 +41,7 @@ export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
Users,
|
||||
DataHooks,
|
||||
FieldPaths,
|
||||
ValueCollection,
|
||||
],
|
||||
globals: [DataHooksGlobal],
|
||||
endpoints: [
|
||||
|
||||
@@ -21,9 +21,10 @@ import {
|
||||
import { relationsSlug } from './collections/Relations/index.js'
|
||||
import { transformSlug } from './collections/Transform/index.js'
|
||||
import { hooksUsersSlug } from './collections/Users/index.js'
|
||||
import { beforeValidateSlug, fieldPathsSlug } from './shared.js'
|
||||
import { valueHooksSlug } from './collections/Value/index.js'
|
||||
import { HooksConfig } from './config.js'
|
||||
import { dataHooksGlobalSlug } from './globals/Data/index.js'
|
||||
import { beforeValidateSlug, fieldPathsSlug } from './shared.js'
|
||||
|
||||
let restClient: NextRESTClient
|
||||
let payload: Payload
|
||||
@@ -612,6 +613,24 @@ describe('Hooks', () => {
|
||||
}),
|
||||
})
|
||||
})
|
||||
|
||||
it('should assign value properly when missing in data', async () => {
|
||||
const doc = await payload.create({
|
||||
collection: valueHooksSlug,
|
||||
data: {
|
||||
slug: 'test',
|
||||
},
|
||||
})
|
||||
|
||||
const updatedDoc = await payload.update({
|
||||
id: doc.id,
|
||||
collection: valueHooksSlug,
|
||||
data: {},
|
||||
})
|
||||
|
||||
expect(updatedDoc.beforeValidate_value).toEqual('test')
|
||||
expect(updatedDoc.beforeChange_value).toEqual('test')
|
||||
})
|
||||
})
|
||||
|
||||
describe('config level after error hook', () => {
|
||||
|
||||
@@ -78,6 +78,7 @@ export interface Config {
|
||||
'hooks-users': HooksUser;
|
||||
'data-hooks': DataHook;
|
||||
'field-paths': FieldPath;
|
||||
'value-hooks': ValueHook;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
@@ -96,6 +97,7 @@ export interface Config {
|
||||
'hooks-users': HooksUsersSelect<false> | HooksUsersSelect<true>;
|
||||
'data-hooks': DataHooksSelect<false> | DataHooksSelect<true>;
|
||||
'field-paths': FieldPathsSelect<false> | FieldPathsSelect<true>;
|
||||
'value-hooks': ValueHooksSelect<false> | ValueHooksSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
@@ -610,6 +612,18 @@ export interface FieldPath {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "value-hooks".
|
||||
*/
|
||||
export interface ValueHook {
|
||||
id: string;
|
||||
slug?: string | null;
|
||||
beforeValidate_value?: string | null;
|
||||
beforeChange_value?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
@@ -664,6 +678,10 @@ export interface PayloadLockedDocument {
|
||||
| ({
|
||||
relationTo: 'field-paths';
|
||||
value: string | FieldPath;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'value-hooks';
|
||||
value: string | ValueHook;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
@@ -910,6 +928,17 @@ export interface FieldPathsSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "value-hooks_select".
|
||||
*/
|
||||
export interface ValueHooksSelect<T extends boolean = true> {
|
||||
slug?: T;
|
||||
beforeValidate_value?: T;
|
||||
beforeChange_value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
|
||||
Reference in New Issue
Block a user