@websolutespa/payload-plugin-bowl
Version:
Bowl PayloadCms plugin of the BOM Repository
331 lines (330 loc) • 13.3 kB
JavaScript
import { isObject } from '@websolutespa/bom-core';
import { deepMerge, withCollectionHook } from '@websolutespa/payload-utils';
import { Address } from './collections/Address';
import { Category } from './collections/Category';
import { ConsentPreference } from './collections/ConsentPreference';
import { Continent } from './collections/Continent';
import { Country } from './collections/Country';
import { CountryZone } from './collections/CountryZone';
import { EmailConfig } from './collections/EmailConfig';
import { EndUsers } from './collections/EndUsers';
import { Label } from './collections/Label';
import { Language } from './collections/Language';
import { LegalNotice } from './collections/LegalNotice';
import { Market } from './collections/Market';
import { Media } from './collections/Media';
import { Menu } from './collections/Menu';
import { Municipality } from './collections/Municipality';
import { Province } from './collections/Province';
import { Redirect } from './collections/Redirect';
import { Region } from './collections/Region';
import { SubContinent } from './collections/SubContinent';
import { Template } from './collections/Template';
import { Users } from './collections/Users';
import { localeGet, optinGet, optoutGet, routeChangesPost, routeGet, routePost, storeGet } from './core/api';
import { healthGet } from './core/api/health.service';
import { configureStaticJobs } from './core/api/static.service';
import { logMissingTranslations } from './core/translations';
import { getLivePreviewURL, sortByGroup } from './core/utils';
import { debugJson } from './debug';
import { App } from './globals/App';
import { Locale } from './globals/Locale';
import { toCollection, toGlobal } from './mapper';
import { options } from './options';
const DEBUG = false;
const LOG_MISSING_TRANSLATIONS = false;
export const bowl = (sourceOptions = {})=>async (sourceConfig)=>{
const defaultSlug = {
...options.slug
};
if (sourceOptions.plugins) {
for (const plugin of sourceOptions.plugins){
sourceConfig = await plugin(sourceConfig, sourceOptions);
}
}
if (sourceOptions.defaultMarket) {
options.defaultMarket = sourceOptions.defaultMarket;
}
if (sourceOptions.group) {
options.group = Object.assign(options.group, sourceOptions.group);
}
if (sourceOptions.menu) {
options.menu = Object.assign(options.menu, sourceOptions.menu);
}
if (sourceOptions.slug) {
options.slug = Object.assign(options.slug, sourceOptions.slug);
}
if (sourceOptions.roles) {
options.roles = Object.assign(options.roles, sourceOptions.roles);
const rolesList = Object.values(options.roles);
rolesList.sort();
options.rolesList = rolesList;
}
if (sourceOptions.rolesUser) {
options.rolesUser = Object.assign(options.rolesUser, sourceOptions.rolesUser);
}
if (sourceOptions.rolesEndUser) {
options.rolesEndUser = Object.assign(options.rolesEndUser, sourceOptions.rolesEndUser);
}
if (sourceConfig.localization && sourceConfig.localization.locales) {
options.locales = sourceConfig.localization.locales;
}
if (sourceConfig.localization && sourceConfig.localization.defaultLocale) {
options.defaultLocale = sourceConfig.localization.defaultLocale;
}
if (sourceConfig.i18n && sourceConfig.i18n.translations) {
options.translations = deepMerge(options.translations, sourceConfig.i18n.translations);
}
const sourceCollections = (sourceConfig.collections || []).map((x)=>typeof x === 'function' ? x(options) : x);
const sourceGlobals = (sourceConfig.globals || []).map((x)=>typeof x === 'function' ? x(options) : x);
// pages
const pages = [
...sourceCollections.filter((x)=>x.type === 'withPage').map((x)=>x.slug)
];
options.pages = pages;
// actions
const actions = [
...sourceCollections.filter((x)=>x.type === 'withAction').map((x)=>x.slug),
...sourceGlobals.filter((x)=>x.type === 'withAction').map((x)=>x.slug)
];
options.actions = actions;
// users
const users = [
...sourceCollections.filter((x)=>x.auth !== undefined).map((x)=>x.slug)
];
options.users = users;
/*
const filteredCollections = sourceCollections.filter(x => !internalSlugs.includes(x.slug)).map(x => deepMerge<BowlCollection, BowlCollection>({}, x));
const filteredGlobals = sourceGlobals.filter(x => !internalSlugs.includes(x.slug)).map(x => deepMerge<BowlGlobal, BowlGlobal>({}, x));
*/ // removing duplicated collections
// sourceOptions collections come first then plugin collections
// this way source collections may override plugin collections
const filteredCollections = sourceCollections.reduce((p, c)=>{
if (!p.find((x)=>x.slug === c.slug)) {
p.push(c);
}
return p;
}, []);
// removing duplicated globals
// sourceOptions globals come first then plugin globals
// this way source globals may override plugin globals
const filteredGlobals = sourceGlobals.reduce((p, c)=>{
if (!p.find((x)=>x.slug === c.slug)) {
p.push(c);
}
return p;
}, []);
/*
const filteredCollections = sourceCollections.filter(x => !internalSlugs.filter(y => y !== options.slug.endUsers && y !== options.slug.users).includes(x.slug));
const filteredGlobals = sourceGlobals.filter(x => !internalSlugs.includes(x.slug));
*/ const bowlCollections = [
// Content
Address,
Media,
// Navigation
Category,
EmailConfig,
Menu,
Redirect,
// GDPR
LegalNotice,
ConsentPreference,
// Users
EndUsers,
Users,
// Configuration
Template,
Label,
Market,
// I18N
Language,
Continent,
SubContinent,
Country,
CountryZone,
Region,
Province,
Municipality
].map((x)=>x(options));
const bowlGlobals = [
// Admin
App,
Locale
].map((x)=>x(options));
const missingCollections = [];
Object.entries(defaultSlug).forEach(([k, v])=>{
const defaultSlug = v;
const newSlug = options.slug[k];
if (!filteredCollections.find((x)=>x.slug === newSlug)) {
const collection = bowlCollections.find((x)=>x.slug === defaultSlug);
if (collection) {
// console.info(`[Bowl] added missing collection ${k}`);
missingCollections.push(collection);
}
}
});
const unmappedCollections = [
...filteredCollections,
...missingCollections
];
const missingGlobals = [];
Object.entries(defaultSlug).forEach(([k, v])=>{
const defaultSlug = v;
const newSlug = options.slug[k];
if (!filteredGlobals.find((x)=>x.slug === newSlug)) {
const global = bowlGlobals.find((x)=>x.slug === defaultSlug);
if (global) {
// console.info(`[Bowl] added missing global ${k}`);
missingGlobals.push(global);
}
}
});
const unmappedGlobals = [
...filteredGlobals,
...missingGlobals
];
options.bowlCollections = unmappedCollections;
options.bowlGlobals = unmappedGlobals;
const adminViews = {};
unmappedCollections.forEach((x)=>{
if (x.views) {
Object.assign(adminViews, x.views);
}
});
unmappedGlobals.forEach((x)=>{
if (x.views) {
Object.assign(adminViews, x.views);
}
});
const collections = unmappedCollections.map((x)=>toCollection(x));
const globals = unmappedGlobals.map((x)=>toGlobal(x));
sortByGroup(collections);
sortByGroup(globals);
options.collections = collections.map((x)=>x.slug);
// decorate fields
// !!! todo centralize decorators & mixer context
// !!! afterRead on relationship fields return id only as value
collections.forEach((collection)=>{
/*
withCollectionHook(collection, 'beforeOperation', async ({ context, req }) => {
if (context?.market || req.query?.market) {
console.log('beforeOperation', collection.slug, context?.market, req.query?.market);
}
});
*/ if (collection.upload) {
withCollectionHook(collection, 'afterRead', async ({ doc, context, req })=>{
if (isObject(doc) && (context?.market || req.query?.market)) {
const { mimeType = '' } = doc;
const mimeTypes = mimeType.split('/');
const type = mimeTypes[0] === 'application' ? mimeTypes[1] : mimeTypes[0];
return {
...doc,
type
};
}
return doc;
});
}
/*
eachFieldSync({
fields: collection.fields,
callback: (props) => {
switch (props.field.type) {
case 'upload':
if (!(props.field.hooks?.afterRead?.includes(afterReadUpload))) {
withFieldHook(props.field, 'afterRead', afterReadUpload);
}
break;
}
return props;
},
});
*/ });
const sourceEndpoints = sourceConfig.endpoints || [];
let targetConfig = {
...sourceConfig,
admin: {
livePreview: {
url: (args)=>{
return getLivePreviewURL(args);
},
collections: pages,
breakpoints: [
{
label: 'Mobile',
name: 'mobile',
width: 375,
height: 667
},
{
label: 'Tablet',
name: 'tablet',
width: 768,
height: 1024
},
{
label: 'Desktop',
name: 'desktop',
width: 1440,
height: 900
}
],
...sourceConfig.admin?.livePreview
},
...sourceConfig.admin,
components: {
graphics: {
Logo: '@websolutespa/payload-plugin-bowl/rsc#LogoServer',
Icon: '@websolutespa/payload-plugin-bowl/rsc#IconServer'
},
...sourceConfig.admin?.components,
views: {
...sourceConfig.admin?.components?.views,
...adminViews
}
}
},
i18n: {
...sourceConfig.i18n,
translations: options.translations
},
collections,
globals,
endpoints: [
healthGet,
localeGet,
optinGet,
optoutGet,
routeChangesPost,
routeGet,
routePost,
storeGet,
...sourceEndpoints
],
custom: {
bowl: options
},
onInit: async (payload)=>{
if (typeof sourceConfig.onInit === 'function') {
await sourceConfig.onInit(payload);
}
console.log('@websolutespa/payload-plugin-bowl.onInit');
/*
const views = payload.config.admin.components.views;
payload.config.collections.forEach(collection => {
console.log(collection.slug, (collection.endpoints || []).map(x => x.path));
});
*/ }
};
targetConfig = configureStaticJobs(targetConfig);
// console.log('added collections', targetConfig.collections.map(x => x.slug));
if (DEBUG) {
debugJson('source-config.json', sourceConfig);
debugJson('target-config.json', targetConfig);
}
if (LOG_MISSING_TRANSLATIONS) {
logMissingTranslations();
}
return targetConfig;
};
//# sourceMappingURL=bowl.js.map