@payloadcms/plugin-multi-tenant 3.29.0-canary.4 → 3.29.0-canary.6

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/README.md CHANGED
@@ -86,6 +86,18 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
86
86
  * Access configuration for the array field
87
87
  */
88
88
  arrayFieldAccess?: ArrayField['access']
89
+ /**
90
+ * Name of the array field
91
+ *
92
+ * @default 'tenants'
93
+ */
94
+ arrayFieldName?: string
95
+ /**
96
+ * Name of the tenant field
97
+ *
98
+ * @default 'tenant'
99
+ */
100
+ arrayTenantFieldName?: string
89
101
  /**
90
102
  * When `includeDefaultField` is `true`, the field will be added to the users collection automatically
91
103
  */
@@ -101,6 +113,8 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
101
113
  }
102
114
  | {
103
115
  arrayFieldAccess?: never
116
+ arrayFieldName?: string
117
+ arrayTenantFieldName?: string
104
118
  /**
105
119
  * When `includeDefaultField` is `false`, you must include the field on your users collection manually
106
120
  */
@@ -108,6 +122,16 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
108
122
  rowFields?: never
109
123
  tenantFieldAccess?: never
110
124
  }
125
+ /**
126
+ * Customize tenant selector label
127
+ *
128
+ * Either a string or an object where the keys are i18n codes and the values are the string labels
129
+ */
130
+ tenantSelectorLabel?:
131
+ | Partial<{
132
+ [key in AcceptedLanguages]?: string
133
+ }>
134
+ | string
111
135
  /**
112
136
  * The slug for the tenant collection
113
137
  *
@@ -120,8 +144,20 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
120
144
  * Useful for super-admin type users
121
145
  */
122
146
  userHasAccessToAllTenants?: (
123
- user: ConfigTypes extends { user } ? ConfigTypes['user'] : User,
147
+ user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : User,
124
148
  ) => boolean
149
+ /**
150
+ * Opt out of adding access constraints to the tenants collection
151
+ */
152
+ useTenantsCollectionAccess?: boolean
153
+ /**
154
+ * Opt out including the baseListFilter to filter tenants by selected tenant
155
+ */
156
+ useTenantsListFilter?: boolean
157
+ /**
158
+ * Opt out including the baseListFilter to filter users by selected tenant
159
+ */
160
+ useUsersTenantFilter?: boolean
125
161
  }
126
162
  ```
127
163
 
@@ -159,7 +195,7 @@ import { Config as ConfigTypes } from './payload-types'
159
195
  // Add the plugin to your payload config
160
196
  export default buildConfig({
161
197
  plugins: [
162
- multiTenantPlugin({
198
+ multiTenantPlugin<ConfigTypes>({
163
199
  collections: {
164
200
  media: {
165
201
  useTenantAccess: false,
@@ -1,6 +1,6 @@
1
1
  import type { ViewTypes } from 'payload';
2
- import './index.scss';
3
2
  import React from 'react';
3
+ import './index.scss';
4
4
  export declare const TenantSelector: ({ label, viewType }: {
5
5
  label: string;
6
6
  viewType?: ViewTypes;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,OAAO,cAAc,CAAA;AAGrB,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,eAAO,MAAM,cAAc,wBAAyB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,6BAgC1F,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,cAAc,CAAA;AAErB,eAAO,MAAM,cAAc,wBAAyB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,6BAgC1F,CAAA"}
@@ -1,12 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import './index.scss';
3
+ import { getTranslation } from '@payloadcms/translations';
4
4
  import { SelectInput, useTranslation } from '@payloadcms/ui';
5
5
  import React from 'react';
6
6
  import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
7
+ import './index.scss';
7
8
  export const TenantSelector = ({ label, viewType })=>{
8
9
  const { options, selectedTenantID, setTenant } = useTenantSelection();
9
- const { t } = useTranslation();
10
+ const { i18n } = useTranslation();
10
11
  const handleChange = React.useCallback((option)=>{
11
12
  if (option && 'value' in option) {
12
13
  setTenant({
@@ -29,7 +30,7 @@ export const TenantSelector = ({ label, viewType })=>{
29
30
  className: "tenant-selector",
30
31
  children: /*#__PURE__*/ _jsx(SelectInput, {
31
32
  isClearable: viewType === 'list',
32
- label: t(label),
33
+ label: getTranslation(label, i18n),
33
34
  name: "setTenant",
34
35
  onChange: handleChange,
35
36
  options: options,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["'use client'\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport type { ViewTypes } from 'payload'\n\nimport './index.scss'\n\nimport { SelectInput, useTranslation } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\n\nexport const TenantSelector = ({ label, viewType }: { label: string; viewType?: ViewTypes }) => {\n const { options, selectedTenantID, setTenant } = useTenantSelection()\n const { t } = useTranslation()\n\n const handleChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (option && 'value' in option) {\n setTenant({ id: option.value as string, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n },\n [setTenant],\n )\n\n if (options.length <= 1) {\n return null\n }\n\n return (\n <div className=\"tenant-selector\">\n <SelectInput\n isClearable={viewType === 'list'}\n label={t(label as any)}\n name=\"setTenant\"\n onChange={handleChange}\n options={options}\n path=\"setTenant\"\n value={selectedTenantID as string | undefined}\n />\n </div>\n )\n}\n"],"names":["SelectInput","useTranslation","React","useTenantSelection","TenantSelector","label","viewType","options","selectedTenantID","setTenant","t","handleChange","useCallback","option","id","value","refresh","undefined","length","div","className","isClearable","name","onChange","path"],"mappings":"AAAA;;AAIA,OAAO,eAAc;AAErB,SAASA,WAAW,EAAEC,cAAc,QAAQ,iBAAgB;AAC5D,OAAOC,WAAW,QAAO;AAEzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAE5F,OAAO,MAAMC,iBAAiB,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAA2C;IACzF,MAAM,EAAEC,OAAO,EAAEC,gBAAgB,EAAEC,SAAS,EAAE,GAAGN;IACjD,MAAM,EAAEO,CAAC,EAAE,GAAGT;IAEd,MAAMU,eAAeT,MAAMU,WAAW,CACpC,CAACC;QACC,IAAIA,UAAU,WAAWA,QAAQ;YAC/BJ,UAAU;gBAAEK,IAAID,OAAOE,KAAK;gBAAYC,SAAS;YAAK;QACxD,OAAO;YACLP,UAAU;gBAAEK,IAAIG;gBAAWD,SAAS;YAAK;QAC3C;IACF,GACA;QAACP;KAAU;IAGb,IAAIF,QAAQW,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAU;kBACb,cAAA,KAACpB;YACCqB,aAAaf,aAAa;YAC1BD,OAAOK,EAAEL;YACTiB,MAAK;YACLC,UAAUZ;YACVJ,SAASA;YACTiB,MAAK;YACLT,OAAOP;;;AAIf,EAAC"}
1
+ {"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["'use client'\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport type { ViewTypes } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { SelectInput, useTranslation } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\nimport './index.scss'\n\nexport const TenantSelector = ({ label, viewType }: { label: string; viewType?: ViewTypes }) => {\n const { options, selectedTenantID, setTenant } = useTenantSelection()\n const { i18n } = useTranslation()\n\n const handleChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (option && 'value' in option) {\n setTenant({ id: option.value as string, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n },\n [setTenant],\n )\n\n if (options.length <= 1) {\n return null\n }\n\n return (\n <div className=\"tenant-selector\">\n <SelectInput\n isClearable={viewType === 'list'}\n label={getTranslation(label, i18n)}\n name=\"setTenant\"\n onChange={handleChange}\n options={options}\n path=\"setTenant\"\n value={selectedTenantID as string | undefined}\n />\n </div>\n )\n}\n"],"names":["getTranslation","SelectInput","useTranslation","React","useTenantSelection","TenantSelector","label","viewType","options","selectedTenantID","setTenant","i18n","handleChange","useCallback","option","id","value","refresh","undefined","length","div","className","isClearable","name","onChange","path"],"mappings":"AAAA;;AAIA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,WAAW,EAAEC,cAAc,QAAQ,iBAAgB;AAC5D,OAAOC,WAAW,QAAO;AAEzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAC5F,OAAO,eAAc;AAErB,OAAO,MAAMC,iBAAiB,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAA2C;IACzF,MAAM,EAAEC,OAAO,EAAEC,gBAAgB,EAAEC,SAAS,EAAE,GAAGN;IACjD,MAAM,EAAEO,IAAI,EAAE,GAAGT;IAEjB,MAAMU,eAAeT,MAAMU,WAAW,CACpC,CAACC;QACC,IAAIA,UAAU,WAAWA,QAAQ;YAC/BJ,UAAU;gBAAEK,IAAID,OAAOE,KAAK;gBAAYC,SAAS;YAAK;QACxD,OAAO;YACLP,UAAU;gBAAEK,IAAIG;gBAAWD,SAAS;YAAK;QAC3C;IACF,GACA;QAACP;KAAU;IAGb,IAAIF,QAAQW,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAU;kBACb,cAAA,KAACpB;YACCqB,aAAaf,aAAa;YAC1BD,OAAON,eAAeM,OAAOK;YAC7BY,MAAK;YACLC,UAAUZ;YACVJ,SAASA;YACTiB,MAAK;YACLT,OAAOP;;;AAIf,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAazD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAoUzB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAazD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAmUzB,CAAA"}
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
19
19
  const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName;
20
20
  const tenantsArrayFieldName = pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName;
21
21
  const tenantsArrayTenantFieldName = pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName;
22
- let tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel;
22
+ const tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel;
23
23
  /**
24
24
  * Add defaults for admin properties
25
25
  */ if (!incomingConfig.admin) {
@@ -46,11 +46,11 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
46
46
  }
47
47
  /**
48
48
  * Add tenant selector localized labels
49
- */ if (pluginConfig.tenantSelectorLabel && typeof pluginConfig.tenantSelectorLabel === 'object') {
49
+ */ if (typeof tenantSelectorLabel === 'object') {
50
50
  if (!incomingConfig.i18n) {
51
51
  incomingConfig.i18n = {};
52
52
  }
53
- Object.entries(pluginConfig.tenantSelectorLabel).forEach(([_locale, label])=>{
53
+ Object.entries(tenantSelectorLabel).forEach(([_locale, label])=>{
54
54
  const locale = _locale;
55
55
  if (!incomingConfig.i18n) {
56
56
  incomingConfig.i18n = {};
@@ -71,7 +71,6 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
71
71
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
72
72
  // @ts-expect-error
73
73
  incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label;
74
- tenantSelectorLabel = 'multiTenant:selectorLabel';
75
74
  });
76
75
  }
77
76
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport 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 { filterDocumentsBySelectedTenant } from './list-filters/filterDocumentsBySelectedTenant.js'\nimport { filterTenantsBySelectedTenant } from './list-filters/filterTenantsBySelectedTenant.js'\nimport { filterUsersBySelectedTenant } from './list-filters/filterUsersBySelectedTenant.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineListFilters } from './utilities/combineListFilters.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 let tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel\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 tenant selector localized labels\n */\n if (pluginConfig.tenantSelectorLabel && typeof pluginConfig.tenantSelectorLabel === 'object') {\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(pluginConfig.tenantSelectorLabel).forEach(([_locale, label]) => {\n const locale = _locale as AcceptedLanguages\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n if (!incomingConfig.i18n.translations) {\n incomingConfig.i18n.translations = {}\n }\n if (!(locale in incomingConfig.i18n.translations)) {\n incomingConfig.i18n.translations[locale] = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (!('multiTenant' in incomingConfig.i18n.translations[locale])) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label\n tenantSelectorLabel = 'multiTenant:selectorLabel'\n })\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 adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n adminUsersCollection.admin.baseListFilter = combineListFilters({\n baseListFilter: adminUsersCollection.admin?.baseListFilter,\n customFilter: (args) =>\n filterUsersBySelectedTenant({\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n })\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 adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterTenantsBySelectedTenant({\n req: args.req,\n tenantsCollectionSlug,\n }),\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 * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsBySelectedTenant({\n req: args.req,\n tenantFieldName,\n tenantsCollectionSlug,\n }),\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 adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\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 clientProps: {\n label: tenantSelectorLabel,\n },\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","filterDocumentsBySelectedTenant","filterTenantsBySelectedTenant","filterUsersBySelectedTenant","addCollectionAccess","addFilterOptionsToFields","combineListFilters","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","tenantSelectorLabel","admin","components","actions","beforeNavLinks","providers","collections","i18n","Object","entries","forEach","_locale","label","locale","translations","multiTenant","selectorLabel","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseListFilter","customFilter","args","req","tenantCollection","collectionSlugs","globalCollectionSlugs","keys","reduce","acc","isGlobal","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport 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 { filterDocumentsBySelectedTenant } from './list-filters/filterDocumentsBySelectedTenant.js'\nimport { filterTenantsBySelectedTenant } from './list-filters/filterTenantsBySelectedTenant.js'\nimport { filterUsersBySelectedTenant } from './list-filters/filterUsersBySelectedTenant.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineListFilters } from './utilities/combineListFilters.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 const tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel\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 tenant selector localized labels\n */\n if (typeof tenantSelectorLabel === 'object') {\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(tenantSelectorLabel).forEach(([_locale, label]) => {\n const locale = _locale as AcceptedLanguages\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n if (!incomingConfig.i18n.translations) {\n incomingConfig.i18n.translations = {}\n }\n if (!(locale in incomingConfig.i18n.translations)) {\n incomingConfig.i18n.translations[locale] = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (!('multiTenant' in incomingConfig.i18n.translations[locale])) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label\n })\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 adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n adminUsersCollection.admin.baseListFilter = combineListFilters({\n baseListFilter: adminUsersCollection.admin?.baseListFilter,\n customFilter: (args) =>\n filterUsersBySelectedTenant({\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n })\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 adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterTenantsBySelectedTenant({\n req: args.req,\n tenantsCollectionSlug,\n }),\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 * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsBySelectedTenant({\n req: args.req,\n tenantFieldName,\n tenantsCollectionSlug,\n }),\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 adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\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 clientProps: {\n label: tenantSelectorLabel,\n },\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","filterDocumentsBySelectedTenant","filterTenantsBySelectedTenant","filterUsersBySelectedTenant","addCollectionAccess","addFilterOptionsToFields","combineListFilters","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","tenantSelectorLabel","admin","components","actions","beforeNavLinks","providers","collections","i18n","Object","entries","forEach","_locale","label","locale","translations","multiTenant","selectorLabel","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseListFilter","customFilter","args","req","tenantCollection","collectionSlugs","globalCollectionSlugs","keys","reduce","acc","isGlobal","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"AAKA,SAASA,QAAQ,QAAQ,gBAAe;AACxC,SAASC,WAAW,QAAQ,gCAA+B;AAC3D,SAASC,iBAAiB,QAAQ,sCAAqC;AACvE,SAASC,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,+BAA+B,QAAQ,oDAAmD;AACnG,SAASC,6BAA6B,QAAQ,kDAAiD;AAC/F,SAASC,2BAA2B,QAAQ,gDAA+C;AAC3F,SAASC,mBAAmB,QAAQ,qCAAoC;AACxE,SAASC,wBAAwB,QAAQ,0CAAyC;AAClF,SAASC,kBAAkB,QAAQ,oCAAmC;AAEtE,OAAO,MAAMC,oBACX,CAAaC,eACb,CAACC;QACC,IAAID,aAAaE,OAAO,KAAK,OAAO;YAClC,OAAOD;QACT;QAEA;;KAEC,GACD,MAAME,4BAGJ,OAAOH,aAAaG,yBAAyB,KAAK,aAC9CH,aAAaG,yBAAyB,GACtC,IAAM;QACZ,MAAMC,wBAAyBJ,aAAaK,WAAW,GACrDL,aAAaK,WAAW,IAAIhB,SAASiB,oBAAoB;QAC3D,MAAMC,kBAAkBP,cAAcV,aAAakB,QAAQnB,SAASkB,eAAe;QACnF,MAAME,wBACJT,cAAcT,mBAAmBmB,kBAAkBrB,SAASoB,qBAAqB;QACnF,MAAME,8BACJX,cAAcT,mBAAmBqB,wBAAwBvB,SAASsB,2BAA2B;QAC/F,MAAME,sBAAsBb,aAAaa,mBAAmB,IAAIxB,SAASwB,mBAAmB;QAE5F;;KAEC,GACD,IAAI,CAACZ,eAAea,KAAK,EAAE;YACzBb,eAAea,KAAK,GAAG,CAAC;QAC1B;QACA,IAAI,CAACb,eAAea,KAAK,EAAEC,YAAY;YACrCd,eAAea,KAAK,CAACC,UAAU,GAAG;gBAChCC,SAAS,EAAE;gBACXC,gBAAgB,EAAE;gBAClBC,WAAW,EAAE;YACf;QACF;QACA,IAAI,CAACjB,eAAea,KAAK,CAACC,UAAU,EAAEG,WAAW;YAC/CjB,eAAea,KAAK,CAACC,UAAU,CAACG,SAAS,GAAG,EAAE;QAChD;QACA,IAAI,CAACjB,eAAea,KAAK,CAACC,UAAU,EAAEC,SAAS;YAC7Cf,eAAea,KAAK,CAACC,UAAU,CAACC,OAAO,GAAG,EAAE;QAC9C;QACA,IAAI,CAACf,eAAea,KAAK,CAACC,UAAU,EAAEE,gBAAgB;YACpDhB,eAAea,KAAK,CAACC,UAAU,CAACE,cAAc,GAAG,EAAE;QACrD;QACA,IAAI,CAAChB,eAAekB,WAAW,EAAE;YAC/BlB,eAAekB,WAAW,GAAG,EAAE;QACjC;QAEA;;KAEC,GACD,IAAI,OAAON,wBAAwB,UAAU;YAC3C,IAAI,CAACZ,eAAemB,IAAI,EAAE;gBACxBnB,eAAemB,IAAI,GAAG,CAAC;YACzB;YACAC,OAAOC,OAAO,CAACT,qBAAqBU,OAAO,CAAC,CAAC,CAACC,SAASC,MAAM;gBAC3D,MAAMC,SAASF;gBACf,IAAI,CAACvB,eAAemB,IAAI,EAAE;oBACxBnB,eAAemB,IAAI,GAAG,CAAC;gBACzB;gBACA,IAAI,CAACnB,eAAemB,IAAI,CAACO,YAAY,EAAE;oBACrC1B,eAAemB,IAAI,CAACO,YAAY,GAAG,CAAC;gBACtC;gBACA,IAAI,CAAED,CAAAA,UAAUzB,eAAemB,IAAI,CAACO,YAAY,AAAD,GAAI;oBACjD1B,eAAemB,IAAI,CAACO,YAAY,CAACD,OAAO,GAAG,CAAC;gBAC9C;gBACA,6DAA6D;gBAC7D,mBAAmB;gBACnB,IAAI,CAAE,CAAA,iBAAiBzB,eAAemB,IAAI,CAACO,YAAY,CAACD,OAAO,AAAD,GAAI;oBAChE,6DAA6D;oBAC7D,mBAAmB;oBACnBzB,eAAemB,IAAI,CAACO,YAAY,CAACD,OAAO,CAACE,WAAW,GAAG,CAAC;gBAC1D;gBACA,6DAA6D;gBAC7D,mBAAmB;gBACnB3B,eAAemB,IAAI,CAACO,YAAY,CAACD,OAAO,CAACE,WAAW,CAACC,aAAa,GAAGJ;YACvE;QACF;QAEA;;KAEC,GACD,MAAMK,uBAAuB7B,eAAekB,WAAW,CAACY,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAEC,IAAI,EAAE;YAC1E,IAAIhC,eAAea,KAAK,EAAEoB,MAAM;gBAC9B,OAAOF,SAAS/B,eAAea,KAAK,CAACoB,IAAI;YAC3C,OAAO,IAAID,MAAM;gBACf,OAAO;YACT;QACF;QAEA,IAAI,CAACH,sBAAsB;YACzB,MAAMK,MAAM;QACd;QAEA;;KAEC,GACD,IAAInC,cAAcT,mBAAmB6C,wBAAwB,OAAO;YAClEN,qBAAqBO,MAAM,CAACC,IAAI,CAC9B/C,kBAAkB;gBAChB,GAAIS,cAAcT,qBAAqB,CAAC,CAAC;gBACzCkB;gBACAE;gBACAP;YACF;QAEJ;QAEAR,oBAAoB;YAClB2C,gBAAgBT,qBAAqBE,IAAI;YACzCQ,YAAYV;YACZW,WAAW,GAAGhC,sBAAsB,CAAC,EAAEE,6BAA6B;YACpEF;YACAE;YACAR;QACF;QAEA,IAAIH,aAAa0C,oBAAoB,KAAK,OAAO;YAC/C,IAAI,CAACZ,qBAAqBhB,KAAK,EAAE;gBAC/BgB,qBAAqBhB,KAAK,GAAG,CAAC;YAChC;YAEAgB,qBAAqBhB,KAAK,CAAC6B,cAAc,GAAG7C,mBAAmB;gBAC7D6C,gBAAgBb,qBAAqBhB,KAAK,EAAE6B;gBAC5CC,cAAc,CAACC,OACblD,4BAA4B;wBAC1BmD,KAAKD,KAAKC,GAAG;wBACbrC;wBACAE;wBACAP;oBACF;YACJ;QACF;QAEA,IAAI2C;QAEJ,MAAM,CAACC,iBAAiBC,sBAAsB,GAAG5B,OAAO6B,IAAI,CAAClD,aAAamB,WAAW,EAAEgC,MAAM,CAG3F,CAACC,KAAKpB;YACJ,IAAIhC,cAAcmB,aAAa,CAACa,KAAK,EAAEqB,UAAU;gBAC/CD,GAAG,CAAC,EAAE,CAACd,IAAI,CAACN;YACd,OAAO;gBACLoB,GAAG,CAAC,EAAE,CAACd,IAAI,CAACN;YACd;YAEA,OAAOoB;QACT,GACA;YAAC,EAAE;YAAE,EAAE;SAAC;QAGV;;KAEC,GACDnD,eAAekB,WAAW,CAACI,OAAO,CAAC,CAACiB;YAClC;;OAEC,GACD,IAAIA,WAAWR,IAAI,KAAK5B,uBAAuB;gBAC7C2C,mBAAmBP;gBAEnB,IAAIxC,aAAasD,0BAA0B,KAAK,OAAO;oBACrD;;;WAGC,GACD1D,oBAAoB;wBAClB2C,gBAAgBT,qBAAqBE,IAAI;wBACzCQ;wBACAC,WAAW;wBACXhC;wBACAE;wBACAR;oBACF;gBACF;gBAEA,IAAIH,aAAauD,oBAAoB,KAAK,OAAO;oBAC/C;;;WAGC,GACD,IAAI,CAACf,WAAW1B,KAAK,EAAE;wBACrB0B,WAAW1B,KAAK,GAAG,CAAC;oBACtB;oBAEA0B,WAAW1B,KAAK,CAAC6B,cAAc,GAAG7C,mBAAmB;wBACnD6C,gBAAgBH,WAAW1B,KAAK,EAAE6B;wBAClCC,cAAc,CAACC,OACbnD,8BAA8B;gCAC5BoD,KAAKD,KAAKC,GAAG;gCACb1C;4BACF;oBACJ;gBACF;gBAEA,IAAIJ,aAAawD,wBAAwB,KAAK,OAAO;oBACnD;;;;WAIC,GACDhE,iBAAiB;wBACfgD;wBACAiB,cAAc;+BAAIT;+BAAoBC;yBAAsB;wBAC5D1C;wBACAH;wBACAsD,WAAW5B,qBAAqBE,IAAI;wBACpC2B,4BAA4BlD;wBAC5BmD,kCAAkCjD;oBACpC;gBACF;YACF,OAAO,IAAIX,aAAamB,WAAW,EAAE,CAACqB,WAAWR,IAAI,CAAC,EAAE;gBACtD,MAAMqB,WAAWQ,QAAQ7D,aAAamB,WAAW,CAACqB,WAAWR,IAAI,CAAC,EAAEqB;gBAEpE,IAAIA,UAAU;oBACZb,WAAWsB,gBAAgB,GAAG;gBAChC;gBAEA;;SAEC,GACDjE,yBAAyB;oBACvBkE,QAAQ9D;oBACRoC,QAAQG,WAAWH,MAAM;oBACzB2B,8BAA8BhB;oBAC9BiB,0BAA0BhB;oBAC1B1C;oBACAH;gBACF;gBAEA;;SAEC,GACDoC,WAAWH,MAAM,CAAC6B,MAAM,CACtB,GACA,GACA5E,YAAY;oBACV,GAAIU,cAAcV,eAAe,CAAC,CAAC;oBACnCkB,MAAMD;oBACN4D,OAAOnE,aAAamE,KAAK;oBACzB/D;oBACAgE,QAAQf;gBACV;gBAGF,IAAIrD,aAAamB,WAAW,CAACqB,WAAWR,IAAI,CAAC,EAAEqC,sBAAsB,OAAO;oBAC1E;;;WAGC,GACD,IAAI,CAAC7B,WAAW1B,KAAK,EAAE;wBACrB0B,WAAW1B,KAAK,GAAG,CAAC;oBACtB;oBAEA0B,WAAW1B,KAAK,CAAC6B,cAAc,GAAG7C,mBAAmB;wBACnD6C,gBAAgBH,WAAW1B,KAAK,EAAE6B;wBAClCC,cAAc,CAACC,OACbpD,gCAAgC;gCAC9BqD,KAAKD,KAAKC,GAAG;gCACbvC;gCACAH;4BACF;oBACJ;gBACF;gBAEA,IAAIJ,aAAamB,WAAW,CAACqB,WAAWR,IAAI,CAAC,EAAEsC,oBAAoB,OAAO;oBACxE;;WAEC,GACD1E,oBAAoB;wBAClB2C,gBAAgBT,qBAAqBE,IAAI;wBACzCQ;wBACAC,WAAWlC;wBACXE;wBACAE;wBACAR;oBACF;gBACF;YACF;QACF;QAEA,IAAI,CAAC4C,kBAAkB;YACrB,MAAM,IAAIZ,MAAM,CAAC,wCAAwC,EAAE/B,uBAAuB;QACpF;QAEA;;KAEC,GACDH,eAAea,KAAK,CAACC,UAAU,CAACG,SAAS,CAACoB,IAAI,CAAC;YAC7CiC,aAAa;gBACXnE,uBAAuB2C,iBAAiBf,IAAI;gBAC5CwC,YAAYzB,iBAAiBjC,KAAK,EAAE0D,cAAc;YACpD;YACAC,MAAM;QACR;QAEA;;KAEC,GACD,IAAIxB,sBAAsByB,MAAM,EAAE;YAChCzE,eAAea,KAAK,CAACC,UAAU,CAACC,OAAO,CAACsB,IAAI,CAAC;gBAC3CmC,MAAM;gBACNE,aAAa;oBACXC,aAAa3B;oBACb1C;oBACAH;oBACAoE,YAAYzB,iBAAiBjC,KAAK,EAAE0D,cAAc;gBACpD;YACF;QACF;QAEA;;KAEC,GACDvE,eAAea,KAAK,CAACC,UAAU,CAACE,cAAc,CAACqB,IAAI,CAAC;YAClDiC,aAAa;gBACX9C,OAAOZ;YACT;YACA4D,MAAM;QACR;QAEA,OAAOxE;IACT,EAAC"}
package/dist/types.d.ts CHANGED
@@ -108,7 +108,7 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
108
108
  /**
109
109
  * Customize tenant selector label
110
110
  *
111
- * Either a string or an object where the keys are locales and the values are the string labels
111
+ * Either a string or an object where the keys are i18n codes and the values are the string labels
112
112
  */
113
113
  tenantSelectorLabel?: Partial<{
114
114
  [key in AcceptedLanguages]?: string;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { ArrayField, CollectionSlug, Field, RelationshipField, User } from 'payload'\n\nexport type MultiTenantPluginConfig<ConfigTypes = unknown> = {\n /**\n * After a tenant is deleted, the plugin will attempt to clean up related documents\n * - removing documents with the tenant ID\n * - removing the tenant from users\n *\n * @default true\n */\n cleanupAfterTenantDelete?: boolean\n /**\n * Automatically\n */\n collections: {\n [key in CollectionSlug]?: {\n /**\n * Set to `true` if you want the collection to behave as a global\n *\n * @default false\n */\n isGlobal?: boolean\n /**\n * Set to `false` if you want to manually apply the baseListFilter\n *\n * @default true\n */\n useBaseListFilter?: boolean\n /**\n * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied\n *\n * @default true\n */\n useTenantAccess?: boolean\n }\n }\n /**\n * Enables debug mode\n * - Makes the tenant field visible in the admin UI within applicable collections\n *\n * @default false\n */\n debug?: boolean\n /**\n * Enables the multi-tenant plugin\n *\n * @default true\n */\n enabled?: boolean\n /**\n * Field configuration for the field added to all tenant enabled collections\n */\n tenantField?: {\n access?: RelationshipField['access']\n /**\n * The name of the field added to all tenant enabled collections\n *\n * @default 'tenant'\n */\n name?: string\n }\n /**\n * Field configuration for the field added to the users collection\n *\n * If `includeDefaultField` is `false`, you must include the field on your users collection manually\n * This is useful if you want to customize the field or place the field in a specific location\n */\n tenantsArrayField?:\n | {\n /**\n * Access configuration for the array field\n */\n arrayFieldAccess?: ArrayField['access']\n /**\n * Name of the array field\n *\n * @default 'tenants'\n */\n arrayFieldName?: string\n /**\n * Name of the tenant field\n *\n * @default 'tenant'\n */\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `true`, the field will be added to the users collection automatically\n */\n includeDefaultField?: true\n /**\n * Additional fields to include on the tenants array field\n */\n rowFields?: Field[]\n /**\n * Access configuration for the tenant field\n */\n tenantFieldAccess?: RelationshipField['access']\n }\n | {\n arrayFieldAccess?: never\n arrayFieldName?: string\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `false`, you must include the field on your users collection manually\n */\n includeDefaultField?: false\n rowFields?: never\n tenantFieldAccess?: never\n }\n /**\n * Customize tenant selector label\n *\n * Either a string or an object where the keys are locales and the values are the string labels\n */\n tenantSelectorLabel?:\n | Partial<{\n [key in AcceptedLanguages]?: string\n }>\n | string\n /**\n * The slug for the tenant collection\n *\n * @default 'tenants'\n */\n tenantsSlug?: string\n /**\n * Function that determines if a user has access to _all_ tenants\n *\n * Useful for super-admin type users\n */\n userHasAccessToAllTenants?: (\n user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : User,\n ) => boolean\n /**\n * Opt out of adding access constraints to the tenants collection\n */\n useTenantsCollectionAccess?: boolean\n /**\n * Opt out including the baseListFilter to filter tenants by selected tenant\n */\n useTenantsListFilter?: boolean\n /**\n * Opt out including the baseListFilter to filter users by selected tenant\n */\n useUsersTenantFilter?: boolean\n}\n\nexport type Tenant<IDType = number | string> = {\n id: IDType\n name: string\n}\n\nexport type UserWithTenantsField = {\n tenants?:\n | {\n tenant: number | string | Tenant\n }[]\n | null\n} & User\n"],"names":[],"mappings":"AAyJA,WAMQ"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { ArrayField, CollectionSlug, Field, RelationshipField, User } from 'payload'\n\nexport type MultiTenantPluginConfig<ConfigTypes = unknown> = {\n /**\n * After a tenant is deleted, the plugin will attempt to clean up related documents\n * - removing documents with the tenant ID\n * - removing the tenant from users\n *\n * @default true\n */\n cleanupAfterTenantDelete?: boolean\n /**\n * Automatically\n */\n collections: {\n [key in CollectionSlug]?: {\n /**\n * Set to `true` if you want the collection to behave as a global\n *\n * @default false\n */\n isGlobal?: boolean\n /**\n * Set to `false` if you want to manually apply the baseListFilter\n *\n * @default true\n */\n useBaseListFilter?: boolean\n /**\n * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied\n *\n * @default true\n */\n useTenantAccess?: boolean\n }\n }\n /**\n * Enables debug mode\n * - Makes the tenant field visible in the admin UI within applicable collections\n *\n * @default false\n */\n debug?: boolean\n /**\n * Enables the multi-tenant plugin\n *\n * @default true\n */\n enabled?: boolean\n /**\n * Field configuration for the field added to all tenant enabled collections\n */\n tenantField?: {\n access?: RelationshipField['access']\n /**\n * The name of the field added to all tenant enabled collections\n *\n * @default 'tenant'\n */\n name?: string\n }\n /**\n * Field configuration for the field added to the users collection\n *\n * If `includeDefaultField` is `false`, you must include the field on your users collection manually\n * This is useful if you want to customize the field or place the field in a specific location\n */\n tenantsArrayField?:\n | {\n /**\n * Access configuration for the array field\n */\n arrayFieldAccess?: ArrayField['access']\n /**\n * Name of the array field\n *\n * @default 'tenants'\n */\n arrayFieldName?: string\n /**\n * Name of the tenant field\n *\n * @default 'tenant'\n */\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `true`, the field will be added to the users collection automatically\n */\n includeDefaultField?: true\n /**\n * Additional fields to include on the tenants array field\n */\n rowFields?: Field[]\n /**\n * Access configuration for the tenant field\n */\n tenantFieldAccess?: RelationshipField['access']\n }\n | {\n arrayFieldAccess?: never\n arrayFieldName?: string\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `false`, you must include the field on your users collection manually\n */\n includeDefaultField?: false\n rowFields?: never\n tenantFieldAccess?: never\n }\n /**\n * Customize tenant selector label\n *\n * Either a string or an object where the keys are i18n codes and the values are the string labels\n */\n tenantSelectorLabel?:\n | Partial<{\n [key in AcceptedLanguages]?: string\n }>\n | string\n /**\n * The slug for the tenant collection\n *\n * @default 'tenants'\n */\n tenantsSlug?: string\n /**\n * Function that determines if a user has access to _all_ tenants\n *\n * Useful for super-admin type users\n */\n userHasAccessToAllTenants?: (\n user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : User,\n ) => boolean\n /**\n * Opt out of adding access constraints to the tenants collection\n */\n useTenantsCollectionAccess?: boolean\n /**\n * Opt out including the baseListFilter to filter tenants by selected tenant\n */\n useTenantsListFilter?: boolean\n /**\n * Opt out including the baseListFilter to filter users by selected tenant\n */\n useUsersTenantFilter?: boolean\n}\n\nexport type Tenant<IDType = number | string> = {\n id: IDType\n name: string\n}\n\nexport type UserWithTenantsField = {\n tenants?:\n | {\n tenant: number | string | Tenant\n }[]\n | null\n} & User\n"],"names":[],"mappings":"AAyJA,WAMQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "3.29.0-canary.4",
3
+ "version": "3.29.0-canary.6",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -66,15 +66,15 @@
66
66
  "types.d.ts"
67
67
  ],
68
68
  "devDependencies": {
69
- "@payloadcms/ui": "3.29.0-canary.4",
70
69
  "@payloadcms/eslint-config": "3.28.0",
71
- "payload": "3.29.0-canary.4",
72
- "@payloadcms/translations": "3.29.0-canary.4"
70
+ "@payloadcms/translations": "3.29.0-canary.6",
71
+ "payload": "3.29.0-canary.6",
72
+ "@payloadcms/ui": "3.29.0-canary.6"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "next": "^15.0.3",
76
- "@payloadcms/ui": "3.29.0-canary.4",
77
- "payload": "3.29.0-canary.4"
76
+ "@payloadcms/ui": "3.29.0-canary.6",
77
+ "payload": "3.29.0-canary.6"
78
78
  },
79
79
  "homepage:": "https://payloadcms.com",
80
80
  "scripts": {