@payloadcms/plugin-multi-tenant 3.25.0-canary.fd53f68 → 3.26.0-canary.bbb3083

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.
Files changed (70) hide show
  1. package/dist/components/TenantSelector/index.d.ts +2 -1
  2. package/dist/components/TenantSelector/index.d.ts.map +1 -1
  3. package/dist/components/TenantSelector/index.js +4 -3
  4. package/dist/components/TenantSelector/index.js.map +1 -1
  5. package/dist/defaults.d.ts +1 -0
  6. package/dist/defaults.d.ts.map +1 -1
  7. package/dist/defaults.js +2 -1
  8. package/dist/defaults.js.map +1 -1
  9. package/dist/exports/client.d.ts +1 -0
  10. package/dist/exports/client.d.ts.map +1 -1
  11. package/dist/exports/client.js +1 -0
  12. package/dist/exports/client.js.map +1 -1
  13. package/dist/exports/utilities.d.ts +1 -1
  14. package/dist/exports/utilities.d.ts.map +1 -1
  15. package/dist/exports/utilities.js +1 -1
  16. package/dist/exports/utilities.js.map +1 -1
  17. package/dist/hooks/afterTenantDelete.d.ts.map +1 -1
  18. package/dist/hooks/afterTenantDelete.js +5 -1
  19. package/dist/hooks/afterTenantDelete.js.map +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +84 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/list-filters/filterDocumentsBySelectedTenant.d.ts +9 -0
  24. package/dist/list-filters/filterDocumentsBySelectedTenant.d.ts.map +1 -0
  25. package/dist/{utilities/getTenantListFilter.js → list-filters/filterDocumentsBySelectedTenant.js} +4 -4
  26. package/dist/list-filters/filterDocumentsBySelectedTenant.js.map +1 -0
  27. package/dist/list-filters/filterTenantsBySelectedTenant.d.ts +8 -0
  28. package/dist/list-filters/filterTenantsBySelectedTenant.d.ts.map +1 -0
  29. package/dist/list-filters/filterTenantsBySelectedTenant.js +20 -0
  30. package/dist/list-filters/filterTenantsBySelectedTenant.js.map +1 -0
  31. package/dist/list-filters/filterUsersBySelectedTenant.d.ts +13 -0
  32. package/dist/list-filters/filterUsersBySelectedTenant.d.ts.map +1 -0
  33. package/dist/list-filters/filterUsersBySelectedTenant.js +24 -0
  34. package/dist/list-filters/filterUsersBySelectedTenant.js.map +1 -0
  35. package/dist/providers/TenantSelectionProvider/index.client.d.ts +17 -0
  36. package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
  37. package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
  38. package/dist/types.d.ts +19 -2
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/types.js.map +1 -1
  41. package/dist/utilities/addCollectionAccess.d.ts +4 -1
  42. package/dist/utilities/addCollectionAccess.d.ts.map +1 -1
  43. package/dist/utilities/addCollectionAccess.js +6 -1
  44. package/dist/utilities/addCollectionAccess.js.map +1 -1
  45. package/dist/utilities/combineListFilters.d.ts +13 -0
  46. package/dist/utilities/combineListFilters.d.ts.map +1 -0
  47. package/dist/utilities/{withTenantListFilter.js → combineListFilters.js} +5 -10
  48. package/dist/utilities/combineListFilters.js.map +1 -0
  49. package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
  50. package/dist/utilities/getGlobalViewRedirect.js +1 -0
  51. package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
  52. package/dist/utilities/getTenantAccess.d.ts +3 -1
  53. package/dist/utilities/getTenantAccess.d.ts.map +1 -1
  54. package/dist/utilities/getTenantAccess.js +6 -2
  55. package/dist/utilities/getTenantAccess.js.map +1 -1
  56. package/dist/utilities/getUserTenantIDs.d.ts +4 -1
  57. package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
  58. package/dist/utilities/getUserTenantIDs.js +6 -4
  59. package/dist/utilities/getUserTenantIDs.js.map +1 -1
  60. package/dist/utilities/withTenantAccess.d.ts +7 -2
  61. package/dist/utilities/withTenantAccess.d.ts.map +1 -1
  62. package/dist/utilities/withTenantAccess.js +20 -4
  63. package/dist/utilities/withTenantAccess.js.map +1 -1
  64. package/package.json +6 -5
  65. package/dist/utilities/getTenantListFilter.d.ts +0 -9
  66. package/dist/utilities/getTenantListFilter.d.ts.map +0 -1
  67. package/dist/utilities/getTenantListFilter.js.map +0 -1
  68. package/dist/utilities/withTenantListFilter.d.ts +0 -14
  69. package/dist/utilities/withTenantListFilter.d.ts.map +0 -1
  70. package/dist/utilities/withTenantListFilter.js.map +0 -1
@@ -1,9 +1,26 @@
1
1
  import type { OptionObject } from 'payload';
2
2
  import React from 'react';
3
3
  type ContextType = {
4
+ /**
5
+ * Array of options to select from
6
+ */
4
7
  options: OptionObject[];
8
+ /**
9
+ * The currently selected tenant ID
10
+ */
5
11
  selectedTenantID: number | string | undefined;
12
+ /**
13
+ * Prevents a refresh when the tenant is changed
14
+ *
15
+ * If not switching tenants while viewing a "global", set to true
16
+ */
6
17
  setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>;
18
+ /**
19
+ * Sets the selected tenant ID
20
+ *
21
+ * @param args.id - The ID of the tenant to select
22
+ * @param args.refresh - Whether to refresh the page after changing the tenant
23
+ */
7
24
  setTenant: (args: {
8
25
  id: number | string | undefined;
9
26
  refresh?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAI5C,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;CAClF,CAAA;AASD,eAAO,MAAM,6BAA6B,6DAKvC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,sBA8FA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAAkC,CAAA"}
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAI5C,KAAK,WAAW,GAAG;IACjB;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;OAIG;IACH,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE;;;;;OAKG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;CAClF,CAAA;AASD,eAAO,MAAM,6BAA6B,6DAKvC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,sBA8FA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAAkC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\n\ntype ContextType = {\n options: OptionObject[]\n selectedTenantID: number | string | undefined\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(SELECT_ALL)\n setCookie(SELECT_ALL)\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [setSelectedTenantID, setCookie, router, preventRefreshOnChange, tenantOptions],\n )\n\n React.useEffect(() => {\n if (\n selectedTenantID &&\n selectedTenantID !== SELECT_ALL &&\n !tenantOptions.find((option) => option.value === selectedTenantID)\n ) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n setCookie(String(initialValue))\n }\n }, [userID, tenantCookie, initialValue, setCookie, router])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context.Provider\n value={{\n options: tenantOptions,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n }}\n >\n {children}\n </Context.Provider>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.useContext(Context)\n"],"names":["useAuth","useRouter","React","createContext","SELECT_ALL","Context","options","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","setSelectedTenantID","useState","preventRefreshOnChange","user","userID","useMemo","id","selectedTenantLabel","find","option","value","label","router","setCookie","useCallback","expires","document","cookie","deleteCookie","refresh","length","String","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","Provider","useTenantSelection","useContext"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\n\ntype ContextType = {\n /**\n * Array of options to select from\n */\n options: OptionObject[]\n /**\n * The currently selected tenant ID\n */\n selectedTenantID: number | string | undefined\n /**\n * Prevents a refresh when the tenant is changed\n *\n * If not switching tenants while viewing a \"global\", set to true\n */\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n /**\n * Sets the selected tenant ID\n *\n * @param args.id - The ID of the tenant to select\n * @param args.refresh - Whether to refresh the page after changing the tenant\n */\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(SELECT_ALL)\n setCookie(SELECT_ALL)\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [setSelectedTenantID, setCookie, router, preventRefreshOnChange, tenantOptions],\n )\n\n React.useEffect(() => {\n if (\n selectedTenantID &&\n selectedTenantID !== SELECT_ALL &&\n !tenantOptions.find((option) => option.value === selectedTenantID)\n ) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n setCookie(String(initialValue))\n }\n }, [userID, tenantCookie, initialValue, setCookie, router])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context.Provider\n value={{\n options: tenantOptions,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n }}\n >\n {children}\n </Context.Provider>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.useContext(Context)\n"],"names":["useAuth","useRouter","React","createContext","SELECT_ALL","Context","options","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","setSelectedTenantID","useState","preventRefreshOnChange","user","userID","useMemo","id","selectedTenantLabel","find","option","value","label","router","setCookie","useCallback","expires","document","cookie","deleteCookie","refresh","length","String","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","Provider","useTenantSelection","useContext"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { AcceptedLanguages } from '@payloadcms/translations';
1
2
  import type { ArrayField, CollectionSlug, Field, RelationshipField, User } from 'payload';
2
3
  export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
3
4
  /**
@@ -104,6 +105,14 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
104
105
  rowFields?: never;
105
106
  tenantFieldAccess?: never;
106
107
  };
108
+ /**
109
+ * Customize tenant selector label
110
+ *
111
+ * Either a string or an object where the keys are locales and the values are the string labels
112
+ */
113
+ tenantSelectorLabel?: Partial<{
114
+ [key in AcceptedLanguages]?: string;
115
+ }> | string;
107
116
  /**
108
117
  * The slug for the tenant collection
109
118
  *
@@ -122,14 +131,22 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
122
131
  * Opt out of adding access constraints to the tenants collection
123
132
  */
124
133
  useTenantsCollectionAccess?: boolean;
134
+ /**
135
+ * Opt out including the baseListFilter to filter tenants by selected tenant
136
+ */
137
+ useTenantsListFilter?: boolean;
138
+ /**
139
+ * Opt out including the baseListFilter to filter users by selected tenant
140
+ */
141
+ useUsersTenantFilter?: boolean;
125
142
  };
126
143
  export type Tenant<IDType = number | string> = {
127
144
  id: IDType;
128
145
  name: string;
129
146
  };
130
147
  export type UserWithTenantsField = {
131
- tenants: {
148
+ tenants?: {
132
149
  tenant: number | string | Tenant;
133
- }[];
150
+ }[] | null;
134
151
  } & User;
135
152
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAEzF,MAAM,MAAM,uBAAuB,CAAC,WAAW,GAAG,OAAO,IAAI;IAC3D;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAClC;;OAEG;IACH,WAAW,EAAE;SACV,GAAG,IAAI,cAAc,CAAC,CAAC,EAAE;YACxB;;;;eAIG;YACH,QAAQ,CAAC,EAAE,OAAO,CAAA;YAClB;;;;eAIG;YACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;YAC3B;;;;eAIG;YACH,eAAe,CAAC,EAAE,OAAO,CAAA;SAC1B;KACF,CAAA;IACD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QACpC;;;;WAIG;QACH,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD;;;;;OAKG;IACH,iBAAiB,CAAC,EACd;QACE;;WAEG;QACH,gBAAgB,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;QACvC;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB;;;;WAIG;QACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;QAC7B;;WAEG;QACH,mBAAmB,CAAC,EAAE,IAAI,CAAA;QAC1B;;WAEG;QACH,SAAS,CAAC,EAAE,KAAK,EAAE,CAAA;QACnB;;WAEG;QACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;KAChD,GACD;QACE,gBAAgB,CAAC,EAAE,KAAK,CAAA;QACxB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;QAC7B;;WAEG;QACH,mBAAmB,CAAC,EAAE,KAAK,CAAA;QAC3B,SAAS,CAAC,EAAE,KAAK,CAAA;QACjB,iBAAiB,CAAC,EAAE,KAAK,CAAA;KAC1B,CAAA;IACL;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,CAC1B,IAAI,EAAE,WAAW,SAAS;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,KACrE,OAAO,CAAA;IACZ;;OAEG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;KACjC,EAAE,CAAA;CACJ,GAAG,IAAI,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAEzF,MAAM,MAAM,uBAAuB,CAAC,WAAW,GAAG,OAAO,IAAI;IAC3D;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAClC;;OAEG;IACH,WAAW,EAAE;SACV,GAAG,IAAI,cAAc,CAAC,CAAC,EAAE;YACxB;;;;eAIG;YACH,QAAQ,CAAC,EAAE,OAAO,CAAA;YAClB;;;;eAIG;YACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;YAC3B;;;;eAIG;YACH,eAAe,CAAC,EAAE,OAAO,CAAA;SAC1B;KACF,CAAA;IACD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QACpC;;;;WAIG;QACH,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD;;;;;OAKG;IACH,iBAAiB,CAAC,EACd;QACE;;WAEG;QACH,gBAAgB,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;QACvC;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB;;;;WAIG;QACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;QAC7B;;WAEG;QACH,mBAAmB,CAAC,EAAE,IAAI,CAAA;QAC1B;;WAEG;QACH,SAAS,CAAC,EAAE,KAAK,EAAE,CAAA;QACnB;;WAEG;QACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;KAChD,GACD;QACE,gBAAgB,CAAC,EAAE,KAAK,CAAA;QACxB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;QAC7B;;WAEG;QACH,mBAAmB,CAAC,EAAE,KAAK,CAAA;QAC3B,SAAS,CAAC,EAAE,KAAK,CAAA;QACjB,iBAAiB,CAAC,EAAE,KAAK,CAAA;KAC1B,CAAA;IACL;;;;OAIG;IACH,mBAAmB,CAAC,EAChB,OAAO,CAAC;SACL,GAAG,IAAI,iBAAiB,CAAC,CAAC,EAAE,MAAM;KACpC,CAAC,GACF,MAAM,CAAA;IACV;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,CAC1B,IAAI,EAAE,WAAW,SAAS;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,KACrE,OAAO,CAAA;IACZ;;OAEG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,CAAC,EACJ;QACE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;KACjC,EAAE,GACH,IAAI,CAAA;CACT,GAAG,IAAI,CAAA"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import 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 * 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\nexport type Tenant<IDType = number | string> = {\n id: IDType\n name: string\n}\n\nexport type UserWithTenantsField = {\n tenants: {\n tenant: number | string | Tenant\n }[]\n} & User\n"],"names":[],"mappings":"AAsIA,WAIQ"}
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,14 +1,17 @@
1
1
  import type { CollectionConfig } from 'payload';
2
2
  import type { MultiTenantPluginConfig } from '../types.js';
3
3
  type Args<ConfigType> = {
4
+ adminUsersSlug: string;
4
5
  collection: CollectionConfig;
5
6
  fieldName: string;
7
+ tenantsArrayFieldName?: string;
8
+ tenantsArrayTenantFieldName?: string;
6
9
  userHasAccessToAllTenants: Required<MultiTenantPluginConfig<ConfigType>>['userHasAccessToAllTenants'];
7
10
  };
8
11
  /**
9
12
  * Adds tenant access constraint to collection
10
13
  * - constrains access a users assigned tenants
11
14
  */
12
- export declare const addCollectionAccess: <ConfigType>({ collection, fieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
15
+ export declare const addCollectionAccess: <ConfigType>({ adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
13
16
  export {};
14
17
  //# sourceMappingURL=addCollectionAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAiB1D,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,yDAI3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAWrB,CAAA"}
1
+ {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAiB1D,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,6HAO3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAgBrB,CAAA"}
@@ -10,14 +10,19 @@ const collectionAccessKeys = [
10
10
  /**
11
11
  * Adds tenant access constraint to collection
12
12
  * - constrains access a users assigned tenants
13
- */ export const addCollectionAccess = ({ collection, fieldName, userHasAccessToAllTenants })=>{
13
+ */ export const addCollectionAccess = ({ adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
14
14
  collectionAccessKeys.forEach((key)=>{
15
15
  if (!collection.access) {
16
16
  collection.access = {};
17
17
  }
18
18
  collection.access[key] = withTenantAccess({
19
19
  accessFunction: collection.access?.[key],
20
+ adminUsersSlug,
21
+ collection,
20
22
  fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,
23
+ operation: key,
24
+ tenantsArrayFieldName,
25
+ tenantsArrayTenantFieldName,
21
26
  userHasAccessToAllTenants
22
27
  });
23
28
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\ntype AllAccessKeys<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nconst collectionAccessKeys: AllAccessKeys<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n> = ['create', 'read', 'update', 'delete', 'readVersions', 'unlock'] as const\n\ntype Args<ConfigType> = {\n collection: CollectionConfig\n fieldName: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n collection,\n fieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","collection","fieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAWxD,MAAMC,uBAEF;IAAC;IAAU;IAAQ;IAAU;IAAU;IAAgB;CAAS;AAUpE;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,UAAU,EACVC,SAAS,EACTC,yBAAyB,EACR;IACjBJ,qBAAqBK,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACJ,WAAWK,MAAM,EAAE;YACtBL,WAAWK,MAAM,GAAG,CAAC;QACvB;QACAL,WAAWK,MAAM,CAACD,IAAI,GAAGP,iBAA6B;YACpDS,gBAAgBN,WAAWK,MAAM,EAAE,CAACD,IAAI;YACxCH,WAAWG,QAAQ,iBAAiB,CAAC,QAAQ,EAAEH,WAAW,GAAGA;YAC7DC;QACF;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\ntype AllAccessKeys<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nconst collectionAccessKeys: AllAccessKeys<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n> = ['create', 'read', 'update', 'delete', 'readVersions', 'unlock'] as const\n\ntype Args<ConfigType> = {\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n adminUsersSlug,\n collection,\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n operation: key,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction","operation"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAWxD,MAAMC,uBAEF;IAAC;IAAU;IAAQ;IAAU;IAAU;IAAgB;CAAS;AAapE;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR;IACjBP,qBAAqBQ,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACN,WAAWO,MAAM,EAAE;YACtBP,WAAWO,MAAM,GAAG,CAAC;QACvB;QACAP,WAAWO,MAAM,CAACD,IAAI,GAAGV,iBAA6B;YACpDY,gBAAgBR,WAAWO,MAAM,EAAE,CAACD,IAAI;YACxCP;YACAC;YACAC,WAAWK,QAAQ,iBAAiB,CAAC,QAAQ,EAAEL,WAAW,GAAGA;YAC7DQ,WAAWH;YACXJ;YACAC;YACAC;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,13 @@
1
+ import type { BaseListFilter } from 'payload';
2
+ type Args = {
3
+ baseListFilter?: BaseListFilter;
4
+ customFilter: BaseListFilter;
5
+ };
6
+ /**
7
+ * Combines a base list filter with a tenant list filter
8
+ *
9
+ * Combines where constraints inside of an AND operator
10
+ */
11
+ export declare const combineListFilters: ({ baseListFilter, customFilter }: Args) => BaseListFilter;
12
+ export {};
13
+ //# sourceMappingURL=combineListFilters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combineListFilters.d.ts","sourceRoot":"","sources":["../../src/utilities/combineListFilters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,SAAS,CAAA;AAEpD,KAAK,IAAI,GAAG;IACV,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,YAAY,EAAE,cAAc,CAAA;CAC7B,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,qCACM,IAAI,KAAG,cA8BzC,CAAA"}
@@ -1,9 +1,8 @@
1
- import { getTenantListFilter } from './getTenantListFilter.js';
2
1
  /**
3
2
  * Combines a base list filter with a tenant list filter
4
3
  *
5
4
  * Combines where constraints inside of an AND operator
6
- */ export const withTenantListFilter = ({ baseListFilter, tenantFieldName, tenantsCollectionSlug })=>async (args)=>{
5
+ */ export const combineListFilters = ({ baseListFilter, customFilter })=>async (args)=>{
7
6
  const filterConstraints = [];
8
7
  if (typeof baseListFilter === 'function') {
9
8
  const baseListFilterResult = await baseListFilter(args);
@@ -11,13 +10,9 @@ import { getTenantListFilter } from './getTenantListFilter.js';
11
10
  filterConstraints.push(baseListFilterResult);
12
11
  }
13
12
  }
14
- const tenantListFilter = getTenantListFilter({
15
- req: args.req,
16
- tenantFieldName,
17
- tenantsCollectionSlug
18
- });
19
- if (tenantListFilter) {
20
- filterConstraints.push(tenantListFilter);
13
+ const customFilterResult = await customFilter(args);
14
+ if (customFilterResult) {
15
+ filterConstraints.push(customFilterResult);
21
16
  }
22
17
  if (filterConstraints.length) {
23
18
  const combinedWhere = {
@@ -34,4 +29,4 @@ import { getTenantListFilter } from './getTenantListFilter.js';
34
29
  return null;
35
30
  };
36
31
 
37
- //# sourceMappingURL=withTenantListFilter.js.map
32
+ //# sourceMappingURL=combineListFilters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/combineListFilters.ts"],"sourcesContent":["import type { BaseListFilter, Where } from 'payload'\n\ntype Args = {\n baseListFilter?: BaseListFilter\n customFilter: BaseListFilter\n}\n/**\n * Combines a base list filter with a tenant list filter\n *\n * Combines where constraints inside of an AND operator\n */\nexport const combineListFilters =\n ({ baseListFilter, customFilter }: Args): BaseListFilter =>\n async (args) => {\n const filterConstraints = []\n\n if (typeof baseListFilter === 'function') {\n const baseListFilterResult = await baseListFilter(args)\n\n if (baseListFilterResult) {\n filterConstraints.push(baseListFilterResult)\n }\n }\n\n const customFilterResult = await customFilter(args)\n\n if (customFilterResult) {\n filterConstraints.push(customFilterResult)\n }\n\n if (filterConstraints.length) {\n const combinedWhere: Where = { and: [] }\n filterConstraints.forEach((constraint) => {\n if (combinedWhere.and && constraint && typeof constraint === 'object') {\n combinedWhere.and.push(constraint)\n }\n })\n return combinedWhere\n }\n\n // Access control will take it from here\n return null\n }\n"],"names":["combineListFilters","baseListFilter","customFilter","args","filterConstraints","baseListFilterResult","push","customFilterResult","length","combinedWhere","and","forEach","constraint"],"mappings":"AAMA;;;;CAIC,GACD,OAAO,MAAMA,qBACX,CAAC,EAAEC,cAAc,EAAEC,YAAY,EAAQ,GACvC,OAAOC;QACL,MAAMC,oBAAoB,EAAE;QAE5B,IAAI,OAAOH,mBAAmB,YAAY;YACxC,MAAMI,uBAAuB,MAAMJ,eAAeE;YAElD,IAAIE,sBAAsB;gBACxBD,kBAAkBE,IAAI,CAACD;YACzB;QACF;QAEA,MAAME,qBAAqB,MAAML,aAAaC;QAE9C,IAAII,oBAAoB;YACtBH,kBAAkBE,IAAI,CAACC;QACzB;QAEA,IAAIH,kBAAkBI,MAAM,EAAE;YAC5B,MAAMC,gBAAuB;gBAAEC,KAAK,EAAE;YAAC;YACvCN,kBAAkBO,OAAO,CAAC,CAACC;gBACzB,IAAIH,cAAcC,GAAG,IAAIE,cAAc,OAAOA,eAAe,UAAU;oBACrEH,cAAcC,GAAG,CAACJ,IAAI,CAACM;gBACzB;YACF;YACA,OAAOH;QACT;QAEA,wCAAwC;QACxC,OAAO;IACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAOvD,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4D/B"}
1
+ {"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAOvD,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6D/B"}
@@ -25,6 +25,7 @@ export async function getGlobalViewRedirect({ slug, docID, headers, payload, ten
25
25
  depth: 0,
26
26
  limit: 1,
27
27
  overrideAccess: false,
28
+ pagination: false,
28
29
  user,
29
30
  where: {
30
31
  [tenantFieldName]: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, User, ViewTypes } from 'payload'\n\nimport { SELECT_ALL } from '../constants.js'\nimport { findTenantOptions } from '../queries/findTenantOptions.js'\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype Args = {\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute\n\n if (!tenant || tenant === SELECT_ALL) {\n const tenantsQuery = await findTenantOptions({\n limit: 1,\n payload,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n })\n\n tenant = tenantsQuery.docs[0]?.id || null\n }\n\n try {\n const { docs } = await payload.find({\n collection: slug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n user,\n where: {\n [tenantFieldName]: {\n equals: tenant,\n },\n },\n })\n\n const tenantDocID = docs?.[0]?.id\n\n if (view === 'document') {\n if (docID && !tenantDocID) {\n // viewing a document with an id but does not match the selected tenant, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n } else if (tenantDocID && docID !== tenantDocID) {\n // tenant document already exists but does not match current route doc ID, redirect to matching tenant doc\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n }\n } else if (view === 'list') {\n if (tenantDocID) {\n // tenant document exists, redirect to edit view\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n } else {\n // tenant document does not exist, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n }\n }\n } catch (e: unknown) {\n payload.logger.error(\n e,\n `${typeof e === 'object' && e && 'message' in e ? `e?.message - ` : ''}Multi Tenant Redirect Error`,\n )\n }\n return redirectRoute\n}\n"],"names":["SELECT_ALL","findTenantOptions","getCollectionIDType","getTenantFromCookie","getGlobalViewRedirect","slug","docID","headers","payload","tenantFieldName","tenantsCollectionSlug","useAsTitle","user","view","idType","collectionSlug","tenant","redirectRoute","tenantsQuery","limit","docs","id","find","collection","depth","overrideAccess","where","equals","tenantDocID","config","routes","admin","e","logger","error"],"mappings":"AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAa9D,OAAO,eAAeC,sBAAsB,EAC1CC,IAAI,EACJC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,eAAe,EACfC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,IAAI,EACC;IACL,MAAMC,SAASZ,oBAAoB;QACjCa,gBAAgBL;QAChBF;IACF;IACA,IAAIQ,SAASb,oBAAoBI,SAASO;IAC1C,IAAIG;IAEJ,IAAI,CAACD,UAAUA,WAAWhB,YAAY;QACpC,MAAMkB,eAAe,MAAMjB,kBAAkB;YAC3CkB,OAAO;YACPX;YACAE;YACAC;YACAC;QACF;QAEAI,SAASE,aAAaE,IAAI,CAAC,EAAE,EAAEC,MAAM;IACvC;IAEA,IAAI;QACF,MAAM,EAAED,IAAI,EAAE,GAAG,MAAMZ,QAAQc,IAAI,CAAC;YAClCC,YAAYlB;YACZmB,OAAO;YACPL,OAAO;YACPM,gBAAgB;YAChBb;YACAc,OAAO;gBACL,CAACjB,gBAAgB,EAAE;oBACjBkB,QAAQX;gBACV;YACF;QACF;QAEA,MAAMY,cAAcR,MAAM,CAAC,EAAE,EAAEC;QAE/B,IAAIR,SAAS,YAAY;YACvB,IAAIP,SAAS,CAACsB,aAAa;gBACzB,iGAAiG;gBACjGX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,OAAO,CAAC;YAC7E,OAAO,IAAIuB,eAAetB,UAAUsB,aAAa;gBAC/C,0GAA0G;gBAC1GX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,CAAC,EAAEuB,aAAa;YACrF;QACF,OAAO,IAAIf,SAAS,QAAQ;YAC1B,IAAIe,aAAa;gBACf,gDAAgD;gBAChDX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,CAAC,EAAEuB,aAAa;YACrF,OAAO;gBACL,2DAA2D;gBAC3DX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,OAAO,CAAC;YAC7E;QACF;IACF,EAAE,OAAO2B,GAAY;QACnBxB,QAAQyB,MAAM,CAACC,KAAK,CAClBF,GACA,GAAG,OAAOA,MAAM,YAAYA,KAAK,aAAaA,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,2BAA2B,CAAC;IAEvG;IACA,OAAOf;AACT"}
1
+ {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, User, ViewTypes } from 'payload'\n\nimport { SELECT_ALL } from '../constants.js'\nimport { findTenantOptions } from '../queries/findTenantOptions.js'\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype Args = {\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute\n\n if (!tenant || tenant === SELECT_ALL) {\n const tenantsQuery = await findTenantOptions({\n limit: 1,\n payload,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n })\n\n tenant = tenantsQuery.docs[0]?.id || null\n }\n\n try {\n const { docs } = await payload.find({\n collection: slug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n pagination: false,\n user,\n where: {\n [tenantFieldName]: {\n equals: tenant,\n },\n },\n })\n\n const tenantDocID = docs?.[0]?.id\n\n if (view === 'document') {\n if (docID && !tenantDocID) {\n // viewing a document with an id but does not match the selected tenant, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n } else if (tenantDocID && docID !== tenantDocID) {\n // tenant document already exists but does not match current route doc ID, redirect to matching tenant doc\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n }\n } else if (view === 'list') {\n if (tenantDocID) {\n // tenant document exists, redirect to edit view\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n } else {\n // tenant document does not exist, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n }\n }\n } catch (e: unknown) {\n payload.logger.error(\n e,\n `${typeof e === 'object' && e && 'message' in e ? `e?.message - ` : ''}Multi Tenant Redirect Error`,\n )\n }\n return redirectRoute\n}\n"],"names":["SELECT_ALL","findTenantOptions","getCollectionIDType","getTenantFromCookie","getGlobalViewRedirect","slug","docID","headers","payload","tenantFieldName","tenantsCollectionSlug","useAsTitle","user","view","idType","collectionSlug","tenant","redirectRoute","tenantsQuery","limit","docs","id","find","collection","depth","overrideAccess","pagination","where","equals","tenantDocID","config","routes","admin","e","logger","error"],"mappings":"AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAa9D,OAAO,eAAeC,sBAAsB,EAC1CC,IAAI,EACJC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,eAAe,EACfC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,IAAI,EACC;IACL,MAAMC,SAASZ,oBAAoB;QACjCa,gBAAgBL;QAChBF;IACF;IACA,IAAIQ,SAASb,oBAAoBI,SAASO;IAC1C,IAAIG;IAEJ,IAAI,CAACD,UAAUA,WAAWhB,YAAY;QACpC,MAAMkB,eAAe,MAAMjB,kBAAkB;YAC3CkB,OAAO;YACPX;YACAE;YACAC;YACAC;QACF;QAEAI,SAASE,aAAaE,IAAI,CAAC,EAAE,EAAEC,MAAM;IACvC;IAEA,IAAI;QACF,MAAM,EAAED,IAAI,EAAE,GAAG,MAAMZ,QAAQc,IAAI,CAAC;YAClCC,YAAYlB;YACZmB,OAAO;YACPL,OAAO;YACPM,gBAAgB;YAChBC,YAAY;YACZd;YACAe,OAAO;gBACL,CAAClB,gBAAgB,EAAE;oBACjBmB,QAAQZ;gBACV;YACF;QACF;QAEA,MAAMa,cAAcT,MAAM,CAAC,EAAE,EAAEC;QAE/B,IAAIR,SAAS,YAAY;YACvB,IAAIP,SAAS,CAACuB,aAAa;gBACzB,iGAAiG;gBACjGZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,OAAO,CAAC;YAC7E,OAAO,IAAIwB,eAAevB,UAAUuB,aAAa;gBAC/C,0GAA0G;gBAC1GZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,CAAC,EAAEwB,aAAa;YACrF;QACF,OAAO,IAAIhB,SAAS,QAAQ;YAC1B,IAAIgB,aAAa;gBACf,gDAAgD;gBAChDZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,CAAC,EAAEwB,aAAa;YACrF,OAAO;gBACL,2DAA2D;gBAC3DZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,OAAO,CAAC;YAC7E;QACF;IACF,EAAE,OAAO4B,GAAY;QACnBzB,QAAQ0B,MAAM,CAACC,KAAK,CAClBF,GACA,GAAG,OAAOA,MAAM,YAAYA,KAAK,aAAaA,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,2BAA2B,CAAC;IAEvG;IACA,OAAOhB;AACT"}
@@ -2,8 +2,10 @@ import type { Where } from 'payload';
2
2
  import type { UserWithTenantsField } from '../types.js';
3
3
  type Args = {
4
4
  fieldName: string;
5
+ tenantsArrayFieldName?: string;
6
+ tenantsArrayTenantFieldName?: string;
5
7
  user: UserWithTenantsField;
6
8
  };
7
- export declare function getTenantAccess({ fieldName, user }: Args): Where;
9
+ export declare function getTenantAccess({ fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, user, }: Args): Where;
8
10
  export {};
9
11
  //# sourceMappingURL=getTenantAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIvD,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,oBAAoB,CAAA;CAC3B,CAAA;AACD,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,GAAG,KAAK,CAQhE"}
1
+ {"version":3,"file":"getTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAKvD,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,IAAI,EAAE,oBAAoB,CAAA;CAC3B,CAAA;AACD,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,qBAAsD,EACtD,2BAAkE,EAClE,IAAI,GACL,EAAE,IAAI,GAAG,KAAK,CAWd"}
@@ -1,6 +1,10 @@
1
+ import { defaults } from '../defaults.js';
1
2
  import { getUserTenantIDs } from './getUserTenantIDs.js';
2
- export function getTenantAccess({ fieldName, user }) {
3
- const userAssignedTenantIDs = getUserTenantIDs(user);
3
+ export function getTenantAccess({ fieldName, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, user }) {
4
+ const userAssignedTenantIDs = getUserTenantIDs(user, {
5
+ tenantsArrayFieldName,
6
+ tenantsArrayTenantFieldName
7
+ });
4
8
  return {
5
9
  [fieldName]: {
6
10
  in: userAssignedTenantIDs || []
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getTenantAccess.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getUserTenantIDs } from './getUserTenantIDs.js'\n\ntype Args = {\n fieldName: string\n user: UserWithTenantsField\n}\nexport function getTenantAccess({ fieldName, user }: Args): Where {\n const userAssignedTenantIDs = getUserTenantIDs(user)\n\n return {\n [fieldName]: {\n in: userAssignedTenantIDs || [],\n },\n }\n}\n"],"names":["getUserTenantIDs","getTenantAccess","fieldName","user","userAssignedTenantIDs","in"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAMxD,OAAO,SAASC,gBAAgB,EAAEC,SAAS,EAAEC,IAAI,EAAQ;IACvD,MAAMC,wBAAwBJ,iBAAiBG;IAE/C,OAAO;QACL,CAACD,UAAU,EAAE;YACXG,IAAID,yBAAyB,EAAE;QACjC;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/utilities/getTenantAccess.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { getUserTenantIDs } from './getUserTenantIDs.js'\n\ntype Args = {\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n user: UserWithTenantsField\n}\nexport function getTenantAccess({\n fieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n user,\n}: Args): Where {\n const userAssignedTenantIDs = getUserTenantIDs(user, {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n })\n\n return {\n [fieldName]: {\n in: userAssignedTenantIDs || [],\n },\n }\n}\n"],"names":["defaults","getUserTenantIDs","getTenantAccess","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","user","userAssignedTenantIDs","in"],"mappings":"AAIA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,gBAAgB,QAAQ,wBAAuB;AAQxD,OAAO,SAASC,gBAAgB,EAC9BC,SAAS,EACTC,wBAAwBJ,SAASI,qBAAqB,EACtDC,8BAA8BL,SAASK,2BAA2B,EAClEC,IAAI,EACC;IACL,MAAMC,wBAAwBN,iBAAiBK,MAAM;QACnDF;QACAC;IACF;IAEA,OAAO;QACL,CAACF,UAAU,EAAE;YACXK,IAAID,yBAAyB,EAAE;QACjC;IACF;AACF"}
@@ -4,5 +4,8 @@ import type { UserWithTenantsField } from '../types.js';
4
4
  *
5
5
  * @param user - User object with tenants field
6
6
  */
7
- export declare const getUserTenantIDs: <IDType extends number | string>(user: null | UserWithTenantsField) => IDType[];
7
+ export declare const getUserTenantIDs: <IDType extends number | string>(user: null | UserWithTenantsField, options?: {
8
+ tenantsArrayFieldName?: string;
9
+ tenantsArrayTenantFieldName?: string;
10
+ }) => IDType[];
8
11
  //# sourceMappingURL=getUserTenantIDs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAI/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,KAChC,MAAM,EAcR,CAAA"}
1
+ {"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAK/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,YACvB;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;CACrC,KACA,MAAM,EAqBR,CAAA"}
@@ -1,15 +1,17 @@
1
+ import { defaults } from '../defaults.js';
1
2
  import { extractID } from './extractID.js';
2
3
  /**
3
4
  * Returns array of all tenant IDs assigned to a user
4
5
  *
5
6
  * @param user - User object with tenants field
6
- */ export const getUserTenantIDs = (user)=>{
7
+ */ export const getUserTenantIDs = (user, options)=>{
7
8
  if (!user) {
8
9
  return [];
9
10
  }
10
- return user?.tenants?.reduce((acc, { tenant })=>{
11
- if (tenant) {
12
- acc.push(extractID(tenant));
11
+ const { tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName } = options || {};
12
+ return (Array.isArray(user[tenantsArrayFieldName]) ? user[tenantsArrayFieldName] : [])?.reduce((acc, row)=>{
13
+ if (row[tenantsArrayTenantFieldName]) {
14
+ acc.push(extractID(row[tenantsArrayTenantFieldName]));
13
15
  }
14
16
  return acc;
15
17
  }, []) || [];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n): IDType[] => {\n if (!user) {\n return []\n }\n\n return (\n user?.tenants?.reduce<IDType[]>((acc, { tenant }) => {\n if (tenant) {\n acc.push(extractID<IDType>(tenant as Tenant<IDType>))\n }\n\n return acc\n }, []) || []\n )\n}\n"],"names":["extractID","getUserTenantIDs","user","tenants","reduce","acc","tenant","push"],"mappings":"AAEA,SAASA,SAAS,QAAQ,iBAAgB;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAC9BC;IAEA,IAAI,CAACA,MAAM;QACT,OAAO,EAAE;IACX;IAEA,OACEA,MAAMC,SAASC,OAAiB,CAACC,KAAK,EAAEC,MAAM,EAAE;QAC9C,IAAIA,QAAQ;YACVD,IAAIE,IAAI,CAACP,UAAkBM;QAC7B;QAEA,OAAOD;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n options?: {\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n },\n): IDType[] => {\n if (!user) {\n return []\n }\n\n const {\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n } = options || {}\n\n return (\n (Array.isArray(user[tenantsArrayFieldName]) ? user[tenantsArrayFieldName] : [])?.reduce<\n IDType[]\n >((acc, row) => {\n if (row[tenantsArrayTenantFieldName]) {\n acc.push(extractID<IDType>(row[tenantsArrayTenantFieldName] as Tenant<IDType>))\n }\n\n return acc\n }, []) || []\n )\n}\n"],"names":["defaults","extractID","getUserTenantIDs","user","options","tenantsArrayFieldName","tenantsArrayTenantFieldName","Array","isArray","reduce","acc","row","push"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,SAAS,QAAQ,iBAAgB;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAC9BC,MACAC;IAKA,IAAI,CAACD,MAAM;QACT,OAAO,EAAE;IACX;IAEA,MAAM,EACJE,wBAAwBL,SAASK,qBAAqB,EACtDC,8BAA8BN,SAASM,2BAA2B,EACnE,GAAGF,WAAW,CAAC;IAEhB,OACE,AAACG,CAAAA,MAAMC,OAAO,CAACL,IAAI,CAACE,sBAAsB,IAAIF,IAAI,CAACE,sBAAsB,GAAG,EAAE,AAAD,GAAII,OAE/E,CAACC,KAAKC;QACN,IAAIA,GAAG,CAACL,4BAA4B,EAAE;YACpCI,IAAIE,IAAI,CAACX,UAAkBU,GAAG,CAACL,4BAA4B;QAC7D;QAEA,OAAOI;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
@@ -1,10 +1,15 @@
1
- import type { Access, AccessArgs, AccessResult } from 'payload';
1
+ import type { Access, AccessArgs, AccessResult, AllOperations, CollectionConfig } from 'payload';
2
2
  import type { MultiTenantPluginConfig } from '../types.js';
3
3
  type Args<ConfigType> = {
4
4
  accessFunction?: Access;
5
+ adminUsersSlug: string;
6
+ collection: CollectionConfig;
5
7
  fieldName: string;
8
+ operation: AllOperations;
9
+ tenantsArrayFieldName?: string;
10
+ tenantsArrayTenantFieldName?: string;
6
11
  userHasAccessToAllTenants: Required<MultiTenantPluginConfig<ConfigType>>['userHasAccessToAllTenants'];
7
12
  };
8
- export declare const withTenantAccess: <ConfigType>({ accessFunction, fieldName, userHasAccessToAllTenants }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
13
+ export declare const withTenantAccess: <ConfigType>({ accessFunction, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
9
14
  export {};
10
15
  //# sourceMappingURL=withTenantAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAQ,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAKhF,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,4DAA4D,IAAI,CAAC,UAAU,CAAC,YAC1E,UAAU,KAAG,OAAO,CAAC,YAAY,CA8B7C,CAAA"}
1
+ {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAGjB,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAKhF,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,aAAa,CAAA;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,6IAQR,IAAI,CAAC,UAAU,CAAC,YACN,UAAU,KAAG,OAAO,CAAC,YAAY,CA6C7C,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { combineWhereConstraints } from './combineWhereConstraints.js';
2
2
  import { getTenantAccess } from './getTenantAccess.js';
3
- export const withTenantAccess = ({ accessFunction, fieldName, userHasAccessToAllTenants })=>async (args)=>{
3
+ export const withTenantAccess = ({ accessFunction, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>async (args)=>{
4
4
  const constraints = [];
5
5
  const accessFn = typeof accessFunction === 'function' ? accessFunction : ({ req })=>Boolean(req.user);
6
6
  const accessResult = await accessFn(args);
@@ -9,11 +9,27 @@ export const withTenantAccess = ({ accessFunction, fieldName, userHasAccessToAll
9
9
  } else if (accessResult && typeof accessResult === 'object') {
10
10
  constraints.push(accessResult);
11
11
  }
12
- if (args.req.user && !userHasAccessToAllTenants(args.req.user)) {
13
- constraints.push(getTenantAccess({
12
+ if (args.req.user && args.req.user.collection === adminUsersSlug && !userHasAccessToAllTenants(args.req.user)) {
13
+ const tenantConstraint = getTenantAccess({
14
14
  fieldName,
15
+ tenantsArrayFieldName,
16
+ tenantsArrayTenantFieldName,
15
17
  user: args.req.user
16
- }));
18
+ });
19
+ if (collection.slug === args.req.user.collection) {
20
+ constraints.push({
21
+ or: [
22
+ {
23
+ id: {
24
+ equals: args.req.user.id
25
+ }
26
+ },
27
+ tenantConstraint
28
+ ]
29
+ });
30
+ } else {
31
+ constraints.push(tenantConstraint);
32
+ }
17
33
  return combineWhereConstraints(constraints);
18
34
  }
19
35
  return accessResult;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type { Access, AccessArgs, AccessResult, User } from 'payload'\n\nimport type { MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n fieldName: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({ accessFunction, fieldName, userHasAccessToAllTenants }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : User,\n )\n ) {\n constraints.push(\n getTenantAccess({\n fieldName,\n user: args.req.user as UserWithTenantsField,\n }),\n )\n return combineWhereConstraints(constraints)\n }\n\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","fieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push"],"mappings":"AAIA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAStD,OAAO,MAAMC,mBACX,CAAa,EAAEC,cAAc,EAAEC,SAAS,EAAEC,yBAAyB,EAAoB,GACvF,OAAOC;QACL,MAAMC,cAAc,EAAE;QACtB,MAAMC,WACJ,OAAOL,mBAAmB,aACtBA,iBACA,CAAC,EAAEM,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,OAAO;QACT,OAAO,IAAIA,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYM,IAAI,CAACD;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACb,CAACN,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACAJ,YAAYM,IAAI,CACdZ,gBAAgB;gBACdG;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YAEF,OAAOX,wBAAwBO;QACjC;QAEA,OAAOK;IACT,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type {\n Access,\n AccessArgs,\n AccessResult,\n AllOperations,\n CollectionConfig,\n User,\n Where,\n} from 'payload'\n\nimport type { MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n operation: AllOperations\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({\n accessFunction,\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints: Where[] = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n args.req.user.collection === adminUsersSlug &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : User,\n )\n ) {\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user: args.req.user as UserWithTenantsField,\n })\n if (collection.slug === args.req.user.collection) {\n constraints.push({\n or: [\n {\n id: {\n equals: args.req.user.id,\n },\n },\n tenantConstraint,\n ],\n })\n } else {\n constraints.push(tenantConstraint)\n }\n return combineWhereConstraints(constraints)\n }\n\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push","tenantConstraint","slug","or","id","equals"],"mappings":"AAYA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AActD,OAAO,MAAMC,mBACX,CAAa,EACXC,cAAc,EACdC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR,GACnB,OAAOC;QACL,MAAMC,cAAuB,EAAE;QAC/B,MAAMC,WACJ,OAAOT,mBAAmB,aACtBA,iBACA,CAAC,EAAEU,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,OAAO;QACT,OAAO,IAAIA,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYM,IAAI,CAACD;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACbL,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,KAAKD,kBAC7B,CAACK,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACA,MAAMG,mBAAmBjB,gBAAgB;gBACvCK;gBACAC;gBACAC;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YACA,IAAIV,WAAWc,IAAI,KAAKT,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,EAAE;gBAChDM,YAAYM,IAAI,CAAC;oBACfG,IAAI;wBACF;4BACEC,IAAI;gCACFC,QAAQZ,KAAKG,GAAG,CAACE,IAAI,CAACM,EAAE;4BAC1B;wBACF;wBACAH;qBACD;gBACH;YACF,OAAO;gBACLP,YAAYM,IAAI,CAACC;YACnB;YACA,OAAOlB,wBAAwBW;QACjC;QAEA,OAAOK;IACT,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "3.25.0-canary.fd53f68",
3
+ "version": "3.26.0-canary.bbb3083",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -67,13 +67,14 @@
67
67
  ],
68
68
  "devDependencies": {
69
69
  "@payloadcms/eslint-config": "3.9.0",
70
- "@payloadcms/ui": "3.25.0-canary.fd53f68",
71
- "payload": "3.25.0-canary.fd53f68"
70
+ "@payloadcms/translations": "3.26.0-canary.bbb3083",
71
+ "payload": "3.26.0-canary.bbb3083",
72
+ "@payloadcms/ui": "3.26.0-canary.bbb3083"
72
73
  },
73
74
  "peerDependencies": {
74
75
  "next": "^15.0.3",
75
- "@payloadcms/ui": "3.25.0-canary.fd53f68",
76
- "payload": "3.25.0-canary.fd53f68"
76
+ "@payloadcms/ui": "3.26.0-canary.bbb3083",
77
+ "payload": "3.26.0-canary.bbb3083"
77
78
  },
78
79
  "homepage:": "https://payloadcms.com",
79
80
  "scripts": {
@@ -1,9 +0,0 @@
1
- import type { PayloadRequest, Where } from 'payload';
2
- type Args = {
3
- req: PayloadRequest;
4
- tenantFieldName: string;
5
- tenantsCollectionSlug: string;
6
- };
7
- export declare const getTenantListFilter: ({ req, tenantFieldName, tenantsCollectionSlug, }: Args) => null | Where;
8
- export {};
9
- //# sourceMappingURL=getTenantListFilter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getTenantListFilter.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantListFilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAMpD,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,cAAc,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;CAC9B,CAAA;AACD,eAAO,MAAM,mBAAmB,qDAI7B,IAAI,KAAG,IAAI,GAAG,KAgBhB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/getTenantListFilter.ts"],"sourcesContent":["import type { PayloadRequest, Where } from 'payload'\n\nimport { SELECT_ALL } from '../constants.js'\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype Args = {\n req: PayloadRequest\n tenantFieldName: string\n tenantsCollectionSlug: string\n}\nexport const getTenantListFilter = ({\n req,\n tenantFieldName,\n tenantsCollectionSlug,\n}: Args): null | Where => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const selectedTenant = getTenantFromCookie(req.headers, idType)\n\n if (selectedTenant === SELECT_ALL) {\n return {}\n }\n\n return {\n [tenantFieldName]: {\n equals: selectedTenant,\n },\n }\n}\n"],"names":["SELECT_ALL","getCollectionIDType","getTenantFromCookie","getTenantListFilter","req","tenantFieldName","tenantsCollectionSlug","idType","collectionSlug","payload","selectedTenant","headers","equals"],"mappings":"AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAO9D,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,GAAG,EACHC,eAAe,EACfC,qBAAqB,EAChB;IACL,MAAMC,SAASN,oBAAoB;QACjCO,gBAAgBF;QAChBG,SAASL,IAAIK,OAAO;IACtB;IACA,MAAMC,iBAAiBR,oBAAoBE,IAAIO,OAAO,EAAEJ;IAExD,IAAIG,mBAAmBV,YAAY;QACjC,OAAO,CAAC;IACV;IAEA,OAAO;QACL,CAACK,gBAAgB,EAAE;YACjBO,QAAQF;QACV;IACF;AACF,EAAC"}
@@ -1,14 +0,0 @@
1
- import type { BaseListFilter } from 'payload';
2
- type Args = {
3
- baseListFilter?: BaseListFilter;
4
- tenantFieldName: string;
5
- tenantsCollectionSlug: string;
6
- };
7
- /**
8
- * Combines a base list filter with a tenant list filter
9
- *
10
- * Combines where constraints inside of an AND operator
11
- */
12
- export declare const withTenantListFilter: ({ baseListFilter, tenantFieldName, tenantsCollectionSlug }: Args) => BaseListFilter;
13
- export {};
14
- //# sourceMappingURL=withTenantListFilter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"withTenantListFilter.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantListFilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,SAAS,CAAA;AAIpD,KAAK,IAAI,GAAG;IACV,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;CAC9B,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,+DAC8B,IAAI,KAAG,cAkCnE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/withTenantListFilter.ts"],"sourcesContent":["import type { BaseListFilter, Where } from 'payload'\n\nimport { getTenantListFilter } from './getTenantListFilter.js'\n\ntype Args = {\n baseListFilter?: BaseListFilter\n tenantFieldName: string\n tenantsCollectionSlug: string\n}\n/**\n * Combines a base list filter with a tenant list filter\n *\n * Combines where constraints inside of an AND operator\n */\nexport const withTenantListFilter =\n ({ baseListFilter, tenantFieldName, tenantsCollectionSlug }: Args): BaseListFilter =>\n async (args) => {\n const filterConstraints = []\n\n if (typeof baseListFilter === 'function') {\n const baseListFilterResult = await baseListFilter(args)\n\n if (baseListFilterResult) {\n filterConstraints.push(baseListFilterResult)\n }\n }\n\n const tenantListFilter = getTenantListFilter({\n req: args.req,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n if (tenantListFilter) {\n filterConstraints.push(tenantListFilter)\n }\n\n if (filterConstraints.length) {\n const combinedWhere: Where = { and: [] }\n filterConstraints.forEach((constraint) => {\n if (combinedWhere.and && constraint && typeof constraint === 'object') {\n combinedWhere.and.push(constraint)\n }\n })\n return combinedWhere\n }\n\n // Access control will take it from here\n return null\n }\n"],"names":["getTenantListFilter","withTenantListFilter","baseListFilter","tenantFieldName","tenantsCollectionSlug","args","filterConstraints","baseListFilterResult","push","tenantListFilter","req","length","combinedWhere","and","forEach","constraint"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,2BAA0B;AAO9D;;;;CAIC,GACD,OAAO,MAAMC,uBACX,CAAC,EAAEC,cAAc,EAAEC,eAAe,EAAEC,qBAAqB,EAAQ,GACjE,OAAOC;QACL,MAAMC,oBAAoB,EAAE;QAE5B,IAAI,OAAOJ,mBAAmB,YAAY;YACxC,MAAMK,uBAAuB,MAAML,eAAeG;YAElD,IAAIE,sBAAsB;gBACxBD,kBAAkBE,IAAI,CAACD;YACzB;QACF;QAEA,MAAME,mBAAmBT,oBAAoB;YAC3CU,KAAKL,KAAKK,GAAG;YACbP;YACAC;QACF;QAEA,IAAIK,kBAAkB;YACpBH,kBAAkBE,IAAI,CAACC;QACzB;QAEA,IAAIH,kBAAkBK,MAAM,EAAE;YAC5B,MAAMC,gBAAuB;gBAAEC,KAAK,EAAE;YAAC;YACvCP,kBAAkBQ,OAAO,CAAC,CAACC;gBACzB,IAAIH,cAAcC,GAAG,IAAIE,cAAc,OAAOA,eAAe,UAAU;oBACrEH,cAAcC,GAAG,CAACL,IAAI,CAACO;gBACzB;YACF;YACA,OAAOH;QACT;QAEA,wCAAwC;QACxC,OAAO;IACT,EAAC"}