UNPKG

@websolutespa/payload-plugin-bowl

Version:

Bowl PayloadCms plugin of the BOM Repository

171 lines (170 loc) 8.12 kB
import { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server'; import { decorateCategory_, decorateComponents_, decorateHref_, decorateNav_, decorateSchema_ } from '../decorators'; import { findByIDHandler } from '../utils/findByIDHandler'; import { findHandler } from '../utils/findHandler'; import { getCollectionItems } from './collection.service'; import { collectPageRedirects } from './redirect.service'; import { isMixerRequest } from './utils'; /** * Rest api page collection get handler. */ export const pageIndexGet = (slug)=>({ path: '/', method: 'get', handler: async (req)=>{ try { const { query } = req; // console.log('pageIndexGet.query', ...Object.entries(query || {})); if (!query) { return findHandler(req); } const { locale, market, pagination } = query; if (typeof market === 'string' && typeof locale === 'string') { // const context = await setMixerContext(req, market, locale); // console.log('pageIndexGet.context', context.market, context.locale, context.routes.length, context.categories.length); if (pagination === 'true') { return findHandler(req); } else { const items = await getCollectionItems(req, slug); return ResponseSuccess(items); } } else if (pagination === 'false') { const items = await getCollectionItems(req, slug); return ResponseSuccess(items); } return findHandler(req); } catch (error) { console.error(`PageService.pageIndexGet.${slug}.error`, error); return ResponseError(error); } } }); /** * Rest api page collection detail get handler. */ export const pageDetailGet = (slug)=>({ path: '/:id', method: 'get', handler: async (req)=>{ try { const { query } = req; // console.log('pageDetailGet.query', ...Object.entries(query || {})); if (!query) { return findByIDHandler(req); } const { market, locale } = query; // console.log('pageDetailGet', 'market', market, 'locale', locale); if (!(typeof market === 'string' && typeof locale === 'string')) { return findByIDHandler(req); } req.query.depth = req.query.depth || '3'; // const context = await setMixerContext(req, market, locale); // console.log('pageDetailGet.context', context.market, context.locale, context.routes.length, context.categories.length); return findByIDHandler(req); } catch (error) { console.error(`PageService.pageDetailGet.${slug}.error`, error); return ResponseError(error); } } }); /** * eg. PAYLOAD_PAGE_FIND = 'components' */ const afterPageOperationFind = process.env.PAYLOAD_FILTER_FIND ? process.env.PAYLOAD_FILTER_FIND.split(',').map((x)=>x.trim()) : []; /** * Modify record for Mixer when queried by market and locale. */ export const afterPageOperationHook = (collectionConfig)=>async ({ args, collection, req, operation, result })=>{ if (afterPageOperationFind.length > 0 && isMixerRequest(req) && operation === 'find' && req.pathname !== '/store' && req.query.optimize !== 'false') { // console.log('withPage.afterPageOperationHook', operation, collection.slug, req.pathname); result.docs = result.docs.map((x)=>Object.fromEntries(Object.entries(x).filter(([k, v])=>!afterPageOperationFind.includes(k)))); // console.log('withPage.afterPageOperationHook.done'); } return result; }; /** * Decorate record for Mixer when queried by market and locale. */ export const afterPageReadHook = (collectionConfig)=>async ({ doc, req, context, findMany })=>{ const { market, locale, routes, categories } = context; // console.log('afterPageReadHook', doc.title, query, market, locale); if (!market || !locale || !routes || !categories) { return doc; } const withSchema = await decorateSchema_(doc, collectionConfig.slug); const withComponents = await decorateComponents_(withSchema, collectionConfig.slug, context); const withCategory = await decorateCategory_(withComponents, collectionConfig.slug, context); const withHref = await decorateHref_(withCategory, collectionConfig.slug, context); const withNav = await decorateNav_(withHref, collectionConfig.slug, context); return withNav; /* const withRichText = await decorateRichText_(withNav, collectionConfig.fields, context as Required<MixerContext>, req.payload.config); return withRichText; */ }; /** * Trigger revalidation in the Next.js Mixer app for a given page document. */ async function triggerPageRevalidation(schema, pageId) { if (!schema || !pageId) return; // todo: dedicated envVar for mixerUrl const mixerUrl = process.env.PAYLOAD_PUBLIC_PREVIEW_URL; const mixerSecret = process.env.MIXER_SECRET; if (!mixerUrl || !mixerSecret) { console.warn(`[revalidation] Skipping revalidation for ${schema}:${pageId}: MIXER_SECRET or PAYLOAD_PUBLIC_PREVIEW_URL is missing.`); return; } try { // console.log(`[revalidation] Triggering revalidation for ${schema}:${pageId}`); const response = await fetch(`${mixerUrl}/api/__revalidate`, { method: 'POST', headers: { 'Authorization': `Bearer ${mixerSecret}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ schema, page: String(pageId) }) }); if (!response.ok) { const text = await response.text().catch(()=>''); console.warn(`[revalidation] Failed to revalidate ${schema}:${pageId}`, response.status, text); } else { // console.log(`[revalidation] Successfully revalidated ${schema}:${pageId}`); } } catch (error) { console.error(`[revalidation] Error triggering revalidation for ${schema}:${pageId}`, error); } } /** * Create a record of the pages collection related to the created document. */ export const afterPageChangeHook = async ({ doc, req, previousDoc, operation, collection })=>{ if (operation === 'update') { const { query = {} } = req; const { draft } = query; // console.log('afterPageChange', operation, draft, doc.isDefault, previousDoc.slug, doc.slug); if (!draft && doc.isDefault !== true && previousDoc.slug && doc.slug) { const redirects = await collectPageRedirects(req, previousDoc, doc); // console.log('redirects', redirects); } } if (doc._status === 'published') { triggerPageRevalidation(collection?.slug, doc.id); } return doc; }; /** * Delete records of the pages collection related to the deleted document. */ export const afterPageDeleteHook = async ({ req, id, doc })=>{ const { query = {} } = req; const { draft } = query; if (!draft && doc.isDefault !== true && doc.slug) { console.log('RedirectService.deletePage !!!'); // !!! todo find and redirect to parentCategory connected to a page } }; /* export const beforeValidateHook: CollectionBeforeValidateHook = async ({ data, // incoming data to update or create with req, // full express request operation, // name of the operation ie. 'create', 'update' originalDoc, // original document }) => { console.log(data, originalDoc, req.query); return data; // Return data to either create or update a document with }; */ //# sourceMappingURL=page.service.js.map