UNPKG

payload

Version:

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

230 lines (229 loc) • 9.4 kB
// @ts-strict-ignore import { status as httpStatus } from 'http-status'; import executeAccess from '../../auth/executeAccess.js'; import { combineQueries } from '../../database/combineQueries.js'; import { validateQueryPaths } from '../../database/queryValidation/validateQueryPaths.js'; import { APIError } from '../../errors/index.js'; import { afterRead } from '../../fields/hooks/afterRead/index.js'; import { deleteUserPreferences } from '../../preferences/deleteUserPreferences.js'; import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles.js'; import { checkDocumentLockStatus } from '../../utilities/checkDocumentLockStatus.js'; import { commitTransaction } from '../../utilities/commitTransaction.js'; import { initTransaction } from '../../utilities/initTransaction.js'; import { killTransaction } from '../../utilities/killTransaction.js'; import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'; import { deleteCollectionVersions } from '../../versions/deleteCollectionVersions.js'; import { deleteScheduledPublishJobs } from '../../versions/deleteScheduledPublishJobs.js'; import { buildAfterOperation } from './utils.js'; export const deleteOperation = async (incomingArgs)=>{ let args = incomingArgs; try { const shouldCommit = !args.disableTransaction && await initTransaction(args.req); // ///////////////////////////////////// // beforeOperation - Collection // ///////////////////////////////////// if (args.collection.config.hooks?.beforeOperation?.length) { for (const hook of args.collection.config.hooks.beforeOperation){ args = await hook({ args, collection: args.collection.config, context: args.req.context, operation: 'delete', req: args.req }) || args; } } const { collection: { config: collectionConfig }, depth, overrideAccess, overrideLock, populate, req: { fallbackLocale, locale, payload: { config }, payload }, req, select: incomingSelect, showHiddenFields, where } = args; if (!where) { throw new APIError("Missing 'where' query of documents to delete.", httpStatus.BAD_REQUEST); } // ///////////////////////////////////// // Access // ///////////////////////////////////// let accessResult; if (!overrideAccess) { accessResult = await executeAccess({ req }, collectionConfig.access.delete); } await validateQueryPaths({ collectionConfig, overrideAccess, req, where }); const fullWhere = combineQueries(where, accessResult); const select = sanitizeSelect({ forceSelect: collectionConfig.forceSelect, select: incomingSelect }); // ///////////////////////////////////// // Retrieve documents // ///////////////////////////////////// const { docs } = await payload.db.find({ collection: collectionConfig.slug, locale, req, select, where: fullWhere }); const errors = []; const promises = docs.map(async (doc)=>{ let result; const { id } = doc; try { // ///////////////////////////////////// // Handle potentially locked documents // ///////////////////////////////////// await checkDocumentLockStatus({ id, collectionSlug: collectionConfig.slug, lockErrorMessage: `Document with ID ${id} is currently locked and cannot be deleted.`, overrideLock, req }); // ///////////////////////////////////// // beforeDelete - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeDelete?.length) { for (const hook of collectionConfig.hooks.beforeDelete){ await hook({ id, collection: collectionConfig, context: req.context, req }); } } await deleteAssociatedFiles({ collectionConfig, config, doc, overrideDelete: true, req }); // ///////////////////////////////////// // Delete versions // ///////////////////////////////////// if (collectionConfig.versions) { await deleteCollectionVersions({ id, slug: collectionConfig.slug, payload, req }); } // ///////////////////////////////////// // Delete scheduled posts // ///////////////////////////////////// if (collectionConfig.versions?.drafts && collectionConfig.versions.drafts.schedulePublish) { await deleteScheduledPublishJobs({ id, slug: collectionConfig.slug, payload, req }); } // ///////////////////////////////////// // Delete document // ///////////////////////////////////// await payload.db.deleteOne({ collection: collectionConfig.slug, req, returning: false, where: { id: { equals: id } } }); // ///////////////////////////////////// // afterRead - Fields // ///////////////////////////////////// result = await afterRead({ collection: collectionConfig, context: req.context, depth, doc: result || doc, draft: undefined, 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 || doc, req }) || result; } } // ///////////////////////////////////// // afterDelete - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.afterDelete?.length) { for (const hook of collectionConfig.hooks.afterDelete){ result = await hook({ id, collection: collectionConfig, context: req.context, doc: result, req }) || result; } } // ///////////////////////////////////// // 8. Return results // ///////////////////////////////////// return result; } catch (error) { errors.push({ id: doc.id, message: error.message }); } return null; }); const awaitedDocs = await Promise.all(promises); // ///////////////////////////////////// // Delete Preferences // ///////////////////////////////////// await deleteUserPreferences({ collectionConfig, ids: docs.map(({ id })=>id), payload, req }); let result = { docs: awaitedDocs.filter(Boolean), errors }; // ///////////////////////////////////// // afterOperation - Collection // ///////////////////////////////////// result = await buildAfterOperation({ args, collection: collectionConfig, operation: 'delete', result }); if (shouldCommit) { await commitTransaction(req); } return result; } catch (error) { await killTransaction(args.req); throw error; } }; //# sourceMappingURL=delete.js.map