@payloadcms/plugin-multi-tenant
Version:
Multi Tenant plugin for Payload
139 lines (138 loc) • 5.53 kB
JavaScript
import { getCollectionIDType } from './getCollectionIDType.js';
import { getTenantFromCookie } from './getTenantFromCookie.js';
export function addFilterOptionsToFields({ config, fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsCollectionSlug }) {
fields.forEach((field)=>{
if (field.type === 'relationship') {
/**
* Adjusts relationship fields to filter by tenant
* and ensures relationTo cannot be a tenant global collection
*/ if (typeof field.relationTo === 'string') {
if (tenantEnabledGlobalSlugs.includes(field.relationTo)) {
throw new Error(`The collection ${field.relationTo} is a global collection and cannot be related to a tenant enabled collection.`);
}
if (tenantEnabledCollectionSlugs.includes(field.relationTo)) {
addFilter({
field,
tenantEnabledCollectionSlugs,
tenantFieldName,
tenantsCollectionSlug
});
}
} else {
field.relationTo.map((relationTo)=>{
if (tenantEnabledGlobalSlugs.includes(relationTo)) {
throw new Error(`The collection ${relationTo} is a global collection and cannot be related to a tenant enabled collection.`);
}
if (tenantEnabledCollectionSlugs.includes(relationTo)) {
addFilter({
field,
tenantEnabledCollectionSlugs,
tenantFieldName,
tenantsCollectionSlug
});
}
});
}
}
if (field.type === 'row' || field.type === 'array' || field.type === 'collapsible' || field.type === 'group') {
addFilterOptionsToFields({
config,
fields: field.fields,
tenantEnabledCollectionSlugs,
tenantEnabledGlobalSlugs,
tenantFieldName,
tenantsCollectionSlug
});
}
if (field.type === 'blocks') {
;
(field.blockReferences ?? field.blocks).forEach((_block)=>{
const block = typeof _block === 'string' ? config?.blocks?.find((b)=>b.slug === _block) : _block;
if (block?.fields) {
addFilterOptionsToFields({
config,
fields: block.fields,
tenantEnabledCollectionSlugs,
tenantEnabledGlobalSlugs,
tenantFieldName,
tenantsCollectionSlug
});
}
});
}
if (field.type === 'tabs') {
field.tabs.forEach((tab)=>{
addFilterOptionsToFields({
config,
fields: tab.fields,
tenantEnabledCollectionSlugs,
tenantEnabledGlobalSlugs,
tenantFieldName,
tenantsCollectionSlug
});
});
}
});
}
function addFilter({ field, tenantEnabledCollectionSlugs, tenantFieldName, tenantsCollectionSlug }) {
// User specified filter
const originalFilter = field.filterOptions;
field.filterOptions = async (args)=>{
const originalFilterResult = typeof originalFilter === 'function' ? await originalFilter(args) : originalFilter ?? true;
// If the relationTo is not a tenant enabled collection, return early
if (args.relationTo && !tenantEnabledCollectionSlugs.includes(args.relationTo)) {
return originalFilterResult;
}
// If the original filtr returns false, return early
if (originalFilterResult === false) {
return false;
}
// Custom tenant filter
const tenantFilterResults = filterOptionsByTenant({
...args,
tenantFieldName,
tenantsCollectionSlug
});
// If the tenant filter returns true, just use the original filter
if (tenantFilterResults === true) {
return originalFilterResult;
}
// If the original filter returns true, just use the tenant filter
if (originalFilterResult === true) {
return tenantFilterResults;
}
return {
and: [
originalFilterResult,
tenantFilterResults
]
};
};
}
const filterOptionsByTenant = ({ req, tenantFieldName = 'tenant', tenantsCollectionSlug })=>{
const idType = getCollectionIDType({
collectionSlug: tenantsCollectionSlug,
payload: req.payload
});
const selectedTenant = getTenantFromCookie(req.headers, idType);
if (!selectedTenant) {
return true;
}
return {
or: [
// ie a related collection that doesn't have a tenant field
{
[tenantFieldName]: {
exists: false
}
},
// related collections that have a tenant field
{
[tenantFieldName]: {
equals: selectedTenant
}
}
]
};
};
//# sourceMappingURL=addFilterOptionsToFields.js.map