@payloadcms/plugin-multi-tenant 3.23.0 → 3.24.0-canary.05013b2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fields/tenantsArrayField/index.d.ts +27 -3
- package/dist/fields/tenantsArrayField/index.d.ts.map +1 -1
- package/dist/fields/tenantsArrayField/index.js +1 -1
- package/dist/fields/tenantsArrayField/index.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utilities/addFilterOptionsToFields.d.ts +3 -2
- package/dist/utilities/addFilterOptionsToFields.d.ts.map +1 -1
- package/dist/utilities/addFilterOptionsToFields.js +16 -9
- package/dist/utilities/addFilterOptionsToFields.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import type { ArrayField, RelationshipField } from 'payload';
|
|
2
2
|
type Args = {
|
|
3
|
+
/**
|
|
4
|
+
* Access configuration for the array field
|
|
5
|
+
*/
|
|
3
6
|
arrayFieldAccess?: ArrayField['access'];
|
|
7
|
+
/**
|
|
8
|
+
* Additional fields to include on the tenant array rows
|
|
9
|
+
*/
|
|
4
10
|
rowFields?: ArrayField['fields'];
|
|
11
|
+
/**
|
|
12
|
+
* Access configuration for the tenant field
|
|
13
|
+
*/
|
|
5
14
|
tenantFieldAccess?: RelationshipField['access'];
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The name of the array field that holds the tenants
|
|
17
|
+
*
|
|
18
|
+
* @default 'tenants'
|
|
19
|
+
*/
|
|
20
|
+
tenantsArrayFieldName?: ArrayField['name'];
|
|
21
|
+
/**
|
|
22
|
+
* The name of the field that will be used to store the tenant relationship in the array
|
|
23
|
+
*
|
|
24
|
+
* @default 'tenant'
|
|
25
|
+
*/
|
|
26
|
+
tenantsArrayTenantFieldName?: RelationshipField['name'];
|
|
27
|
+
/**
|
|
28
|
+
* The slug for the tenant collection
|
|
29
|
+
*
|
|
30
|
+
* @default 'tenants'
|
|
31
|
+
*/
|
|
32
|
+
tenantsCollectionSlug?: string;
|
|
9
33
|
};
|
|
10
34
|
export declare const tenantsArrayField: ({ arrayFieldAccess, rowFields, tenantFieldAccess, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, }: Args) => ArrayField;
|
|
11
35
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantsArrayField/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAI5D,KAAK,IAAI,GAAG;IACV,gBAAgB,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IACvC,SAAS,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC/C,qBAAqB,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantsArrayField/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAI5D,KAAK,IAAI,GAAG;IACV;;OAEG;IACH,gBAAgB,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAChC;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC/C;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAC1C;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACvD;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,iBAAiB,mIAO3B,IAAI,KAAG,UAiBR,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defaults } from '../../defaults.js';
|
|
2
|
-
export const tenantsArrayField = ({ arrayFieldAccess, rowFields, tenantFieldAccess, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.
|
|
2
|
+
export const tenantsArrayField = ({ arrayFieldAccess, rowFields, tenantFieldAccess, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, tenantsCollectionSlug = defaults.tenantCollectionSlug })=>({
|
|
3
3
|
name: tenantsArrayFieldName,
|
|
4
4
|
type: 'array',
|
|
5
5
|
access: arrayFieldAccess,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/tenantsArrayField/index.ts"],"sourcesContent":["import type { ArrayField, RelationshipField } from 'payload'\n\nimport { defaults } from '../../defaults.js'\n\ntype Args = {\n arrayFieldAccess?: ArrayField['access']\n rowFields?: ArrayField['fields']\n tenantFieldAccess?: RelationshipField['access']\n tenantsArrayFieldName
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/tenantsArrayField/index.ts"],"sourcesContent":["import type { ArrayField, RelationshipField } from 'payload'\n\nimport { defaults } from '../../defaults.js'\n\ntype Args = {\n /**\n * Access configuration for the array field\n */\n arrayFieldAccess?: ArrayField['access']\n /**\n * Additional fields to include on the tenant array rows\n */\n rowFields?: ArrayField['fields']\n /**\n * Access configuration for the tenant field\n */\n tenantFieldAccess?: RelationshipField['access']\n /**\n * The name of the array field that holds the tenants\n *\n * @default 'tenants'\n */\n tenantsArrayFieldName?: ArrayField['name']\n /**\n * The name of the field that will be used to store the tenant relationship in the array\n *\n * @default 'tenant'\n */\n tenantsArrayTenantFieldName?: RelationshipField['name']\n /**\n * The slug for the tenant collection\n *\n * @default 'tenants'\n */\n tenantsCollectionSlug?: string\n}\nexport const tenantsArrayField = ({\n arrayFieldAccess,\n rowFields,\n tenantFieldAccess,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug = defaults.tenantCollectionSlug,\n}: Args): ArrayField => ({\n name: tenantsArrayFieldName,\n type: 'array',\n access: arrayFieldAccess,\n fields: [\n {\n name: tenantsArrayTenantFieldName,\n type: 'relationship',\n access: tenantFieldAccess,\n index: true,\n relationTo: tenantsCollectionSlug,\n required: true,\n saveToJWT: true,\n },\n ...(rowFields || []),\n ],\n saveToJWT: true,\n})\n"],"names":["defaults","tenantsArrayField","arrayFieldAccess","rowFields","tenantFieldAccess","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","tenantCollectionSlug","name","type","access","fields","index","relationTo","required","saveToJWT"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,oBAAmB;AAkC5C,OAAO,MAAMC,oBAAoB,CAAC,EAChCC,gBAAgB,EAChBC,SAAS,EACTC,iBAAiB,EACjBC,wBAAwBL,SAASK,qBAAqB,EACtDC,8BAA8BN,SAASM,2BAA2B,EAClEC,wBAAwBP,SAASQ,oBAAoB,EAChD,GAAkB,CAAA;QACvBC,MAAMJ;QACNK,MAAM;QACNC,QAAQT;QACRU,QAAQ;YACN;gBACEH,MAAMH;gBACNI,MAAM;gBACNC,QAAQP;gBACRS,OAAO;gBACPC,YAAYP;gBACZQ,UAAU;gBACVC,WAAW;YACb;eACIb,aAAa,EAAE;SACpB;QACDa,WAAW;IACb,CAAA,EAAE"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAUzD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAUzD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MA6OzB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -122,6 +122,7 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
122
122
|
/**
|
|
123
123
|
* Modify enabled collections
|
|
124
124
|
*/ addFilterOptionsToFields({
|
|
125
|
+
config: incomingConfig,
|
|
125
126
|
fields: collection.fields,
|
|
126
127
|
tenantEnabledCollectionSlugs: collectionSlugs,
|
|
127
128
|
tenantEnabledGlobalSlugs: globalCollectionSlugs,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\n\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { withTenantListFilter } from './utilities/withTenantListFilter.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n userHasAccessToAllTenants,\n })\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n collection,\n fieldName: 'id',\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Collection baseListFilter with selected tenant constraint (if selected)\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n collection.admin.baseListFilter = withTenantListFilter({\n baseListFilter: collection.admin?.baseListFilter,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n collection,\n fieldName: tenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","addCollectionAccess","addFilterOptionsToFields","withTenantListFilter","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","collection","fieldName","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","forEach","useTenantsCollectionAccess","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","baseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\n\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { withTenantListFilter } from './utilities/withTenantListFilter.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n userHasAccessToAllTenants,\n })\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n collection,\n fieldName: 'id',\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Collection baseListFilter with selected tenant constraint (if selected)\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n collection.admin.baseListFilter = withTenantListFilter({\n baseListFilter: collection.admin?.baseListFilter,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n collection,\n fieldName: tenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","addCollectionAccess","addFilterOptionsToFields","withTenantListFilter","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","collection","fieldName","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","forEach","useTenantsCollectionAccess","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","baseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { Field } from 'payload';
|
|
1
|
+
import type { Config, Field, SanitizedConfig } from 'payload';
|
|
2
2
|
type AddFilterOptionsToFieldsArgs = {
|
|
3
|
+
config: Config | SanitizedConfig;
|
|
3
4
|
fields: Field[];
|
|
4
5
|
tenantEnabledCollectionSlugs: string[];
|
|
5
6
|
tenantEnabledGlobalSlugs: string[];
|
|
6
7
|
tenantFieldName: string;
|
|
7
8
|
tenantsCollectionSlug: string;
|
|
8
9
|
};
|
|
9
|
-
export declare function addFilterOptionsToFields({ fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsCollectionSlug, }: AddFilterOptionsToFieldsArgs): void;
|
|
10
|
+
export declare function addFilterOptionsToFields({ config, fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsCollectionSlug, }: AddFilterOptionsToFieldsArgs): void;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=addFilterOptionsToFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addFilterOptionsToFields.d.ts","sourceRoot":"","sources":["../../src/utilities/addFilterOptionsToFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAyC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"addFilterOptionsToFields.d.ts","sourceRoot":"","sources":["../../src/utilities/addFilterOptionsToFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAyC,eAAe,EAAE,MAAM,SAAS,CAAA;AAKpG,KAAK,4BAA4B,GAAG;IAClC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAA;IAChC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,4BAA4B,EAAE,MAAM,EAAE,CAAA;IACtC,wBAAwB,EAAE,MAAM,EAAE,CAAA;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,MAAM,EACN,4BAA4B,EAC5B,wBAAwB,EACxB,eAAe,EACf,qBAAqB,GACtB,EAAE,4BAA4B,QAqF9B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getCollectionIDType } from './getCollectionIDType.js';
|
|
2
2
|
import { getTenantFromCookie } from './getTenantFromCookie.js';
|
|
3
|
-
export function addFilterOptionsToFields({ fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsCollectionSlug }) {
|
|
3
|
+
export function addFilterOptionsToFields({ config, fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsCollectionSlug }) {
|
|
4
4
|
fields.forEach((field)=>{
|
|
5
5
|
if (field.type === 'relationship') {
|
|
6
6
|
/**
|
|
@@ -36,6 +36,7 @@ export function addFilterOptionsToFields({ fields, tenantEnabledCollectionSlugs,
|
|
|
36
36
|
}
|
|
37
37
|
if (field.type === 'row' || field.type === 'array' || field.type === 'collapsible' || field.type === 'group') {
|
|
38
38
|
addFilterOptionsToFields({
|
|
39
|
+
config,
|
|
39
40
|
fields: field.fields,
|
|
40
41
|
tenantEnabledCollectionSlugs,
|
|
41
42
|
tenantEnabledGlobalSlugs,
|
|
@@ -44,19 +45,25 @@ export function addFilterOptionsToFields({ fields, tenantEnabledCollectionSlugs,
|
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
if (field.type === 'blocks') {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
;
|
|
49
|
+
(field.blockReferences ?? field.blocks).forEach((_block)=>{
|
|
50
|
+
const block = typeof _block === 'string' ? config?.blocks?.find((b)=>b.slug === _block) : _block;
|
|
51
|
+
if (block?.fields) {
|
|
52
|
+
addFilterOptionsToFields({
|
|
53
|
+
config,
|
|
54
|
+
fields: block.fields,
|
|
55
|
+
tenantEnabledCollectionSlugs,
|
|
56
|
+
tenantEnabledGlobalSlugs,
|
|
57
|
+
tenantFieldName,
|
|
58
|
+
tenantsCollectionSlug
|
|
59
|
+
});
|
|
60
|
+
}
|
|
55
61
|
});
|
|
56
62
|
}
|
|
57
63
|
if (field.type === 'tabs') {
|
|
58
64
|
field.tabs.forEach((tab)=>{
|
|
59
65
|
addFilterOptionsToFields({
|
|
66
|
+
config,
|
|
60
67
|
fields: tab.fields,
|
|
61
68
|
tenantEnabledCollectionSlugs,
|
|
62
69
|
tenantEnabledGlobalSlugs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addFilterOptionsToFields.ts"],"sourcesContent":["import type { Field, FilterOptionsProps, RelationshipField } from 'payload'\n\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype AddFilterOptionsToFieldsArgs = {\n fields: Field[]\n tenantEnabledCollectionSlugs: string[]\n tenantEnabledGlobalSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n}\n\nexport function addFilterOptionsToFields({\n fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n}: AddFilterOptionsToFieldsArgs) {\n fields.forEach((field) => {\n if (field.type === 'relationship') {\n /**\n * Adjusts relationship fields to filter by tenant\n * and ensures relationTo cannot be a tenant global collection\n */\n if (typeof field.relationTo === 'string') {\n if (tenantEnabledGlobalSlugs.includes(field.relationTo)) {\n throw new Error(\n `The collection ${field.relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(field.relationTo)) {\n addFilter({ field, tenantEnabledCollectionSlugs, tenantFieldName, tenantsCollectionSlug })\n }\n } else {\n field.relationTo.map((relationTo) => {\n if (tenantEnabledGlobalSlugs.includes(relationTo)) {\n throw new Error(\n `The collection ${relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(relationTo)) {\n addFilter({\n field,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n })\n }\n }\n\n if (\n field.type === 'row' ||\n field.type === 'array' ||\n field.type === 'collapsible' ||\n field.type === 'group'\n ) {\n addFilterOptionsToFields({\n fields: field.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (field.type === 'blocks') {\n field.blocks.forEach((block) => {\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addFilterOptionsToFields.ts"],"sourcesContent":["import type { Config, Field, FilterOptionsProps, RelationshipField, SanitizedConfig } from 'payload'\n\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype AddFilterOptionsToFieldsArgs = {\n config: Config | SanitizedConfig\n fields: Field[]\n tenantEnabledCollectionSlugs: string[]\n tenantEnabledGlobalSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n}\n\nexport function addFilterOptionsToFields({\n config,\n fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n}: AddFilterOptionsToFieldsArgs) {\n fields.forEach((field) => {\n if (field.type === 'relationship') {\n /**\n * Adjusts relationship fields to filter by tenant\n * and ensures relationTo cannot be a tenant global collection\n */\n if (typeof field.relationTo === 'string') {\n if (tenantEnabledGlobalSlugs.includes(field.relationTo)) {\n throw new Error(\n `The collection ${field.relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(field.relationTo)) {\n addFilter({ field, tenantEnabledCollectionSlugs, tenantFieldName, tenantsCollectionSlug })\n }\n } else {\n field.relationTo.map((relationTo) => {\n if (tenantEnabledGlobalSlugs.includes(relationTo)) {\n throw new Error(\n `The collection ${relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(relationTo)) {\n addFilter({\n field,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n })\n }\n }\n\n if (\n field.type === 'row' ||\n field.type === 'array' ||\n field.type === 'collapsible' ||\n field.type === 'group'\n ) {\n addFilterOptionsToFields({\n config,\n fields: field.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (field.type === 'blocks') {\n ;(field.blockReferences ?? field.blocks).forEach((_block) => {\n const block =\n typeof _block === 'string'\n ? // TODO: iterate over blocks mapped to block slug in v4, or pass through payload.blocks\n config?.blocks?.find((b) => b.slug === _block)\n : _block\n\n if (block?.fields) {\n addFilterOptionsToFields({\n config,\n fields: block.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n })\n }\n\n if (field.type === 'tabs') {\n field.tabs.forEach((tab) => {\n addFilterOptionsToFields({\n config,\n fields: tab.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n })\n }\n })\n}\n\ntype AddFilterArgs = {\n field: RelationshipField\n tenantEnabledCollectionSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n}\nfunction addFilter({\n field,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n}: AddFilterArgs) {\n // User specified filter\n const originalFilter = field.filterOptions\n field.filterOptions = async (args) => {\n const originalFilterResult =\n typeof originalFilter === 'function' ? await originalFilter(args) : (originalFilter ?? true)\n\n // If the relationTo is not a tenant enabled collection, return early\n if (args.relationTo && !tenantEnabledCollectionSlugs.includes(args.relationTo)) {\n return originalFilterResult\n }\n\n // If the original filtr returns false, return early\n if (originalFilterResult === false) {\n return false\n }\n\n // Custom tenant filter\n const tenantFilterResults = filterOptionsByTenant({\n ...args,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n // If the tenant filter returns true, just use the original filter\n if (tenantFilterResults === true) {\n return originalFilterResult\n }\n\n // If the original filter returns true, just use the tenant filter\n if (originalFilterResult === true) {\n return tenantFilterResults\n }\n\n return {\n and: [originalFilterResult, tenantFilterResults],\n }\n }\n}\n\ntype Args = {\n tenantFieldName?: string\n tenantsCollectionSlug: string\n} & FilterOptionsProps\nconst filterOptionsByTenant = ({\n req,\n tenantFieldName = 'tenant',\n tenantsCollectionSlug,\n}: Args) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const selectedTenant = getTenantFromCookie(req.headers, idType)\n if (!selectedTenant) {\n return true\n }\n\n return {\n or: [\n // ie a related collection that doesn't have a tenant field\n {\n [tenantFieldName]: {\n exists: false,\n },\n },\n // related collections that have a tenant field\n {\n [tenantFieldName]: {\n equals: selectedTenant,\n },\n },\n ],\n }\n}\n"],"names":["getCollectionIDType","getTenantFromCookie","addFilterOptionsToFields","config","fields","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","tenantFieldName","tenantsCollectionSlug","forEach","field","type","relationTo","includes","Error","addFilter","map","blockReferences","blocks","_block","block","find","b","slug","tabs","tab","originalFilter","filterOptions","args","originalFilterResult","tenantFilterResults","filterOptionsByTenant","and","req","idType","collectionSlug","payload","selectedTenant","headers","or","exists","equals"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-multi-tenant",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.24.0-canary.05013b2",
|
|
4
4
|
"description": "Multi Tenant plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -66,14 +66,14 @@
|
|
|
66
66
|
"types.d.ts"
|
|
67
67
|
],
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"payload": "3.23.0",
|
|
70
69
|
"@payloadcms/eslint-config": "3.9.0",
|
|
71
|
-
"@payloadcms/ui": "3.
|
|
70
|
+
"@payloadcms/ui": "3.24.0-canary.05013b2",
|
|
71
|
+
"payload": "3.24.0-canary.05013b2"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"next": "^15.0.3",
|
|
75
|
-
"@payloadcms/ui": "3.
|
|
76
|
-
"payload": "3.
|
|
75
|
+
"@payloadcms/ui": "3.24.0-canary.05013b2",
|
|
76
|
+
"payload": "3.24.0-canary.05013b2"
|
|
77
77
|
},
|
|
78
78
|
"homepage:": "https://payloadcms.com",
|
|
79
79
|
"scripts": {
|