Skip to content

Commit e9cd2a5

Browse files
fix: add missing afterOperation and beforeOperation hook calls (#14778)
Fixes #14726 Refactors how we call beforeOperation hooks more similarly to how we call afterOperation hooks. Adds beforeOperations and afterOperations functions to operations. Both were missing in `unlock`, `findVersions` and `findVersionByID`
1 parent 51c951f commit e9cd2a5

File tree

24 files changed

+626
-403
lines changed

24 files changed

+626
-403
lines changed

packages/payload/src/auth/operations/forgotPassword.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import type {
99
import type { CollectionSlug } from '../../index.js'
1010
import type { PayloadRequest, Where } from '../../types/index.js'
1111

12-
import { buildAfterOperation } from '../../collections/operations/utils.js'
12+
import { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'
13+
import { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'
1314
import { APIError } from '../../errors/index.js'
1415
import { Forbidden } from '../../index.js'
1516
import { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'
@@ -64,19 +65,11 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
6465
// /////////////////////////////////////
6566
// beforeOperation - Collection
6667
// /////////////////////////////////////
67-
68-
if (args.collection.config.hooks?.beforeOperation?.length) {
69-
for (const hook of args.collection.config.hooks.beforeOperation) {
70-
args =
71-
(await hook({
72-
args,
73-
collection: args.collection?.config,
74-
context: args.req.context,
75-
operation: 'forgotPassword',
76-
req: args.req,
77-
})) || args
78-
}
79-
}
68+
args = await buildBeforeOperation({
69+
args,
70+
collection: args.collection.config,
71+
operation: 'forgotPassword',
72+
})
8073

8174
const {
8275
collection: { config: collectionConfig },

packages/payload/src/auth/operations/login.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type {
66
import type { CollectionSlug, TypedUser } from '../../index.js'
77
import type { PayloadRequest, Where } from '../../types/index.js'
88

9-
import { buildAfterOperation } from '../../collections/operations/utils.js'
9+
import { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'
10+
import { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'
1011
import {
1112
AuthenticationError,
1213
LockedAuth,
@@ -81,18 +82,11 @@ export const loginOperation = async <TSlug extends CollectionSlug>(
8182
// beforeOperation - Collection
8283
// /////////////////////////////////////
8384

84-
if (args.collection.config.hooks?.beforeOperation?.length) {
85-
for (const hook of args.collection.config.hooks.beforeOperation) {
86-
args =
87-
(await hook({
88-
args,
89-
collection: args.collection?.config,
90-
context: args.req.context,
91-
operation: 'login',
92-
req: args.req,
93-
})) || args
94-
}
95-
}
85+
args = await buildBeforeOperation({
86+
args,
87+
collection: args.collection.config,
88+
operation: 'login',
89+
})
9690

9791
const {
9892
collection: { config: collectionConfig },

packages/payload/src/auth/operations/refresh.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import url from 'url'
33
import type { Collection } from '../../collections/config/types.js'
44
import type { Document, PayloadRequest } from '../../types/index.js'
55

6-
import { buildAfterOperation } from '../../collections/operations/utils.js'
6+
import { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'
7+
import { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'
78
import { Forbidden } from '../../errors/index.js'
89
import { commitTransaction } from '../../utilities/commitTransaction.js'
910
import { initTransaction } from '../../utilities/initTransaction.js'
@@ -41,18 +42,11 @@ export const refreshOperation = async (incomingArgs: Arguments): Promise<Result>
4142
// beforeOperation - Collection
4243
// /////////////////////////////////////
4344

44-
if (args.collection.config.hooks?.beforeOperation?.length) {
45-
for (const hook of args.collection.config.hooks.beforeOperation) {
46-
args =
47-
(await hook({
48-
args,
49-
collection: args.collection?.config,
50-
context: args.req.context,
51-
operation: 'refresh',
52-
req: args.req,
53-
})) || args
54-
}
55-
}
45+
args = await buildBeforeOperation({
46+
args,
47+
collection: args.collection.config,
48+
operation: 'refresh',
49+
})
5650

5751
// /////////////////////////////////////
5852
// Refresh

packages/payload/src/auth/operations/resetPassword.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import type { Collection, DataFromCollectionSlug } from '../../collections/confi
44
import type { CollectionSlug } from '../../index.js'
55
import type { PayloadRequest } from '../../types/index.js'
66

7-
import { buildAfterOperation } from '../../collections/operations/utils.js'
7+
import { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'
8+
import { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'
89
import { APIError, Forbidden } from '../../errors/index.js'
910
import { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'
1011
import { commitTransaction } from '../../utilities/commitTransaction.js'
@@ -61,18 +62,11 @@ export const resetPasswordOperation = async <TSlug extends CollectionSlug>(
6162
try {
6263
const shouldCommit = await initTransaction(req)
6364

64-
if (args.collection.config.hooks?.beforeOperation?.length) {
65-
for (const hook of args.collection.config.hooks.beforeOperation) {
66-
args =
67-
(await hook({
68-
args,
69-
collection: args.collection?.config,
70-
context: args.req.context,
71-
operation: 'resetPassword',
72-
req: args.req,
73-
})) || args
74-
}
75-
}
65+
args = await buildBeforeOperation({
66+
args,
67+
collection: args.collection.config,
68+
operation: 'resetPassword',
69+
})
7670

7771
// /////////////////////////////////////
7872
// Reset Password

packages/payload/src/auth/operations/unlock.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import type {
77
import type { CollectionSlug } from '../../index.js'
88
import type { PayloadRequest, Where } from '../../types/index.js'
99

10+
import { buildAfterOperation } from '../../collections/operations/utilities/buildAfterOperation.js'
11+
import { buildBeforeOperation } from '../../collections/operations/utilities/buildBeforeOperation.js'
1012
import { APIError } from '../../errors/index.js'
1113
import { combineQueries, Forbidden } from '../../index.js'
1214
import { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'
@@ -57,6 +59,12 @@ export const unlockOperation = async <TSlug extends CollectionSlug>(
5759
}
5860

5961
try {
62+
args = await buildBeforeOperation({
63+
args,
64+
collection: args.collection.config,
65+
operation: 'unlock',
66+
})
67+
6068
const shouldCommit = await initTransaction(req)
6169
let whereConstraint: Where = {}
6270

@@ -123,7 +131,14 @@ export const unlockOperation = async <TSlug extends CollectionSlug>(
123131
await commitTransaction(req)
124132
}
125133

126-
return result
134+
result = await buildAfterOperation({
135+
args,
136+
collection: args.collection.config,
137+
operation: 'unlock',
138+
result,
139+
})
140+
141+
return Boolean(result)
127142
} catch (error: unknown) {
128143
await killTransaction(req)
129144
throw error

packages/payload/src/collections/config/types.ts

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ import type {
5858
IncomingCollectionVersions,
5959
SanitizedCollectionVersions,
6060
} from '../../versions/types.js'
61-
import type { AfterOperationArg, AfterOperationMap } from '../operations/utils.js'
61+
import type {
62+
AfterOperationArg,
63+
BeforeOperationArg,
64+
OperationMap,
65+
} from '../operations/utilities/types.js'
6266

6367
export type DataFromCollectionSlug<TSlug extends CollectionSlug> = TypedCollection[TSlug]
6468

@@ -69,7 +73,7 @@ export type AuthOperationsFromCollectionSlug<TSlug extends CollectionSlug> =
6973

7074
export type RequiredDataFromCollection<TData extends JsonObject> = MarkOptional<
7175
TData,
72-
'createdAt' | 'deletedAt' | 'id' | 'sizes' | 'updatedAt'
76+
'createdAt' | 'deletedAt' | 'id' | 'updatedAt'
7377
>
7478

7579
export type RequiredDataFromCollectionSlug<TSlug extends CollectionSlug> =
@@ -80,7 +84,7 @@ export type RequiredDataFromCollectionSlug<TSlug extends CollectionSlug> =
8084
* When creating a draft, required fields don't need to be provided as validation is skipped
8185
*/
8286
export type DraftDataFromCollection<TData extends JsonObject> = Partial<
83-
MarkOptional<TData, 'createdAt' | 'deletedAt' | 'id' | 'sizes' | 'updatedAt'>
87+
MarkOptional<TData, 'createdAt' | 'deletedAt' | 'id' | 'updatedAt'>
8488
>
8589

8690
export type DraftDataFromCollectionSlug<TSlug extends CollectionSlug> = DraftDataFromCollection<
@@ -104,19 +108,13 @@ export type HookOperationType =
104108

105109
type CreateOrUpdateOperation = Extract<HookOperationType, 'create' | 'update'>
106110

107-
export type BeforeOperationHook = (args: {
108-
args?: any
109-
/**
110-
* The collection which this hook is being run on
111-
*/
112-
collection: SanitizedCollectionConfig
113-
context: RequestContext
114-
/**
115-
* Hook operation being performed
116-
*/
117-
operation: HookOperationType
118-
req: PayloadRequest
119-
}) => any
111+
export type BeforeOperationHook<TOperationGeneric extends CollectionSlug = string> = (
112+
arg: BeforeOperationArg<TOperationGeneric>,
113+
) =>
114+
| Parameters<OperationMap<TOperationGeneric>[keyof OperationMap<TOperationGeneric>]>[0]
115+
| Promise<Parameters<OperationMap<TOperationGeneric>[keyof OperationMap<TOperationGeneric>]>[0]>
116+
| Promise<void>
117+
| void
120118

121119
export type BeforeValidateHook<T extends TypeWithID = any> = (args: {
122120
/** The collection which this hook is being run on */
@@ -207,13 +205,9 @@ export type AfterDeleteHook<T extends TypeWithID = any> = (args: {
207205
export type AfterOperationHook<TOperationGeneric extends CollectionSlug = string> = (
208206
arg: AfterOperationArg<TOperationGeneric>,
209207
) =>
210-
| Awaited<
211-
ReturnType<AfterOperationMap<TOperationGeneric>[keyof AfterOperationMap<TOperationGeneric>]>
212-
>
208+
| Awaited<ReturnType<OperationMap<TOperationGeneric>[keyof OperationMap<TOperationGeneric>]>>
213209
| Promise<
214-
Awaited<
215-
ReturnType<AfterOperationMap<TOperationGeneric>[keyof AfterOperationMap<TOperationGeneric>]>
216-
>
210+
Awaited<ReturnType<OperationMap<TOperationGeneric>[keyof OperationMap<TOperationGeneric>]>>
217211
>
218212

219213
export type BeforeLoginHook<T extends TypeWithID = any> = (args: {
@@ -577,7 +571,7 @@ export type CollectionConfig<TSlug extends CollectionSlug = any> = {
577571
beforeChange?: BeforeChangeHook[]
578572
beforeDelete?: BeforeDeleteHook[]
579573
beforeLogin?: BeforeLoginHook[]
580-
beforeOperation?: BeforeOperationHook[]
574+
beforeOperation?: BeforeOperationHook<TSlug>[]
581575
beforeRead?: BeforeReadHook[]
582576
beforeValidate?: BeforeValidateHook[]
583577
/**

packages/payload/src/collections/operations/count.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { validateQueryPaths } from '../../database/queryValidation/validateQuery
99
import { sanitizeWhereQuery } from '../../database/sanitizeWhereQuery.js'
1010
import { appendNonTrashedFilter } from '../../utilities/appendNonTrashedFilter.js'
1111
import { killTransaction } from '../../utilities/killTransaction.js'
12-
import { buildAfterOperation } from './utils.js'
12+
import { buildAfterOperation } from './utilities/buildAfterOperation.js'
13+
import { buildBeforeOperation } from './utilities/buildBeforeOperation.js'
1314

1415
export type Arguments = {
1516
collection: Collection
@@ -31,18 +32,11 @@ export const countOperation = async <TSlug extends CollectionSlug>(
3132
// beforeOperation - Collection
3233
// /////////////////////////////////////
3334

34-
if (args.collection.config.hooks?.beforeOperation?.length) {
35-
for (const hook of args.collection.config.hooks.beforeOperation) {
36-
args =
37-
(await hook({
38-
args,
39-
collection: args.collection.config,
40-
context: args.req!.context,
41-
operation: 'count',
42-
req: args.req!,
43-
})) || args
44-
}
45-
}
35+
args = await buildBeforeOperation({
36+
args,
37+
collection: args.collection.config,
38+
operation: 'count',
39+
})
4640

4741
const {
4842
collection: { config: collectionConfig },

packages/payload/src/collections/operations/countVersions.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { validateQueryPaths } from '../../database/queryValidation/validateQuery
88
import { sanitizeWhereQuery } from '../../database/sanitizeWhereQuery.js'
99
import { buildVersionCollectionFields, type CollectionSlug } from '../../index.js'
1010
import { killTransaction } from '../../utilities/killTransaction.js'
11-
import { buildAfterOperation } from './utils.js'
11+
import { buildAfterOperation } from './utilities/buildAfterOperation.js'
12+
import { buildBeforeOperation } from './utilities/buildBeforeOperation.js'
1213

1314
export type Arguments = {
1415
collection: Collection
@@ -29,18 +30,11 @@ export const countVersionsOperation = async <TSlug extends CollectionSlug>(
2930
// beforeOperation - Collection
3031
// /////////////////////////////////////
3132

32-
if (args.collection.config.hooks.beforeOperation?.length) {
33-
for (const hook of args.collection.config.hooks.beforeOperation) {
34-
args =
35-
(await hook({
36-
args,
37-
collection: args.collection.config,
38-
context: args.req!.context,
39-
operation: 'countVersions',
40-
req: args.req!,
41-
})) || args
42-
}
43-
}
33+
args = await buildBeforeOperation({
34+
args,
35+
collection: args.collection.config,
36+
operation: 'countVersions',
37+
})
4438

4539
const {
4640
collection: { config: collectionConfig },

packages/payload/src/collections/operations/create.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import { initTransaction } from '../../utilities/initTransaction.js'
3434
import { killTransaction } from '../../utilities/killTransaction.js'
3535
import { sanitizeInternalFields } from '../../utilities/sanitizeInternalFields.js'
3636
import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'
37-
import { buildAfterOperation } from './utils.js'
37+
import { buildAfterOperation } from './utilities/buildAfterOperation.js'
38+
import { buildBeforeOperation } from './utilities/buildBeforeOperation.js'
3839

3940
export type Arguments<TSlug extends CollectionSlug> = {
4041
autosave?: boolean
@@ -78,18 +79,11 @@ export const createOperation = async <
7879
// beforeOperation - Collection
7980
// /////////////////////////////////////
8081

81-
if (args.collection.config.hooks.beforeOperation?.length) {
82-
for (const hook of args.collection.config.hooks.beforeOperation) {
83-
args =
84-
(await hook({
85-
args,
86-
collection: args.collection.config,
87-
context: args.req.context,
88-
operation: 'create',
89-
req: args.req,
90-
})) || args
91-
}
92-
}
82+
args = await buildBeforeOperation({
83+
args,
84+
collection: args.collection.config,
85+
operation: 'create',
86+
})
9387

9488
if (args.publishSpecificLocale) {
9589
args.req.locale = args.publishSpecificLocale

packages/payload/src/collections/operations/delete.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import { killTransaction } from '../../utilities/killTransaction.js'
2828
import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'
2929
import { deleteCollectionVersions } from '../../versions/deleteCollectionVersions.js'
3030
import { deleteScheduledPublishJobs } from '../../versions/deleteScheduledPublishJobs.js'
31-
import { buildAfterOperation } from './utils.js'
31+
import { buildAfterOperation } from './utilities/buildAfterOperation.js'
32+
import { buildBeforeOperation } from './utilities/buildBeforeOperation.js'
3233

3334
export type Arguments = {
3435
collection: Collection
@@ -58,18 +59,11 @@ export const deleteOperation = async <
5859
// beforeOperation - Collection
5960
// /////////////////////////////////////
6061

61-
if (args.collection.config.hooks?.beforeOperation?.length) {
62-
for (const hook of args.collection.config.hooks.beforeOperation) {
63-
args =
64-
(await hook({
65-
args,
66-
collection: args.collection.config,
67-
context: args.req.context,
68-
operation: 'delete',
69-
req: args.req,
70-
})) || args
71-
}
72-
}
62+
args = await buildBeforeOperation({
63+
args,
64+
collection: args.collection.config,
65+
operation: 'delete',
66+
})
7367

7468
const {
7569
collection: { config: collectionConfig },

0 commit comments

Comments
 (0)