UNPKG

payload

Version:

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

220 lines (219 loc) • 8.57 kB
// @ts-strict-ignore import executeAccess from '../../auth/executeAccess.js'; import { combineQueries } from '../../database/combineQueries.js'; import { sanitizeJoinQuery } from '../../database/sanitizeJoinQuery.js'; import { NotFound } from '../../errors/index.js'; import { afterRead } from '../../fields/hooks/afterRead/index.js'; import { validateQueryPaths } from '../../index.js'; import { lockedDocumentsCollectionSlug } from '../../locked-documents/config.js'; import { killTransaction } from '../../utilities/killTransaction.js'; import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'; import replaceWithDraftIfAvailable from '../../versions/drafts/replaceWithDraftIfAvailable.js'; import { buildAfterOperation } from './utils.js'; export const findByIDOperation = async (incomingArgs)=>{ let args = incomingArgs; try { // ///////////////////////////////////// // 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: 'read', req: args.req }) || args; } } const { id, collection: { config: collectionConfig }, currentDepth, depth, disableErrors, draft: draftEnabled = false, includeLockStatus, joins, overrideAccess = false, populate, req: { fallbackLocale, locale, t }, req, select: incomingSelect, showHiddenFields } = args; const select = sanitizeSelect({ forceSelect: collectionConfig.forceSelect, select: incomingSelect }); // ///////////////////////////////////// // Access // ///////////////////////////////////// const accessResult = !overrideAccess ? await executeAccess({ id, disableErrors, req }, collectionConfig.access.read) : true; // If errors are disabled, and access returns false, return null if (accessResult === false) { return null; } const where = { id: { equals: id } }; const fullWhere = combineQueries(where, accessResult); const sanitizedJoins = await sanitizeJoinQuery({ collectionConfig, joins, overrideAccess, req }); const findOneArgs = { collection: collectionConfig.slug, draftsEnabled: draftEnabled, joins: req.payloadAPI === 'GraphQL' ? false : sanitizedJoins, locale, req: { transactionID: req.transactionID }, select, where: fullWhere }; // execute only if there's a custom ID and potentially overwriten access on id if (req.payload.collections[collectionConfig.slug].customIDType) { await validateQueryPaths({ collectionConfig, overrideAccess, req, where }); } // ///////////////////////////////////// // Find by ID // ///////////////////////////////////// if (!findOneArgs.where.and[0].id) { throw new NotFound(t); } let result = await req.payload.db.findOne(findOneArgs); if (!result) { if (!disableErrors) { throw new NotFound(req.t); } return null; } // ///////////////////////////////////// // Include Lock Status if required // ///////////////////////////////////// if (includeLockStatus && id) { let lockStatus = null; try { const lockDocumentsProp = collectionConfig?.lockDocuments; const lockDurationDefault = 300 // Default 5 minutes in seconds ; const lockDuration = typeof lockDocumentsProp === 'object' ? lockDocumentsProp.duration : lockDurationDefault; const lockDurationInMilliseconds = lockDuration * 1000; const lockedDocument = await req.payload.find({ collection: lockedDocumentsCollectionSlug, depth: 1, limit: 1, overrideAccess: false, pagination: false, req, where: { and: [ { 'document.relationTo': { equals: collectionConfig.slug } }, { 'document.value': { equals: id } }, // Query where the lock is newer than the current time minus lock time { updatedAt: { greater_than: new Date(new Date().getTime() - lockDurationInMilliseconds) } } ] } }); if (lockedDocument && lockedDocument.docs.length > 0) { lockStatus = lockedDocument.docs[0]; } } catch { // swallow error } result._isLocked = !!lockStatus; result._userEditing = lockStatus?.user?.value ?? null; } // ///////////////////////////////////// // Replace document with draft if available // ///////////////////////////////////// if (collectionConfig.versions?.drafts && draftEnabled) { result = await replaceWithDraftIfAvailable({ accessResult, doc: result, entity: collectionConfig, entityType: 'collection', overrideAccess, req, select }); } // ///////////////////////////////////// // beforeRead - Collection // ///////////////////////////////////// if (collectionConfig.hooks?.beforeRead?.length) { for (const hook of collectionConfig.hooks.beforeRead){ result = await hook({ collection: collectionConfig, context: req.context, doc: result, query: findOneArgs.where, req }) || result; } } // ///////////////////////////////////// // afterRead - Fields // ///////////////////////////////////// result = await afterRead({ collection: collectionConfig, context: req.context, currentDepth, depth, doc: result, draft: draftEnabled, 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, query: findOneArgs.where, req }) || result; } } // ///////////////////////////////////// // afterOperation - Collection // ///////////////////////////////////// result = await buildAfterOperation({ args, collection: collectionConfig, operation: 'findByID', result }); // ///////////////////////////////////// // Return results // ///////////////////////////////////// return result; } catch (error) { await killTransaction(args.req); throw error; } }; //# sourceMappingURL=findByID.js.map