@payloadcms/plugin-multi-tenant 4.0.0-internal.2fddfc0 → 4.0.0-internal.314c594
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/dist/components/AssignTenantFieldModal/index.client.d.ts +2 -2
- package/dist/components/AssignTenantFieldModal/index.client.d.ts.map +1 -1
- package/dist/components/AssignTenantFieldModal/index.client.js.map +1 -1
- package/dist/components/GlobalViewRedirect/index.d.ts +1 -1
- package/dist/components/GlobalViewRedirect/index.d.ts.map +1 -1
- package/dist/components/GlobalViewRedirect/index.js.map +1 -1
- package/dist/components/TenantField/index.client.d.ts.map +1 -1
- package/dist/components/TenantField/index.client.js +84 -74
- package/dist/components/TenantField/index.client.js.map +1 -1
- package/dist/components/TenantSelector/index.client.d.ts +1 -1
- package/dist/components/TenantSelector/index.client.d.ts.map +1 -1
- package/dist/components/TenantSelector/index.d.ts.map +1 -1
- package/dist/defaults.d.ts.map +1 -1
- package/dist/endpoints/getTenantOptionsEndpoint.d.ts +2 -2
- package/dist/endpoints/getTenantOptionsEndpoint.d.ts.map +1 -1
- package/dist/endpoints/getTenantOptionsEndpoint.js.map +1 -1
- package/dist/fields/tenantField/index.d.ts.map +1 -1
- package/dist/fields/tenantsArrayField/index.d.ts.map +1 -1
- package/dist/filters/filterDocumentsByTenants.d.ts +3 -3
- package/dist/filters/filterDocumentsByTenants.d.ts.map +1 -1
- package/dist/filters/filterDocumentsByTenants.js.map +1 -1
- package/dist/hooks/afterTenantDelete.d.ts +1 -1
- package/dist/hooks/afterTenantDelete.d.ts.map +1 -1
- package/dist/hooks/afterTenantDelete.js +4 -1
- package/dist/hooks/afterTenantDelete.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -5
- package/dist/index.js.map +1 -1
- package/dist/index.spec.js +70 -0
- package/dist/index.spec.js.map +1 -0
- package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.js +22 -0
- package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.d.ts +5 -5
- package/dist/providers/TenantSelectionProvider/index.d.ts.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.js.map +1 -1
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/types.d.ts +5 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/addCollectionAccess.d.ts +8 -10
- package/dist/utilities/addCollectionAccess.d.ts.map +1 -1
- package/dist/utilities/addCollectionAccess.js +91 -20
- package/dist/utilities/addCollectionAccess.js.map +1 -1
- package/dist/utilities/addCollectionAccess.spec.js +134 -0
- package/dist/utilities/addCollectionAccess.spec.js.map +1 -0
- package/dist/utilities/addFilterOptionsToFields.d.ts +3 -3
- package/dist/utilities/addFilterOptionsToFields.d.ts.map +1 -1
- package/dist/utilities/addFilterOptionsToFields.js.map +1 -1
- package/dist/utilities/combineFilters.d.ts.map +1 -1
- package/dist/utilities/extractID.d.ts.map +1 -1
- package/dist/utilities/generateCookie.d.ts.map +1 -1
- package/dist/utilities/getCollectionIDType.d.ts +1 -1
- package/dist/utilities/getCollectionIDType.d.ts.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.d.ts +3 -3
- package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
- package/dist/utilities/getTenantOptions.d.ts +3 -3
- package/dist/utilities/getTenantOptions.d.ts.map +1 -1
- package/dist/utilities/getTenantOptions.js.map +1 -1
- package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
- package/dist/utilities/getUserTenantIDs.js +2 -1
- package/dist/utilities/getUserTenantIDs.js.map +1 -1
- package/dist/utilities/miniChalk.d.ts.map +1 -1
- package/package.json +7 -8
- package/dist/@types/assets.d.js +0 -2
- package/dist/@types/assets.d.js.map +0 -1
- package/dist/utilities/combineWhereConstraints.d.ts +0 -3
- package/dist/utilities/combineWhereConstraints.d.ts.map +0 -1
- package/dist/utilities/combineWhereConstraints.js +0 -19
- package/dist/utilities/combineWhereConstraints.js.map +0 -1
- package/dist/utilities/withTenantAccess.d.ts +0 -16
- package/dist/utilities/withTenantAccess.d.ts.map +0 -1
- package/dist/utilities/withTenantAccess.js +0 -76
- package/dist/utilities/withTenantAccess.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,gBAAgB,EAAE,MAAM,EAAe,MAAM,SAAS,CAAA;AAE9F,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAIzE,eAAO,MAAM,oBAAoB,EAAE,aAOzB,CAAA;AAEV,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oBAAoB,CAAC,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAA;IAC3E,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,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;CAC1F,CAAA;AAsED,eAAO,MAAM,mBAAmB,wBAG7B;IACD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,EAAE,CAAA;CAC7B,KAAG,IA4CH,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getTenantAccess } from './getTenantAccess.js';
|
|
2
2
|
export const collectionAccessKeys = [
|
|
3
3
|
'create',
|
|
4
4
|
'read',
|
|
@@ -7,26 +7,97 @@ export const collectionAccessKeys = [
|
|
|
7
7
|
'readVersions',
|
|
8
8
|
'unlock'
|
|
9
9
|
];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
const getTenantAccessResult = ({ accessKey, accessResult, accessResultCallback, adminUsersSlug, args, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
|
|
11
|
+
const finish = (result)=>accessResultCallback ? accessResultCallback({
|
|
12
|
+
accessKey,
|
|
13
|
+
accessResult: result,
|
|
14
|
+
...args
|
|
15
|
+
}) : result;
|
|
16
|
+
if (!accessResult) {
|
|
17
|
+
return finish(false);
|
|
18
|
+
}
|
|
19
|
+
const user = args.req.user;
|
|
20
|
+
if (!user || user.collection !== adminUsersSlug || userHasAccessToAllTenants(user)) {
|
|
21
|
+
return finish(accessResult);
|
|
22
|
+
}
|
|
23
|
+
const tenantConstraint = getTenantAccess({
|
|
24
|
+
fieldName,
|
|
25
|
+
tenantsArrayFieldName,
|
|
26
|
+
tenantsArrayTenantFieldName,
|
|
27
|
+
user
|
|
28
|
+
});
|
|
29
|
+
if (tenantConstraint[fieldName]?.in.length === 0) {
|
|
30
|
+
return finish(collection.slug === user.collection ? {
|
|
31
|
+
id: {
|
|
32
|
+
equals: user.id
|
|
33
|
+
}
|
|
34
|
+
} : false);
|
|
35
|
+
}
|
|
36
|
+
const tenantResult = collection.slug === user.collection ? {
|
|
37
|
+
or: [
|
|
38
|
+
{
|
|
39
|
+
id: {
|
|
40
|
+
equals: user.id
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
tenantConstraint
|
|
44
|
+
]
|
|
45
|
+
} : tenantConstraint;
|
|
46
|
+
return finish(accessResult === true ? tenantResult : {
|
|
47
|
+
and: [
|
|
48
|
+
accessResult,
|
|
49
|
+
tenantResult
|
|
50
|
+
]
|
|
29
51
|
});
|
|
30
52
|
};
|
|
53
|
+
const wrapCollectionAccess = (scope)=>{
|
|
54
|
+
scope.collection.access ??= {};
|
|
55
|
+
for (const accessKey of collectionAccessKeys){
|
|
56
|
+
const accessFunction = scope.collection.access[accessKey] ?? (({ req })=>Boolean(req.user));
|
|
57
|
+
scope.collection.access[accessKey] = async (args)=>getTenantAccessResult({
|
|
58
|
+
...scope,
|
|
59
|
+
accessKey,
|
|
60
|
+
accessResult: await accessFunction(args),
|
|
61
|
+
args,
|
|
62
|
+
fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
export const addCollectionAccess = ({ config, scopes })=>{
|
|
67
|
+
const baseAccessScopes = new Map();
|
|
68
|
+
for (const scope of scopes){
|
|
69
|
+
if (scope.accessResultCallback) {
|
|
70
|
+
wrapCollectionAccess(scope);
|
|
71
|
+
} else {
|
|
72
|
+
baseAccessScopes.set(scope.collection.slug, scope);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!baseAccessScopes.size) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
config.baseAccess ??= {};
|
|
79
|
+
config.baseAccess.collections ??= {};
|
|
80
|
+
for (const accessKey of collectionAccessKeys){
|
|
81
|
+
const baseAccessFunction = config.baseAccess.collections[accessKey];
|
|
82
|
+
config.baseAccess.collections[accessKey] = async (args)=>{
|
|
83
|
+
const baseResult = baseAccessFunction ? await baseAccessFunction(args) : true;
|
|
84
|
+
const scope = baseAccessScopes.get(args.slug);
|
|
85
|
+
if (!baseResult || !scope) {
|
|
86
|
+
return baseResult;
|
|
87
|
+
}
|
|
88
|
+
if (accessKey === 'create' && typeof baseResult === 'object') {
|
|
89
|
+
return baseResult;
|
|
90
|
+
}
|
|
91
|
+
const tenantResult = await getTenantAccessResult({
|
|
92
|
+
...scope,
|
|
93
|
+
accessKey,
|
|
94
|
+
accessResult: baseResult,
|
|
95
|
+
args,
|
|
96
|
+
fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName
|
|
97
|
+
});
|
|
98
|
+
return accessKey === 'create' ? Boolean(tenantResult) : tenantResult;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
31
102
|
|
|
32
103
|
//# sourceMappingURL=addCollectionAccess.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { AccessArgs, AccessResult, CollectionConfig, Config, User, Where } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js'\n\nimport { getTenantAccess } from './getTenantAccess.js'\n\nexport const collectionAccessKeys: AllAccessKeys = [\n 'create',\n 'read',\n 'update',\n 'delete',\n 'readVersions',\n 'unlock',\n] as const\n\nexport type TenantAccessConfig = {\n accessResultCallback?: MultiTenantPluginConfig['usersAccessResultOverride']\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}\n\nconst getTenantAccessResult = ({\n accessKey,\n accessResult,\n accessResultCallback,\n adminUsersSlug,\n args,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: {\n accessKey: AllAccessKeys[number]\n accessResult: AccessResult\n args: AccessArgs\n} & TenantAccessConfig): AccessResult | Promise<AccessResult> => {\n const finish = (result: AccessResult): AccessResult | Promise<AccessResult> =>\n accessResultCallback\n ? accessResultCallback({ accessKey, accessResult: result, ...args })\n : result\n\n if (!accessResult) {\n return finish(false)\n }\n\n const user = args.req.user\n\n if (!user || user.collection !== adminUsersSlug || userHasAccessToAllTenants(user as User)) {\n return finish(accessResult)\n }\n\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user,\n })\n\n if (tenantConstraint[fieldName]?.in.length === 0) {\n return finish(collection.slug === user.collection ? { id: { equals: user.id } } : false)\n }\n\n const tenantResult: Where =\n collection.slug === user.collection\n ? { or: [{ id: { equals: user.id } }, tenantConstraint] }\n : tenantConstraint\n\n return finish(accessResult === true ? tenantResult : { and: [accessResult, tenantResult] })\n}\n\nconst wrapCollectionAccess = (scope: TenantAccessConfig): void => {\n scope.collection.access ??= {}\n\n for (const accessKey of collectionAccessKeys) {\n const accessFunction =\n scope.collection.access[accessKey] ?? (({ req }: AccessArgs) => Boolean(req.user))\n\n scope.collection.access[accessKey] = async (args) =>\n getTenantAccessResult({\n ...scope,\n accessKey,\n accessResult: await accessFunction(args),\n args,\n fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName,\n })\n }\n}\n\nexport const addCollectionAccess = ({\n config,\n scopes,\n}: {\n config: Config\n scopes: TenantAccessConfig[]\n}): void => {\n const baseAccessScopes = new Map<string, TenantAccessConfig>()\n\n for (const scope of scopes) {\n if (scope.accessResultCallback) {\n wrapCollectionAccess(scope)\n } else {\n baseAccessScopes.set(scope.collection.slug, scope)\n }\n }\n\n if (!baseAccessScopes.size) {\n return\n }\n\n config.baseAccess ??= {}\n config.baseAccess.collections ??= {}\n\n for (const accessKey of collectionAccessKeys) {\n const baseAccessFunction = config.baseAccess.collections[accessKey]\n\n config.baseAccess.collections[accessKey] = async (args) => {\n const baseResult = baseAccessFunction ? await baseAccessFunction(args) : true\n const scope = baseAccessScopes.get(args.slug)\n\n if (!baseResult || !scope) {\n return baseResult\n }\n\n if (accessKey === 'create' && typeof baseResult === 'object') {\n return baseResult\n }\n\n const tenantResult = await getTenantAccessResult({\n ...scope,\n accessKey,\n accessResult: baseResult,\n args,\n fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName,\n })\n\n return accessKey === 'create' ? Boolean(tenantResult) : tenantResult\n }\n }\n}\n"],"names":["getTenantAccess","collectionAccessKeys","getTenantAccessResult","accessKey","accessResult","accessResultCallback","adminUsersSlug","args","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","finish","result","user","req","tenantConstraint","in","length","slug","id","equals","tenantResult","or","and","wrapCollectionAccess","scope","access","accessFunction","Boolean","addCollectionAccess","config","scopes","baseAccessScopes","Map","set","size","baseAccess","collections","baseAccessFunction","baseResult","get"],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { addCollectionAccess } from './addCollectionAccess.js';
|
|
3
|
+
const createScope = (collection, accessResultCallback)=>({
|
|
4
|
+
accessResultCallback,
|
|
5
|
+
adminUsersSlug: 'users',
|
|
6
|
+
collection,
|
|
7
|
+
fieldName: 'tenant',
|
|
8
|
+
userHasAccessToAllTenants: ()=>false
|
|
9
|
+
});
|
|
10
|
+
const createArgs = (slug = 'posts')=>({
|
|
11
|
+
req: {
|
|
12
|
+
user: {
|
|
13
|
+
collection: 'users',
|
|
14
|
+
id: 'user-1',
|
|
15
|
+
tenants: [
|
|
16
|
+
{
|
|
17
|
+
tenant: 'tenant-1'
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
slug
|
|
23
|
+
});
|
|
24
|
+
describe('addCollectionAccess', ()=>{
|
|
25
|
+
it('adds tenant constraints through base access without replacing collection access', async ()=>{
|
|
26
|
+
const documentRead = vi.fn(()=>({
|
|
27
|
+
published: {
|
|
28
|
+
equals: true
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
const collection = {
|
|
32
|
+
slug: 'posts',
|
|
33
|
+
access: {
|
|
34
|
+
read: documentRead
|
|
35
|
+
},
|
|
36
|
+
fields: []
|
|
37
|
+
};
|
|
38
|
+
const config = {
|
|
39
|
+
baseAccess: {
|
|
40
|
+
collections: {
|
|
41
|
+
read: ()=>({
|
|
42
|
+
archived: {
|
|
43
|
+
not_equals: true
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
addCollectionAccess({
|
|
50
|
+
config,
|
|
51
|
+
scopes: [
|
|
52
|
+
createScope(collection)
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
expect(collection.access?.read).toBe(documentRead);
|
|
56
|
+
await expect(config.baseAccess?.collections?.read?.(createArgs())).resolves.toEqual({
|
|
57
|
+
and: [
|
|
58
|
+
{
|
|
59
|
+
archived: {
|
|
60
|
+
not_equals: true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
tenant: {
|
|
65
|
+
in: [
|
|
66
|
+
'tenant-1'
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
});
|
|
72
|
+
await expect(config.baseAccess?.collections?.read?.(createArgs('pages'))).resolves.toEqual({
|
|
73
|
+
archived: {
|
|
74
|
+
not_equals: true
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
expect(documentRead).not.toHaveBeenCalled();
|
|
78
|
+
});
|
|
79
|
+
it('returns a boolean tenant result for collection create access', async ()=>{
|
|
80
|
+
const collection = {
|
|
81
|
+
slug: 'posts',
|
|
82
|
+
fields: []
|
|
83
|
+
};
|
|
84
|
+
const config = {};
|
|
85
|
+
addCollectionAccess({
|
|
86
|
+
config,
|
|
87
|
+
scopes: [
|
|
88
|
+
createScope(collection)
|
|
89
|
+
]
|
|
90
|
+
});
|
|
91
|
+
await expect(config.baseAccess?.collections?.create?.(createArgs())).resolves.toBe(true);
|
|
92
|
+
});
|
|
93
|
+
it('keeps callback wrapping when an access result override is configured', async ()=>{
|
|
94
|
+
const documentResult = {
|
|
95
|
+
published: {
|
|
96
|
+
equals: true
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const documentRead = vi.fn(()=>documentResult);
|
|
100
|
+
const accessResultCallback = vi.fn(({ accessResult })=>accessResult);
|
|
101
|
+
const collection = {
|
|
102
|
+
slug: 'posts',
|
|
103
|
+
access: {
|
|
104
|
+
read: documentRead
|
|
105
|
+
},
|
|
106
|
+
fields: []
|
|
107
|
+
};
|
|
108
|
+
const config = {};
|
|
109
|
+
addCollectionAccess({
|
|
110
|
+
config,
|
|
111
|
+
scopes: [
|
|
112
|
+
createScope(collection, accessResultCallback)
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
expect(config.baseAccess).toBeUndefined();
|
|
116
|
+
await expect(collection.access?.read?.(createArgs())).resolves.toEqual({
|
|
117
|
+
and: [
|
|
118
|
+
documentResult,
|
|
119
|
+
{
|
|
120
|
+
tenant: {
|
|
121
|
+
in: [
|
|
122
|
+
'tenant-1'
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
});
|
|
128
|
+
expect(accessResultCallback).toHaveBeenCalledWith(expect.objectContaining({
|
|
129
|
+
accessKey: 'read'
|
|
130
|
+
}));
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
//# sourceMappingURL=addCollectionAccess.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addCollectionAccess.spec.ts"],"sourcesContent":["import type { AccessArgs, CollectionConfig, Config } from 'payload'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport type { TenantAccessConfig } from './addCollectionAccess.js'\n\nimport { addCollectionAccess } from './addCollectionAccess.js'\n\nconst createScope = (\n collection: CollectionConfig,\n accessResultCallback?: TenantAccessConfig['accessResultCallback'],\n): TenantAccessConfig => ({\n accessResultCallback,\n adminUsersSlug: 'users',\n collection,\n fieldName: 'tenant',\n userHasAccessToAllTenants: () => false,\n})\n\nconst createArgs = (slug = 'posts'): AccessArgs => ({\n req: {\n user: {\n collection: 'users',\n id: 'user-1',\n tenants: [{ tenant: 'tenant-1' }],\n },\n } as unknown as AccessArgs['req'],\n slug,\n})\n\ndescribe('addCollectionAccess', () => {\n it('adds tenant constraints through base access without replacing collection access', async () => {\n const documentRead = vi.fn(() => ({ published: { equals: true } }))\n const collection: CollectionConfig = {\n slug: 'posts',\n access: { read: documentRead },\n fields: [],\n }\n const config = {\n baseAccess: {\n collections: {\n read: () => ({ archived: { not_equals: true } }),\n },\n },\n } as Config\n\n addCollectionAccess({ config, scopes: [createScope(collection)] })\n\n expect(collection.access?.read).toBe(documentRead)\n await expect(config.baseAccess?.collections?.read?.(createArgs())).resolves.toEqual({\n and: [{ archived: { not_equals: true } }, { tenant: { in: ['tenant-1'] } }],\n })\n await expect(config.baseAccess?.collections?.read?.(createArgs('pages'))).resolves.toEqual({\n archived: { not_equals: true },\n })\n expect(documentRead).not.toHaveBeenCalled()\n })\n\n it('returns a boolean tenant result for collection create access', async () => {\n const collection: CollectionConfig = { slug: 'posts', fields: [] }\n const config = {} as Config\n\n addCollectionAccess({ config, scopes: [createScope(collection)] })\n\n await expect(config.baseAccess?.collections?.create?.(createArgs())).resolves.toBe(true)\n })\n\n it('keeps callback wrapping when an access result override is configured', async () => {\n const documentResult = { published: { equals: true } }\n const documentRead = vi.fn(() => documentResult)\n const accessResultCallback = vi.fn(({ accessResult }) => accessResult)\n const collection: CollectionConfig = {\n slug: 'posts',\n access: { read: documentRead },\n fields: [],\n }\n const config = {} as Config\n\n addCollectionAccess({\n config,\n scopes: [createScope(collection, accessResultCallback)],\n })\n\n expect(config.baseAccess).toBeUndefined()\n await expect(collection.access?.read?.(createArgs())).resolves.toEqual({\n and: [documentResult, { tenant: { in: ['tenant-1'] } }],\n })\n expect(accessResultCallback).toHaveBeenCalledWith(\n expect.objectContaining({ accessKey: 'read' }),\n )\n })\n})\n"],"names":["describe","expect","it","vi","addCollectionAccess","createScope","collection","accessResultCallback","adminUsersSlug","fieldName","userHasAccessToAllTenants","createArgs","slug","req","user","id","tenants","tenant","documentRead","fn","published","equals","access","read","fields","config","baseAccess","collections","archived","not_equals","scopes","toBe","resolves","toEqual","and","in","not","toHaveBeenCalled","create","documentResult","accessResult","toBeUndefined","toHaveBeenCalledWith","objectContaining","accessKey"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAIjD,SAASC,mBAAmB,QAAQ,2BAA0B;AAE9D,MAAMC,cAAc,CAClBC,YACAC,uBACwB,CAAA;QACxBA;QACAC,gBAAgB;QAChBF;QACAG,WAAW;QACXC,2BAA2B,IAAM;IACnC,CAAA;AAEA,MAAMC,aAAa,CAACC,OAAO,OAAO,GAAkB,CAAA;QAClDC,KAAK;YACHC,MAAM;gBACJR,YAAY;gBACZS,IAAI;gBACJC,SAAS;oBAAC;wBAAEC,QAAQ;oBAAW;iBAAE;YACnC;QACF;QACAL;IACF,CAAA;AAEAZ,SAAS,uBAAuB;IAC9BE,GAAG,mFAAmF;QACpF,MAAMgB,eAAef,GAAGgB,EAAE,CAAC,IAAO,CAAA;gBAAEC,WAAW;oBAAEC,QAAQ;gBAAK;YAAE,CAAA;QAChE,MAAMf,aAA+B;YACnCM,MAAM;YACNU,QAAQ;gBAAEC,MAAML;YAAa;YAC7BM,QAAQ,EAAE;QACZ;QACA,MAAMC,SAAS;YACbC,YAAY;gBACVC,aAAa;oBACXJ,MAAM,IAAO,CAAA;4BAAEK,UAAU;gCAAEC,YAAY;4BAAK;wBAAE,CAAA;gBAChD;YACF;QACF;QAEAzB,oBAAoB;YAAEqB;YAAQK,QAAQ;gBAACzB,YAAYC;aAAY;QAAC;QAEhEL,OAAOK,WAAWgB,MAAM,EAAEC,MAAMQ,IAAI,CAACb;QACrC,MAAMjB,OAAOwB,OAAOC,UAAU,EAAEC,aAAaJ,OAAOZ,eAAeqB,QAAQ,CAACC,OAAO,CAAC;YAClFC,KAAK;gBAAC;oBAAEN,UAAU;wBAAEC,YAAY;oBAAK;gBAAE;gBAAG;oBAAEZ,QAAQ;wBAAEkB,IAAI;4BAAC;yBAAW;oBAAC;gBAAE;aAAE;QAC7E;QACA,MAAMlC,OAAOwB,OAAOC,UAAU,EAAEC,aAAaJ,OAAOZ,WAAW,WAAWqB,QAAQ,CAACC,OAAO,CAAC;YACzFL,UAAU;gBAAEC,YAAY;YAAK;QAC/B;QACA5B,OAAOiB,cAAckB,GAAG,CAACC,gBAAgB;IAC3C;IAEAnC,GAAG,gEAAgE;QACjE,MAAMI,aAA+B;YAAEM,MAAM;YAASY,QAAQ,EAAE;QAAC;QACjE,MAAMC,SAAS,CAAC;QAEhBrB,oBAAoB;YAAEqB;YAAQK,QAAQ;gBAACzB,YAAYC;aAAY;QAAC;QAEhE,MAAML,OAAOwB,OAAOC,UAAU,EAAEC,aAAaW,SAAS3B,eAAeqB,QAAQ,CAACD,IAAI,CAAC;IACrF;IAEA7B,GAAG,wEAAwE;QACzE,MAAMqC,iBAAiB;YAAEnB,WAAW;gBAAEC,QAAQ;YAAK;QAAE;QACrD,MAAMH,eAAef,GAAGgB,EAAE,CAAC,IAAMoB;QACjC,MAAMhC,uBAAuBJ,GAAGgB,EAAE,CAAC,CAAC,EAAEqB,YAAY,EAAE,GAAKA;QACzD,MAAMlC,aAA+B;YACnCM,MAAM;YACNU,QAAQ;gBAAEC,MAAML;YAAa;YAC7BM,QAAQ,EAAE;QACZ;QACA,MAAMC,SAAS,CAAC;QAEhBrB,oBAAoB;YAClBqB;YACAK,QAAQ;gBAACzB,YAAYC,YAAYC;aAAsB;QACzD;QAEAN,OAAOwB,OAAOC,UAAU,EAAEe,aAAa;QACvC,MAAMxC,OAAOK,WAAWgB,MAAM,EAAEC,OAAOZ,eAAeqB,QAAQ,CAACC,OAAO,CAAC;YACrEC,KAAK;gBAACK;gBAAgB;oBAAEtB,QAAQ;wBAAEkB,IAAI;4BAAC;yBAAW;oBAAC;gBAAE;aAAE;QACzD;QACAlC,OAAOM,sBAAsBmC,oBAAoB,CAC/CzC,OAAO0C,gBAAgB,CAAC;YAAEC,WAAW;QAAO;IAEhD;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Config, Field, SanitizedConfig } from 'payload';
|
|
2
2
|
import type { MultiTenantPluginConfig } from '../types.js';
|
|
3
|
-
type AddFilterOptionsToFieldsArgs
|
|
3
|
+
type AddFilterOptionsToFieldsArgs = {
|
|
4
4
|
blockReferencesWithFilters: string[];
|
|
5
5
|
config: Config | SanitizedConfig;
|
|
6
6
|
fields: Field[];
|
|
@@ -10,8 +10,8 @@ type AddFilterOptionsToFieldsArgs<ConfigType = unknown> = {
|
|
|
10
10
|
tenantsArrayFieldName: string;
|
|
11
11
|
tenantsArrayTenantFieldName: string;
|
|
12
12
|
tenantsCollectionSlug: string;
|
|
13
|
-
userHasAccessToAllTenants: Required<MultiTenantPluginConfig
|
|
13
|
+
userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants'];
|
|
14
14
|
};
|
|
15
|
-
export declare function addFilterOptionsToFields
|
|
15
|
+
export declare function addFilterOptionsToFields({ blockReferencesWithFilters, config, fields, tenantEnabledCollectionSlugs, tenantEnabledGlobalSlugs, tenantFieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, userHasAccessToAllTenants, }: AddFilterOptionsToFieldsArgs): Field[];
|
|
16
16
|
export {};
|
|
17
17
|
//# sourceMappingURL=addFilterOptionsToFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addFilterOptionsToFields.d.ts","sourceRoot":"","sources":["../../src/utilities/addFilterOptionsToFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,MAAM,EAAE,KAAK,EAAqB,eAAe,EAAE,MAAM,SAAS,CAAA;AAEvF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAK1D,KAAK,4BAA4B,
|
|
1
|
+
{"version":3,"file":"addFilterOptionsToFields.d.ts","sourceRoot":"","sources":["../../src/utilities/addFilterOptionsToFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,MAAM,EAAE,KAAK,EAAqB,eAAe,EAAE,MAAM,SAAS,CAAA;AAEvF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAK1D,KAAK,4BAA4B,GAAG;IAClC,0BAA0B,EAAE,MAAM,EAAE,CAAA;IACpC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAA;IAChC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,4BAA4B,EAAE,MAAM,EAAE,CAAA;IACtC,wBAAwB,EAAE,MAAM,EAAE,CAAA;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,yBAAyB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;CAC1F,CAAA;AAED,wBAAgB,wBAAwB,CAAC,EACvC,0BAA0B,EAC1B,MAAM,EACN,MAAM,EACN,4BAA4B,EAC5B,wBAAwB,EACxB,eAAe,EACf,qBAAsD,EACtD,2BAAkE,EAClE,qBAAqB,EACrB,yBAAyB,GAC1B,EAAE,4BAA4B,GAAG,KAAK,EAAE,CA6HxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addFilterOptionsToFields.ts"],"sourcesContent":["import type { Block, Config, Field, RelationshipField, SanitizedConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js'\n\ntype AddFilterOptionsToFieldsArgs<ConfigType = unknown> = {\n blockReferencesWithFilters: string[]\n config: Config | SanitizedConfig\n fields: Field[]\n tenantEnabledCollectionSlugs: string[]\n tenantEnabledGlobalSlugs: string[]\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\nexport function addFilterOptionsToFields<ConfigType = unknown>({\n blockReferencesWithFilters,\n config,\n fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n}: AddFilterOptionsToFieldsArgs<ConfigType>): Field[] {\n const newFields = []\n for (const field of fields) {\n let newField: Field = { ...field }\n if (newField.type === 'relationship') {\n let hasTenantRelationsips = false\n /**\n * Adjusts relationship fields to filter by tenant\n * and ensures relationTo cannot be a tenant global collection\n */\n if (typeof newField.relationTo === 'string') {\n if (tenantEnabledGlobalSlugs.includes(newField.relationTo)) {\n throw new Error(\n `The collection ${newField.relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(newField.relationTo)) {\n hasTenantRelationsips = true\n }\n } else {\n for (const relationTo of newField.relationTo) {\n if (tenantEnabledGlobalSlugs.includes(relationTo)) {\n throw new Error(\n `The collection ${relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(relationTo)) {\n hasTenantRelationsips = true\n }\n }\n }\n\n if (hasTenantRelationsips) {\n newField = addRelationshipFilter({\n field: newField as RelationshipField,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n }\n\n if (\n newField.type === 'row' ||\n newField.type === 'array' ||\n newField.type === 'collapsible' ||\n newField.type === 'group'\n ) {\n newField.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: newField.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n\n if (newField.type === 'blocks') {\n const newBlocks: (Block | string)[] = []\n newField.blocks.forEach((_block) => {\n let block: Block | undefined\n let isReference = false\n\n if (typeof _block === 'string') {\n isReference = true\n if (!blockReferencesWithFilters.includes(_block)) {\n block = config?.blocks?.find((b) => b.slug === _block)\n blockReferencesWithFilters.push(_block)\n }\n } else {\n // Create a shallow copy to avoid mutating the original block reference\n block = { ..._block }\n }\n\n if (block?.fields) {\n block.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: block.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n\n newBlocks.push(isReference ? _block : block!)\n })\n newField.blocks = newBlocks\n }\n\n if (newField.type === 'tabs') {\n newField.tabs = newField.tabs.map((tab) => {\n const newTab = { ...tab }\n newTab.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: tab.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n return newTab\n })\n }\n\n newFields.push(newField)\n }\n\n return newFields\n}\n\ntype AddFilterArgs<ConfigType = unknown> = {\n field: RelationshipField\n tenantEnabledCollectionSlugs: string[]\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nfunction addRelationshipFilter<ConfigType = unknown>({\n field,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n}: AddFilterArgs<ConfigType>): Field {\n // User specified filter\n const originalFilter = field.filterOptions\n field.filterOptions = async (args) => {\n const originalFilterResult =\n typeof originalFilter === 'function' ? await originalFilter(args) : (originalFilter ?? true)\n\n // If the relationTo is not a tenant enabled collection, return early\n if (args.relationTo && !tenantEnabledCollectionSlugs.includes(args.relationTo)) {\n return originalFilterResult\n }\n\n // If the original filtr returns false, return early\n if (originalFilterResult === false) {\n return false\n }\n\n // Custom tenant filter\n const tenantFilterResults = filterDocumentsByTenants({\n docTenantID: args.data?.[tenantFieldName],\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n // If the tenant filter returns null, meaning no tenant filter, just use the original filter\n if (tenantFilterResults === null) {\n return originalFilterResult\n }\n\n // If the original filter returns true, just use the tenant filter\n if (originalFilterResult === true) {\n return tenantFilterResults\n }\n\n return {\n and: [originalFilterResult, tenantFilterResults],\n }\n }\n\n return field\n}\n"],"names":["defaults","filterDocumentsByTenants","addFilterOptionsToFields","blockReferencesWithFilters","config","fields","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","userHasAccessToAllTenants","newFields","field","newField","type","hasTenantRelationsips","relationTo","includes","Error","addRelationshipFilter","newBlocks","blocks","forEach","_block","block","isReference","find","b","slug","push","tabs","map","tab","newTab","originalFilter","filterOptions","args","originalFilterResult","tenantFilterResults","docTenantID","data","filterFieldName","req","and"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addFilterOptionsToFields.ts"],"sourcesContent":["import type { Block, Config, Field, RelationshipField, SanitizedConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js'\n\ntype AddFilterOptionsToFieldsArgs = {\n blockReferencesWithFilters: string[]\n config: Config | SanitizedConfig\n fields: Field[]\n tenantEnabledCollectionSlugs: string[]\n tenantEnabledGlobalSlugs: string[]\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}\n\nexport function addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n}: AddFilterOptionsToFieldsArgs): Field[] {\n const newFields = []\n for (const field of fields) {\n let newField: Field = { ...field }\n if (newField.type === 'relationship') {\n let hasTenantRelationsips = false\n /**\n * Adjusts relationship fields to filter by tenant\n * and ensures relationTo cannot be a tenant global collection\n */\n if (typeof newField.relationTo === 'string') {\n if (tenantEnabledGlobalSlugs.includes(newField.relationTo)) {\n throw new Error(\n `The collection ${newField.relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(newField.relationTo)) {\n hasTenantRelationsips = true\n }\n } else {\n for (const relationTo of newField.relationTo) {\n if (tenantEnabledGlobalSlugs.includes(relationTo)) {\n throw new Error(\n `The collection ${relationTo} is a global collection and cannot be related to a tenant enabled collection.`,\n )\n }\n if (tenantEnabledCollectionSlugs.includes(relationTo)) {\n hasTenantRelationsips = true\n }\n }\n }\n\n if (hasTenantRelationsips) {\n newField = addRelationshipFilter({\n field: newField as RelationshipField,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n }\n\n if (\n newField.type === 'row' ||\n newField.type === 'array' ||\n newField.type === 'collapsible' ||\n newField.type === 'group'\n ) {\n newField.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: newField.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n\n if (newField.type === 'blocks') {\n const newBlocks: (Block | string)[] = []\n newField.blocks.forEach((_block) => {\n let block: Block | undefined\n let isReference = false\n\n if (typeof _block === 'string') {\n isReference = true\n if (!blockReferencesWithFilters.includes(_block)) {\n block = config?.blocks?.find((b) => b.slug === _block)\n blockReferencesWithFilters.push(_block)\n }\n } else {\n // Create a shallow copy to avoid mutating the original block reference\n block = { ..._block }\n }\n\n if (block?.fields) {\n block.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: block.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n }\n\n newBlocks.push(isReference ? _block : block!)\n })\n newField.blocks = newBlocks\n }\n\n if (newField.type === 'tabs') {\n newField.tabs = newField.tabs.map((tab) => {\n const newTab = { ...tab }\n newTab.fields = addFilterOptionsToFields({\n blockReferencesWithFilters,\n config,\n fields: tab.fields,\n tenantEnabledCollectionSlugs,\n tenantEnabledGlobalSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n return newTab\n })\n }\n\n newFields.push(newField)\n }\n\n return newFields\n}\n\ntype AddFilterArgs = {\n field: RelationshipField\n tenantEnabledCollectionSlugs: string[]\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}\nfunction addRelationshipFilter({\n field,\n tenantEnabledCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n}: AddFilterArgs): Field {\n // User specified filter\n const originalFilter = field.filterOptions\n field.filterOptions = async (args) => {\n const originalFilterResult =\n typeof originalFilter === 'function' ? await originalFilter(args) : (originalFilter ?? true)\n\n // If the relationTo is not a tenant enabled collection, return early\n if (args.relationTo && !tenantEnabledCollectionSlugs.includes(args.relationTo)) {\n return originalFilterResult\n }\n\n // If the original filtr returns false, return early\n if (originalFilterResult === false) {\n return false\n }\n\n // Custom tenant filter\n const tenantFilterResults = filterDocumentsByTenants({\n docTenantID: args.data?.[tenantFieldName],\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n // If the tenant filter returns null, meaning no tenant filter, just use the original filter\n if (tenantFilterResults === null) {\n return originalFilterResult\n }\n\n // If the original filter returns true, just use the tenant filter\n if (originalFilterResult === true) {\n return tenantFilterResults\n }\n\n return {\n and: [originalFilterResult, tenantFilterResults],\n }\n }\n\n return field\n}\n"],"names":["defaults","filterDocumentsByTenants","addFilterOptionsToFields","blockReferencesWithFilters","config","fields","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","userHasAccessToAllTenants","newFields","field","newField","type","hasTenantRelationsips","relationTo","includes","Error","addRelationshipFilter","newBlocks","blocks","forEach","_block","block","isReference","find","b","slug","push","tabs","map","tab","newTab","originalFilter","filterOptions","args","originalFilterResult","tenantFilterResults","docTenantID","data","filterFieldName","req","and"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combineFilters.d.ts","sourceRoot":"","sources":["../../src/utilities/combineFilters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,SAAS,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,YAAY,EAAE,UAAU,CAAA;CACzB,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"combineFilters.d.ts","sourceRoot":"","sources":["../../src/utilities/combineFilters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,SAAS,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,YAAY,EAAE,UAAU,CAAA;CACzB,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,cAAc,iCACM,IAAI,KAAG,UA8BrC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractID.d.ts","sourceRoot":"","sources":["../../src/utilities/extractID.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"extractID.d.ts","sourceRoot":"","sources":["../../src/utilities/extractID.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,cAC1C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAClC,MAMF,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateCookie.d.ts","sourceRoot":"","sources":["../../src/utilities/generateCookie.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oBAAoB,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACpC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACpC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,oBAAoB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"generateCookie.d.ts","sourceRoot":"","sources":["../../src/utilities/generateCookie.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oBAAoB,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACpC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACpC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,oBAAoB,GAAG,OAAO,QACrD,aAAa,KAClB,oBAAoB,SAAS,IAAI,GAAG,YAAY,GAAG,MA6ErD,CAAA"}
|
|
@@ -3,6 +3,6 @@ type Args = {
|
|
|
3
3
|
collectionSlug: CollectionSlug;
|
|
4
4
|
payload: Payload;
|
|
5
5
|
};
|
|
6
|
-
export declare const getCollectionIDType: ({ collectionSlug, payload }: Args) =>
|
|
6
|
+
export declare const getCollectionIDType: ({ collectionSlug, payload }: Args) => 'number' | 'text';
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=getCollectionIDType.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCollectionIDType.d.ts","sourceRoot":"","sources":["../../src/utilities/getCollectionIDType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtD,KAAK,IAAI,GAAG;IACV,cAAc,EAAE,cAAc,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AACD,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"getCollectionIDType.d.ts","sourceRoot":"","sources":["../../src/utilities/getCollectionIDType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtD,KAAK,IAAI,GAAG;IACV,cAAc,EAAE,cAAc,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AACD,eAAO,MAAM,mBAAmB,gCAAiC,IAAI,KAAG,QAAQ,GAAG,MAElF,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Payload, ServerAdapter,
|
|
1
|
+
import type { Payload, ServerAdapter, User, ViewTypes } from 'payload';
|
|
2
2
|
import type { MultiTenantPluginConfig } from '../types.js';
|
|
3
3
|
type Args = {
|
|
4
4
|
/**
|
|
@@ -17,8 +17,8 @@ type Args = {
|
|
|
17
17
|
tenantsArrayTenantFieldName: string;
|
|
18
18
|
tenantsCollectionSlug: string;
|
|
19
19
|
useAsTitle: string;
|
|
20
|
-
user?:
|
|
21
|
-
userHasAccessToAllTenants: Required<MultiTenantPluginConfig
|
|
20
|
+
user?: User;
|
|
21
|
+
userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants'];
|
|
22
22
|
view: ViewTypes;
|
|
23
23
|
};
|
|
24
24
|
export declare function getGlobalViewRedirect({ slug: collectionSlug, docID, headers, payload, server, tenantFieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, useAsTitle, user, userHasAccessToAllTenants, view, }: Args): Promise<string | void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAItE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAM1D,KAAK,IAAI,GAAG;IACV;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,yBAAyB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;IACzF,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EAAE,cAAc,EACpB,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,yBAAyB,EACzB,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmG/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, ServerAdapter,
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, ServerAdapter, User, ViewTypes } from 'payload'\n\nimport { formatAdminURL, hasAutosaveEnabled } from 'payload/shared'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\nimport { getTenantOptions } from './getTenantOptions.js'\n\ntype Args = {\n /**\n * This is no longer needed and is handled internally.\n *\n * @deprecated\n */\n basePath?: string\n docID?: number | string\n headers: Headers\n payload: Payload\n server: ServerAdapter\n slug: string\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug: collectionSlug,\n docID,\n headers,\n payload,\n server,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\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: `/${string}` | void = undefined\n\n if (!user) {\n return server.unauthorized()\n }\n\n if (!tenant) {\n const tenantOptions = await getTenantOptions({\n payload,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n })\n\n tenant = tenantOptions[0]?.value || null\n }\n\n if (tenant) {\n try {\n const globalTenantDocQuery = await payload.find({\n collection: collectionSlug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: {\n id: true,\n },\n where: {\n [tenantFieldName]: {\n in: [tenant],\n },\n },\n })\n\n const globalTenantDocID = globalTenantDocQuery?.docs?.[0]?.id\n\n if (view === 'document') {\n // global tenant document edit view\n if (globalTenantDocID && docID !== globalTenantDocID) {\n // tenant document already exists but does not match current route docID\n // redirect to matching tenant docID from query\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else if (docID && !globalTenantDocID) {\n // a docID was found in the route but no global document with this tenant exists\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n } else if (view === 'list') {\n // global tenant document list view\n if (globalTenantDocID) {\n // tenant document exists, redirect from list view to the document edit view\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else {\n // no matching document was found for the current tenant\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n }\n } catch (e: unknown) {\n const prefix = `${e && typeof e === 'object' && 'message' in e && typeof e.message === 'string' ? `${e.message} - ` : ''}`\n payload.logger.error(e, `${prefix}Multi Tenant Redirect Error`)\n }\n } else {\n // no tenants were found, redirect to the admin view\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n path: '',\n serverURL: payload.config.serverURL,\n })\n }\n\n if (redirectRoute) {\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n path: redirectRoute,\n serverURL: payload.config.serverURL,\n })\n }\n\n // no redirect is needed\n // the current route is valid\n return undefined\n}\n\ntype GenerateCreateArgs = {\n collectionSlug: string\n payload: Payload\n tenantID: number | string\n}\n/**\n * Generate a redirect URL for creating a new document in a multi-tenant collection.\n *\n * If autosave is enabled on the collection, we need to create the document and then redirect to it.\n * Otherwise we can redirect to the default create route.\n */\nasync function generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID,\n}: GenerateCreateArgs): Promise<`/${string}` | undefined> {\n const collectionConfig = payload.collections[collectionSlug]?.config\n if (hasAutosaveEnabled(collectionConfig!)) {\n // Autosave is enabled, create a document first\n try {\n const doc = await payload.create({\n collection: collectionSlug,\n data: {\n tenant: tenantID,\n },\n depth: 0,\n draft: true,\n select: {\n id: true,\n },\n })\n return `/collections/${collectionSlug}/${doc.id}`\n } catch (error) {\n payload.logger.error(\n error,\n `Error creating autosave global multi tenant document for ${collectionSlug}`,\n )\n }\n\n return '/'\n }\n\n // Autosave is not enabled, redirect to default create route\n return `/collections/${collectionSlug}/create`\n}\n"],"names":["formatAdminURL","hasAutosaveEnabled","getCollectionIDType","getTenantFromCookie","getTenantOptions","getGlobalViewRedirect","slug","collectionSlug","docID","headers","payload","server","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","view","idType","tenant","redirectRoute","undefined","unauthorized","tenantOptions","value","globalTenantDocQuery","find","collection","depth","limit","pagination","select","id","where","in","globalTenantDocID","docs","generateCreateRedirect","tenantID","e","prefix","message","logger","error","adminRoute","config","routes","admin","path","serverURL","collectionConfig","collections","doc","create","data","draft"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OptionObject, Payload,
|
|
1
|
+
import type { OptionObject, Payload, User } from 'payload';
|
|
2
2
|
import type { MultiTenantPluginConfig } from '../types.js';
|
|
3
3
|
export declare const getTenantOptions: ({ payload, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, useAsTitle, user, userHasAccessToAllTenants, }: {
|
|
4
4
|
payload: Payload;
|
|
@@ -6,7 +6,7 @@ export declare const getTenantOptions: ({ payload, tenantsArrayFieldName, tenant
|
|
|
6
6
|
tenantsArrayTenantFieldName: string;
|
|
7
7
|
tenantsCollectionSlug: string;
|
|
8
8
|
useAsTitle: string;
|
|
9
|
-
user:
|
|
10
|
-
userHasAccessToAllTenants: Required<MultiTenantPluginConfig
|
|
9
|
+
user: User;
|
|
10
|
+
userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants'];
|
|
11
11
|
}) => Promise<OptionObject[]>;
|
|
12
12
|
//# sourceMappingURL=getTenantOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTenantOptions.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"getTenantOptions.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE1D,eAAO,MAAM,gBAAgB,yIAQ1B;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,IAAI,CAAA;IACV,yBAAyB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;CAC1F,KAAG,OAAO,CAAC,YAAY,EAAE,CAuDzB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getTenantOptions.ts"],"sourcesContent":["import type { OptionObject, Payload,
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getTenantOptions.ts"],"sourcesContent":["import type { OptionObject, Payload, User } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nexport const getTenantOptions = async ({\n payload,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n}: {\n payload: Payload\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user: User\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}): Promise<OptionObject[]> => {\n let tenantOptions: OptionObject[] = []\n\n if (!user) {\n return tenantOptions\n }\n\n const isOrderable = payload.collections[tenantsCollectionSlug]?.config?.orderable || false\n\n const userTenantIds = !userHasAccessToAllTenants(user)\n ? (\n ((user as Record<string, unknown>)[tenantsArrayFieldName] as {\n [key: string]: unknown\n }[]) || []\n ).map((tenantRow) => {\n const tenantField = tenantRow[tenantsArrayTenantFieldName]\n if (typeof tenantField === 'string' || typeof tenantField === 'number') {\n return tenantField\n }\n if (tenantField && typeof tenantField === 'object' && 'id' in tenantField) {\n return tenantField.id as number | string\n }\n })\n : undefined\n\n if (userTenantIds !== undefined && userTenantIds.length === 0) {\n return tenantOptions\n }\n\n const tenants = await payload.find({\n collection: tenantsCollectionSlug,\n depth: 0,\n limit: 0,\n overrideAccess: false,\n select: {\n [useAsTitle]: true,\n ...(isOrderable && { _order: true }),\n },\n sort: isOrderable ? '_order' : useAsTitle,\n user,\n ...(userTenantIds && {\n where: {\n id: {\n in: userTenantIds,\n },\n },\n }),\n })\n\n tenantOptions = tenants.docs.map((doc) => ({\n label: String(doc[useAsTitle as 'id']),\n value: doc.id as string,\n }))\n\n return tenantOptions\n}\n"],"names":["getTenantOptions","payload","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","tenantOptions","isOrderable","collections","config","orderable","userTenantIds","map","tenantRow","tenantField","id","undefined","length","tenants","find","collection","depth","limit","overrideAccess","select","_order","sort","where","in","docs","doc","label","String","value"],"mappings":"AAIA,OAAO,MAAMA,mBAAmB,OAAO,EACrCC,OAAO,EACPC,qBAAqB,EACrBC,2BAA2B,EAC3BC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,yBAAyB,EAS1B;IACC,IAAIC,gBAAgC,EAAE;IAEtC,IAAI,CAACF,MAAM;QACT,OAAOE;IACT;IAEA,MAAMC,cAAcR,QAAQS,WAAW,CAACN,sBAAsB,EAAEO,QAAQC,aAAa;IAErF,MAAMC,gBAAgB,CAACN,0BAA0BD,QAC7C,AACE,CAAA,AAAC,AAACA,IAAgC,CAACJ,sBAAsB,IAEjD,EAAE,AAAD,EACTY,GAAG,CAAC,CAACC;QACL,MAAMC,cAAcD,SAAS,CAACZ,4BAA4B;QAC1D,IAAI,OAAOa,gBAAgB,YAAY,OAAOA,gBAAgB,UAAU;YACtE,OAAOA;QACT;QACA,IAAIA,eAAe,OAAOA,gBAAgB,YAAY,QAAQA,aAAa;YACzE,OAAOA,YAAYC,EAAE;QACvB;IACF,KACAC;IAEJ,IAAIL,kBAAkBK,aAAaL,cAAcM,MAAM,KAAK,GAAG;QAC7D,OAAOX;IACT;IAEA,MAAMY,UAAU,MAAMnB,QAAQoB,IAAI,CAAC;QACjCC,YAAYlB;QACZmB,OAAO;QACPC,OAAO;QACPC,gBAAgB;QAChBC,QAAQ;YACN,CAACrB,WAAW,EAAE;YACd,GAAII,eAAe;gBAAEkB,QAAQ;YAAK,CAAC;QACrC;QACAC,MAAMnB,cAAc,WAAWJ;QAC/BC;QACA,GAAIO,iBAAiB;YACnBgB,OAAO;gBACLZ,IAAI;oBACFa,IAAIjB;gBACN;YACF;QACF,CAAC;IACH;IAEAL,gBAAgBY,QAAQW,IAAI,CAACjB,GAAG,CAAC,CAACkB,MAAS,CAAA;YACzCC,OAAOC,OAAOF,GAAG,CAAC3B,WAAmB;YACrC8B,OAAOH,IAAIf,EAAE;QACf,CAAA;IAEA,OAAOT;AACT,EAAC"}
|
|
@@ -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;AAK/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,
|
|
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,EAoBR,CAAA"}
|
|
@@ -10,7 +10,8 @@ import { extractID } from './extractID.js';
|
|
|
10
10
|
}
|
|
11
11
|
const tenantsArrayFieldName = options?.tenantsArrayFieldName || defaults.tenantsArrayFieldName;
|
|
12
12
|
const tenantsArrayTenantFieldName = options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName;
|
|
13
|
-
|
|
13
|
+
const tenantsArray = user[tenantsArrayFieldName];
|
|
14
|
+
return (Array.isArray(tenantsArray) ? tenantsArray : [])?.reduce((acc, row)=>{
|
|
14
15
|
if (row[tenantsArrayTenantFieldName]) {
|
|
15
16
|
acc.push(extractID(row[tenantsArrayTenantFieldName]));
|
|
16
17
|
}
|
|
@@ -1 +1 @@
|
|
|
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 tenantsArrayFieldName = options?.tenantsArrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n return (\n (Array.isArray(
|
|
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 tenantsArrayFieldName = options?.tenantsArrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n const tenantsArray = (user as Record<string, unknown>)[tenantsArrayFieldName]\n\n return (\n (Array.isArray(tenantsArray) ? tenantsArray : [])?.reduce<IDType[]>((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","tenantsArray","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,MAAME,wBAAwBD,SAASC,yBAAyBL,SAASK,qBAAqB;IAC9F,MAAMC,8BACJF,SAASE,+BAA+BN,SAASM,2BAA2B;IAE9E,MAAMC,eAAe,AAACJ,IAAgC,CAACE,sBAAsB;IAE7E,OACE,AAACG,CAAAA,MAAMC,OAAO,CAACF,gBAAgBA,eAAe,EAAE,AAAD,GAAIG,OAAiB,CAACC,KAAKC;QACxE,IAAIA,GAAG,CAACN,4BAA4B,EAAE;YACpCK,IAAIE,IAAI,CAACZ,UAAkBW,GAAG,CAACN,4BAA4B;QAC7D;QAEA,OAAOK;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"miniChalk.d.ts","sourceRoot":"","sources":["../../src/utilities/miniChalk.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,SAAS;
|
|
1
|
+
{"version":3,"file":"miniChalk.d.ts","sourceRoot":"","sources":["../../src/utilities/miniChalk.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,SAAS;IACpB,IAAI,QAAQ,MAAM;IAClB,IAAI,QAAQ,MAAM;IAClB,IAAI,QAAQ,MAAM;IAClB,GAAG,QAAQ,MAAM;IACjB,KAAK,QAAQ,MAAM;IACnB,OAAO,QAAQ,MAAM;IACrB,GAAG,QAAQ,MAAM;IACjB,SAAS,QAAQ,MAAM;IACvB,KAAK,QAAQ,MAAM;IACnB,MAAM,QAAQ,MAAM;IAGpB,OAAO,QAAQ,MAAM;IACrB,UAAU,QAAQ,MAAM;CACzB,CAAA"}
|