feat: consolidates logic in update and updateByID operations (#9998)
### What? Consolidates logic in update and updateByID. These two operations used a lot of the same core functionality. This is a QOL improvement for future features/fixes on each operation. You will not need to make changes to both operations now. ### Why? Recently we released a feature for `publishSpecificLocale` and that was only implemented on the updateByID operation. I think future enhancements and fixes may suffer the same treatment. ### How? Moves shared logic into a new file with a function called `updateDocument`.
This commit is contained in:
@@ -13,26 +13,18 @@ import type {
|
|||||||
SelectFromCollectionSlug,
|
SelectFromCollectionSlug,
|
||||||
} from '../config/types.js'
|
} from '../config/types.js'
|
||||||
|
|
||||||
import { ensureUsernameOrEmail } from '../../auth/ensureUsernameOrEmail.js'
|
|
||||||
import executeAccess from '../../auth/executeAccess.js'
|
import executeAccess from '../../auth/executeAccess.js'
|
||||||
import { combineQueries } from '../../database/combineQueries.js'
|
import { combineQueries } from '../../database/combineQueries.js'
|
||||||
import { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths.js'
|
import { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths.js'
|
||||||
import { APIError } from '../../errors/index.js'
|
import { APIError } from '../../errors/index.js'
|
||||||
import { afterChange } from '../../fields/hooks/afterChange/index.js'
|
|
||||||
import { afterRead } from '../../fields/hooks/afterRead/index.js'
|
|
||||||
import { beforeChange } from '../../fields/hooks/beforeChange/index.js'
|
|
||||||
import { beforeValidate } from '../../fields/hooks/beforeValidate/index.js'
|
|
||||||
import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles.js'
|
|
||||||
import { generateFileData } from '../../uploads/generateFileData.js'
|
import { generateFileData } from '../../uploads/generateFileData.js'
|
||||||
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'
|
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'
|
||||||
import { uploadFiles } from '../../uploads/uploadFiles.js'
|
|
||||||
import { checkDocumentLockStatus } from '../../utilities/checkDocumentLockStatus.js'
|
|
||||||
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
||||||
import { initTransaction } from '../../utilities/initTransaction.js'
|
import { initTransaction } from '../../utilities/initTransaction.js'
|
||||||
import { killTransaction } from '../../utilities/killTransaction.js'
|
import { killTransaction } from '../../utilities/killTransaction.js'
|
||||||
import { buildVersionCollectionFields } from '../../versions/buildCollectionFields.js'
|
import { buildVersionCollectionFields } from '../../versions/buildCollectionFields.js'
|
||||||
import { appendVersionToQueryKey } from '../../versions/drafts/appendVersionToQueryKey.js'
|
import { appendVersionToQueryKey } from '../../versions/drafts/appendVersionToQueryKey.js'
|
||||||
import { saveVersion } from '../../versions/saveVersion.js'
|
import { updateDocument } from './utilities/update.js'
|
||||||
import { buildAfterOperation } from './utils.js'
|
import { buildAfterOperation } from './utils.js'
|
||||||
|
|
||||||
export type Arguments<TSlug extends CollectionSlug> = {
|
export type Arguments<TSlug extends CollectionSlug> = {
|
||||||
@@ -47,6 +39,7 @@ export type Arguments<TSlug extends CollectionSlug> = {
|
|||||||
overrideLock?: boolean
|
overrideLock?: boolean
|
||||||
overwriteExistingFiles?: boolean
|
overwriteExistingFiles?: boolean
|
||||||
populate?: PopulateType
|
populate?: PopulateType
|
||||||
|
publishSpecificLocale?: string
|
||||||
req: PayloadRequest
|
req: PayloadRequest
|
||||||
select?: SelectType
|
select?: SelectType
|
||||||
showHiddenFields?: boolean
|
showHiddenFields?: boolean
|
||||||
@@ -91,6 +84,7 @@ export const updateOperation = async <
|
|||||||
overrideLock,
|
overrideLock,
|
||||||
overwriteExistingFiles = false,
|
overwriteExistingFiles = false,
|
||||||
populate,
|
populate,
|
||||||
|
publishSpecificLocale,
|
||||||
req: {
|
req: {
|
||||||
fallbackLocale,
|
fallbackLocale,
|
||||||
locale,
|
locale,
|
||||||
@@ -172,7 +166,7 @@ export const updateOperation = async <
|
|||||||
// Generate data for all files and sizes
|
// Generate data for all files and sizes
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
const { data: newFileData, files: filesToUpload } = await generateFileData({
|
const { data, files: filesToUpload } = await generateFileData({
|
||||||
collection,
|
collection,
|
||||||
config,
|
config,
|
||||||
data: bulkUpdateData,
|
data: bulkUpdateData,
|
||||||
@@ -184,251 +178,37 @@ export const updateOperation = async <
|
|||||||
|
|
||||||
const errors = []
|
const errors = []
|
||||||
|
|
||||||
const promises = docs.map(async (doc) => {
|
const promises = docs.map(async (docWithLocales) => {
|
||||||
const { id } = doc
|
const { id } = docWithLocales
|
||||||
let data = {
|
|
||||||
...newFileData,
|
|
||||||
...bulkUpdateData,
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// /////////////////////////////////////
|
// ///////////////////////////////////////////////
|
||||||
// Handle potentially locked documents
|
// Update document, runs all document level hooks
|
||||||
// /////////////////////////////////////
|
// ///////////////////////////////////////////////
|
||||||
|
const updatedDoc = await updateDocument({
|
||||||
await checkDocumentLockStatus({
|
|
||||||
id,
|
id,
|
||||||
collectionSlug: collectionConfig.slug,
|
accessResults: accessResult,
|
||||||
lockErrorMessage: `Document with ID ${id} is currently locked by another user and cannot be updated.`,
|
autosave: false,
|
||||||
overrideLock,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
const originalDoc = await afterRead({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
depth: 0,
|
|
||||||
doc,
|
|
||||||
draft: draftArg,
|
|
||||||
fallbackLocale,
|
|
||||||
global: null,
|
|
||||||
locale,
|
|
||||||
overrideAccess: true,
|
|
||||||
req,
|
|
||||||
showHiddenFields: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
await deleteAssociatedFiles({
|
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
config,
|
config,
|
||||||
doc,
|
|
||||||
files: filesToUpload,
|
|
||||||
overrideDelete: false,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (args.collection.config.auth) {
|
|
||||||
ensureUsernameOrEmail<TSlug>({
|
|
||||||
authOptions: args.collection.config.auth,
|
|
||||||
collectionSlug: args.collection.config.slug,
|
|
||||||
data: args.data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req: args.req,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeValidate - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
data = await beforeValidate<DeepPartial<DataFromCollectionSlug<TSlug>>>({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
data,
|
||||||
doc: originalDoc,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
overrideAccess,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeValidate - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
data =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req,
|
|
||||||
})) || data
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Write files to local storage
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (!collectionConfig.upload.disableLocalStorage) {
|
|
||||||
await uploadFiles(payload, filesToUpload, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeChange - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
data =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req,
|
|
||||||
})) || data
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeChange - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
let result = await beforeChange({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
doc: originalDoc,
|
|
||||||
docWithLocales: doc,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
req,
|
|
||||||
skipValidation:
|
|
||||||
shouldSaveDraft &&
|
|
||||||
collectionConfig.versions.drafts &&
|
|
||||||
!collectionConfig.versions.drafts.validate &&
|
|
||||||
data._status !== 'published',
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Update
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (!shouldSaveDraft || data._status === 'published') {
|
|
||||||
result = await req.payload.db.updateOne({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig.slug,
|
|
||||||
data: result,
|
|
||||||
locale,
|
|
||||||
req,
|
|
||||||
select,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Create version
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (collectionConfig.versions) {
|
|
||||||
result = await saveVersion({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig,
|
|
||||||
docWithLocales: result,
|
|
||||||
payload,
|
|
||||||
req,
|
|
||||||
select,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterRead - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
result = await afterRead({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
depth,
|
depth,
|
||||||
doc: result,
|
docWithLocales,
|
||||||
draft: draftArg,
|
draftArg,
|
||||||
fallbackLocale: null,
|
fallbackLocale,
|
||||||
global: null,
|
filesToUpload,
|
||||||
locale,
|
locale,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
|
overrideLock,
|
||||||
|
payload,
|
||||||
populate,
|
populate,
|
||||||
|
publishSpecificLocale,
|
||||||
req,
|
req,
|
||||||
select,
|
select,
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
|
|
||||||
// /////////////////////////////////////
|
return updatedDoc
|
||||||
// afterRead - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
result =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
doc: result,
|
|
||||||
req,
|
|
||||||
})) || result
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterChange - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
result = await afterChange({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
doc: result,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
previousDoc: originalDoc,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterChange - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
result =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
doc: result,
|
|
||||||
operation: 'update',
|
|
||||||
previousDoc: originalDoc,
|
|
||||||
req,
|
|
||||||
})) || result
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
await unlinkTempFiles({
|
|
||||||
collectionConfig,
|
|
||||||
config,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Return results
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
return result
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
id,
|
id,
|
||||||
@@ -438,6 +218,12 @@ export const updateOperation = async <
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await unlinkTempFiles({
|
||||||
|
collectionConfig,
|
||||||
|
config,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
const awaitedDocs = await Promise.all(promises)
|
const awaitedDocs = await Promise.all(promises)
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { DeepPartial } from 'ts-essentials'
|
|||||||
import httpStatus from 'http-status'
|
import httpStatus from 'http-status'
|
||||||
|
|
||||||
import type { FindOneArgs } from '../../database/types.js'
|
import type { FindOneArgs } from '../../database/types.js'
|
||||||
import type { Args } from '../../fields/hooks/beforeChange/index.js'
|
|
||||||
import type { CollectionSlug } from '../../index.js'
|
import type { CollectionSlug } from '../../index.js'
|
||||||
import type {
|
import type {
|
||||||
PayloadRequest,
|
PayloadRequest,
|
||||||
@@ -13,31 +12,21 @@ import type {
|
|||||||
} from '../../types/index.js'
|
} from '../../types/index.js'
|
||||||
import type {
|
import type {
|
||||||
Collection,
|
Collection,
|
||||||
DataFromCollectionSlug,
|
|
||||||
RequiredDataFromCollectionSlug,
|
RequiredDataFromCollectionSlug,
|
||||||
SelectFromCollectionSlug,
|
SelectFromCollectionSlug,
|
||||||
} from '../config/types.js'
|
} from '../config/types.js'
|
||||||
|
|
||||||
import { ensureUsernameOrEmail } from '../../auth/ensureUsernameOrEmail.js'
|
|
||||||
import executeAccess from '../../auth/executeAccess.js'
|
import executeAccess from '../../auth/executeAccess.js'
|
||||||
import { generatePasswordSaltHash } from '../../auth/strategies/local/generatePasswordSaltHash.js'
|
|
||||||
import { hasWhereAccessResult } from '../../auth/types.js'
|
import { hasWhereAccessResult } from '../../auth/types.js'
|
||||||
import { combineQueries } from '../../database/combineQueries.js'
|
import { combineQueries } from '../../database/combineQueries.js'
|
||||||
import { APIError, Forbidden, NotFound } from '../../errors/index.js'
|
import { APIError, Forbidden, NotFound } from '../../errors/index.js'
|
||||||
import { afterChange } from '../../fields/hooks/afterChange/index.js'
|
|
||||||
import { afterRead } from '../../fields/hooks/afterRead/index.js'
|
|
||||||
import { beforeChange } from '../../fields/hooks/beforeChange/index.js'
|
|
||||||
import { beforeValidate } from '../../fields/hooks/beforeValidate/index.js'
|
|
||||||
import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles.js'
|
|
||||||
import { generateFileData } from '../../uploads/generateFileData.js'
|
import { generateFileData } from '../../uploads/generateFileData.js'
|
||||||
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'
|
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles.js'
|
||||||
import { uploadFiles } from '../../uploads/uploadFiles.js'
|
|
||||||
import { checkDocumentLockStatus } from '../../utilities/checkDocumentLockStatus.js'
|
|
||||||
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
import { commitTransaction } from '../../utilities/commitTransaction.js'
|
||||||
import { initTransaction } from '../../utilities/initTransaction.js'
|
import { initTransaction } from '../../utilities/initTransaction.js'
|
||||||
import { killTransaction } from '../../utilities/killTransaction.js'
|
import { killTransaction } from '../../utilities/killTransaction.js'
|
||||||
import { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion.js'
|
import { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion.js'
|
||||||
import { saveVersion } from '../../versions/saveVersion.js'
|
import { updateDocument } from './utilities/update.js'
|
||||||
import { buildAfterOperation } from './utils.js'
|
import { buildAfterOperation } from './utils.js'
|
||||||
|
|
||||||
export type Arguments<TSlug extends CollectionSlug> = {
|
export type Arguments<TSlug extends CollectionSlug> = {
|
||||||
@@ -118,10 +107,7 @@ export const updateByIDOperation = async <
|
|||||||
throw new APIError('Missing ID of document to update.', httpStatus.BAD_REQUEST)
|
throw new APIError('Missing ID of document to update.', httpStatus.BAD_REQUEST)
|
||||||
}
|
}
|
||||||
|
|
||||||
let { data } = args
|
const { data } = args
|
||||||
const password = data?.password
|
|
||||||
const shouldSaveDraft = Boolean(draftArg && collectionConfig.versions.drafts)
|
|
||||||
const shouldSavePassword = Boolean(password && collectionConfig.auth && !shouldSaveDraft)
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
// Access
|
// Access
|
||||||
@@ -158,43 +144,6 @@ export const updateByIDOperation = async <
|
|||||||
throw new Forbidden(req.t)
|
throw new Forbidden(req.t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Handle potentially locked documents
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await checkDocumentLockStatus({
|
|
||||||
id,
|
|
||||||
collectionSlug: collectionConfig.slug,
|
|
||||||
lockErrorMessage: `Document with ID ${id} is currently locked by another user and cannot be updated.`,
|
|
||||||
overrideLock,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
const originalDoc = await afterRead({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
depth: 0,
|
|
||||||
doc: docWithLocales,
|
|
||||||
draft: draftArg,
|
|
||||||
fallbackLocale: null,
|
|
||||||
global: null,
|
|
||||||
locale,
|
|
||||||
overrideAccess: true,
|
|
||||||
req,
|
|
||||||
showHiddenFields: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (args.collection.config.auth) {
|
|
||||||
ensureUsernameOrEmail<TSlug>({
|
|
||||||
authOptions: args.collection.config.auth,
|
|
||||||
collectionSlug: args.collection.config.slug,
|
|
||||||
data: args.data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req: args.req,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
// Generate data for all files and sizes
|
// Generate data for all files and sizes
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
@@ -209,266 +158,50 @@ export const updateByIDOperation = async <
|
|||||||
throwOnMissingFile: false,
|
throwOnMissingFile: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
data = newFileData
|
// ///////////////////////////////////////////////
|
||||||
|
// Update document, runs all document level hooks
|
||||||
|
// ///////////////////////////////////////////////
|
||||||
|
|
||||||
// /////////////////////////////////////
|
let result = await updateDocument<TSlug, TSelect>({
|
||||||
// Delete any associated files
|
id,
|
||||||
// /////////////////////////////////////
|
accessResults,
|
||||||
|
autosave,
|
||||||
await deleteAssociatedFiles({
|
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
config,
|
config,
|
||||||
doc: docWithLocales,
|
data: newFileData,
|
||||||
files: filesToUpload,
|
|
||||||
overrideDelete: false,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeValidate - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
data = await beforeValidate<DeepPartial<DataFromCollectionSlug<TSlug>>>({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
doc: originalDoc,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
overrideAccess,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeValidate - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
data =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req,
|
|
||||||
})) || data
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Write files to local storage
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (!collectionConfig.upload.disableLocalStorage) {
|
|
||||||
await uploadFiles(payload, filesToUpload, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeChange - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
data =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
operation: 'update',
|
|
||||||
originalDoc,
|
|
||||||
req,
|
|
||||||
})) || data
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// beforeChange - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
let publishedDocWithLocales = docWithLocales
|
|
||||||
let versionSnapshotResult
|
|
||||||
|
|
||||||
const beforeChangeArgs: Args<DataFromCollectionSlug<TSlug>> = {
|
|
||||||
id,
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data: { ...data, id },
|
|
||||||
doc: originalDoc,
|
|
||||||
docWithLocales: undefined,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
req,
|
|
||||||
skipValidation:
|
|
||||||
shouldSaveDraft &&
|
|
||||||
collectionConfig.versions.drafts &&
|
|
||||||
!collectionConfig.versions.drafts.validate &&
|
|
||||||
data._status !== 'published',
|
|
||||||
}
|
|
||||||
|
|
||||||
if (publishSpecificLocale) {
|
|
||||||
versionSnapshotResult = await beforeChange({
|
|
||||||
...beforeChangeArgs,
|
|
||||||
docWithLocales,
|
|
||||||
})
|
|
||||||
|
|
||||||
const lastPublished = await getLatestCollectionVersion({
|
|
||||||
id,
|
|
||||||
config: collectionConfig,
|
|
||||||
payload,
|
|
||||||
published: true,
|
|
||||||
query: findOneArgs,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
publishedDocWithLocales = lastPublished ? lastPublished : {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = await beforeChange({
|
|
||||||
...beforeChangeArgs,
|
|
||||||
docWithLocales: publishedDocWithLocales,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Handle potential password update
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
const dataToUpdate: Record<string, unknown> = { ...result }
|
|
||||||
|
|
||||||
if (shouldSavePassword && typeof password === 'string') {
|
|
||||||
const { hash, salt } = await generatePasswordSaltHash({
|
|
||||||
collection: collectionConfig,
|
|
||||||
password,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
dataToUpdate.salt = salt
|
|
||||||
dataToUpdate.hash = hash
|
|
||||||
delete dataToUpdate.password
|
|
||||||
delete data.password
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Update
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (!shouldSaveDraft || data._status === 'published') {
|
|
||||||
result = await req.payload.db.updateOne({
|
|
||||||
id,
|
|
||||||
collection: collectionConfig.slug,
|
|
||||||
data: dataToUpdate,
|
|
||||||
locale,
|
|
||||||
req,
|
|
||||||
select,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// Create version
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
if (collectionConfig.versions) {
|
|
||||||
result = await saveVersion({
|
|
||||||
id,
|
|
||||||
autosave,
|
|
||||||
collection: collectionConfig,
|
|
||||||
docWithLocales: result,
|
|
||||||
draft: shouldSaveDraft,
|
|
||||||
payload,
|
|
||||||
publishSpecificLocale,
|
|
||||||
req,
|
|
||||||
select,
|
|
||||||
snapshot: versionSnapshotResult,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterRead - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
result = await afterRead({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
depth,
|
depth,
|
||||||
doc: result,
|
docWithLocales,
|
||||||
draft: draftArg,
|
draftArg,
|
||||||
fallbackLocale,
|
fallbackLocale,
|
||||||
global: null,
|
filesToUpload,
|
||||||
locale,
|
locale,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
|
overrideLock,
|
||||||
|
payload,
|
||||||
populate,
|
populate,
|
||||||
|
publishSpecificLocale,
|
||||||
req,
|
req,
|
||||||
select,
|
select,
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterRead - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
result =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
doc: result,
|
|
||||||
req,
|
|
||||||
})) || result
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterChange - Fields
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
result = await afterChange({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
data,
|
|
||||||
doc: result,
|
|
||||||
global: null,
|
|
||||||
operation: 'update',
|
|
||||||
previousDoc: originalDoc,
|
|
||||||
req,
|
|
||||||
})
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterChange - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
await collectionConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
|
||||||
await priorHook
|
|
||||||
|
|
||||||
result =
|
|
||||||
(await hook({
|
|
||||||
collection: collectionConfig,
|
|
||||||
context: req.context,
|
|
||||||
doc: result,
|
|
||||||
operation: 'update',
|
|
||||||
previousDoc: originalDoc,
|
|
||||||
req,
|
|
||||||
})) || result
|
|
||||||
}, Promise.resolve())
|
|
||||||
|
|
||||||
// /////////////////////////////////////
|
|
||||||
// afterOperation - Collection
|
|
||||||
// /////////////////////////////////////
|
|
||||||
|
|
||||||
result = await buildAfterOperation({
|
|
||||||
args,
|
|
||||||
collection: collectionConfig,
|
|
||||||
operation: 'updateByID',
|
|
||||||
result,
|
|
||||||
})
|
|
||||||
|
|
||||||
await unlinkTempFiles({
|
await unlinkTempFiles({
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
config,
|
config,
|
||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// afterOperation - Collection
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
result = (await buildAfterOperation({
|
||||||
|
args,
|
||||||
|
collection: collectionConfig,
|
||||||
|
operation: 'updateByID',
|
||||||
|
result,
|
||||||
|
})) as TransformCollectionWithSelect<TSlug, TSelect>
|
||||||
|
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
// Return results
|
// Return results
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
@@ -477,7 +210,7 @@ export const updateByIDOperation = async <
|
|||||||
await commitTransaction(req)
|
await commitTransaction(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result as TransformCollectionWithSelect<TSlug, TSelect>
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
await killTransaction(args.req)
|
await killTransaction(args.req)
|
||||||
throw error
|
throw error
|
||||||
|
|||||||
380
packages/payload/src/collections/operations/utilities/update.ts
Normal file
380
packages/payload/src/collections/operations/utilities/update.ts
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
import type { DeepPartial } from 'ts-essentials'
|
||||||
|
|
||||||
|
import type { Args } from '../../../fields/hooks/beforeChange/index.js'
|
||||||
|
import type { AccessResult, CollectionSlug, FileToSave, SanitizedConfig } from '../../../index.js'
|
||||||
|
import type {
|
||||||
|
Payload,
|
||||||
|
PayloadRequest,
|
||||||
|
PopulateType,
|
||||||
|
SelectType,
|
||||||
|
TransformCollectionWithSelect,
|
||||||
|
} from '../../../types/index.js'
|
||||||
|
import type {
|
||||||
|
DataFromCollectionSlug,
|
||||||
|
SanitizedCollectionConfig,
|
||||||
|
SelectFromCollectionSlug,
|
||||||
|
} from '../../config/types.js'
|
||||||
|
|
||||||
|
import { ensureUsernameOrEmail } from '../../../auth/ensureUsernameOrEmail.js'
|
||||||
|
import { generatePasswordSaltHash } from '../../../auth/strategies/local/generatePasswordSaltHash.js'
|
||||||
|
import { combineQueries } from '../../../database/combineQueries.js'
|
||||||
|
import { afterChange } from '../../../fields/hooks/afterChange/index.js'
|
||||||
|
import { afterRead } from '../../../fields/hooks/afterRead/index.js'
|
||||||
|
import { beforeChange } from '../../../fields/hooks/beforeChange/index.js'
|
||||||
|
import { beforeValidate } from '../../../fields/hooks/beforeValidate/index.js'
|
||||||
|
import { deleteAssociatedFiles } from '../../../uploads/deleteAssociatedFiles.js'
|
||||||
|
import { uploadFiles } from '../../../uploads/uploadFiles.js'
|
||||||
|
import { checkDocumentLockStatus } from '../../../utilities/checkDocumentLockStatus.js'
|
||||||
|
import { getLatestCollectionVersion } from '../../../versions/getLatestCollectionVersion.js'
|
||||||
|
import { saveVersion } from '../../../versions/saveVersion.js'
|
||||||
|
|
||||||
|
export type SharedUpdateDocumentArgs<TSlug extends CollectionSlug> = {
|
||||||
|
accessResults: AccessResult
|
||||||
|
autosave: boolean
|
||||||
|
collectionConfig: SanitizedCollectionConfig
|
||||||
|
config: SanitizedConfig
|
||||||
|
data: DeepPartial<DataFromCollectionSlug<TSlug>>
|
||||||
|
depth: number
|
||||||
|
docWithLocales: any
|
||||||
|
draftArg: boolean
|
||||||
|
fallbackLocale: string
|
||||||
|
filesToUpload: FileToSave[]
|
||||||
|
id: number | string
|
||||||
|
locale: string
|
||||||
|
overrideAccess: boolean
|
||||||
|
overrideLock: boolean
|
||||||
|
payload: Payload
|
||||||
|
populate?: PopulateType
|
||||||
|
publishSpecificLocale?: string
|
||||||
|
req: PayloadRequest
|
||||||
|
select: SelectType
|
||||||
|
showHiddenFields: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used to update a document in the DB and return the result.
|
||||||
|
*
|
||||||
|
* It runs the following hooks in order:
|
||||||
|
* - beforeValidate - Fields
|
||||||
|
* - beforeValidate - Collection
|
||||||
|
* - beforeChange - Collection
|
||||||
|
* - beforeChange - Fields
|
||||||
|
* - afterRead - Fields
|
||||||
|
* - afterRead - Collection
|
||||||
|
* - afterChange - Fields
|
||||||
|
* - afterChange - Collection
|
||||||
|
*/
|
||||||
|
export const updateDocument = async <
|
||||||
|
TSlug extends CollectionSlug,
|
||||||
|
TSelect extends SelectFromCollectionSlug<TSlug> = SelectType,
|
||||||
|
>({
|
||||||
|
id,
|
||||||
|
accessResults,
|
||||||
|
autosave,
|
||||||
|
collectionConfig,
|
||||||
|
config,
|
||||||
|
data,
|
||||||
|
depth,
|
||||||
|
docWithLocales,
|
||||||
|
draftArg,
|
||||||
|
fallbackLocale,
|
||||||
|
filesToUpload,
|
||||||
|
locale,
|
||||||
|
overrideAccess,
|
||||||
|
overrideLock,
|
||||||
|
payload,
|
||||||
|
populate,
|
||||||
|
publishSpecificLocale,
|
||||||
|
req,
|
||||||
|
select,
|
||||||
|
showHiddenFields,
|
||||||
|
}: SharedUpdateDocumentArgs<TSlug>): Promise<TransformCollectionWithSelect<TSlug, TSelect>> => {
|
||||||
|
const password = data?.password
|
||||||
|
const shouldSaveDraft =
|
||||||
|
Boolean(draftArg && collectionConfig.versions.drafts) && data._status !== 'published'
|
||||||
|
const shouldSavePassword = Boolean(password && collectionConfig.auth && !shouldSaveDraft)
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Handle potentially locked documents
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await checkDocumentLockStatus({
|
||||||
|
id,
|
||||||
|
collectionSlug: collectionConfig.slug,
|
||||||
|
lockErrorMessage: `Document with ID ${id} is currently locked by another user and cannot be updated.`,
|
||||||
|
overrideLock,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
|
const originalDoc = await afterRead({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
depth: 0,
|
||||||
|
doc: docWithLocales,
|
||||||
|
draft: draftArg,
|
||||||
|
fallbackLocale: id ? null : fallbackLocale,
|
||||||
|
global: null,
|
||||||
|
locale,
|
||||||
|
overrideAccess: true,
|
||||||
|
req,
|
||||||
|
showHiddenFields: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (collectionConfig.auth) {
|
||||||
|
ensureUsernameOrEmail<TSlug>({
|
||||||
|
authOptions: collectionConfig.auth,
|
||||||
|
collectionSlug: collectionConfig.slug,
|
||||||
|
data,
|
||||||
|
operation: 'update',
|
||||||
|
originalDoc,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Delete any associated files
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await deleteAssociatedFiles({
|
||||||
|
collectionConfig,
|
||||||
|
config,
|
||||||
|
doc: docWithLocales,
|
||||||
|
files: filesToUpload,
|
||||||
|
overrideDelete: false,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// beforeValidate - Fields
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
data = await beforeValidate<DeepPartial<DataFromCollectionSlug<TSlug>>>({
|
||||||
|
id,
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
data,
|
||||||
|
doc: originalDoc,
|
||||||
|
global: null,
|
||||||
|
operation: 'update',
|
||||||
|
overrideAccess,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// beforeValidate - Collection
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await collectionConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
|
||||||
|
await priorHook
|
||||||
|
|
||||||
|
data =
|
||||||
|
(await hook({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
data,
|
||||||
|
operation: 'update',
|
||||||
|
originalDoc,
|
||||||
|
req,
|
||||||
|
})) || data
|
||||||
|
}, Promise.resolve())
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Write files to local storage
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
if (!collectionConfig.upload.disableLocalStorage) {
|
||||||
|
await uploadFiles(payload, filesToUpload, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// beforeChange - Collection
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await collectionConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
|
||||||
|
await priorHook
|
||||||
|
|
||||||
|
data =
|
||||||
|
(await hook({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
data,
|
||||||
|
operation: 'update',
|
||||||
|
originalDoc,
|
||||||
|
req,
|
||||||
|
})) || data
|
||||||
|
}, Promise.resolve())
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// beforeChange - Fields
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
let publishedDocWithLocales = docWithLocales
|
||||||
|
let versionSnapshotResult
|
||||||
|
|
||||||
|
const beforeChangeArgs: Args<DataFromCollectionSlug<TSlug>> = {
|
||||||
|
id,
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
data: { ...data, id },
|
||||||
|
doc: originalDoc,
|
||||||
|
docWithLocales: undefined,
|
||||||
|
global: null,
|
||||||
|
operation: 'update',
|
||||||
|
req,
|
||||||
|
skipValidation:
|
||||||
|
shouldSaveDraft &&
|
||||||
|
collectionConfig.versions.drafts &&
|
||||||
|
!collectionConfig.versions.drafts.validate,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (publishSpecificLocale) {
|
||||||
|
versionSnapshotResult = await beforeChange({
|
||||||
|
...beforeChangeArgs,
|
||||||
|
docWithLocales,
|
||||||
|
})
|
||||||
|
|
||||||
|
const lastPublished = await getLatestCollectionVersion({
|
||||||
|
id,
|
||||||
|
config: collectionConfig,
|
||||||
|
payload,
|
||||||
|
published: true,
|
||||||
|
query: {
|
||||||
|
collection: collectionConfig.slug,
|
||||||
|
locale,
|
||||||
|
req,
|
||||||
|
where: combineQueries({ id: { equals: id } }, accessResults),
|
||||||
|
},
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
|
publishedDocWithLocales = lastPublished ? lastPublished : {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await beforeChange({
|
||||||
|
...beforeChangeArgs,
|
||||||
|
docWithLocales: publishedDocWithLocales,
|
||||||
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Handle potential password update
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
const dataToUpdate: Record<string, unknown> = { ...result }
|
||||||
|
|
||||||
|
if (shouldSavePassword && typeof password === 'string') {
|
||||||
|
const { hash, salt } = await generatePasswordSaltHash({
|
||||||
|
collection: collectionConfig,
|
||||||
|
password,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
dataToUpdate.salt = salt
|
||||||
|
dataToUpdate.hash = hash
|
||||||
|
delete dataToUpdate.password
|
||||||
|
delete data.password
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Update
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
if (!shouldSaveDraft) {
|
||||||
|
result = await req.payload.db.updateOne({
|
||||||
|
id,
|
||||||
|
collection: collectionConfig.slug,
|
||||||
|
data: dataToUpdate,
|
||||||
|
locale,
|
||||||
|
req,
|
||||||
|
select,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// Create version
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
if (collectionConfig.versions) {
|
||||||
|
result = await saveVersion({
|
||||||
|
id,
|
||||||
|
autosave,
|
||||||
|
collection: collectionConfig,
|
||||||
|
docWithLocales: result,
|
||||||
|
draft: shouldSaveDraft,
|
||||||
|
payload,
|
||||||
|
publishSpecificLocale,
|
||||||
|
req,
|
||||||
|
select,
|
||||||
|
snapshot: versionSnapshotResult,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// afterRead - Fields
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
result = await afterRead({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
depth,
|
||||||
|
doc: result,
|
||||||
|
draft: draftArg,
|
||||||
|
fallbackLocale,
|
||||||
|
global: null,
|
||||||
|
locale,
|
||||||
|
overrideAccess,
|
||||||
|
populate,
|
||||||
|
req,
|
||||||
|
select,
|
||||||
|
showHiddenFields,
|
||||||
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// afterRead - Collection
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||||
|
await priorHook
|
||||||
|
|
||||||
|
result =
|
||||||
|
(await hook({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
doc: result,
|
||||||
|
req,
|
||||||
|
})) || result
|
||||||
|
}, Promise.resolve())
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// afterChange - Fields
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
result = await afterChange({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
data,
|
||||||
|
doc: result,
|
||||||
|
global: null,
|
||||||
|
operation: 'update',
|
||||||
|
previousDoc: originalDoc,
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
|
||||||
|
// /////////////////////////////////////
|
||||||
|
// afterChange - Collection
|
||||||
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
await collectionConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
|
||||||
|
await priorHook
|
||||||
|
|
||||||
|
result =
|
||||||
|
(await hook({
|
||||||
|
collection: collectionConfig,
|
||||||
|
context: req.context,
|
||||||
|
doc: result,
|
||||||
|
operation: 'update',
|
||||||
|
previousDoc: originalDoc,
|
||||||
|
req,
|
||||||
|
})) || result
|
||||||
|
}, Promise.resolve())
|
||||||
|
|
||||||
|
return result as TransformCollectionWithSelect<TSlug, TSelect>
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user