@payloadcms/plugin-multi-tenant 3.24.0 → 3.25.0-canary.3d5c763

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 (33) hide show
  1. package/dist/exports/client.d.ts +1 -0
  2. package/dist/exports/client.d.ts.map +1 -1
  3. package/dist/exports/client.js +1 -0
  4. package/dist/exports/client.js.map +1 -1
  5. package/dist/hooks/afterTenantDelete.d.ts.map +1 -1
  6. package/dist/hooks/afterTenantDelete.js +5 -1
  7. package/dist/hooks/afterTenantDelete.js.map +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +6 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/providers/TenantSelectionProvider/index.client.d.ts +17 -0
  12. package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
  13. package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
  14. package/dist/utilities/addCollectionAccess.d.ts +3 -1
  15. package/dist/utilities/addCollectionAccess.d.ts.map +1 -1
  16. package/dist/utilities/addCollectionAccess.js +5 -1
  17. package/dist/utilities/addCollectionAccess.js.map +1 -1
  18. package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
  19. package/dist/utilities/getGlobalViewRedirect.js +1 -0
  20. package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
  21. package/dist/utilities/getTenantAccess.d.ts +3 -1
  22. package/dist/utilities/getTenantAccess.d.ts.map +1 -1
  23. package/dist/utilities/getTenantAccess.js +6 -2
  24. package/dist/utilities/getTenantAccess.js.map +1 -1
  25. package/dist/utilities/getUserTenantIDs.d.ts +4 -1
  26. package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
  27. package/dist/utilities/getUserTenantIDs.js +6 -4
  28. package/dist/utilities/getUserTenantIDs.js.map +1 -1
  29. package/dist/utilities/withTenantAccess.d.ts +6 -2
  30. package/dist/utilities/withTenantAccess.d.ts.map +1 -1
  31. package/dist/utilities/withTenantAccess.js +19 -3
  32. package/dist/utilities/withTenantAccess.js.map +1 -1
  33. package/package.json +5 -5
@@ -1,3 +1,4 @@
1
1
  export { TenantField } from '../components/TenantField/index.client.js';
2
2
  export { TenantSelector } from '../components/TenantSelector/index.js';
3
+ export { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js';
3
4
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sDAAsD,CAAA"}
@@ -1,4 +1,5 @@
1
1
  export { TenantField } from '../components/TenantField/index.client.js';
2
2
  export { TenantSelector } from '../components/TenantSelector/index.js';
3
+ export { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js';
3
4
 
4
5
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { TenantField } from '../components/TenantField/index.client.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\n"],"names":["TenantField","TenantSelector"],"mappings":"AAAA,SAASA,WAAW,QAAQ,4CAA2C;AACvE,SAASC,cAAc,QAAQ,wCAAuC"}
1
+ {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { TenantField } from '../components/TenantField/index.client.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\nexport { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js'\n"],"names":["TenantField","TenantSelector","useTenantSelection"],"mappings":"AAAA,SAASA,WAAW,QAAQ,4CAA2C;AACvE,SAASC,cAAc,QAAQ,wCAAuC;AACtE,SAASC,kBAAkB,QAAQ,uDAAsD"}
@@ -1 +1 @@
1
- {"version":3,"file":"afterTenantDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterTenantDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAGjB,MAAM,SAAS,CAAA;AAShB,KAAK,IAAI,GAAG;IACV,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B,EAAE,MAAM,CAAA;IAClC,gCAAgC,EAAE,MAAM,CAAA;CACzC,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,mJAQ1B,IAAI,SAiBN,CAAA;AAED,eAAO,MAAM,iBAAiB,uIAQzB,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,KAAG,yBAgE7B,CAAA"}
1
+ {"version":3,"file":"afterTenantDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterTenantDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAGjB,MAAM,SAAS,CAAA;AAShB,KAAK,IAAI,GAAG;IACV,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B,EAAE,MAAM,CAAA;IAClC,gCAAgC,EAAE,MAAM,CAAA;CACzC,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,mJAQ1B,IAAI,SAiBN,CAAA;AAED,eAAO,MAAM,iBAAiB,uIAQzB,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,KAAG,yBAsE7B,CAAA"}
@@ -66,7 +66,11 @@ export const afterTenantDelete = ({ enabledSlugs, tenantFieldName, tenantsCollec
66
66
  id: user.id,
67
67
  collection: usersSlug,
68
68
  data: {
69
- tenants: (user.tenants || []).filter(({ tenant: tenantID })=>tenantID !== id)
69
+ [usersTenantsArrayFieldName]: (user[usersTenantsArrayFieldName] || []).filter((row)=>{
70
+ if (row[usersTenantsArrayTenantFieldName]) {
71
+ return row[usersTenantsArrayTenantFieldName] !== id;
72
+ }
73
+ })
70
74
  }
71
75
  }));
72
76
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/afterTenantDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n JsonObject,\n PaginatedDocs,\n} from 'payload'\n\nimport { generateCookie, mergeHeaders } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getCollectionIDType } from '../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\n\ntype Args = {\n collection: CollectionConfig\n enabledSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n usersSlug: string\n usersTenantsArrayFieldName: string\n usersTenantsArrayTenantFieldName: string\n}\n/**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\nexport const addTenantCleanup = ({\n collection,\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n}: Args) => {\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks?.afterDelete) {\n collection.hooks.afterDelete = []\n }\n collection.hooks.afterDelete.push(\n afterTenantDelete({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }),\n )\n}\n\nexport const afterTenantDelete =\n ({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }: Omit<Args, 'collection'>): CollectionAfterDeleteHook =>\n async ({ id, req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const currentTenantCookieID = getTenantFromCookie(req.headers, idType)\n if (currentTenantCookieID === id) {\n const newHeaders = new Headers({\n 'Set-Cookie': generateCookie<string>({\n name: 'payload-tenant',\n expires: new Date(Date.now() - 1000),\n path: '/',\n returnCookieAsObject: false,\n value: '',\n }),\n })\n\n req.responseHeaders = req.responseHeaders\n ? mergeHeaders(req.responseHeaders, newHeaders)\n : newHeaders\n }\n const cleanupPromises: Promise<JsonObject>[] = []\n enabledSlugs.forEach((slug) => {\n cleanupPromises.push(\n req.payload.delete({\n collection: slug,\n where: {\n [tenantFieldName]: {\n equals: id,\n },\n },\n }),\n )\n })\n\n try {\n const usersWithTenant = (await req.payload.find({\n collection: usersSlug,\n depth: 0,\n limit: 0,\n where: {\n [`${usersTenantsArrayFieldName}.${usersTenantsArrayTenantFieldName}`]: {\n equals: id,\n },\n },\n })) as PaginatedDocs<UserWithTenantsField>\n\n usersWithTenant?.docs?.forEach((user) => {\n cleanupPromises.push(\n req.payload.update({\n id: user.id,\n collection: usersSlug,\n data: {\n tenants: (user.tenants || []).filter(({ tenant: tenantID }) => tenantID !== id),\n },\n }),\n )\n })\n } catch (e) {\n console.error('Error deleting tenants from users:', e)\n }\n\n await Promise.all(cleanupPromises)\n }\n"],"names":["generateCookie","mergeHeaders","getCollectionIDType","getTenantFromCookie","addTenantCleanup","collection","enabledSlugs","tenantFieldName","tenantsCollectionSlug","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","hooks","afterDelete","push","afterTenantDelete","id","req","idType","collectionSlug","payload","currentTenantCookieID","headers","newHeaders","Headers","name","expires","Date","now","path","returnCookieAsObject","value","responseHeaders","cleanupPromises","forEach","slug","delete","where","equals","usersWithTenant","find","depth","limit","docs","user","update","data","tenants","filter","tenant","tenantID","e","console","error","Promise","all"],"mappings":"AAOA,SAASA,cAAc,EAAEC,YAAY,QAAQ,UAAS;AAItD,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AAWzE;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,UAAU,EACVC,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EAC3B;IACL,IAAI,CAACN,WAAWO,KAAK,EAAE;QACrBP,WAAWO,KAAK,GAAG,CAAC;IACtB;IACA,IAAI,CAACP,WAAWO,KAAK,EAAEC,aAAa;QAClCR,WAAWO,KAAK,CAACC,WAAW,GAAG,EAAE;IACnC;IACAR,WAAWO,KAAK,CAACC,WAAW,CAACC,IAAI,CAC/BC,kBAAkB;QAChBT;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;AAEJ,EAAC;AAED,OAAO,MAAMI,oBACX,CAAC,EACCT,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EACP,GAC3B,OAAO,EAAEK,EAAE,EAAEC,GAAG,EAAE;QAChB,MAAMC,SAAShB,oBAAoB;YACjCiB,gBAAgBX;YAChBY,SAASH,IAAIG,OAAO;QACtB;QACA,MAAMC,wBAAwBlB,oBAAoBc,IAAIK,OAAO,EAAEJ;QAC/D,IAAIG,0BAA0BL,IAAI;YAChC,MAAMO,aAAa,IAAIC,QAAQ;gBAC7B,cAAcxB,eAAuB;oBACnCyB,MAAM;oBACNC,SAAS,IAAIC,KAAKA,KAAKC,GAAG,KAAK;oBAC/BC,MAAM;oBACNC,sBAAsB;oBACtBC,OAAO;gBACT;YACF;YAEAd,IAAIe,eAAe,GAAGf,IAAIe,eAAe,GACrC/B,aAAagB,IAAIe,eAAe,EAAET,cAClCA;QACN;QACA,MAAMU,kBAAyC,EAAE;QACjD3B,aAAa4B,OAAO,CAAC,CAACC;YACpBF,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACgB,MAAM,CAAC;gBACjB/B,YAAY8B;gBACZE,OAAO;oBACL,CAAC9B,gBAAgB,EAAE;wBACjB+B,QAAQtB;oBACV;gBACF;YACF;QAEJ;QAEA,IAAI;YACF,MAAMuB,kBAAmB,MAAMtB,IAAIG,OAAO,CAACoB,IAAI,CAAC;gBAC9CnC,YAAYI;gBACZgC,OAAO;gBACPC,OAAO;gBACPL,OAAO;oBACL,CAAC,GAAG3B,2BAA2B,CAAC,EAAEC,kCAAkC,CAAC,EAAE;wBACrE2B,QAAQtB;oBACV;gBACF;YACF;YAEAuB,iBAAiBI,MAAMT,QAAQ,CAACU;gBAC9BX,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACyB,MAAM,CAAC;oBACjB7B,IAAI4B,KAAK5B,EAAE;oBACXX,YAAYI;oBACZqC,MAAM;wBACJC,SAAS,AAACH,CAAAA,KAAKG,OAAO,IAAI,EAAE,AAAD,EAAGC,MAAM,CAAC,CAAC,EAAEC,QAAQC,QAAQ,EAAE,GAAKA,aAAalC;oBAC9E;gBACF;YAEJ;QACF,EAAE,OAAOmC,GAAG;YACVC,QAAQC,KAAK,CAAC,sCAAsCF;QACtD;QAEA,MAAMG,QAAQC,GAAG,CAACtB;IACpB,EAAC"}
1
+ {"version":3,"sources":["../../src/hooks/afterTenantDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n JsonObject,\n PaginatedDocs,\n} from 'payload'\n\nimport { generateCookie, mergeHeaders } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getCollectionIDType } from '../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\n\ntype Args = {\n collection: CollectionConfig\n enabledSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n usersSlug: string\n usersTenantsArrayFieldName: string\n usersTenantsArrayTenantFieldName: string\n}\n/**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\nexport const addTenantCleanup = ({\n collection,\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n}: Args) => {\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks?.afterDelete) {\n collection.hooks.afterDelete = []\n }\n collection.hooks.afterDelete.push(\n afterTenantDelete({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }),\n )\n}\n\nexport const afterTenantDelete =\n ({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }: Omit<Args, 'collection'>): CollectionAfterDeleteHook =>\n async ({ id, req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const currentTenantCookieID = getTenantFromCookie(req.headers, idType)\n if (currentTenantCookieID === id) {\n const newHeaders = new Headers({\n 'Set-Cookie': generateCookie<string>({\n name: 'payload-tenant',\n expires: new Date(Date.now() - 1000),\n path: '/',\n returnCookieAsObject: false,\n value: '',\n }),\n })\n\n req.responseHeaders = req.responseHeaders\n ? mergeHeaders(req.responseHeaders, newHeaders)\n : newHeaders\n }\n const cleanupPromises: Promise<JsonObject>[] = []\n enabledSlugs.forEach((slug) => {\n cleanupPromises.push(\n req.payload.delete({\n collection: slug,\n where: {\n [tenantFieldName]: {\n equals: id,\n },\n },\n }),\n )\n })\n\n try {\n const usersWithTenant = (await req.payload.find({\n collection: usersSlug,\n depth: 0,\n limit: 0,\n where: {\n [`${usersTenantsArrayFieldName}.${usersTenantsArrayTenantFieldName}`]: {\n equals: id,\n },\n },\n })) as PaginatedDocs<UserWithTenantsField>\n\n usersWithTenant?.docs?.forEach((user) => {\n cleanupPromises.push(\n req.payload.update({\n id: user.id,\n collection: usersSlug,\n data: {\n [usersTenantsArrayFieldName]: (user[usersTenantsArrayFieldName] || []).filter(\n (row: Record<string, string>) => {\n if (row[usersTenantsArrayTenantFieldName]) {\n return row[usersTenantsArrayTenantFieldName] !== id\n }\n },\n ),\n },\n }),\n )\n })\n } catch (e) {\n console.error('Error deleting tenants from users:', e)\n }\n\n await Promise.all(cleanupPromises)\n }\n"],"names":["generateCookie","mergeHeaders","getCollectionIDType","getTenantFromCookie","addTenantCleanup","collection","enabledSlugs","tenantFieldName","tenantsCollectionSlug","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","hooks","afterDelete","push","afterTenantDelete","id","req","idType","collectionSlug","payload","currentTenantCookieID","headers","newHeaders","Headers","name","expires","Date","now","path","returnCookieAsObject","value","responseHeaders","cleanupPromises","forEach","slug","delete","where","equals","usersWithTenant","find","depth","limit","docs","user","update","data","filter","row","e","console","error","Promise","all"],"mappings":"AAOA,SAASA,cAAc,EAAEC,YAAY,QAAQ,UAAS;AAItD,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AAWzE;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,UAAU,EACVC,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EAC3B;IACL,IAAI,CAACN,WAAWO,KAAK,EAAE;QACrBP,WAAWO,KAAK,GAAG,CAAC;IACtB;IACA,IAAI,CAACP,WAAWO,KAAK,EAAEC,aAAa;QAClCR,WAAWO,KAAK,CAACC,WAAW,GAAG,EAAE;IACnC;IACAR,WAAWO,KAAK,CAACC,WAAW,CAACC,IAAI,CAC/BC,kBAAkB;QAChBT;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;AAEJ,EAAC;AAED,OAAO,MAAMI,oBACX,CAAC,EACCT,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EACP,GAC3B,OAAO,EAAEK,EAAE,EAAEC,GAAG,EAAE;QAChB,MAAMC,SAAShB,oBAAoB;YACjCiB,gBAAgBX;YAChBY,SAASH,IAAIG,OAAO;QACtB;QACA,MAAMC,wBAAwBlB,oBAAoBc,IAAIK,OAAO,EAAEJ;QAC/D,IAAIG,0BAA0BL,IAAI;YAChC,MAAMO,aAAa,IAAIC,QAAQ;gBAC7B,cAAcxB,eAAuB;oBACnCyB,MAAM;oBACNC,SAAS,IAAIC,KAAKA,KAAKC,GAAG,KAAK;oBAC/BC,MAAM;oBACNC,sBAAsB;oBACtBC,OAAO;gBACT;YACF;YAEAd,IAAIe,eAAe,GAAGf,IAAIe,eAAe,GACrC/B,aAAagB,IAAIe,eAAe,EAAET,cAClCA;QACN;QACA,MAAMU,kBAAyC,EAAE;QACjD3B,aAAa4B,OAAO,CAAC,CAACC;YACpBF,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACgB,MAAM,CAAC;gBACjB/B,YAAY8B;gBACZE,OAAO;oBACL,CAAC9B,gBAAgB,EAAE;wBACjB+B,QAAQtB;oBACV;gBACF;YACF;QAEJ;QAEA,IAAI;YACF,MAAMuB,kBAAmB,MAAMtB,IAAIG,OAAO,CAACoB,IAAI,CAAC;gBAC9CnC,YAAYI;gBACZgC,OAAO;gBACPC,OAAO;gBACPL,OAAO;oBACL,CAAC,GAAG3B,2BAA2B,CAAC,EAAEC,kCAAkC,CAAC,EAAE;wBACrE2B,QAAQtB;oBACV;gBACF;YACF;YAEAuB,iBAAiBI,MAAMT,QAAQ,CAACU;gBAC9BX,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACyB,MAAM,CAAC;oBACjB7B,IAAI4B,KAAK5B,EAAE;oBACXX,YAAYI;oBACZqC,MAAM;wBACJ,CAACpC,2BAA2B,EAAE,AAACkC,CAAAA,IAAI,CAAClC,2BAA2B,IAAI,EAAE,AAAD,EAAGqC,MAAM,CAC3E,CAACC;4BACC,IAAIA,GAAG,CAACrC,iCAAiC,EAAE;gCACzC,OAAOqC,GAAG,CAACrC,iCAAiC,KAAKK;4BACnD;wBACF;oBAEJ;gBACF;YAEJ;QACF,EAAE,OAAOiC,GAAG;YACVC,QAAQC,KAAK,CAAC,sCAAsCF;QACtD;QAEA,MAAMG,QAAQC,GAAG,CAACpB;IACpB,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAUzD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MA6OzB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAUzD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAmPzB,CAAA"}
package/dist/index.js CHANGED
@@ -65,6 +65,8 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
65
65
  addCollectionAccess({
66
66
  collection: adminUsersCollection,
67
67
  fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,
68
+ tenantsArrayFieldName,
69
+ tenantsArrayTenantFieldName,
68
70
  userHasAccessToAllTenants
69
71
  });
70
72
  let tenantCollection;
@@ -93,6 +95,8 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
93
95
  */ addCollectionAccess({
94
96
  collection,
95
97
  fieldName: 'id',
98
+ tenantsArrayFieldName,
99
+ tenantsArrayTenantFieldName,
96
100
  userHasAccessToAllTenants
97
101
  });
98
102
  }
@@ -156,6 +160,8 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
156
160
  */ addCollectionAccess({
157
161
  collection,
158
162
  fieldName: tenantFieldName,
163
+ tenantsArrayFieldName,
164
+ tenantsArrayTenantFieldName,
159
165
  userHasAccessToAllTenants
160
166
  });
161
167
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\n\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { withTenantListFilter } from './utilities/withTenantListFilter.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n userHasAccessToAllTenants,\n })\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n collection,\n fieldName: 'id',\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Collection baseListFilter with selected tenant constraint (if selected)\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n collection.admin.baseListFilter = withTenantListFilter({\n baseListFilter: collection.admin?.baseListFilter,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n collection,\n fieldName: tenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","addCollectionAccess","addFilterOptionsToFields","withTenantListFilter","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","collection","fieldName","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","forEach","useTenantsCollectionAccess","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","baseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\n\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { withTenantListFilter } from './utilities/withTenantListFilter.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Collection baseListFilter with selected tenant constraint (if selected)\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n collection.admin.baseListFilter = withTenantListFilter({\n baseListFilter: collection.admin?.baseListFilter,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","addCollectionAccess","addFilterOptionsToFields","withTenantListFilter","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","collection","fieldName","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","forEach","useTenantsCollectionAccess","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","baseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
@@ -1,9 +1,26 @@
1
1
  import type { OptionObject } from 'payload';
2
2
  import React from 'react';
3
3
  type ContextType = {
4
+ /**
5
+ * Array of options to select from
6
+ */
4
7
  options: OptionObject[];
8
+ /**
9
+ * The currently selected tenant ID
10
+ */
5
11
  selectedTenantID: number | string | undefined;
12
+ /**
13
+ * Prevents a refresh when the tenant is changed
14
+ *
15
+ * If not switching tenants while viewing a "global", set to true
16
+ */
6
17
  setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>;
18
+ /**
19
+ * Sets the selected tenant ID
20
+ *
21
+ * @param args.id - The ID of the tenant to select
22
+ * @param args.refresh - Whether to refresh the page after changing the tenant
23
+ */
7
24
  setTenant: (args: {
8
25
  id: number | string | undefined;
9
26
  refresh?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAI5C,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;CAClF,CAAA;AASD,eAAO,MAAM,6BAA6B,6DAKvC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,sBA8FA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAAkC,CAAA"}
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAI5C,KAAK,WAAW,GAAG;IACjB;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;OAIG;IACH,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE;;;;;OAKG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;CAClF,CAAA;AASD,eAAO,MAAM,6BAA6B,6DAKvC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,sBA8FA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAAkC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\n\ntype ContextType = {\n options: OptionObject[]\n selectedTenantID: number | string | undefined\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(SELECT_ALL)\n setCookie(SELECT_ALL)\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [setSelectedTenantID, setCookie, router, preventRefreshOnChange, tenantOptions],\n )\n\n React.useEffect(() => {\n if (\n selectedTenantID &&\n selectedTenantID !== SELECT_ALL &&\n !tenantOptions.find((option) => option.value === selectedTenantID)\n ) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n setCookie(String(initialValue))\n }\n }, [userID, tenantCookie, initialValue, setCookie, router])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context.Provider\n value={{\n options: tenantOptions,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n }}\n >\n {children}\n </Context.Provider>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.useContext(Context)\n"],"names":["useAuth","useRouter","React","createContext","SELECT_ALL","Context","options","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","setSelectedTenantID","useState","preventRefreshOnChange","user","userID","useMemo","id","selectedTenantLabel","find","option","value","label","router","setCookie","useCallback","expires","document","cookie","deleteCookie","refresh","length","String","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","Provider","useTenantSelection","useContext"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\n\ntype ContextType = {\n /**\n * Array of options to select from\n */\n options: OptionObject[]\n /**\n * The currently selected tenant ID\n */\n selectedTenantID: number | string | undefined\n /**\n * Prevents a refresh when the tenant is changed\n *\n * If not switching tenants while viewing a \"global\", set to true\n */\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n /**\n * Sets the selected tenant ID\n *\n * @param args.id - The ID of the tenant to select\n * @param args.refresh - Whether to refresh the page after changing the tenant\n */\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(SELECT_ALL)\n setCookie(SELECT_ALL)\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [setSelectedTenantID, setCookie, router, preventRefreshOnChange, tenantOptions],\n )\n\n React.useEffect(() => {\n if (\n selectedTenantID &&\n selectedTenantID !== SELECT_ALL &&\n !tenantOptions.find((option) => option.value === selectedTenantID)\n ) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n setCookie(String(initialValue))\n }\n }, [userID, tenantCookie, initialValue, setCookie, router])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context.Provider\n value={{\n options: tenantOptions,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n }}\n >\n {children}\n </Context.Provider>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.useContext(Context)\n"],"names":["useAuth","useRouter","React","createContext","SELECT_ALL","Context","options","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","setSelectedTenantID","useState","preventRefreshOnChange","user","userID","useMemo","id","selectedTenantLabel","find","option","value","label","router","setCookie","useCallback","expires","document","cookie","deleteCookie","refresh","length","String","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","Provider","useTenantSelection","useContext"],"mappings":"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"}
@@ -3,12 +3,14 @@ import type { MultiTenantPluginConfig } from '../types.js';
3
3
  type Args<ConfigType> = {
4
4
  collection: CollectionConfig;
5
5
  fieldName: string;
6
+ tenantsArrayFieldName?: string;
7
+ tenantsArrayTenantFieldName?: string;
6
8
  userHasAccessToAllTenants: Required<MultiTenantPluginConfig<ConfigType>>['userHasAccessToAllTenants'];
7
9
  };
8
10
  /**
9
11
  * Adds tenant access constraint to collection
10
12
  * - constrains access a users assigned tenants
11
13
  */
12
- export declare const addCollectionAccess: <ConfigType>({ collection, fieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
14
+ export declare const addCollectionAccess: <ConfigType>({ collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
13
15
  export {};
14
16
  //# sourceMappingURL=addCollectionAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAiB1D,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,yDAI3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAWrB,CAAA"}
1
+ {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAiB1D,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,6GAM3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAerB,CAAA"}
@@ -10,14 +10,18 @@ const collectionAccessKeys = [
10
10
  /**
11
11
  * Adds tenant access constraint to collection
12
12
  * - constrains access a users assigned tenants
13
- */ export const addCollectionAccess = ({ collection, fieldName, userHasAccessToAllTenants })=>{
13
+ */ export const addCollectionAccess = ({ collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
14
14
  collectionAccessKeys.forEach((key)=>{
15
15
  if (!collection.access) {
16
16
  collection.access = {};
17
17
  }
18
18
  collection.access[key] = withTenantAccess({
19
19
  accessFunction: collection.access?.[key],
20
+ collection,
20
21
  fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,
22
+ operation: key,
23
+ tenantsArrayFieldName,
24
+ tenantsArrayTenantFieldName,
21
25
  userHasAccessToAllTenants
22
26
  });
23
27
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\ntype AllAccessKeys<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nconst collectionAccessKeys: AllAccessKeys<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n> = ['create', 'read', 'update', 'delete', 'readVersions', 'unlock'] as const\n\ntype Args<ConfigType> = {\n collection: CollectionConfig\n fieldName: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n collection,\n fieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","collection","fieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAWxD,MAAMC,uBAEF;IAAC;IAAU;IAAQ;IAAU;IAAU;IAAgB;CAAS;AAUpE;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,UAAU,EACVC,SAAS,EACTC,yBAAyB,EACR;IACjBJ,qBAAqBK,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACJ,WAAWK,MAAM,EAAE;YACtBL,WAAWK,MAAM,GAAG,CAAC;QACvB;QACAL,WAAWK,MAAM,CAACD,IAAI,GAAGP,iBAA6B;YACpDS,gBAAgBN,WAAWK,MAAM,EAAE,CAACD,IAAI;YACxCH,WAAWG,QAAQ,iBAAiB,CAAC,QAAQ,EAAEH,WAAW,GAAGA;YAC7DC;QACF;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\ntype AllAccessKeys<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nconst collectionAccessKeys: AllAccessKeys<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n> = ['create', 'read', 'update', 'delete', 'readVersions', 'unlock'] as const\n\ntype Args<ConfigType> = {\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n collection,\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n operation: key,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction","operation"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAWxD,MAAMC,uBAEF;IAAC;IAAU;IAAQ;IAAU;IAAU;IAAgB;CAAS;AAYpE;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR;IACjBN,qBAAqBO,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACN,WAAWO,MAAM,EAAE;YACtBP,WAAWO,MAAM,GAAG,CAAC;QACvB;QACAP,WAAWO,MAAM,CAACD,IAAI,GAAGT,iBAA6B;YACpDW,gBAAgBR,WAAWO,MAAM,EAAE,CAACD,IAAI;YACxCN;YACAC,WAAWK,QAAQ,iBAAiB,CAAC,QAAQ,EAAEL,WAAW,GAAGA;YAC7DQ,WAAWH;YACXJ;YACAC;YACAC;QACF;IACF;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAOvD,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4D/B"}
1
+ {"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAOvD,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6D/B"}
@@ -25,6 +25,7 @@ export async function getGlobalViewRedirect({ slug, docID, headers, payload, ten
25
25
  depth: 0,
26
26
  limit: 1,
27
27
  overrideAccess: false,
28
+ pagination: false,
28
29
  user,
29
30
  where: {
30
31
  [tenantFieldName]: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, User, ViewTypes } from 'payload'\n\nimport { SELECT_ALL } from '../constants.js'\nimport { findTenantOptions } from '../queries/findTenantOptions.js'\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype Args = {\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute\n\n if (!tenant || tenant === SELECT_ALL) {\n const tenantsQuery = await findTenantOptions({\n limit: 1,\n payload,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n })\n\n tenant = tenantsQuery.docs[0]?.id || null\n }\n\n try {\n const { docs } = await payload.find({\n collection: slug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n user,\n where: {\n [tenantFieldName]: {\n equals: tenant,\n },\n },\n })\n\n const tenantDocID = docs?.[0]?.id\n\n if (view === 'document') {\n if (docID && !tenantDocID) {\n // viewing a document with an id but does not match the selected tenant, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n } else if (tenantDocID && docID !== tenantDocID) {\n // tenant document already exists but does not match current route doc ID, redirect to matching tenant doc\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n }\n } else if (view === 'list') {\n if (tenantDocID) {\n // tenant document exists, redirect to edit view\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n } else {\n // tenant document does not exist, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n }\n }\n } catch (e: unknown) {\n payload.logger.error(\n e,\n `${typeof e === 'object' && e && 'message' in e ? `e?.message - ` : ''}Multi Tenant Redirect Error`,\n )\n }\n return redirectRoute\n}\n"],"names":["SELECT_ALL","findTenantOptions","getCollectionIDType","getTenantFromCookie","getGlobalViewRedirect","slug","docID","headers","payload","tenantFieldName","tenantsCollectionSlug","useAsTitle","user","view","idType","collectionSlug","tenant","redirectRoute","tenantsQuery","limit","docs","id","find","collection","depth","overrideAccess","where","equals","tenantDocID","config","routes","admin","e","logger","error"],"mappings":"AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAa9D,OAAO,eAAeC,sBAAsB,EAC1CC,IAAI,EACJC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,eAAe,EACfC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,IAAI,EACC;IACL,MAAMC,SAASZ,oBAAoB;QACjCa,gBAAgBL;QAChBF;IACF;IACA,IAAIQ,SAASb,oBAAoBI,SAASO;IAC1C,IAAIG;IAEJ,IAAI,CAACD,UAAUA,WAAWhB,YAAY;QACpC,MAAMkB,eAAe,MAAMjB,kBAAkB;YAC3CkB,OAAO;YACPX;YACAE;YACAC;YACAC;QACF;QAEAI,SAASE,aAAaE,IAAI,CAAC,EAAE,EAAEC,MAAM;IACvC;IAEA,IAAI;QACF,MAAM,EAAED,IAAI,EAAE,GAAG,MAAMZ,QAAQc,IAAI,CAAC;YAClCC,YAAYlB;YACZmB,OAAO;YACPL,OAAO;YACPM,gBAAgB;YAChBb;YACAc,OAAO;gBACL,CAACjB,gBAAgB,EAAE;oBACjBkB,QAAQX;gBACV;YACF;QACF;QAEA,MAAMY,cAAcR,MAAM,CAAC,EAAE,EAAEC;QAE/B,IAAIR,SAAS,YAAY;YACvB,IAAIP,SAAS,CAACsB,aAAa;gBACzB,iGAAiG;gBACjGX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,OAAO,CAAC;YAC7E,OAAO,IAAIuB,eAAetB,UAAUsB,aAAa;gBAC/C,0GAA0G;gBAC1GX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,CAAC,EAAEuB,aAAa;YACrF;QACF,OAAO,IAAIf,SAAS,QAAQ;YAC1B,IAAIe,aAAa;gBACf,gDAAgD;gBAChDX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,CAAC,EAAEuB,aAAa;YACrF,OAAO;gBACL,2DAA2D;gBAC3DX,gBAAgB,GAAGT,QAAQqB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE1B,KAAK,OAAO,CAAC;YAC7E;QACF;IACF,EAAE,OAAO2B,GAAY;QACnBxB,QAAQyB,MAAM,CAACC,KAAK,CAClBF,GACA,GAAG,OAAOA,MAAM,YAAYA,KAAK,aAAaA,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,2BAA2B,CAAC;IAEvG;IACA,OAAOf;AACT"}
1
+ {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, User, ViewTypes } from 'payload'\n\nimport { SELECT_ALL } from '../constants.js'\nimport { findTenantOptions } from '../queries/findTenantOptions.js'\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\n\ntype Args = {\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute\n\n if (!tenant || tenant === SELECT_ALL) {\n const tenantsQuery = await findTenantOptions({\n limit: 1,\n payload,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n })\n\n tenant = tenantsQuery.docs[0]?.id || null\n }\n\n try {\n const { docs } = await payload.find({\n collection: slug,\n depth: 0,\n limit: 1,\n overrideAccess: false,\n pagination: false,\n user,\n where: {\n [tenantFieldName]: {\n equals: tenant,\n },\n },\n })\n\n const tenantDocID = docs?.[0]?.id\n\n if (view === 'document') {\n if (docID && !tenantDocID) {\n // viewing a document with an id but does not match the selected tenant, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n } else if (tenantDocID && docID !== tenantDocID) {\n // tenant document already exists but does not match current route doc ID, redirect to matching tenant doc\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n }\n } else if (view === 'list') {\n if (tenantDocID) {\n // tenant document exists, redirect to edit view\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/${tenantDocID}`\n } else {\n // tenant document does not exist, redirect to create route\n redirectRoute = `${payload.config.routes.admin}/collections/${slug}/create`\n }\n }\n } catch (e: unknown) {\n payload.logger.error(\n e,\n `${typeof e === 'object' && e && 'message' in e ? `e?.message - ` : ''}Multi Tenant Redirect Error`,\n )\n }\n return redirectRoute\n}\n"],"names":["SELECT_ALL","findTenantOptions","getCollectionIDType","getTenantFromCookie","getGlobalViewRedirect","slug","docID","headers","payload","tenantFieldName","tenantsCollectionSlug","useAsTitle","user","view","idType","collectionSlug","tenant","redirectRoute","tenantsQuery","limit","docs","id","find","collection","depth","overrideAccess","pagination","where","equals","tenantDocID","config","routes","admin","e","logger","error"],"mappings":"AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAa9D,OAAO,eAAeC,sBAAsB,EAC1CC,IAAI,EACJC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,eAAe,EACfC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,IAAI,EACC;IACL,MAAMC,SAASZ,oBAAoB;QACjCa,gBAAgBL;QAChBF;IACF;IACA,IAAIQ,SAASb,oBAAoBI,SAASO;IAC1C,IAAIG;IAEJ,IAAI,CAACD,UAAUA,WAAWhB,YAAY;QACpC,MAAMkB,eAAe,MAAMjB,kBAAkB;YAC3CkB,OAAO;YACPX;YACAE;YACAC;YACAC;QACF;QAEAI,SAASE,aAAaE,IAAI,CAAC,EAAE,EAAEC,MAAM;IACvC;IAEA,IAAI;QACF,MAAM,EAAED,IAAI,EAAE,GAAG,MAAMZ,QAAQc,IAAI,CAAC;YAClCC,YAAYlB;YACZmB,OAAO;YACPL,OAAO;YACPM,gBAAgB;YAChBC,YAAY;YACZd;YACAe,OAAO;gBACL,CAAClB,gBAAgB,EAAE;oBACjBmB,QAAQZ;gBACV;YACF;QACF;QAEA,MAAMa,cAAcT,MAAM,CAAC,EAAE,EAAEC;QAE/B,IAAIR,SAAS,YAAY;YACvB,IAAIP,SAAS,CAACuB,aAAa;gBACzB,iGAAiG;gBACjGZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,OAAO,CAAC;YAC7E,OAAO,IAAIwB,eAAevB,UAAUuB,aAAa;gBAC/C,0GAA0G;gBAC1GZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,CAAC,EAAEwB,aAAa;YACrF;QACF,OAAO,IAAIhB,SAAS,QAAQ;YAC1B,IAAIgB,aAAa;gBACf,gDAAgD;gBAChDZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,CAAC,EAAEwB,aAAa;YACrF,OAAO;gBACL,2DAA2D;gBAC3DZ,gBAAgB,GAAGT,QAAQsB,MAAM,CAACC,MAAM,CAACC,KAAK,CAAC,aAAa,EAAE3B,KAAK,OAAO,CAAC;YAC7E;QACF;IACF,EAAE,OAAO4B,GAAY;QACnBzB,QAAQ0B,MAAM,CAACC,KAAK,CAClBF,GACA,GAAG,OAAOA,MAAM,YAAYA,KAAK,aAAaA,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,2BAA2B,CAAC;IAEvG;IACA,OAAOhB;AACT"}
@@ -2,8 +2,10 @@ import type { Where } from 'payload';
2
2
  import type { UserWithTenantsField } from '../types.js';
3
3
  type Args = {
4
4
  fieldName: string;
5
+ tenantsArrayFieldName?: string;
6
+ tenantsArrayTenantFieldName?: string;
5
7
  user: UserWithTenantsField;
6
8
  };
7
- export declare function getTenantAccess({ fieldName, user }: Args): Where;
9
+ export declare function getTenantAccess({ fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, user, }: Args): Where;
8
10
  export {};
9
11
  //# sourceMappingURL=getTenantAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIvD,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,oBAAoB,CAAA;CAC3B,CAAA;AACD,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,GAAG,KAAK,CAQhE"}
1
+ {"version":3,"file":"getTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAKvD,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,IAAI,EAAE,oBAAoB,CAAA;CAC3B,CAAA;AACD,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,qBAAsD,EACtD,2BAAkE,EAClE,IAAI,GACL,EAAE,IAAI,GAAG,KAAK,CAWd"}
@@ -1,6 +1,10 @@
1
+ import { defaults } from '../defaults.js';
1
2
  import { getUserTenantIDs } from './getUserTenantIDs.js';
2
- export function getTenantAccess({ fieldName, user }) {
3
- const userAssignedTenantIDs = getUserTenantIDs(user);
3
+ export function getTenantAccess({ fieldName, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, user }) {
4
+ const userAssignedTenantIDs = getUserTenantIDs(user, {
5
+ tenantsArrayFieldName,
6
+ tenantsArrayTenantFieldName
7
+ });
4
8
  return {
5
9
  [fieldName]: {
6
10
  in: userAssignedTenantIDs || []
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getTenantAccess.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getUserTenantIDs } from './getUserTenantIDs.js'\n\ntype Args = {\n fieldName: string\n user: UserWithTenantsField\n}\nexport function getTenantAccess({ fieldName, user }: Args): Where {\n const userAssignedTenantIDs = getUserTenantIDs(user)\n\n return {\n [fieldName]: {\n in: userAssignedTenantIDs || [],\n },\n }\n}\n"],"names":["getUserTenantIDs","getTenantAccess","fieldName","user","userAssignedTenantIDs","in"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAMxD,OAAO,SAASC,gBAAgB,EAAEC,SAAS,EAAEC,IAAI,EAAQ;IACvD,MAAMC,wBAAwBJ,iBAAiBG;IAE/C,OAAO;QACL,CAACD,UAAU,EAAE;YACXG,IAAID,yBAAyB,EAAE;QACjC;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/utilities/getTenantAccess.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { getUserTenantIDs } from './getUserTenantIDs.js'\n\ntype Args = {\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n user: UserWithTenantsField\n}\nexport function getTenantAccess({\n fieldName,\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n user,\n}: Args): Where {\n const userAssignedTenantIDs = getUserTenantIDs(user, {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n })\n\n return {\n [fieldName]: {\n in: userAssignedTenantIDs || [],\n },\n }\n}\n"],"names":["defaults","getUserTenantIDs","getTenantAccess","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","user","userAssignedTenantIDs","in"],"mappings":"AAIA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,gBAAgB,QAAQ,wBAAuB;AAQxD,OAAO,SAASC,gBAAgB,EAC9BC,SAAS,EACTC,wBAAwBJ,SAASI,qBAAqB,EACtDC,8BAA8BL,SAASK,2BAA2B,EAClEC,IAAI,EACC;IACL,MAAMC,wBAAwBN,iBAAiBK,MAAM;QACnDF;QACAC;IACF;IAEA,OAAO;QACL,CAACF,UAAU,EAAE;YACXK,IAAID,yBAAyB,EAAE;QACjC;IACF;AACF"}
@@ -4,5 +4,8 @@ import type { UserWithTenantsField } from '../types.js';
4
4
  *
5
5
  * @param user - User object with tenants field
6
6
  */
7
- export declare const getUserTenantIDs: <IDType extends number | string>(user: null | UserWithTenantsField) => IDType[];
7
+ export declare const getUserTenantIDs: <IDType extends number | string>(user: null | UserWithTenantsField, options?: {
8
+ tenantsArrayFieldName?: string;
9
+ tenantsArrayTenantFieldName?: string;
10
+ }) => IDType[];
8
11
  //# sourceMappingURL=getUserTenantIDs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAI/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,KAChC,MAAM,EAcR,CAAA"}
1
+ {"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAK/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,YACvB;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;CACrC,KACA,MAAM,EAqBR,CAAA"}
@@ -1,15 +1,17 @@
1
+ import { defaults } from '../defaults.js';
1
2
  import { extractID } from './extractID.js';
2
3
  /**
3
4
  * Returns array of all tenant IDs assigned to a user
4
5
  *
5
6
  * @param user - User object with tenants field
6
- */ export const getUserTenantIDs = (user)=>{
7
+ */ export const getUserTenantIDs = (user, options)=>{
7
8
  if (!user) {
8
9
  return [];
9
10
  }
10
- return user?.tenants?.reduce((acc, { tenant })=>{
11
- if (tenant) {
12
- acc.push(extractID(tenant));
11
+ const { tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName } = options || {};
12
+ return (Array.isArray(user[tenantsArrayFieldName]) ? user[tenantsArrayFieldName] : [])?.reduce((acc, row)=>{
13
+ if (row[tenantsArrayTenantFieldName]) {
14
+ acc.push(extractID(row[tenantsArrayTenantFieldName]));
13
15
  }
14
16
  return acc;
15
17
  }, []) || [];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n): IDType[] => {\n if (!user) {\n return []\n }\n\n return (\n user?.tenants?.reduce<IDType[]>((acc, { tenant }) => {\n if (tenant) {\n acc.push(extractID<IDType>(tenant as Tenant<IDType>))\n }\n\n return acc\n }, []) || []\n )\n}\n"],"names":["extractID","getUserTenantIDs","user","tenants","reduce","acc","tenant","push"],"mappings":"AAEA,SAASA,SAAS,QAAQ,iBAAgB;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAC9BC;IAEA,IAAI,CAACA,MAAM;QACT,OAAO,EAAE;IACX;IAEA,OACEA,MAAMC,SAASC,OAAiB,CAACC,KAAK,EAAEC,MAAM,EAAE;QAC9C,IAAIA,QAAQ;YACVD,IAAIE,IAAI,CAACP,UAAkBM;QAC7B;QAEA,OAAOD;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n options?: {\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n },\n): IDType[] => {\n if (!user) {\n return []\n }\n\n const {\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n } = options || {}\n\n return (\n (Array.isArray(user[tenantsArrayFieldName]) ? user[tenantsArrayFieldName] : [])?.reduce<\n IDType[]\n >((acc, row) => {\n if (row[tenantsArrayTenantFieldName]) {\n acc.push(extractID<IDType>(row[tenantsArrayTenantFieldName] as Tenant<IDType>))\n }\n\n return acc\n }, []) || []\n )\n}\n"],"names":["defaults","extractID","getUserTenantIDs","user","options","tenantsArrayFieldName","tenantsArrayTenantFieldName","Array","isArray","reduce","acc","row","push"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,SAAS,QAAQ,iBAAgB;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAC9BC,MACAC;IAKA,IAAI,CAACD,MAAM;QACT,OAAO,EAAE;IACX;IAEA,MAAM,EACJE,wBAAwBL,SAASK,qBAAqB,EACtDC,8BAA8BN,SAASM,2BAA2B,EACnE,GAAGF,WAAW,CAAC;IAEhB,OACE,AAACG,CAAAA,MAAMC,OAAO,CAACL,IAAI,CAACE,sBAAsB,IAAIF,IAAI,CAACE,sBAAsB,GAAG,EAAE,AAAD,GAAII,OAE/E,CAACC,KAAKC;QACN,IAAIA,GAAG,CAACL,4BAA4B,EAAE;YACpCI,IAAIE,IAAI,CAACX,UAAkBU,GAAG,CAACL,4BAA4B;QAC7D;QAEA,OAAOI;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
@@ -1,10 +1,14 @@
1
- import type { Access, AccessArgs, AccessResult } from 'payload';
1
+ import type { Access, AccessArgs, AccessResult, AllOperations, CollectionConfig } from 'payload';
2
2
  import type { MultiTenantPluginConfig } from '../types.js';
3
3
  type Args<ConfigType> = {
4
4
  accessFunction?: Access;
5
+ collection: CollectionConfig;
5
6
  fieldName: string;
7
+ operation: AllOperations;
8
+ tenantsArrayFieldName?: string;
9
+ tenantsArrayTenantFieldName?: string;
6
10
  userHasAccessToAllTenants: Required<MultiTenantPluginConfig<ConfigType>>['userHasAccessToAllTenants'];
7
11
  };
8
- export declare const withTenantAccess: <ConfigType>({ accessFunction, fieldName, userHasAccessToAllTenants }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
12
+ export declare const withTenantAccess: <ConfigType>({ accessFunction, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
9
13
  export {};
10
14
  //# sourceMappingURL=withTenantAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAQ,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAKhF,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,4DAA4D,IAAI,CAAC,UAAU,CAAC,YAC1E,UAAU,KAAG,OAAO,CAAC,YAAY,CA8B7C,CAAA"}
1
+ {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAGjB,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAKhF,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,aAAa,CAAA;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,6HAOR,IAAI,CAAC,UAAU,CAAC,YACN,UAAU,KAAG,OAAO,CAAC,YAAY,CA4C7C,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { combineWhereConstraints } from './combineWhereConstraints.js';
2
2
  import { getTenantAccess } from './getTenantAccess.js';
3
- export const withTenantAccess = ({ accessFunction, fieldName, userHasAccessToAllTenants })=>async (args)=>{
3
+ export const withTenantAccess = ({ accessFunction, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>async (args)=>{
4
4
  const constraints = [];
5
5
  const accessFn = typeof accessFunction === 'function' ? accessFunction : ({ req })=>Boolean(req.user);
6
6
  const accessResult = await accessFn(args);
@@ -10,10 +10,26 @@ export const withTenantAccess = ({ accessFunction, fieldName, userHasAccessToAll
10
10
  constraints.push(accessResult);
11
11
  }
12
12
  if (args.req.user && !userHasAccessToAllTenants(args.req.user)) {
13
- constraints.push(getTenantAccess({
13
+ const tenantConstraint = getTenantAccess({
14
14
  fieldName,
15
+ tenantsArrayFieldName,
16
+ tenantsArrayTenantFieldName,
15
17
  user: args.req.user
16
- }));
18
+ });
19
+ if (collection.slug === args.req.user.collection) {
20
+ constraints.push({
21
+ or: [
22
+ {
23
+ id: {
24
+ equals: args.req.user.id
25
+ }
26
+ },
27
+ tenantConstraint
28
+ ]
29
+ });
30
+ } else {
31
+ constraints.push(tenantConstraint);
32
+ }
17
33
  return combineWhereConstraints(constraints);
18
34
  }
19
35
  return accessResult;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type { Access, AccessArgs, AccessResult, User } from 'payload'\n\nimport type { MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n fieldName: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({ accessFunction, fieldName, userHasAccessToAllTenants }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : User,\n )\n ) {\n constraints.push(\n getTenantAccess({\n fieldName,\n user: args.req.user as UserWithTenantsField,\n }),\n )\n return combineWhereConstraints(constraints)\n }\n\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","fieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push"],"mappings":"AAIA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAStD,OAAO,MAAMC,mBACX,CAAa,EAAEC,cAAc,EAAEC,SAAS,EAAEC,yBAAyB,EAAoB,GACvF,OAAOC;QACL,MAAMC,cAAc,EAAE;QACtB,MAAMC,WACJ,OAAOL,mBAAmB,aACtBA,iBACA,CAAC,EAAEM,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,OAAO;QACT,OAAO,IAAIA,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYM,IAAI,CAACD;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACb,CAACN,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACAJ,YAAYM,IAAI,CACdZ,gBAAgB;gBACdG;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YAEF,OAAOX,wBAAwBO;QACjC;QAEA,OAAOK;IACT,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type {\n Access,\n AccessArgs,\n AccessResult,\n AllOperations,\n CollectionConfig,\n User,\n Where,\n} from 'payload'\n\nimport type { MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n collection: CollectionConfig\n fieldName: string\n operation: AllOperations\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({\n accessFunction,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints: Where[] = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : User,\n )\n ) {\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user: args.req.user as UserWithTenantsField,\n })\n if (collection.slug === args.req.user.collection) {\n constraints.push({\n or: [\n {\n id: {\n equals: args.req.user.id,\n },\n },\n tenantConstraint,\n ],\n })\n } else {\n constraints.push(tenantConstraint)\n }\n return combineWhereConstraints(constraints)\n }\n\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push","tenantConstraint","slug","or","id","equals"],"mappings":"AAYA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAatD,OAAO,MAAMC,mBACX,CAAa,EACXC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR,GACnB,OAAOC;QACL,MAAMC,cAAuB,EAAE;QAC/B,MAAMC,WACJ,OAAOR,mBAAmB,aACtBA,iBACA,CAAC,EAAES,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,OAAO;QACT,OAAO,IAAIA,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYM,IAAI,CAACD;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACb,CAACN,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACA,MAAMG,mBAAmBhB,gBAAgB;gBACvCI;gBACAC;gBACAC;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YACA,IAAIV,WAAWc,IAAI,KAAKT,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,EAAE;gBAChDM,YAAYM,IAAI,CAAC;oBACfG,IAAI;wBACF;4BACEC,IAAI;gCACFC,QAAQZ,KAAKG,GAAG,CAACE,IAAI,CAACM,EAAE;4BAC1B;wBACF;wBACAH;qBACD;gBACH;YACF,OAAO;gBACLP,YAAYM,IAAI,CAACC;YACnB;YACA,OAAOjB,wBAAwBU;QACjC;QAEA,OAAOK;IACT,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "3.24.0",
3
+ "version": "3.25.0-canary.3d5c763",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -67,13 +67,13 @@
67
67
  ],
68
68
  "devDependencies": {
69
69
  "@payloadcms/eslint-config": "3.9.0",
70
- "@payloadcms/ui": "3.24.0",
71
- "payload": "3.24.0"
70
+ "@payloadcms/ui": "3.25.0-canary.3d5c763",
71
+ "payload": "3.25.0-canary.3d5c763"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "next": "^15.0.3",
75
- "@payloadcms/ui": "3.24.0",
76
- "payload": "3.24.0"
75
+ "@payloadcms/ui": "3.25.0-canary.3d5c763",
76
+ "payload": "3.25.0-canary.3d5c763"
77
77
  },
78
78
  "homepage:": "https://payloadcms.com",
79
79
  "scripts": {