UNPKG

@payloadcms/plugin-search

Version:
215 lines (214 loc) • 8.54 kB
export const syncDocAsSearchIndex = async ({ collection, doc, locale, onSyncError, operation, pluginConfig, req: { payload }, req })=>{ const { id, _status: status, title } = doc || {}; const { beforeSync, defaultPriorities, deleteDrafts, searchOverrides, syncDrafts } = pluginConfig; const searchSlug = searchOverrides?.slug || 'search'; const syncLocale = locale || req.locale; let dataToSave = { doc: { relationTo: collection, value: id }, title }; const docKey = `${collection}:${id}`; const syncedDocsSet = req.context?.syncedDocsSet || new Set(); if (syncedDocsSet.has(docKey)) { /* * prevents duplicate syncing of documents in the same request * this can happen when hooks call `payload.update` within the create lifecycle * like the nested-docs plugin does */ return; } else { syncedDocsSet.add(docKey); } req.context.syncedDocsSet = syncedDocsSet; if (typeof beforeSync === 'function') { let docToSyncWith = doc; if (payload.config?.localization) { docToSyncWith = await payload.findByID({ id, collection, locale: syncLocale, req }); } dataToSave = await beforeSync({ originalDoc: docToSyncWith, payload, req, searchDoc: dataToSave }); } let defaultPriority = 0; if (defaultPriorities) { const { [collection]: priority } = defaultPriorities; if (typeof priority === 'function') { try { defaultPriority = await priority(doc); } catch (err) { payload.logger.error(err); payload.logger.error(`Error gathering default priority for ${searchSlug} documents related to ${collection}`); } } else if (priority !== undefined) { defaultPriority = priority; } } const doSync = syncDrafts || !syncDrafts && status !== 'draft'; try { if (operation === 'create' && doSync) { await payload.create({ collection: searchSlug, data: { ...dataToSave, priority: defaultPriority }, depth: 0, locale: syncLocale, req }); } if (operation === 'update') { try { // find the correct doc to sync with const searchDocQuery = await payload.find({ collection: searchSlug, depth: 0, locale: syncLocale, req, where: { 'doc.relationTo': { equals: collection }, 'doc.value': { equals: id } } }); const docs = searchDocQuery?.docs || []; const [foundDoc, ...duplicativeDocs] = docs; // delete all duplicative search docs (docs that reference the same page) // to ensure the same, out-of-date result does not appear twice (where only syncing the first found doc) if (duplicativeDocs.length > 0) { try { const duplicativeDocIDs = duplicativeDocs.map(({ id })=>id); await payload.delete({ collection: searchSlug, depth: 0, req, where: { id: { in: duplicativeDocIDs } } }); } catch (err) { payload.logger.error({ err, msg: `Error deleting duplicative ${searchSlug} documents.` }); } } if (foundDoc) { const { id: searchDocID } = foundDoc; if (doSync) { // update the doc normally try { await payload.update({ id: searchDocID, collection: searchSlug, data: { ...dataToSave, priority: foundDoc.priority || defaultPriority }, depth: 0, locale: syncLocale, req }); } catch (err) { payload.logger.error({ err, msg: `Error updating ${searchSlug} document.` }); } } if (deleteDrafts && status === 'draft') { // Check to see if there's a published version of the doc // We don't want to remove the search doc if there is a published version but a new draft has been created const { docs: [docWithPublish] } = await payload.find({ collection, depth: 0, draft: false, limit: 1, locale: syncLocale, pagination: false, req, where: { and: [ { _status: { equals: 'published' } }, { id: { equals: id } } ] } }); if (!docWithPublish) { // do not include draft docs in search results, so delete the record try { await payload.delete({ id: searchDocID, collection: searchSlug, depth: 0, req }); } catch (err) { payload.logger.error({ err, msg: `Error deleting ${searchSlug} document.` }); } } } } else if (doSync) { try { await payload.create({ collection: searchSlug, data: { ...dataToSave, priority: defaultPriority }, depth: 0, locale: syncLocale, req }); } catch (err) { payload.logger.error({ err, msg: `Error creating ${searchSlug} document.` }); } } } catch (err) { payload.logger.error({ err, msg: `Error finding ${searchSlug} document.` }); } } } catch (err) { payload.logger.error({ err, msg: `Error syncing ${searchSlug} document related to ${collection} with id: '${id}'.` }); if (onSyncError) { onSyncError(); } } return doc; }; //# sourceMappingURL=syncDocAsSearchIndex.js.map