@payloadcms/plugin-multi-tenant 0.0.1

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 (88) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +204 -0
  3. package/dist/components/GlobalViewRedirect/index.d.ts +10 -0
  4. package/dist/components/GlobalViewRedirect/index.d.ts.map +1 -0
  5. package/dist/components/GlobalViewRedirect/index.js +18 -0
  6. package/dist/components/GlobalViewRedirect/index.js.map +1 -0
  7. package/dist/components/TenantField/index.client.d.ts +10 -0
  8. package/dist/components/TenantField/index.client.d.ts.map +1 -0
  9. package/dist/components/TenantField/index.client.js +34 -0
  10. package/dist/components/TenantField/index.client.js.map +1 -0
  11. package/dist/components/TenantField/index.d.ts +3 -0
  12. package/dist/components/TenantField/index.d.ts.map +1 -0
  13. package/dist/components/TenantField/index.js +33 -0
  14. package/dist/components/TenantField/index.js.map +1 -0
  15. package/dist/components/TenantSelector/index.client.d.ts +11 -0
  16. package/dist/components/TenantSelector/index.client.d.ts.map +1 -0
  17. package/dist/components/TenantSelector/index.client.js +61 -0
  18. package/dist/components/TenantSelector/index.client.js.map +1 -0
  19. package/dist/components/TenantSelector/index.d.ts +10 -0
  20. package/dist/components/TenantSelector/index.d.ts.map +1 -0
  21. package/dist/components/TenantSelector/index.js +31 -0
  22. package/dist/components/TenantSelector/index.js.map +1 -0
  23. package/dist/components/TenantSelector/index.scss +4 -0
  24. package/dist/exports/rsc.d.ts +4 -0
  25. package/dist/exports/rsc.d.ts.map +1 -0
  26. package/dist/exports/rsc.js +5 -0
  27. package/dist/exports/rsc.js.map +1 -0
  28. package/dist/exports/types.d.ts +2 -0
  29. package/dist/exports/types.d.ts.map +1 -0
  30. package/dist/exports/types.js +3 -0
  31. package/dist/exports/types.js.map +1 -0
  32. package/dist/exports/utilities.d.ts +6 -0
  33. package/dist/exports/utilities.d.ts.map +1 -0
  34. package/dist/exports/utilities.js +7 -0
  35. package/dist/exports/utilities.js.map +1 -0
  36. package/dist/fields/tenantField/index.d.ts +12 -0
  37. package/dist/fields/tenantField/index.d.ts.map +1 -0
  38. package/dist/fields/tenantField/index.js +38 -0
  39. package/dist/fields/tenantField/index.js.map +1 -0
  40. package/dist/fields/userTenantsArrayField/index.d.ts +4 -0
  41. package/dist/fields/userTenantsArrayField/index.d.ts.map +1 -0
  42. package/dist/fields/userTenantsArrayField/index.js +20 -0
  43. package/dist/fields/userTenantsArrayField/index.js.map +1 -0
  44. package/dist/index.d.ts +4 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +112 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/types.d.ts +80 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +3 -0
  51. package/dist/types.js.map +1 -0
  52. package/dist/utilities/combineWhereConstraints.d.ts +3 -0
  53. package/dist/utilities/combineWhereConstraints.d.ts.map +1 -0
  54. package/dist/utilities/combineWhereConstraints.js +19 -0
  55. package/dist/utilities/combineWhereConstraints.js.map +1 -0
  56. package/dist/utilities/extractID.d.ts +3 -0
  57. package/dist/utilities/extractID.d.ts.map +1 -0
  58. package/dist/utilities/extractID.js +8 -0
  59. package/dist/utilities/extractID.js.map +1 -0
  60. package/dist/utilities/getGlobalViewRedirect.d.ts +10 -0
  61. package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -0
  62. package/dist/utilities/getGlobalViewRedirect.js +44 -0
  63. package/dist/utilities/getGlobalViewRedirect.js.map +1 -0
  64. package/dist/utilities/getTenantAccess.d.ts +5 -0
  65. package/dist/utilities/getTenantAccess.d.ts.map +1 -0
  66. package/dist/utilities/getTenantAccess.js +14 -0
  67. package/dist/utilities/getTenantAccess.js.map +1 -0
  68. package/dist/utilities/getTenantFromCookie.d.ts +2 -0
  69. package/dist/utilities/getTenantFromCookie.d.ts.map +1 -0
  70. package/dist/utilities/getTenantFromCookie.js +8 -0
  71. package/dist/utilities/getTenantFromCookie.js.map +1 -0
  72. package/dist/utilities/getTenantListFilter.d.ts +8 -0
  73. package/dist/utilities/getTenantListFilter.d.ts.map +1 -0
  74. package/dist/utilities/getTenantListFilter.js +15 -0
  75. package/dist/utilities/getTenantListFilter.js.map +1 -0
  76. package/dist/utilities/getUserTenantIDs.d.ts +9 -0
  77. package/dist/utilities/getUserTenantIDs.d.ts.map +1 -0
  78. package/dist/utilities/getUserTenantIDs.js +22 -0
  79. package/dist/utilities/getUserTenantIDs.js.map +1 -0
  80. package/dist/utilities/withTenantAccess.d.ts +9 -0
  81. package/dist/utilities/withTenantAccess.d.ts.map +1 -0
  82. package/dist/utilities/withTenantAccess.js +26 -0
  83. package/dist/utilities/withTenantAccess.js.map +1 -0
  84. package/dist/utilities/withTenantListFilter.d.ts +13 -0
  85. package/dist/utilities/withTenantListFilter.d.ts.map +1 -0
  86. package/dist/utilities/withTenantListFilter.js +36 -0
  87. package/dist/utilities/withTenantListFilter.js.map +1 -0
  88. package/package.json +79 -0
package/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018-2024 Payload CMS, Inc. <info@payloadcms.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,204 @@
1
+ # Multi Tenant Plugin
2
+
3
+ A plugin for [Payload](https://github.com/payloadcms/payload) to easily manage multiple tenants from within your admin panel.
4
+
5
+ - [Source code](https://github.com/payloadcms/payload/tree/main/packages/plugin-multi-tenant)
6
+ <!-- - [Documentation](https://payloadcms.com/docs/plugins/multi-tenant)
7
+ - [Documentation source](https://github.com/payloadcms/payload/tree/main/docs/plugins/multi-tenant.mdx) -->
8
+
9
+ ## Plugin config example
10
+
11
+ ```ts
12
+ multiTenantPlugin({
13
+ /**
14
+ * Enable debugging:
15
+ * - shows the relationship field on enabled collection documents
16
+ *
17
+ * optional - @default false
18
+ */
19
+ debug: false,
20
+ /**
21
+ * Enables/Disables the plugin
22
+ *
23
+ * optional - @default true
24
+ */
25
+ enabled: true,
26
+ /**
27
+ * The slug of the tenants collection you added to your config
28
+ *
29
+ * optional - @default 'tenants'
30
+ */
31
+ tenantsSlug: 'tenants',
32
+ /**
33
+ * Define what collections you would like multi-tenancy to apply to
34
+ *
35
+ * Keyed on the slug of the collection
36
+ */
37
+ collections: {
38
+ pages: {
39
+ /**
40
+ * Used to opt out of using the provided baseListFilter
41
+ *
42
+ * You can use the exported utility "getTenantFilter" within your own list filter
43
+ *
44
+ * optional - @default true
45
+ */
46
+ useBaseListFilter: true
47
+ /**
48
+ * Used to opt out of the merged access control provided
49
+ *
50
+ * You can use the exported utility "getTenantAccess" within your access control functions
51
+ *
52
+ * optional - @default true
53
+ */
54
+ useTenantAccess: true
55
+ /**
56
+ * Used to make a collection feel like a global. When navigating to the list view, they will be redirected to the document view.
57
+ *
58
+ * optional - @default false
59
+ */
60
+ isGlobal: false
61
+ },
62
+ /**
63
+ * Custom configuration for the tenant field placed on every enabled collection
64
+ */
65
+ documentTenantField: {
66
+ // optional - provide access control on the injected tenant field
67
+ access: {
68
+ create,
69
+ read,
70
+ update,
71
+ },
72
+ /**
73
+ * Name of the field
74
+ *
75
+ * optional - @default true
76
+ */
77
+ name: 'tenant',
78
+ },
79
+ /**
80
+ * Function that allows you to determine if certain users should have access to all tenants
81
+ *
82
+ * optional - @default () => false
83
+ */
84
+ userHasAccessToAllTenants: (user) => user.isSuperAdmin === true
85
+ /**
86
+ * Options for the array field that gets added to the users collection.
87
+ *
88
+ * The field is an array of rows, by default each row has a relationship to a tenant
89
+ *
90
+ * optional - @default undefined
91
+ */
92
+ userTenantsField: {
93
+ /**
94
+ * Allows you to set access control on the array field
95
+ *
96
+ * optional - @default undefined
97
+ */
98
+ access: {
99
+ create, // optional
100
+ read, // optional
101
+ update, // optional
102
+ },
103
+ /**
104
+ * If you want to add additional fields to the tenant rows, you can specify them under rowFields
105
+ *
106
+ * optional - @default undefined
107
+ */
108
+ rowFields: [
109
+ // Example adding a field onto the array row
110
+ {
111
+ name: 'roles',
112
+ type: 'select',
113
+ options: [
114
+ { label: 'Admin', value: 'admin' },
115
+ { label: 'User', value: 'user' },
116
+ ],
117
+ },
118
+ ],
119
+ }
120
+ },
121
+ })
122
+ ```
123
+
124
+ ### How to configure Collections as Globals for multi-tenant
125
+
126
+ When using multi-tenant, globals need to actually be configured as collections so the content can be specific per tenant.
127
+ To do that, you can mark a collection with `isGlobal` and it will behave like a global and users will not see the list view.
128
+
129
+ ```ts
130
+ multiTenantPlugin({
131
+ collections: {
132
+ navigation: {
133
+ isGlobal: true,
134
+ },
135
+ },
136
+ })
137
+ ```
138
+
139
+ ### Customizing access control
140
+
141
+ In some cases, the access control supplied out of the box may be too strict. For example, if you need _some_ documents to be shared between tenants, you will need to opt out of the supplied access control functionality.
142
+
143
+ By default this plugin merges your access control result with a constraint based on tenants the user has access to within an _AND_ condition. That would not work for the above scenario.
144
+
145
+ In the multi-tenant plugin config you can set `useTenantAccess` to false:
146
+
147
+ ```ts
148
+ // File: payload.config.ts
149
+
150
+ import { buildConfig } from 'payload'
151
+ import { multiTenantPlugin } from '@payloadcms/plugin-multi-tenant'
152
+ import { getTenantAccess } from '@payloadcms/plugin-multi-tenant/utilities'
153
+ import { Config as ConfigTypes } from './payload-types'
154
+
155
+ // Add the plugin to your payload config
156
+ export default buildConfig({
157
+ plugins: [
158
+ multiTenantPlugin({
159
+ collections: {
160
+ media: {
161
+ useTenantAccess: false,
162
+ },
163
+ },
164
+ }),
165
+ ],
166
+ collections: [
167
+ {
168
+ slug: 'media',
169
+ fields: [
170
+ {
171
+ name: 'isShared',
172
+ type: 'checkbox',
173
+ defaultValue: false,
174
+ // you likely want to set access control on fields like this
175
+ // to prevent just any user from modifying it
176
+ },
177
+ ],
178
+ access: {
179
+ read: ({ req, doc }) => {
180
+ if (!req.user) return false
181
+
182
+ const whereConstraint = {
183
+ or: [
184
+ {
185
+ isShared: {
186
+ equals: true,
187
+ },
188
+ },
189
+ ],
190
+ }
191
+
192
+ const tenantAccessResult = getTenantAccess({ user: req.user })
193
+
194
+ if (tenantAccessResult) {
195
+ whereConstraint.or.push(tenantAccessResult)
196
+ }
197
+
198
+ return whereConstraint
199
+ },
200
+ },
201
+ },
202
+ ],
203
+ })
204
+ ```
@@ -0,0 +1,10 @@
1
+ import type { CollectionSlug, ServerProps } from 'payload';
2
+ type Args = {
3
+ collectionSlug: CollectionSlug;
4
+ docID?: number | string;
5
+ globalSlugs: string[];
6
+ viewType: 'edit' | 'list';
7
+ } & ServerProps;
8
+ export declare const GlobalViewRedirect: (args: Args) => Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/GlobalViewRedirect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAM1D,KAAK,IAAI,GAAG;IACV,cAAc,EAAE,cAAc,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,GAAG,WAAW,CAAA;AAEf,eAAO,MAAM,kBAAkB,SAAgB,IAAI,kBAelD,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { redirect } from 'next/navigation.js';
2
+ import { getGlobalViewRedirect } from '../../utilities/getGlobalViewRedirect.js';
3
+ export const GlobalViewRedirect = async (args)=>{
4
+ const collectionSlug = args?.collectionSlug;
5
+ if (collectionSlug && args.globalSlugs?.includes(collectionSlug)) {
6
+ const redirectRoute = await getGlobalViewRedirect({
7
+ slug: collectionSlug,
8
+ docID: args.docID,
9
+ payload: args.payload,
10
+ view: args.viewType
11
+ });
12
+ if (redirectRoute) {
13
+ redirect(redirectRoute);
14
+ }
15
+ }
16
+ };
17
+
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/GlobalViewRedirect/index.ts"],"sourcesContent":["import type { CollectionSlug, ServerProps } from 'payload'\n\nimport { redirect } from 'next/navigation.js'\n\nimport { getGlobalViewRedirect } from '../../utilities/getGlobalViewRedirect.js'\n\ntype Args = {\n collectionSlug: CollectionSlug\n docID?: number | string\n globalSlugs: string[]\n viewType: 'edit' | 'list'\n} & ServerProps\n\nexport const GlobalViewRedirect = async (args: Args) => {\n const collectionSlug = args?.collectionSlug\n\n if (collectionSlug && args.globalSlugs?.includes(collectionSlug)) {\n const redirectRoute = await getGlobalViewRedirect({\n slug: collectionSlug,\n docID: args.docID,\n payload: args.payload,\n view: args.viewType,\n })\n\n if (redirectRoute) {\n redirect(redirectRoute)\n }\n }\n}\n"],"names":["redirect","getGlobalViewRedirect","GlobalViewRedirect","args","collectionSlug","globalSlugs","includes","redirectRoute","slug","docID","payload","view","viewType"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,qBAAoB;AAE7C,SAASC,qBAAqB,QAAQ,2CAA0C;AAShF,OAAO,MAAMC,qBAAqB,OAAOC;IACvC,MAAMC,iBAAiBD,MAAMC;IAE7B,IAAIA,kBAAkBD,KAAKE,WAAW,EAAEC,SAASF,iBAAiB;QAChE,MAAMG,gBAAgB,MAAMN,sBAAsB;YAChDO,MAAMJ;YACNK,OAAON,KAAKM,KAAK;YACjBC,SAASP,KAAKO,OAAO;YACrBC,MAAMR,KAAKS,QAAQ;QACrB;QAEA,IAAIL,eAAe;YACjBP,SAASO;QACX;IACF;AACF,EAAC"}
@@ -0,0 +1,10 @@
1
+ import type { RelationshipFieldClientProps } from 'payload';
2
+ import React from 'react';
3
+ type Props = {
4
+ debug?: boolean;
5
+ serverValue?: number | string;
6
+ tenantsCollectionSlug: string;
7
+ } & RelationshipFieldClientProps;
8
+ export declare const TenantFieldClient: (args: Props) => React.JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=index.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/components/TenantField/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AAG3D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC7B,qBAAqB,EAAE,MAAM,CAAA;CAC9B,GAAG,4BAA4B,CAAA;AAEhC,eAAO,MAAM,iBAAiB,SAAU,KAAK,sBA2B5C,CAAA"}
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { RelationshipField, useField } from '@payloadcms/ui';
4
+ import React from 'react';
5
+ export const TenantFieldClient = (args)=>{
6
+ const { path, serverValue } = args;
7
+ const { setValue, value } = useField({
8
+ path
9
+ });
10
+ React.useEffect(()=>{
11
+ if (serverValue && value !== serverValue) {
12
+ setValue(serverValue);
13
+ }
14
+ }, [
15
+ serverValue,
16
+ setValue,
17
+ value
18
+ ]);
19
+ if (args.debug) {
20
+ return /*#__PURE__*/ _jsx(RelationshipField, {
21
+ field: {
22
+ name: path,
23
+ type: 'relationship',
24
+ label: 'Tenant',
25
+ relationTo: args.tenantsCollectionSlug,
26
+ required: true
27
+ },
28
+ path: path
29
+ });
30
+ }
31
+ return null;
32
+ };
33
+
34
+ //# sourceMappingURL=index.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/TenantField/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { RelationshipFieldClientProps } from 'payload'\n\nimport { RelationshipField, useField } from '@payloadcms/ui'\nimport React from 'react'\n\ntype Props = {\n debug?: boolean\n serverValue?: number | string\n tenantsCollectionSlug: string\n} & RelationshipFieldClientProps\n\nexport const TenantFieldClient = (args: Props) => {\n const { path, serverValue } = args\n\n const { setValue, value } = useField({ path })\n\n React.useEffect(() => {\n if (serverValue && value !== serverValue) {\n setValue(serverValue)\n }\n }, [serverValue, setValue, value])\n\n if (args.debug) {\n return (\n <RelationshipField\n field={{\n name: path,\n type: 'relationship',\n label: 'Tenant',\n relationTo: args.tenantsCollectionSlug,\n required: true,\n }}\n path={path}\n />\n )\n }\n\n return null\n}\n"],"names":["RelationshipField","useField","React","TenantFieldClient","args","path","serverValue","setValue","value","useEffect","debug","field","name","type","label","relationTo","tenantsCollectionSlug","required"],"mappings":"AAAA;;AAIA,SAASA,iBAAiB,EAAEC,QAAQ,QAAQ,iBAAgB;AAC5D,OAAOC,WAAW,QAAO;AAQzB,OAAO,MAAMC,oBAAoB,CAACC;IAChC,MAAM,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGF;IAE9B,MAAM,EAAEG,QAAQ,EAAEC,KAAK,EAAE,GAAGP,SAAS;QAAEI;IAAK;IAE5CH,MAAMO,SAAS,CAAC;QACd,IAAIH,eAAeE,UAAUF,aAAa;YACxCC,SAASD;QACX;IACF,GAAG;QAACA;QAAaC;QAAUC;KAAM;IAEjC,IAAIJ,KAAKM,KAAK,EAAE;QACd,qBACE,KAACV;YACCW,OAAO;gBACLC,MAAMP;gBACNQ,MAAM;gBACNC,OAAO;gBACPC,YAAYX,KAAKY,qBAAqB;gBACtCC,UAAU;YACZ;YACAZ,MAAMA;;IAGZ;IAEA,OAAO;AACT,EAAC"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const TenantField: React.FC;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantField/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAwC/B,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js';
4
+ import { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js';
5
+ import { TenantFieldClient } from './index.client.js';
6
+ export const TenantField = async ({ clientField, debug, path, payload, readOnly, req, tenantsCollectionSlug, user })=>{
7
+ let serverValue = getTenantFromCookie(req.headers, payload.db.defaultIDType) || getUserTenantIDs(user)?.[0];
8
+ if (serverValue) {
9
+ try {
10
+ // validate that the tenant exists
11
+ const doc = await payload.findByID({
12
+ id: serverValue,
13
+ collection: tenantsCollectionSlug,
14
+ depth: 0
15
+ });
16
+ if (!doc) {
17
+ serverValue = undefined;
18
+ }
19
+ } catch (_) {
20
+ serverValue = undefined;
21
+ }
22
+ }
23
+ return /*#__PURE__*/ _jsx(TenantFieldClient, {
24
+ debug: debug,
25
+ field: clientField,
26
+ path: path,
27
+ readOnly: readOnly,
28
+ serverValue: serverValue,
29
+ tenantsCollectionSlug: tenantsCollectionSlug
30
+ });
31
+ };
32
+
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/TenantField/index.tsx"],"sourcesContent":["import type { RelationshipFieldServerProps } from 'payload'\n\nimport React from 'react'\n\nimport type { UserWithTenantsField } from '../../types.js'\n\nimport { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js'\nimport { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js'\nimport { TenantFieldClient } from './index.client.js'\n\ntype Props = {\n debug?: boolean\n tenantsCollectionSlug: string\n} & RelationshipFieldServerProps\n\nexport const TenantField: React.FC = async ({\n clientField,\n debug,\n path,\n payload,\n readOnly,\n req,\n tenantsCollectionSlug,\n user,\n}: Props) => {\n let serverValue: number | string | undefined =\n getTenantFromCookie(req.headers, payload.db.defaultIDType) ||\n getUserTenantIDs(user as UserWithTenantsField)?.[0]\n\n if (serverValue) {\n try {\n // validate that the tenant exists\n const doc = await payload.findByID({\n id: serverValue,\n collection: tenantsCollectionSlug,\n depth: 0,\n })\n if (!doc) {\n serverValue = undefined\n }\n } catch (_) {\n serverValue = undefined\n }\n }\n\n return (\n <TenantFieldClient\n debug={debug}\n field={clientField}\n path={path}\n readOnly={readOnly}\n serverValue={serverValue}\n tenantsCollectionSlug={tenantsCollectionSlug}\n />\n )\n}\n"],"names":["React","getTenantFromCookie","getUserTenantIDs","TenantFieldClient","TenantField","clientField","debug","path","payload","readOnly","req","tenantsCollectionSlug","user","serverValue","headers","db","defaultIDType","doc","findByID","id","collection","depth","undefined","_","field"],"mappings":";AAEA,OAAOA,WAAW,QAAO;AAIzB,SAASC,mBAAmB,QAAQ,yCAAwC;AAC5E,SAASC,gBAAgB,QAAQ,sCAAqC;AACtE,SAASC,iBAAiB,QAAQ,oBAAmB;AAOrD,OAAO,MAAMC,cAAwB,OAAO,EAC1CC,WAAW,EACXC,KAAK,EACLC,IAAI,EACJC,OAAO,EACPC,QAAQ,EACRC,GAAG,EACHC,qBAAqB,EACrBC,IAAI,EACE;IACN,IAAIC,cACFZ,oBAAoBS,IAAII,OAAO,EAAEN,QAAQO,EAAE,CAACC,aAAa,KACzDd,iBAAiBU,OAA+B,CAAC,EAAE;IAErD,IAAIC,aAAa;QACf,IAAI;YACF,kCAAkC;YAClC,MAAMI,MAAM,MAAMT,QAAQU,QAAQ,CAAC;gBACjCC,IAAIN;gBACJO,YAAYT;gBACZU,OAAO;YACT;YACA,IAAI,CAACJ,KAAK;gBACRJ,cAAcS;YAChB;QACF,EAAE,OAAOC,GAAG;YACVV,cAAcS;QAChB;IACF;IAEA,qBACE,KAACnB;QACCG,OAAOA;QACPkB,OAAOnB;QACPE,MAAMA;QACNE,UAAUA;QACVI,aAAaA;QACbF,uBAAuBA;;AAG7B,EAAC"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import './index.scss';
3
+ export declare const TenantSelectorClient: ({ cookieToSet, initialValue, options, }: {
4
+ cookieToSet?: string;
5
+ initialValue?: string;
6
+ options: {
7
+ label: string;
8
+ value: string;
9
+ }[];
10
+ }) => React.JSX.Element;
11
+ //# sourceMappingURL=index.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.client.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,cAAc,CAAA;AAMrB,eAAO,MAAM,oBAAoB,4CAI9B;IACD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,CAAA;KACd,EAAE,CAAA;CACJ,sBAsDA,CAAA"}
@@ -0,0 +1,61 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { SelectInput } from '@payloadcms/ui';
4
+ import { useRouter } from 'next/navigation.js';
5
+ import React from 'react';
6
+ import './index.scss';
7
+ function findValue(options, value) {
8
+ return options.find((opt)=>opt.value === value)?.value;
9
+ }
10
+ export const TenantSelectorClient = ({ cookieToSet, initialValue, options })=>{
11
+ const [value, setValue] = React.useState(()=>{
12
+ if (initialValue) {
13
+ return findValue(options, initialValue);
14
+ }
15
+ });
16
+ const router = useRouter();
17
+ const setCookieAndReload = React.useCallback((value)=>{
18
+ const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
19
+ document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/';
20
+ setValue(value);
21
+ router.refresh();
22
+ }, [
23
+ router
24
+ ]);
25
+ const handleChange = React.useCallback((option)=>{
26
+ if (!option) {
27
+ setCookieAndReload(undefined);
28
+ } else if ('value' in option) {
29
+ setCookieAndReload(option.value);
30
+ }
31
+ }, [
32
+ setCookieAndReload
33
+ ]);
34
+ React.useEffect(()=>{
35
+ if (cookieToSet) {
36
+ setCookieAndReload(findValue(options, cookieToSet));
37
+ }
38
+ }, [
39
+ cookieToSet,
40
+ options,
41
+ setCookieAndReload
42
+ ]);
43
+ if (options.length <= 1) {
44
+ return null;
45
+ }
46
+ return /*#__PURE__*/ _jsx("div", {
47
+ className: "tenant-selector",
48
+ children: /*#__PURE__*/ _jsx(SelectInput, {
49
+ isClearable: false,
50
+ label: "Select a tenant",
51
+ name: "setTenant",
52
+ onChange: handleChange,
53
+ options: options,
54
+ path: "setTenant",
55
+ readOnly: !value,
56
+ value: value
57
+ })
58
+ });
59
+ };
60
+
61
+ //# sourceMappingURL=index.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/TenantSelector/index.client.tsx"],"sourcesContent":["'use client'\nimport type { ReactSelectOption } from '@payloadcms/ui'\n\nimport { SelectInput } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React from 'react'\n\nimport './index.scss'\n\nfunction findValue(options: { label: string; value: string }[], value?: string) {\n return options.find((opt) => opt.value === value)?.value\n}\n\nexport const TenantSelectorClient = ({\n cookieToSet,\n initialValue,\n options,\n}: {\n cookieToSet?: string\n initialValue?: string\n options: {\n label: string\n value: string\n }[]\n}) => {\n const [value, setValue] = React.useState<string | undefined>(() => {\n if (initialValue) {\n return findValue(options, initialValue)\n }\n })\n\n const router = useRouter()\n\n const setCookieAndReload = React.useCallback(\n (value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n setValue(value)\n router.refresh()\n },\n [router],\n )\n\n const handleChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (!option) {\n setCookieAndReload(undefined)\n } else if ('value' in option) {\n setCookieAndReload(option.value as string)\n }\n },\n [setCookieAndReload],\n )\n\n React.useEffect(() => {\n if (cookieToSet) {\n setCookieAndReload(findValue(options, cookieToSet))\n }\n }, [cookieToSet, options, setCookieAndReload])\n\n if (options.length <= 1) {\n return null\n }\n\n return (\n <div className=\"tenant-selector\">\n <SelectInput\n isClearable={false}\n label=\"Select a tenant\"\n name=\"setTenant\"\n onChange={handleChange}\n options={options}\n path=\"setTenant\"\n readOnly={!value}\n value={value}\n />\n </div>\n )\n}\n"],"names":["SelectInput","useRouter","React","findValue","options","value","find","opt","TenantSelectorClient","cookieToSet","initialValue","setValue","useState","router","setCookieAndReload","useCallback","expires","document","cookie","refresh","handleChange","option","undefined","useEffect","length","div","className","isClearable","label","name","onChange","path","readOnly"],"mappings":"AAAA;;AAGA,SAASA,WAAW,QAAQ,iBAAgB;AAC5C,SAASC,SAAS,QAAQ,qBAAoB;AAC9C,OAAOC,WAAW,QAAO;AAEzB,OAAO,eAAc;AAErB,SAASC,UAAUC,OAA2C,EAAEC,KAAc;IAC5E,OAAOD,QAAQE,IAAI,CAAC,CAACC,MAAQA,IAAIF,KAAK,KAAKA,QAAQA;AACrD;AAEA,OAAO,MAAMG,uBAAuB,CAAC,EACnCC,WAAW,EACXC,YAAY,EACZN,OAAO,EAQR;IACC,MAAM,CAACC,OAAOM,SAAS,GAAGT,MAAMU,QAAQ,CAAqB;QAC3D,IAAIF,cAAc;YAChB,OAAOP,UAAUC,SAASM;QAC5B;IACF;IAEA,MAAMG,SAASZ;IAEf,MAAMa,qBAAqBZ,MAAMa,WAAW,CAC1C,CAACV;QACC,MAAMW,UAAU;QAChBC,SAASC,MAAM,GAAG,oBAAqBb,CAAAA,SAAS,EAAC,IAAKW,UAAU;QAChEL,SAASN;QACTQ,OAAOM,OAAO;IAChB,GACA;QAACN;KAAO;IAGV,MAAMO,eAAelB,MAAMa,WAAW,CACpC,CAACM;QACC,IAAI,CAACA,QAAQ;YACXP,mBAAmBQ;QACrB,OAAO,IAAI,WAAWD,QAAQ;YAC5BP,mBAAmBO,OAAOhB,KAAK;QACjC;IACF,GACA;QAACS;KAAmB;IAGtBZ,MAAMqB,SAAS,CAAC;QACd,IAAId,aAAa;YACfK,mBAAmBX,UAAUC,SAASK;QACxC;IACF,GAAG;QAACA;QAAaL;QAASU;KAAmB;IAE7C,IAAIV,QAAQoB,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAU;kBACb,cAAA,KAAC1B;YACC2B,aAAa;YACbC,OAAM;YACNC,MAAK;YACLC,UAAUV;YACVhB,SAASA;YACT2B,MAAK;YACLC,UAAU,CAAC3B;YACXA,OAAOA;;;AAIf,EAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ServerProps } from 'payload';
2
+ import React from 'react';
3
+ import type { MultiTenantPluginConfig, UserWithTenantsField } from '../../types.js';
4
+ type Args = {
5
+ tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug'];
6
+ user?: UserWithTenantsField;
7
+ } & ServerProps;
8
+ export declare const TenantSelector: ({ payload, tenantsCollectionSlug, user }: Args) => Promise<React.JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,uBAAuB,EAAU,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAI3F,KAAK,IAAI,GAAG;IACV,qBAAqB,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAA;IAC7D,IAAI,CAAC,EAAE,oBAAoB,CAAA;CAC5B,GAAG,WAAW,CAAA;AAEf,eAAO,MAAM,cAAc,6CAAoD,IAAI,+BAgClF,CAAA"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cookies as getCookies } from 'next/headers.js';
3
+ import React from 'react';
4
+ import { TenantSelectorClient } from './index.client.js';
5
+ export const TenantSelector = async ({ payload, tenantsCollectionSlug, user })=>{
6
+ const { docs: userTenants } = await payload.find({
7
+ collection: tenantsCollectionSlug,
8
+ depth: 0,
9
+ limit: 1000,
10
+ overrideAccess: false,
11
+ sort: 'name',
12
+ user
13
+ });
14
+ const tenantOptions = userTenants.map((doc)=>({
15
+ label: doc.name,
16
+ value: String(doc.id)
17
+ }));
18
+ let cookieToSet;
19
+ const cookies = await getCookies();
20
+ const selectedTenant = tenantOptions.find((tenant)=>tenant.value === cookies.get('payload-tenant')?.value)?.value;
21
+ if (!selectedTenant && userTenants.length > 0) {
22
+ cookieToSet = String(userTenants[0].id);
23
+ }
24
+ return /*#__PURE__*/ _jsx(TenantSelectorClient, {
25
+ cookieToSet: cookieToSet,
26
+ initialValue: selectedTenant,
27
+ options: tenantOptions
28
+ });
29
+ };
30
+
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["import type { ServerProps } from 'payload'\n\nimport { cookies as getCookies } from 'next/headers.js'\nimport React from 'react'\n\nimport type { MultiTenantPluginConfig, Tenant, UserWithTenantsField } from '../../types.js'\n\nimport { TenantSelectorClient } from './index.client.js'\n\ntype Args = {\n tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug']\n user?: UserWithTenantsField\n} & ServerProps\n\nexport const TenantSelector = async ({ payload, tenantsCollectionSlug, user }: Args) => {\n const { docs: userTenants } = await payload.find({\n collection: tenantsCollectionSlug,\n depth: 0,\n limit: 1000,\n overrideAccess: false,\n sort: 'name',\n user,\n })\n\n const tenantOptions = userTenants.map((doc: Tenant) => ({\n label: doc.name,\n value: String(doc.id),\n }))\n\n let cookieToSet: string | undefined\n const cookies = await getCookies()\n const selectedTenant = tenantOptions.find(\n (tenant) => tenant.value === cookies.get('payload-tenant')?.value,\n )?.value\n\n if (!selectedTenant && userTenants.length > 0) {\n cookieToSet = String(userTenants[0].id)\n }\n\n return (\n <TenantSelectorClient\n cookieToSet={cookieToSet}\n initialValue={selectedTenant}\n options={tenantOptions}\n />\n )\n}\n"],"names":["cookies","getCookies","React","TenantSelectorClient","TenantSelector","payload","tenantsCollectionSlug","user","docs","userTenants","find","collection","depth","limit","overrideAccess","sort","tenantOptions","map","doc","label","name","value","String","id","cookieToSet","selectedTenant","tenant","get","length","initialValue","options"],"mappings":";AAEA,SAASA,WAAWC,UAAU,QAAQ,kBAAiB;AACvD,OAAOC,WAAW,QAAO;AAIzB,SAASC,oBAAoB,QAAQ,oBAAmB;AAOxD,OAAO,MAAMC,iBAAiB,OAAO,EAAEC,OAAO,EAAEC,qBAAqB,EAAEC,IAAI,EAAQ;IACjF,MAAM,EAAEC,MAAMC,WAAW,EAAE,GAAG,MAAMJ,QAAQK,IAAI,CAAC;QAC/CC,YAAYL;QACZM,OAAO;QACPC,OAAO;QACPC,gBAAgB;QAChBC,MAAM;QACNR;IACF;IAEA,MAAMS,gBAAgBP,YAAYQ,GAAG,CAAC,CAACC,MAAiB,CAAA;YACtDC,OAAOD,IAAIE,IAAI;YACfC,OAAOC,OAAOJ,IAAIK,EAAE;QACtB,CAAA;IAEA,IAAIC;IACJ,MAAMxB,UAAU,MAAMC;IACtB,MAAMwB,iBAAiBT,cAAcN,IAAI,CACvC,CAACgB,SAAWA,OAAOL,KAAK,KAAKrB,QAAQ2B,GAAG,CAAC,mBAAmBN,QAC3DA;IAEH,IAAI,CAACI,kBAAkBhB,YAAYmB,MAAM,GAAG,GAAG;QAC7CJ,cAAcF,OAAOb,WAAW,CAAC,EAAE,CAACc,EAAE;IACxC;IAEA,qBACE,KAACpB;QACCqB,aAAaA;QACbK,cAAcJ;QACdK,SAASd;;AAGf,EAAC"}
@@ -0,0 +1,4 @@
1
+ .tenant-selector {
2
+ width: 100%;
3
+ margin-bottom: 2rem;
4
+ }
@@ -0,0 +1,4 @@
1
+ export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js';
2
+ export { TenantField } from '../components/TenantField/index.js';
3
+ export { TenantSelector } from '../components/TenantSelector/index.js';
4
+ //# sourceMappingURL=rsc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js';
2
+ export { TenantField } from '../components/TenantField/index.js';
3
+ export { TenantSelector } from '../components/TenantSelector/index.js';
4
+
5
+ //# sourceMappingURL=rsc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js'\nexport { TenantField } from '../components/TenantField/index.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\n"],"names":["GlobalViewRedirect","TenantField","TenantSelector"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,4CAA2C;AAC9E,SAASC,WAAW,QAAQ,qCAAoC;AAChE,SAASC,cAAc,QAAQ,wCAAuC"}
@@ -0,0 +1,2 @@
1
+ export type { MultiTenantPluginConfig } from '../types.js';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { MultiTenantPluginConfig } from '../types.js'\n"],"names":[],"mappings":"AAAA,WAA0D"}
@@ -0,0 +1,6 @@
1
+ export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js';
2
+ export { getTenantAccess } from '../utilities/getTenantAccess.js';
3
+ export { getTenantFromCookie } from '../utilities/getTenantFromCookie.js';
4
+ export { getTenantListFilter } from '../utilities/getTenantListFilter.js';
5
+ export { getUserTenantIDs } from '../utilities/getUserTenantIDs.js';
6
+ //# sourceMappingURL=utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js';
2
+ export { getTenantAccess } from '../utilities/getTenantAccess.js';
3
+ export { getTenantFromCookie } from '../utilities/getTenantFromCookie.js';
4
+ export { getTenantListFilter } from '../utilities/getTenantListFilter.js';
5
+ export { getUserTenantIDs } from '../utilities/getUserTenantIDs.js';
6
+
7
+ //# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js'\nexport { getTenantAccess } from '../utilities/getTenantAccess.js'\nexport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\nexport { getTenantListFilter } from '../utilities/getTenantListFilter.js'\nexport { getUserTenantIDs } from '../utilities/getUserTenantIDs.js'\n"],"names":["getGlobalViewRedirect","getTenantAccess","getTenantFromCookie","getTenantListFilter","getUserTenantIDs"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,wCAAuC;AAC7E,SAASC,eAAe,QAAQ,kCAAiC;AACjE,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,gBAAgB,QAAQ,mCAAkC"}
@@ -0,0 +1,12 @@
1
+ import { type RelationshipField } from 'payload';
2
+ import type { MultiTenantPluginConfig } from '../../types.js';
3
+ type Args = {
4
+ access: MultiTenantPluginConfig['documentTenantField']['access'];
5
+ debug?: boolean;
6
+ name: string;
7
+ tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug'];
8
+ unique: boolean;
9
+ };
10
+ export declare const tenantField: ({ name, access, debug, tenantsCollectionSlug, unique, }: Args) => RelationshipField;
11
+ export {};
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantField/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAGhD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAI7D,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,uBAAuB,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,CAAA;IAChE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAA;IAC7D,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AACD,eAAO,MAAM,WAAW,4DAMrB,IAAI,KAAG,iBAiCR,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { APIError } from 'payload';
2
+ import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js';
3
+ export const tenantField = ({ name, access, debug, tenantsCollectionSlug, unique })=>({
4
+ name,
5
+ type: 'relationship',
6
+ access,
7
+ admin: {
8
+ components: {
9
+ Field: {
10
+ clientProps: {
11
+ debug,
12
+ tenantsCollectionSlug
13
+ },
14
+ path: '@payloadcms/plugin-multi-tenant/rsc#TenantField'
15
+ }
16
+ },
17
+ position: debug ? 'sidebar' : undefined
18
+ },
19
+ hasMany: false,
20
+ hooks: {
21
+ beforeChange: [
22
+ ({ req, value })=>{
23
+ if (!value) {
24
+ const tenantFromCookie = getTenantFromCookie(req.headers, req.payload.db.defaultIDType);
25
+ if (tenantFromCookie) {
26
+ return tenantFromCookie;
27
+ }
28
+ throw new APIError('You must select a tenant', 400, null, true);
29
+ }
30
+ }
31
+ ]
32
+ },
33
+ index: true,
34
+ relationTo: tenantsCollectionSlug,
35
+ unique
36
+ });
37
+
38
+ //# sourceMappingURL=index.js.map