UNPKG

@websolutespa/payload-plugin-bowl

Version:

Bowl PayloadCms plugin of the BOM Repository

336 lines (335 loc) 12.4 kB
import { isArray, isObject } from '@websolutespa/bom-core'; import { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server'; import qs from 'qs'; import { options } from '../../options'; import { InMemoryCache } from './cache.service'; import { parseDepth } from './collection.service'; import { getRoutes } from './route.service'; import { setMixerContext } from './utils'; const USE_CACHE = true; const CACHE_ = new InMemoryCache(); function getStoreRequest_(req, market = 'all', locale = 'all') { const { query = {} } = req; const { where: w, market: m, locale: l, ...rest } = query; const subQuery = { market, locale }; req.query = { ...rest, ...subQuery }; req.locale = locale; return req; } async function getStore_(req) { const { user } = req; // console.log('getStore_.user', user); if (!user) { throw { status: 403, message: 'Unauthorized' }; } const roles = user.roles || []; const tenants = Array.isArray(user.tenants) ? user.tenants.map((x)=>isObject(x) ? x.id : x) : []; const keys = [ ...roles, ...tenants ]; keys.sort(); // console.log('getStore_.roles', roles); const strategy = req.query?.strategy === 'runtime' ? 'runtime' : 'static'; const market = 'all'; const locale = 'all'; const key = `store-${market}-${locale}-${strategy}-${keys.join('-')}`; if (USE_CACHE && CACHE_.has(key) && req.query?.nocache != null && req.query?.t != null) { // console.log('StoreService return from cache'); return CACHE_.get(key); } console.log('StoreService.getStore_', key); // console.log('StoreService skipping cache'); const store = {}; const subRequest = getStoreRequest_(req, market, locale); const context = await setMixerContext(subRequest, market, locale); for (const slug of options.collections){ try { const collection = req.payload.collections[slug]; // console.log('getStore.collection', collection.config.slug); if (!collection) { throw `collection '${slug}' not found`; } const disallowedCollection = options.actions.includes(slug) || options.users.includes(slug); if (!disallowedCollection) { const bowlCollection = options.bowlCollections.find((x)=>x.slug === slug); // console.log('getStore_.bowlCollection', bowlCollection.slug, bowlCollection.type); const type = bowlCollection?.type; // console.log('getStore.type', type, 'strategy', strategy); switch(type){ case 'withStatic': { if (strategy === 'runtime') { store[slug] = []; } else { // we fetch static collection through custom endpoints // fetching through local api would return empty array const items = await fetchStaticCollection_(subRequest, slug); // console.log('getStore_.withStatic', slug, items.length); store[slug] = items; } } break; case 'withPage': { if (strategy === 'runtime') { store[slug] = []; } else { // we fetch pages via local api const items = await findCollection(subRequest, slug); // console.log('getStore_.withPage', slug, items.length); store[slug] = items; /* // we fetch pages via local api filtered by _status == published const options: Omit<FindOptions, 'req'> = { where: { _status: { equals: 'published', }, }, }; const items = await findCollection<IEntity>(subRequest, slug, options); // console.log('getStore_.withPage', slug, items.length); store[slug] = items; */ } } break; default: { if (strategy === 'runtime' && ![ 'category', 'market', 'template', 'menu', 'label' ].includes(slug) || [ 'media', 'template', 'email_config' ].includes(slug)) { store[slug] = []; } else { // we fetch others collection via local api const options = slug === 'category' ? { sort: 'order' } : undefined; const items = await findCollection(subRequest, slug, options); // console.log('getStore_.withCollection', slug, items.length); store[slug] = items; } } } } } catch (error) { // 403 is expected, it means the collection is private if (error.status !== 403) { throw error; } console.log('StoreService', `no access granted for collection '${slug}'`); store[slug] = []; } } let app = { id: 'app', brand: { name: 'Mixer', social: [] } }; try { app = await findGlobal(subRequest, 'app'); } catch (error) { console.log('IApp not found', error); } store.app = [ { ...app, id: app.id || 'app' } ]; try { // we fetch locale through custom endpoint const locale = await fetchGlobal_(subRequest, 'locale', { richText: false }); // we fetch locale through custom endpoint api/locale // const localeCollection = await fetchCollection_(subRequest, 'locale', { richText: false }); // console.log('localeCollection', localeCollection); store.locale = locale.items; } catch (error) { // 403 is expected, it means the collection is private if (error.status !== 403) { throw error; } console.log('StoreService', 'no access granted for collection \'locale\''); store.locale = []; } // we handle routes separately const routes = await getRoutes(subRequest); store.route = routes; CACHE_.set(key, store); return store; } export async function findCollection(req, slug, findOptions) { /* const requestOptions = { lng: (req as any).lng, locale: req.locale, language: (req as any).language, languages: (req as any).languages }; console.log('requestOptions', requestOptions, options); */ // console.log('findCollection', slug); const { query = {}, payload, user } = req; const { draft } = query; const depth = parseDepth(query.depth, 3); // type FindOptions = ArgumentTypes<typeof payload.find>[0]; const findOptions_ = { ...findOptions, collection: slug, draft: draft === 'true', locale: req.locale || 'all', fallbackLocale: undefined, // fallbackLocale: options.defaultLocale, depth, limit: 10000, pagination: false, req: req, user: user, overrideAccess: false }; // console.log('findCollection', slug, findOptions_); try { const response = await payload.find(findOptions_); // console.log('findCollection.success', slug); const items = isArray(response) ? response : isArray(response.docs) ? response.docs : []; /* const firstItem = items[0]; if (firstItem) { console.log('findCollection', slug, 'firstItem', firstItem); } */ return items; } catch (error) { // 403 is expected, it means the collection is private if (error.status !== 403) { throw error; } console.log('StoreService.findCollection', `no access granted for collection '${slug}'`); return []; } } export async function findGlobal(req, slug, findOptions) { // console.log('findGlobal', global); const { query = {}, payload, user } = req; const { draft } = query; const depth = parseDepth(query.depth, 3); const response = await payload.findGlobal({ slug, draft: draft === 'true', locale: req.locale || 'all', fallbackLocale: undefined, // fallbackLocale: options.defaultLocale, depth, req: req, user: user, ...findOptions, overrideAccess: false }); return response; } export function getSearchUrl(req, overrideQuery) { const { query = {} } = req; const params = Object.assign({ locale: 'all', depth: 1, limit: 10000 }, query, overrideQuery); const search = qs.stringify(params); const url = search ? `?${search}` : ''; return url; } /* async function fetchEndpoint_<T>(req: PayloadRequest, endpoint: string, query?: {}): Promise<T> { try { const apiUrl = getApiUrl(req); const searchUrl = getSearchUrl(req, query); const url = `${apiUrl}${endpoint}${searchUrl}`; // console.log('fetchEndpoint_.url', url, req.headers.authorization); const httpGetResponse = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', ...(req.headers.authorization ? { 'Authorization': req.headers.authorization, } : {}), ...(req.headers.cookie ? { 'Cookie': req.headers.cookie, } : {}), }, }); // console.log('fetchEndpoint_', url, req.headers.authorization, httpGetResponse.ok, httpGetResponse.status, httpGetResponse.statusText, httpGetResponse.type); if (!httpGetResponse.ok) { // console.log('fetchEndpoint_', url, endpoint, httpGetResponse.status, httpGetResponse.statusText); throw httpGetResponse; } const json = await httpGetResponse.json(); return json; } catch (error) { console.log('StoreService.fetchEndpoint_.error', endpoint, error.statusText); throw (error); } } */ async function fetchStaticCollection_(req, slug, query) { try { const response = await req.payload.find({ ...req, pagination: false, collection: slug }); return response.docs; } catch (error) { // 403 is expected, it means the collection is private if (error.status !== 403) { throw error; } console.log('StoreService.fetchStaticCollection_', `no access granted for collection '${slug}'`); return []; } } async function fetchGlobal_(req, slug, query) { try { const response = await req.payload.findGlobal({ ...req, slug }); // console.log('fetchGlobal_', response); return response; } catch (error) { // 403 is expected, it means the collection is private if (error.status !== 403) { throw error; } console.log('StoreService.fetchGlobal_', `no access granted for collection '${slug}'`); return { items: [] }; } } export const storeGet = { path: '/store', method: 'get', handler: async (req)=>{ try { const store = await getStore_(req); return ResponseSuccess(store); } catch (error) { console.error('StoreService.storeGet.error', error); return ResponseError(error); } } }; //# sourceMappingURL=store.service.js.map