UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

282 lines (281 loc) • 9.75 kB
// @ts-strict-ignore 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 { deepCopyObjectSimple } from '../../../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'; /** * 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 ({ id, accessResults, autosave, collectionConfig, config, data, depth, docWithLocales, draftArg, fallbackLocale, filesToUpload, locale, overrideAccess, overrideLock, payload, populate, publishSpecificLocale, req, select, showHiddenFields })=>{ const password = data?.password; const shouldSaveDraft = Boolean(draftArg && collectionConfig.versions.drafts) && data._status !== 'published'; const shouldSavePassword = Boolean(password && collectionConfig.auth && (!collectionConfig.auth.disableLocalStrategy || typeof collectionConfig.auth.disableLocalStrategy === 'object' && collectionConfig.auth.disableLocalStrategy.enableFields) && !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: deepCopyObjectSimple(docWithLocales), draft: draftArg, fallbackLocale: id ? null : fallbackLocale, global: null, locale, overrideAccess: true, req, showHiddenFields: true }); if (collectionConfig.auth) { ensureUsernameOrEmail({ 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({ id, collection: collectionConfig, context: req.context, data, doc: originalDoc, global: null, operation: 'update', overrideAccess, req }); // ///////////////////////////////////// // beforeValidate - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeValidate?.length) { for (const hook of collectionConfig.hooks.beforeValidate){ data = await hook({ collection: collectionConfig, context: req.context, data, operation: 'update', originalDoc, req }) || data; } } // ///////////////////////////////////// // Write files to local storage // ///////////////////////////////////// if (!collectionConfig.upload.disableLocalStorage) { await uploadFiles(payload, filesToUpload, req); } // ///////////////////////////////////// // beforeChange - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeChange?.length) { for (const hook of collectionConfig.hooks.beforeChange){ data = await hook({ collection: collectionConfig, context: req.context, data, operation: 'update', originalDoc, req }) || data; } } // ///////////////////////////////////// // beforeChange - Fields // ///////////////////////////////////// let publishedDocWithLocales = docWithLocales; let versionSnapshotResult; const beforeChangeArgs = { 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 = { ...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 // ///////////////////////////////////// if (collectionConfig.hooks?.afterRead?.length) { for (const hook of collectionConfig.hooks.afterRead){ result = await hook({ collection: collectionConfig, context: req.context, doc: result, req }) || result; } } // ///////////////////////////////////// // afterChange - Fields // ///////////////////////////////////// result = await afterChange({ collection: collectionConfig, context: req.context, data, doc: result, global: null, operation: 'update', previousDoc: originalDoc, req }); // ///////////////////////////////////// // afterChange - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.afterChange?.length) { for (const hook of collectionConfig.hooks.afterChange){ result = await hook({ collection: collectionConfig, context: req.context, doc: result, operation: 'update', previousDoc: originalDoc, req }) || result; } } return result; }; //# sourceMappingURL=update.js.map