@authhero/multi-tenancy 13.14.0 → 13.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -117,6 +117,52 @@ const config: AuthHeroConfig = {
117
117
  };
118
118
  ```
119
119
 
120
+ ## Migration Guide
121
+
122
+ ### Migrating from Legacy Settings Inheritance
123
+
124
+ If you're using the deprecated settings inheritance functions, migrate to the new runtime fallback API:
125
+
126
+ #### Before (Deprecated)
127
+
128
+ ```typescript
129
+ import {
130
+ withSettingsInheritance,
131
+ SettingsInheritanceConfig,
132
+ } from "@authhero/multi-tenancy";
133
+
134
+ const config: SettingsInheritanceConfig = {
135
+ controlPlaneTenantId: "main",
136
+ controlPlaneClientId: "main-client",
137
+ };
138
+
139
+ const adapters = withSettingsInheritance(baseAdapters, config);
140
+ ```
141
+
142
+ #### After (Current)
143
+
144
+ ```typescript
145
+ import {
146
+ withRuntimeFallback,
147
+ RuntimeFallbackConfig,
148
+ } from "@authhero/multi-tenancy";
149
+
150
+ const config: RuntimeFallbackConfig = {
151
+ controlPlaneTenantId: "main",
152
+ controlPlaneClientId: "main-client",
153
+ };
154
+
155
+ const adapters = withRuntimeFallback(baseAdapters, config);
156
+ ```
157
+
158
+ **What changed:**
159
+
160
+ - `withSettingsInheritance` → `withRuntimeFallback`
161
+ - `createSettingsInheritanceAdapter` → `createRuntimeFallbackAdapter`
162
+ - `SettingsInheritanceConfig` → `RuntimeFallbackConfig`
163
+
164
+ The functionality remains identical - this is purely a naming change to better reflect that settings are inherited at runtime without copying data between tenants.
165
+
120
166
  ## License
121
167
 
122
168
  MIT
@@ -1 +1 @@
1
- "use strict";var ue=Object.defineProperty;var me=(t,e,n)=>e in t?ue(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var B=(t,e,n)=>me(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("hono"),I=require("authhero"),S=require("@hono/zod-openapi"),F=require("@authhero/adapter-interfaces");var P=class extends Error{constructor(e=500,n){super(n==null?void 0:n.message,{cause:n==null?void 0:n.cause});B(this,"res");B(this,"status");this.res=n==null?void 0:n.res,this.status=e}getResponse(){return this.res?new Response(this.res.body,{status:this.status,headers:this.res.headers}):new Response(this.message,{status:this.status})}};function ee(t){const{controlPlaneTenantId:e,requireOrganizationMatch:n=!0}=t;return{async onTenantAccessValidation(a,r){if(r===e)return!0;if(n){const i=a.var.org_name,l=a.var.organization_id,o=i||l;return o?o===r:!1}return!0}}}function te(t,e,n,a){if(e===n)return!0;const r=a||t;return r?r===e:!1}function ne(t){return{async resolveDataAdapters(e){try{return await t.getAdapters(e)}catch(n){console.error(`Failed to resolve data adapters for tenant ${e}:`,n);return}}}}function re(t){return{async beforeCreate(e,n){return!n.audience&&n.id?{...n,audience:I.getTenantAudience(n.id)}:n},async afterCreate(e,n){const{accessControl:a,databaseIsolation:r,settingsInheritance:i}=t;a&&e.ctx&&await pe(e,n,a),r!=null&&r.onProvision&&await r.onProvision(n.id),(i==null?void 0:i.inheritFromControlPlane)!==!1&&e.ctx&&await he(e,n,t)},async beforeDelete(e,n){const{accessControl:a,databaseIsolation:r}=t;if(a)try{const l=(await e.adapters.organizations.list(a.controlPlaneTenantId)).organizations.find(o=>o.name===n);l&&await e.adapters.organizations.remove(a.controlPlaneTenantId,l.id)}catch(i){console.warn(`Failed to remove organization for tenant ${n}:`,i)}if(r!=null&&r.onDeprovision)try{await r.onDeprovision(n)}catch(i){console.warn(`Failed to deprovision database for tenant ${n}:`,i)}}}}async function pe(t,e,n){const{controlPlaneTenantId:a,defaultPermissions:r,defaultRoles:i,issuer:l,adminRoleName:o="Tenant Admin",adminRoleDescription:m="Full access to all tenant management operations",addCreatorToOrganization:s=!0}=n,c=await t.adapters.organizations.create(a,{name:e.id,display_name:e.friendly_name||e.id});let d;if(l&&(d=await we(t,a,o,m)),s&&t.ctx){const u=t.ctx.var.user;if(u!=null&&u.sub&&!await fe(t,a,u.sub))try{await t.adapters.userOrganizations.create(a,{user_id:u.sub,organization_id:c.id}),d&&await t.adapters.userRoles.create(a,u.sub,d,c.id)}catch(f){console.warn(`Failed to add creator ${u.sub} to organization ${c.id}:`,f)}}i&&i.length>0&&console.log(`Would assign roles ${i.join(", ")} to organization ${c.id}`),r&&r.length>0&&console.log(`Would grant permissions ${r.join(", ")} to organization ${c.id}`)}async function fe(t,e,n){const a=await t.adapters.userRoles.list(e,n,void 0,"");for(const r of a)if((await t.adapters.rolePermissions.list(e,r.id,{per_page:1e3})).some(o=>o.permission_name==="admin:organizations"))return!0;return!1}async function we(t,e,n,a){const i=(await t.adapters.roles.list(e,{})).roles.find(s=>s.name===n);if(i)return i.id;const l=await t.adapters.roles.create(e,{name:n,description:a}),o=I.MANAGEMENT_API_AUDIENCE,m=I.MANAGEMENT_API_SCOPES.map(s=>({role_id:l.id,resource_server_identifier:o,permission_name:s.value}));return await t.adapters.rolePermissions.assign(e,l.id,m),l.id}async function he(t,e,n){const{accessControl:a,settingsInheritance:r}=n;if(!a)return;const i=await t.adapters.tenants.get(a.controlPlaneTenantId);if(!i)return;let l={...i};const o=["id","created_at","updated_at","friendly_name","audience","sender_email","sender_name"];for(const m of o)delete l[m];if(r!=null&&r.inheritedKeys){const m={};for(const s of r.inheritedKeys)s in i&&!o.includes(s)&&(m[s]=i[s]);l=m}if(r!=null&&r.excludedKeys)for(const m of r.excludedKeys)delete l[m];r!=null&&r.transformSettings&&(l=r.transformSettings(l,e.id)),Object.keys(l).length>0&&await t.adapters.tenants.update(e.id,l)}const ge=["client_id","client_secret","app_secret","kid","team_id","twilio_sid","twilio_token"];function G(t,e,n=()=>!0){const{controlPlaneTenantId:a,getChildTenantIds:r,getAdapters:i}=t,l=new Map;async function o(c,d,u){return(await e(c).list(d,{q:`name:${u}`,per_page:1}))[0]??null}async function m(c){const d=await r(),u=e(await i(a));await Promise.all(d.map(async p=>{try{const f=await i(p),w=e(f),g={...u.transform(c),is_system:!0},v=await o(f,p,c.name),y=v?w.getId(v):void 0;if(v&&y){const C=w.preserveOnUpdate?w.preserveOnUpdate(v,g):g;await w.update(p,y,C)}else await w.create(p,g)}catch(f){console.error(`Failed to sync ${u.listKey} "${c.name}" to tenant "${p}":`,f)}}))}async function s(c){const d=await r();await Promise.all(d.map(async u=>{try{const p=await i(u),f=e(p),w=await o(p,u,c),h=w?f.getId(w):void 0;w&&h&&await f.remove(u,h)}catch(p){console.error(`Failed to delete entity "${c}" from tenant "${u}":`,p)}}))}return{afterCreate:async(c,d)=>{c.tenantId===a&&n(d)&&await m(d)},afterUpdate:async(c,d,u)=>{c.tenantId===a&&n(u)&&await m(u)},beforeDelete:async(c,d)=>{if(c.tenantId!==a)return;const p=await e(c.adapters).get(c.tenantId,d);p&&n(p)&&l.set(d,p)},afterDelete:async(c,d)=>{if(c.tenantId!==a)return;const u=l.get(d);u&&(l.delete(d),await s(u.name))}}}function L(t,e,n=()=>!0){const{controlPlaneTenantId:a,getControlPlaneAdapters:r,getAdapters:i}=t;return{async afterCreate(l,o){if(o.id!==a)try{const m=await r(),s=await i(o.id),c=e(m),d=e(s),u=await I.fetchAll(p=>c.listPaginated(a,p),c.listKey,{cursorField:"id",pageSize:100});await Promise.all(u.filter(p=>n(p)).map(async p=>{try{const f=c.transform(p);await d.create(o.id,{...f,is_system:!0})}catch(f){console.error(`Failed to sync entity to new tenant "${o.id}":`,f)}}))}catch(m){console.error(`Failed to sync entities to new tenant "${o.id}":`,m)}}}}const E=t=>({list:async(e,n)=>(await t.resourceServers.list(e,n)).resource_servers,listPaginated:(e,n)=>t.resourceServers.list(e,n),get:(e,n)=>t.resourceServers.get(e,n),create:(e,n)=>t.resourceServers.create(e,n),update:(e,n,a)=>t.resourceServers.update(e,n,a),remove:(e,n)=>t.resourceServers.remove(e,n),listKey:"resource_servers",getId:e=>e.id,transform:e=>({name:e.name,identifier:e.identifier,scopes:e.scopes,signing_alg:e.signing_alg,token_lifetime:e.token_lifetime,token_lifetime_for_web:e.token_lifetime_for_web})}),H=t=>({list:async(e,n)=>(await t.roles.list(e,n)).roles,listPaginated:(e,n)=>t.roles.list(e,n),get:(e,n)=>t.roles.get(e,n),create:(e,n)=>t.roles.create(e,n),update:(e,n,a)=>t.roles.update(e,n,a),remove:(e,n)=>t.roles.remove(e,n),listKey:"roles",getId:e=>e.id,transform:e=>({name:e.name,description:e.description})}),k=t=>({list:async(e,n)=>(await t.connections.list(e,n)).connections,listPaginated:(e,n)=>t.connections.list(e,n),get:(e,n)=>t.connections.get(e,n),create:(e,n)=>t.connections.create(e,n),update:(e,n,a)=>t.connections.update(e,n,a),remove:(e,n)=>t.connections.remove(e,n),listKey:"connections",getId:e=>e.id,transform:e=>{const n=e.options?{...e.options}:{};for(const a of ge)delete n[a];return{name:e.name,display_name:e.display_name,strategy:e.strategy,options:n,response_type:e.response_type,response_mode:e.response_mode,is_domain_connection:e.is_domain_connection,show_as_button:e.show_as_button,metadata:e.metadata}},preserveOnUpdate:(e,n)=>{const a=e.options||{};return{...n,options:{...n.options,client_id:a.client_id,client_secret:a.client_secret,app_secret:a.app_secret,kid:a.kid,team_id:a.team_id,twilio_sid:a.twilio_sid,twilio_token:a.twilio_token}}}});function ae(t){const{sync:e={},filters:n={}}=t,a=e.resourceServers??!0,r=e.roles??!0,i=e.connections??!0,l=a?G(t,E,n.resourceServers):void 0,o=r?G(t,H,n.roles):void 0,m=i?G(t,k,n.connections):void 0,s=a?L(t,E,n.resourceServers):void 0,c=r?L(t,H,n.roles):void 0,d=i?L(t,k,n.connections):void 0,u=r?{async afterCreate(w,h){var g;if(h.id!==t.controlPlaneTenantId){await((g=c==null?void 0:c.afterCreate)==null?void 0:g.call(c,w,h));try{const v=await t.getControlPlaneAdapters(),y=await t.getAdapters(h.id),C=await I.fetchAll(b=>v.roles.list(t.controlPlaneTenantId,b),"roles",{cursorField:"id",pageSize:100}),M=new Map;for(const b of C.filter(_=>{var A;return((A=n.roles)==null?void 0:A.call(n,_))??!0})){const _=await p(y,h.id,b.name);_&&M.set(b.name,_.id)}for(const b of C.filter(_=>{var A;return((A=n.roles)==null?void 0:A.call(n,_))??!0})){const _=M.get(b.name);if(_)try{const A=await v.rolePermissions.list(t.controlPlaneTenantId,b.id,{});A.length>0&&await y.rolePermissions.assign(h.id,_,A.map(z=>({role_id:_,resource_server_identifier:z.resource_server_identifier,permission_name:z.permission_name})))}catch(A){console.error(`Failed to sync permissions for role "${b.name}" to tenant "${h.id}":`,A)}}}catch(v){console.error(`Failed to sync role permissions to tenant "${h.id}":`,v)}}}}:void 0;async function p(w,h,g){return(await w.roles.list(h,{q:`name:${g}`,per_page:1})).roles[0]??null}return{entityHooks:{resourceServers:l,roles:o,connections:m},tenantHooks:{async afterCreate(w,h){const g=[s==null?void 0:s.afterCreate,(u==null?void 0:u.afterCreate)??(c==null?void 0:c.afterCreate),d==null?void 0:d.afterCreate],v=[];for(const y of g)if(y)try{await y(w,h)}catch(C){v.push(C instanceof Error?C:new Error(String(C)))}if(v.length===1)throw v[0];if(v.length>1)throw new AggregateError(v,v.map(y=>y.message).join("; "))}}}}function N(t,e){const n=new S.OpenAPIHono;return n.openapi(S.createRoute({tags:["tenants"],method:"get",path:"/",request:{query:F.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:S.z.object({tenants:S.z.array(F.tenantSchema),start:S.z.number().optional(),limit:S.z.number().optional(),length:S.z.number().optional()})}},description:"List of tenants"}}}),async a=>{var p,f,w,h;const r=a.req.valid("query"),{page:i,per_page:l,include_totals:o,q:m}=r,s=a.var.user,c=(s==null?void 0:s.permissions)||[];if(c.includes("auth:read")||c.includes("admin:organizations")){const g=await a.env.data.tenants.list({page:i,per_page:l,include_totals:o,q:m});return o?a.json({tenants:g.tenants,start:((p=g.totals)==null?void 0:p.start)??0,limit:((f=g.totals)==null?void 0:f.limit)??l,length:g.tenants.length}):a.json({tenants:g.tenants})}if(t.accessControl&&(s!=null&&s.sub)){const g=t.accessControl.controlPlaneTenantId,y=(await I.fetchAll(O=>a.env.data.userOrganizations.listUserOrganizations(g,s.sub,O),"organizations")).map(O=>O.name);if(y.length===0)return o?a.json({tenants:[],start:0,limit:l??50,length:0}):a.json({tenants:[]});const C=y.length,M=i??0,b=l??50,_=M*b,A=y.slice(_,_+b);if(A.length===0)return o?a.json({tenants:[],start:_,limit:b,length:C}):a.json({tenants:[]});const z=A.map(O=>`id:${O}`).join(" OR "),q=m?`(${z}) AND (${m})`:z,R=await a.env.data.tenants.list({q,per_page:b,include_totals:!1});return o?a.json({tenants:R.tenants,start:_,limit:b,length:C}):a.json({tenants:R.tenants})}const u=await a.env.data.tenants.list({page:i,per_page:l,include_totals:o,q:m});return o?a.json({tenants:u.tenants,start:((w=u.totals)==null?void 0:w.start)??0,limit:((h=u.totals)==null?void 0:h.limit)??l,length:u.tenants.length}):a.json({tenants:u.tenants})}),n.openapi(S.createRoute({tags:["tenants"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:F.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:F.tenantSchema}},description:"Tenant created"},400:{description:"Validation error"},409:{description:"Tenant with this ID already exists"}}}),async a=>{var m,s;const r=a.var.user;if(!(r!=null&&r.sub))throw new P(401,{message:"Authentication required to create tenants"});let i=a.req.valid("json");const l={adapters:a.env.data,ctx:a};(m=e.tenants)!=null&&m.beforeCreate&&(i=await e.tenants.beforeCreate(l,i));const o=await a.env.data.tenants.create(i);return(s=e.tenants)!=null&&s.afterCreate&&await e.tenants.afterCreate(l,o),a.json(o,201)}),n.openapi(S.createRoute({tags:["tenants"],method:"delete",path:"/{id}",request:{params:S.z.object({id:S.z.string()})},security:[{Bearer:["delete:tenants"]}],responses:{204:{description:"Tenant deleted"},403:{description:"Access denied or cannot delete the control plane"},404:{description:"Tenant not found"}}}),async a=>{var o,m;const{id:r}=a.req.valid("param");if(t.accessControl){const s=a.var.user,c=t.accessControl.controlPlaneTenantId;if(!(s!=null&&s.sub))throw new P(401,{message:"Authentication required"});if(r===c)throw new P(403,{message:"Cannot delete the control plane"});if(!(await I.fetchAll(p=>a.env.data.userOrganizations.listUserOrganizations(c,s.sub,p),"organizations")).some(p=>p.name===r))throw new P(403,{message:"Access denied to this tenant"})}if(!await a.env.data.tenants.get(r))throw new P(404,{message:"Tenant not found"});const l={adapters:a.env.data,ctx:a};return(o=e.tenants)!=null&&o.beforeDelete&&await e.tenants.beforeDelete(l,r),await a.env.data.tenants.remove(r),(m=e.tenants)!=null&&m.afterDelete&&await e.tenants.afterDelete(l,r),a.body(null,204)}),n}function ve(t){const e=[{pattern:/\/api\/v2\/resource-servers\/([^/]+)$/,type:"resource_server"},{pattern:/\/api\/v2\/roles\/([^/]+)$/,type:"role"},{pattern:/\/api\/v2\/connections\/([^/]+)$/,type:"connection"}];for(const{pattern:n,type:a}of e){const r=t.match(n);if(r&&r[1])return{type:a,id:r[1]}}return null}async function ye(t,e,n){try{switch(n.type){case"resource_server":{const a=await t.resourceServers.get(e,n.id);return(a==null?void 0:a.is_system)===!0}case"role":{const a=await t.roles.get(e,n.id);return(a==null?void 0:a.is_system)===!0}case"connection":{const a=await t.connections.get(e,n.id);return(a==null?void 0:a.is_system)===!0}default:return!1}}catch{return!1}}function _e(t){return{resource_server:"resource server",role:"role",connection:"connection"}[t]}function se(){return async(t,e)=>{if(!["PATCH","PUT","DELETE"].includes(t.req.method))return e();const n=ve(t.req.path);if(!n)return e();const a=t.var.tenant_id||t.req.header("x-tenant-id")||t.req.header("tenant-id");if(!a)return e();if(await ye(t.env.data,a,n))throw new P(403,{message:`This ${_e(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return e()}}function oe(t){return async(e,n)=>{if(!t.accessControl)return n();const a=e.var.tenant_id,r=e.var.organization_id;if(!a)throw new P(400,{message:"Tenant ID not found in request"});if(!te(r,a,t.accessControl.controlPlaneTenantId))throw new P(403,{message:`Access denied to tenant ${a}`});return n()}}function ie(t){return async(e,n)=>{if(!t.subdomainRouting)return n();const{baseDomain:a,reservedSubdomains:r=[],resolveSubdomain:i}=t.subdomainRouting,l=e.req.header("host")||"";let o=null;if(l.endsWith(a)){const s=l.slice(0,-(a.length+1));s&&!s.includes(".")&&(o=s)}if(o&&r.includes(o)&&(o=null),!o)return t.accessControl&&e.set("tenant_id",t.accessControl.controlPlaneTenantId),n();let m=null;if(i)m=await i(o);else if(t.subdomainRouting.useOrganizations!==!1&&t.accessControl)try{const s=await e.env.data.organizations.get(t.accessControl.controlPlaneTenantId,o);s&&(m=s.id)}catch{}if(!m)throw new P(404,{message:`Tenant not found for subdomain: ${o}`});return e.set("tenant_id",m),n()}}function ce(t){return async(e,n)=>{if(!t.databaseIsolation)return n();const a=e.var.tenant_id;if(!a)throw new P(400,{message:"Tenant ID not found in request"});try{const r=await t.databaseIsolation.getAdapters(a);e.env.data=r}catch(r){throw console.error(`Failed to resolve database for tenant ${a}:`,r),new P(500,{message:"Failed to resolve tenant database"})}return n()}}function V(t){const e=ie(t),n=oe(t),a=ce(t);return async(r,i)=>(await e(r,async()=>{}),await n(r,async()=>{}),await a(r,async()=>{}),i())}function be(t){const e=j(t);return{name:"multi-tenancy",middleware:V(t),hooks:e,routes:[{path:"/management",handler:N(t,e)}],onRegister:async()=>{console.log("Multi-tenancy plugin registered"),t.accessControl&&console.log(` - Access control enabled (control plane: ${t.accessControl.controlPlaneTenantId})`),t.subdomainRouting&&console.log(` - Subdomain routing enabled (base domain: ${t.subdomainRouting.baseDomain})`),t.databaseIsolation&&console.log(" - Database isolation enabled")}}}function j(t){const e=t.accessControl?ee(t.accessControl):{},n=t.databaseIsolation?ne(t.databaseIsolation):{},a=re(t);return{...e,...n,tenants:a}}function le(t){const e=new x.Hono,n=j(t);return e.route("/tenants",N(t,n)),e}function Ae(t){return{hooks:j(t),middleware:V(t),app:le(t),config:t}}function Ce(t){var C,M,b,_,A,z,q,R,O,W,Q,J,X,Y,Z;const{controlPlaneTenantId:e="control_plane",sync:n,multiTenancy:a,entityHooks:r,...i}=t,l={...a,accessControl:{controlPlaneTenantId:e,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...a==null?void 0:a.accessControl}},o=j(l),m=((C=a==null?void 0:a.databaseIsolation)==null?void 0:C.getAdapters)??(async()=>t.dataAdapter),{entityHooks:s,tenantHooks:c}=ae({controlPlaneTenantId:e,getChildTenantIds:async()=>(await I.fetchAll(T=>t.dataAdapter.tenants.list(T),"tenants",{cursorField:"id",pageSize:100})).filter(T=>T.id!==e).map(T=>T.id),getAdapters:m,getControlPlaneAdapters:async()=>m(e),sync:n});function d(D,T){if(!(!D&&!T))return D?T?async(...de)=>{const $=[];for(const U of[D,T])try{await U(...de)}catch(K){$.push(K instanceof Error?K:new Error(String(K)))}if($.length===1)throw $[0];if($.length>1)throw new AggregateError($,$.map(U=>U.message).join("; "))}:D:T}const u={...r,resourceServers:s!=null&&s.resourceServers?{...r==null?void 0:r.resourceServers,afterCreate:d((M=r==null?void 0:r.resourceServers)==null?void 0:M.afterCreate,s.resourceServers.afterCreate),afterUpdate:d((b=r==null?void 0:r.resourceServers)==null?void 0:b.afterUpdate,s.resourceServers.afterUpdate),beforeDelete:d((_=r==null?void 0:r.resourceServers)==null?void 0:_.beforeDelete,s.resourceServers.beforeDelete),afterDelete:d((A=r==null?void 0:r.resourceServers)==null?void 0:A.afterDelete,s.resourceServers.afterDelete)}:r==null?void 0:r.resourceServers,roles:s!=null&&s.roles?{...r==null?void 0:r.roles,afterCreate:d((z=r==null?void 0:r.roles)==null?void 0:z.afterCreate,s.roles.afterCreate),afterUpdate:d((q=r==null?void 0:r.roles)==null?void 0:q.afterUpdate,s.roles.afterUpdate),beforeDelete:d((R=r==null?void 0:r.roles)==null?void 0:R.beforeDelete,s.roles.beforeDelete),afterDelete:d((O=r==null?void 0:r.roles)==null?void 0:O.afterDelete,s.roles.afterDelete)}:r==null?void 0:r.roles,connections:s!=null&&s.connections?{...r==null?void 0:r.connections,afterCreate:d((W=r==null?void 0:r.connections)==null?void 0:W.afterCreate,s.connections.afterCreate),afterUpdate:d((Q=r==null?void 0:r.connections)==null?void 0:Q.afterUpdate,s.connections.afterUpdate),beforeDelete:d((J=r==null?void 0:r.connections)==null?void 0:J.beforeDelete,s.connections.beforeDelete),afterDelete:d((X=r==null?void 0:r.connections)==null?void 0:X.afterDelete,s.connections.afterDelete)}:r==null?void 0:r.connections,tenants:c?{...r==null?void 0:r.tenants,afterCreate:d((Y=r==null?void 0:r.tenants)==null?void 0:Y.afterCreate,c.afterCreate)}:r==null?void 0:r.tenants},p={...o,tenants:c?{...o.tenants,afterCreate:d((Z=o.tenants)==null?void 0:Z.afterCreate,c.afterCreate)}:o.tenants},f=N(l,p),w=I.init({...i,entityHooks:u,managementApiExtensions:[...i.managementApiExtensions||[],{path:"/tenants",router:f}]}),{app:h,managementApp:g,...v}=w,y=new x.Hono;return y.onError((D,T)=>D instanceof P?D.getResponse():(console.error(D),T.json({message:"Internal Server Error"},500))),y.use("/api/v2/*",se()),y.route("/",h),{app:y,managementApp:g,...v,multiTenancyConfig:l,multiTenancyHooks:o}}exports.createAccessControlHooks=ee;exports.createAccessControlMiddleware=oe;exports.createDatabaseHooks=ne;exports.createDatabaseMiddleware=ce;exports.createMultiTenancy=le;exports.createMultiTenancyHooks=j;exports.createMultiTenancyMiddleware=V;exports.createMultiTenancyPlugin=be;exports.createProtectSyncedMiddleware=se;exports.createProvisioningHooks=re;exports.createSubdomainMiddleware=ie;exports.createSyncHooks=ae;exports.createTenantsOpenAPIRouter=N;exports.init=Ce;exports.setupMultiTenancy=Ae;exports.validateTenantAccess=te;Object.keys(I).forEach(t=>{t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:()=>I[t]})});
1
+ "use strict";var pe=Object.defineProperty;var fe=(t,e,n)=>e in t?pe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var G=(t,e,n)=>fe(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ee=require("hono"),P=require("authhero"),I=require("@hono/zod-openapi"),D=require("@authhero/adapter-interfaces");var S=class extends Error{constructor(e=500,n){super(n==null?void 0:n.message,{cause:n==null?void 0:n.cause});G(this,"res");G(this,"status");this.res=n==null?void 0:n.res,this.status=e}getResponse(){return this.res?new Response(this.res.body,{status:this.status,headers:this.res.headers}):new Response(this.message,{status:this.status})}};function te(t){const{controlPlaneTenantId:e,requireOrganizationMatch:n=!0}=t;return{async onTenantAccessValidation(a,r){if(r===e)return!0;if(n){const l=a.var.org_name,s=a.var.organization_id,i=l||s;return i?i===r:!1}return!0}}}function ne(t,e,n,a){if(e===n)return!0;const r=a||t;return r?r===e:!1}function re(t){return{async resolveDataAdapters(e){try{return await t.getAdapters(e)}catch(n){console.error(`Failed to resolve data adapters for tenant ${e}:`,n);return}}}}function ae(t){return{async beforeCreate(e,n){return!n.audience&&n.id?{...n,audience:P.getTenantAudience(n.id)}:n},async afterCreate(e,n){const{accessControl:a,databaseIsolation:r}=t;a&&e.ctx&&await we(e,n,a),r!=null&&r.onProvision&&await r.onProvision(n.id)},async beforeDelete(e,n){const{accessControl:a,databaseIsolation:r}=t;if(a)try{const s=(await e.adapters.organizations.list(a.controlPlaneTenantId)).organizations.find(i=>i.name===n);s&&await e.adapters.organizations.remove(a.controlPlaneTenantId,s.id)}catch(l){console.warn(`Failed to remove organization for tenant ${n}:`,l)}if(r!=null&&r.onDeprovision)try{await r.onDeprovision(n)}catch(l){console.warn(`Failed to deprovision database for tenant ${n}:`,l)}}}}async function we(t,e,n){const{controlPlaneTenantId:a,defaultPermissions:r,defaultRoles:l,issuer:s,adminRoleName:i="Tenant Admin",adminRoleDescription:p="Full access to all tenant management operations",addCreatorToOrganization:o=!0}=n,c=await t.adapters.organizations.create(a,{name:e.id,display_name:e.friendly_name||e.id});let u;if(s&&(u=await he(t,a,i,p)),o&&t.ctx){const d=t.ctx.var.user;if(d!=null&&d.sub&&!await ge(t,a,d.sub))try{await t.adapters.userOrganizations.create(a,{user_id:d.sub,organization_id:c.id}),u&&await t.adapters.userRoles.create(a,d.sub,u,c.id)}catch(f){console.warn(`Failed to add creator ${d.sub} to organization ${c.id}:`,f)}}l&&l.length>0&&console.log(`Would assign roles ${l.join(", ")} to organization ${c.id}`),r&&r.length>0&&console.log(`Would grant permissions ${r.join(", ")} to organization ${c.id}`)}async function ge(t,e,n){const a=await t.adapters.userRoles.list(e,n,void 0,"");for(const r of a)if((await t.adapters.rolePermissions.list(e,r.id,{per_page:1e3})).some(i=>i.permission_name==="admin:organizations"))return!0;return!1}async function he(t,e,n,a){const l=(await t.adapters.roles.list(e,{})).roles.find(o=>o.name===n);if(l)return l.id;const s=await t.adapters.roles.create(e,{name:n,description:a}),i=P.MANAGEMENT_API_AUDIENCE,p=P.MANAGEMENT_API_SCOPES.map(o=>({role_id:s.id,resource_server_identifier:i,permission_name:o.value}));return await t.adapters.rolePermissions.assign(e,s.id,p),s.id}const ve=["client_id","client_secret","app_secret","kid","team_id","twilio_sid","twilio_token"];function K(t,e,n=()=>!0){const{controlPlaneTenantId:a,getChildTenantIds:r,getAdapters:l}=t,s=new Map;async function i(c,u,d){return(await e(c).list(u,{q:`name:${d}`,per_page:1}))[0]??null}async function p(c){const u=await r(),d=e(await l(a));await Promise.all(u.map(async m=>{try{const f=await l(m),w=e(f),h={...d.transform(c),is_system:!0},v=await i(f,m,c.name),_=v?w.getId(v):void 0;if(v&&_){const T=w.preserveOnUpdate?w.preserveOnUpdate(v,h):h;await w.update(m,_,T)}else await w.create(m,h)}catch(f){console.error(`Failed to sync ${d.listKey} "${c.name}" to tenant "${m}":`,f)}}))}async function o(c){const u=await r();await Promise.all(u.map(async d=>{try{const m=await l(d),f=e(m),w=await i(m,d,c),g=w?f.getId(w):void 0;w&&g&&await f.remove(d,g)}catch(m){console.error(`Failed to delete entity "${c}" from tenant "${d}":`,m)}}))}return{afterCreate:async(c,u)=>{c.tenantId===a&&n(u)&&await p(u)},afterUpdate:async(c,u,d)=>{c.tenantId===a&&n(d)&&await p(d)},beforeDelete:async(c,u)=>{if(c.tenantId!==a)return;const m=await e(c.adapters).get(c.tenantId,u);m&&n(m)&&s.set(u,m)},afterDelete:async(c,u)=>{if(c.tenantId!==a)return;const d=s.get(u);d&&(s.delete(u),await o(d.name))}}}function L(t,e,n=()=>!0){const{controlPlaneTenantId:a,getControlPlaneAdapters:r,getAdapters:l}=t;return{async afterCreate(s,i){if(i.id!==a)try{const p=await r(),o=await l(i.id),c=e(p),u=e(o),d=await P.fetchAll(m=>c.listPaginated(a,m),c.listKey,{cursorField:"id",pageSize:100});await Promise.all(d.filter(m=>n(m)).map(async m=>{try{const f=c.transform(m);await u.create(i.id,{...f,is_system:!0})}catch(f){console.error(`Failed to sync entity to new tenant "${i.id}":`,f)}}))}catch(p){console.error(`Failed to sync entities to new tenant "${i.id}":`,p)}}}}const E=t=>({list:async(e,n)=>(await t.resourceServers.list(e,n)).resource_servers,listPaginated:(e,n)=>t.resourceServers.list(e,n),get:(e,n)=>t.resourceServers.get(e,n),create:(e,n)=>t.resourceServers.create(e,n),update:(e,n,a)=>t.resourceServers.update(e,n,a),remove:(e,n)=>t.resourceServers.remove(e,n),listKey:"resource_servers",getId:e=>e.id,transform:e=>({name:e.name,identifier:e.identifier,scopes:e.scopes,signing_alg:e.signing_alg,token_lifetime:e.token_lifetime,token_lifetime_for_web:e.token_lifetime_for_web})}),H=t=>({list:async(e,n)=>(await t.roles.list(e,n)).roles,listPaginated:(e,n)=>t.roles.list(e,n),get:(e,n)=>t.roles.get(e,n),create:(e,n)=>t.roles.create(e,n),update:(e,n,a)=>t.roles.update(e,n,a),remove:(e,n)=>t.roles.remove(e,n),listKey:"roles",getId:e=>e.id,transform:e=>({name:e.name,description:e.description})}),x=t=>({list:async(e,n)=>(await t.connections.list(e,n)).connections,listPaginated:(e,n)=>t.connections.list(e,n),get:(e,n)=>t.connections.get(e,n),create:(e,n)=>t.connections.create(e,n),update:(e,n,a)=>t.connections.update(e,n,a),remove:(e,n)=>t.connections.remove(e,n),listKey:"connections",getId:e=>e.id,transform:e=>{const n=e.options?{...e.options}:{};for(const a of ve)delete n[a];return{name:e.name,display_name:e.display_name,strategy:e.strategy,options:n,response_type:e.response_type,response_mode:e.response_mode,is_domain_connection:e.is_domain_connection,show_as_button:e.show_as_button,metadata:e.metadata}},preserveOnUpdate:(e,n)=>{const a=e.options||{};return{...n,options:{...n.options,client_id:a.client_id,client_secret:a.client_secret,app_secret:a.app_secret,kid:a.kid,team_id:a.team_id,twilio_sid:a.twilio_sid,twilio_token:a.twilio_token}}}});function se(t){const{sync:e={},filters:n={}}=t,a=e.resourceServers??!0,r=e.roles??!0,l=e.connections??!0,s=a?K(t,E,n.resourceServers):void 0,i=r?K(t,H,n.roles):void 0,p=l?K(t,x,n.connections):void 0,o=a?L(t,E,n.resourceServers):void 0,c=r?L(t,H,n.roles):void 0,u=l?L(t,x,n.connections):void 0,d=r?{async afterCreate(w,g){var h;if(g.id!==t.controlPlaneTenantId){await((h=c==null?void 0:c.afterCreate)==null?void 0:h.call(c,w,g));try{const v=await t.getControlPlaneAdapters(),_=await t.getAdapters(g.id),T=await P.fetchAll(b=>v.roles.list(t.controlPlaneTenantId,b),"roles",{cursorField:"id",pageSize:100}),M=new Map;for(const b of T.filter(y=>{var A;return((A=n.roles)==null?void 0:A.call(n,y))??!0})){const y=await m(_,g.id,b.name);y&&M.set(b.name,y.id)}for(const b of T.filter(y=>{var A;return((A=n.roles)==null?void 0:A.call(n,y))??!0})){const y=M.get(b.name);if(y)try{const A=await v.rolePermissions.list(t.controlPlaneTenantId,b.id,{});A.length>0&&await _.rolePermissions.assign(g.id,y,A.map(O=>({role_id:y,resource_server_identifier:O.resource_server_identifier,permission_name:O.permission_name})))}catch(A){console.error(`Failed to sync permissions for role "${b.name}" to tenant "${g.id}":`,A)}}}catch(v){console.error(`Failed to sync role permissions to tenant "${g.id}":`,v)}}}}:void 0;async function m(w,g,h){return(await w.roles.list(g,{q:`name:${h}`,per_page:1})).roles[0]??null}return{entityHooks:{resourceServers:s,roles:i,connections:p},tenantHooks:{async afterCreate(w,g){const h=[o==null?void 0:o.afterCreate,(d==null?void 0:d.afterCreate)??(c==null?void 0:c.afterCreate),u==null?void 0:u.afterCreate],v=[];for(const _ of h)if(_)try{await _(w,g)}catch(T){v.push(T instanceof Error?T:new Error(String(T)))}if(v.length===1)throw v[0];if(v.length>1)throw new AggregateError(v,v.map(_=>_.message).join("; "))}}}}function N(t,e){const n=new I.OpenAPIHono;return n.openapi(I.createRoute({tags:["tenants"],method:"get",path:"/",request:{query:D.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:I.z.object({tenants:I.z.array(D.tenantSchema),start:I.z.number().optional(),limit:I.z.number().optional(),length:I.z.number().optional()})}},description:"List of tenants"}}}),async a=>{var m,f,w,g;const r=a.req.valid("query"),{page:l,per_page:s,include_totals:i,q:p}=r,o=a.var.user,c=(o==null?void 0:o.permissions)||[];if(c.includes("auth:read")||c.includes("admin:organizations")){const h=await a.env.data.tenants.list({page:l,per_page:s,include_totals:i,q:p});return i?a.json({tenants:h.tenants,start:((m=h.totals)==null?void 0:m.start)??0,limit:((f=h.totals)==null?void 0:f.limit)??s,length:h.tenants.length}):a.json({tenants:h.tenants})}if(t.accessControl&&(o!=null&&o.sub)){const h=t.accessControl.controlPlaneTenantId,_=(await P.fetchAll(R=>a.env.data.userOrganizations.listUserOrganizations(h,o.sub,R),"organizations")).map(R=>R.name);if(_.length===0)return i?a.json({tenants:[],start:0,limit:s??50,length:0}):a.json({tenants:[]});const T=_.length,M=l??0,b=s??50,y=M*b,A=_.slice(y,y+b);if(A.length===0)return i?a.json({tenants:[],start:y,limit:b,length:T}):a.json({tenants:[]});const O=A.map(R=>`id:${R}`).join(" OR "),j=p?`(${O}) AND (${p})`:O,q=await a.env.data.tenants.list({q:j,per_page:b,include_totals:!1});return i?a.json({tenants:q.tenants,start:y,limit:b,length:T}):a.json({tenants:q.tenants})}const d=await a.env.data.tenants.list({page:l,per_page:s,include_totals:i,q:p});return i?a.json({tenants:d.tenants,start:((w=d.totals)==null?void 0:w.start)??0,limit:((g=d.totals)==null?void 0:g.limit)??s,length:d.tenants.length}):a.json({tenants:d.tenants})}),n.openapi(I.createRoute({tags:["tenants"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:D.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:D.tenantSchema}},description:"Tenant created"},400:{description:"Validation error"},409:{description:"Tenant with this ID already exists"}}}),async a=>{var p,o;const r=a.var.user;if(!(r!=null&&r.sub))throw new S(401,{message:"Authentication required to create tenants"});let l=a.req.valid("json");const s={adapters:a.env.data,ctx:a};(p=e.tenants)!=null&&p.beforeCreate&&(l=await e.tenants.beforeCreate(s,l));const i=await a.env.data.tenants.create(l);return(o=e.tenants)!=null&&o.afterCreate&&await e.tenants.afterCreate(s,i),a.json(i,201)}),n.openapi(I.createRoute({tags:["tenants"],method:"delete",path:"/{id}",request:{params:I.z.object({id:I.z.string()})},security:[{Bearer:["delete:tenants"]}],responses:{204:{description:"Tenant deleted"},403:{description:"Access denied or cannot delete the control plane"},404:{description:"Tenant not found"}}}),async a=>{var i,p;const{id:r}=a.req.valid("param");if(t.accessControl){const o=a.var.user,c=t.accessControl.controlPlaneTenantId;if(!(o!=null&&o.sub))throw new S(401,{message:"Authentication required"});if(r===c)throw new S(403,{message:"Cannot delete the control plane"});if(!(await P.fetchAll(m=>a.env.data.userOrganizations.listUserOrganizations(c,o.sub,m),"organizations")).some(m=>m.name===r))throw new S(403,{message:"Access denied to this tenant"})}if(!await a.env.data.tenants.get(r))throw new S(404,{message:"Tenant not found"});const s={adapters:a.env.data,ctx:a};return(i=e.tenants)!=null&&i.beforeDelete&&await e.tenants.beforeDelete(s,r),await a.env.data.tenants.remove(r),(p=e.tenants)!=null&&p.afterDelete&&await e.tenants.afterDelete(s,r),a.body(null,204)}),n}function _e(t){const e=[{pattern:/\/api\/v2\/resource-servers\/([^/]+)$/,type:"resource_server"},{pattern:/\/api\/v2\/roles\/([^/]+)$/,type:"role"},{pattern:/\/api\/v2\/connections\/([^/]+)$/,type:"connection"}];for(const{pattern:n,type:a}of e){const r=t.match(n);if(r&&r[1])return{type:a,id:r[1]}}return null}async function ye(t,e,n){try{switch(n.type){case"resource_server":{const a=await t.resourceServers.get(e,n.id);return(a==null?void 0:a.is_system)===!0}case"role":{const a=await t.roles.get(e,n.id);return(a==null?void 0:a.is_system)===!0}case"connection":{const a=await t.connections.get(e,n.id);return(a==null?void 0:a.is_system)===!0}default:return!1}}catch{return!1}}function be(t){return{resource_server:"resource server",role:"role",connection:"connection"}[t]}function oe(){return async(t,e)=>{if(!["PATCH","PUT","DELETE"].includes(t.req.method))return e();const n=_e(t.req.path);if(!n)return e();const a=t.var.tenant_id||t.req.header("x-tenant-id")||t.req.header("tenant-id");if(!a)return e();if(await ye(t.env.data,a,n))throw new S(403,{message:`This ${be(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return e()}}function V(t,e){const{controlPlaneTenantId:n,controlPlaneClientId:a}=e;return{...t,legacyClients:{...t.legacyClients,get:async r=>{var u;const l=await t.legacyClients.get(r);if(!l)return null;const s=a?await t.legacyClients.get(a):void 0,i=await t.connections.list(l.tenant.id),p=n?await t.connections.list(n):{connections:[]},o=i.connections.map(d=>{var w;const m=(w=p.connections)==null?void 0:w.find(g=>g.name===d.name);if(!(m!=null&&m.options))return d;const f=D.connectionSchema.parse({...m||{},...d});return f.options=D.connectionOptionsSchema.parse({...m.options||{},...d.options}),f}).filter(d=>d),c={...(s==null?void 0:s.tenant)||{},...l.tenant};return!l.tenant.audience&&((u=s==null?void 0:s.tenant)!=null&&u.audience)&&(c.audience=s.tenant.audience),{...l,web_origins:[...(s==null?void 0:s.web_origins)||[],...l.web_origins||[]],allowed_logout_urls:[...(s==null?void 0:s.allowed_logout_urls)||[],...l.allowed_logout_urls||[]],callbacks:[...(s==null?void 0:s.callbacks)||[],...l.callbacks||[]],connections:o,tenant:c}}},connections:{...t.connections,get:async(r,l)=>{const s=await t.connections.get(r,l);if(!s||!n)return s;const i=await t.connections.get(n,l);if(!i)return s;const p=D.connectionSchema.parse({...i,...s});return p.options=D.connectionOptionsSchema.parse({...i.options||{},...s.options}),p},list:async(r,l)=>{const s=await t.connections.list(r,l);if(!n||r===n)return s;const i=await t.connections.list(n),p=s.connections.map(o=>{var d;const c=(d=i.connections)==null?void 0:d.find(m=>m.name===o.name);if(!(c!=null&&c.options))return o;const u=D.connectionSchema.parse({...c,...o});return u.options=D.connectionOptionsSchema.parse({...c.options||{},...o.options}),u});return{...s,connections:p}}}}}function ie(t,e){return V(t,e)}const Ae=V,Te=ie;function ce(t){return async(e,n)=>{if(!t.accessControl)return n();const a=e.var.tenant_id,r=e.var.organization_id;if(!a)throw new S(400,{message:"Tenant ID not found in request"});if(!ne(r,a,t.accessControl.controlPlaneTenantId))throw new S(403,{message:`Access denied to tenant ${a}`});return n()}}function le(t){return async(e,n)=>{if(!t.subdomainRouting)return n();const{baseDomain:a,reservedSubdomains:r=[],resolveSubdomain:l}=t.subdomainRouting,s=e.req.header("host")||"";let i=null;if(s.endsWith(a)){const o=s.slice(0,-(a.length+1));o&&!o.includes(".")&&(i=o)}if(i&&r.includes(i)&&(i=null),!i)return t.accessControl&&e.set("tenant_id",t.accessControl.controlPlaneTenantId),n();let p=null;if(l)p=await l(i);else if(t.subdomainRouting.useOrganizations!==!1&&t.accessControl)try{const o=await e.env.data.organizations.get(t.accessControl.controlPlaneTenantId,i);o&&(p=o.id)}catch{}if(!p)throw new S(404,{message:`Tenant not found for subdomain: ${i}`});return e.set("tenant_id",p),n()}}function de(t){return async(e,n)=>{if(!t.databaseIsolation)return n();const a=e.var.tenant_id;if(!a)throw new S(400,{message:"Tenant ID not found in request"});try{const r=await t.databaseIsolation.getAdapters(a);e.env.data=r}catch(r){throw console.error(`Failed to resolve database for tenant ${a}:`,r),new S(500,{message:"Failed to resolve tenant database"})}return n()}}function W(t){const e=le(t),n=ce(t),a=de(t);return async(r,l)=>(await e(r,async()=>{}),await n(r,async()=>{}),await a(r,async()=>{}),l())}function Ce(t){const e=F(t);return{name:"multi-tenancy",middleware:W(t),hooks:e,routes:[{path:"/management",handler:N(t,e)}],onRegister:async()=>{console.log("Multi-tenancy plugin registered"),t.accessControl&&console.log(` - Access control enabled (control plane: ${t.accessControl.controlPlaneTenantId})`),t.subdomainRouting&&console.log(` - Subdomain routing enabled (base domain: ${t.subdomainRouting.baseDomain})`),t.databaseIsolation&&console.log(" - Database isolation enabled")}}}function F(t){const e=t.accessControl?te(t.accessControl):{},n=t.databaseIsolation?re(t.databaseIsolation):{},a=ae(t);return{...e,...n,tenants:a}}function ue(t){const e=new ee.Hono,n=F(t);return e.route("/tenants",N(t,n)),e}function Se(t){return{hooks:F(t),middleware:W(t),app:ue(t),config:t}}function Ie(t){var T,M,b,y,A,O,j,q,R,Q,J,X,Y,Z,k;const{controlPlaneTenantId:e="control_plane",sync:n,multiTenancy:a,entityHooks:r,...l}=t,s={...a,accessControl:{controlPlaneTenantId:e,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...a==null?void 0:a.accessControl}},i=F(s),p=((T=a==null?void 0:a.databaseIsolation)==null?void 0:T.getAdapters)??(async()=>t.dataAdapter),{entityHooks:o,tenantHooks:c}=se({controlPlaneTenantId:e,getChildTenantIds:async()=>(await P.fetchAll(C=>t.dataAdapter.tenants.list(C),"tenants",{cursorField:"id",pageSize:100})).filter(C=>C.id!==e).map(C=>C.id),getAdapters:p,getControlPlaneAdapters:async()=>p(e),sync:n});function u(z,C){if(!(!z&&!C))return z?C?async(...me)=>{const $=[];for(const U of[z,C])try{await U(...me)}catch(B){$.push(B instanceof Error?B:new Error(String(B)))}if($.length===1)throw $[0];if($.length>1)throw new AggregateError($,$.map(U=>U.message).join("; "))}:z:C}const d={...r,resourceServers:o!=null&&o.resourceServers?{...r==null?void 0:r.resourceServers,afterCreate:u((M=r==null?void 0:r.resourceServers)==null?void 0:M.afterCreate,o.resourceServers.afterCreate),afterUpdate:u((b=r==null?void 0:r.resourceServers)==null?void 0:b.afterUpdate,o.resourceServers.afterUpdate),beforeDelete:u((y=r==null?void 0:r.resourceServers)==null?void 0:y.beforeDelete,o.resourceServers.beforeDelete),afterDelete:u((A=r==null?void 0:r.resourceServers)==null?void 0:A.afterDelete,o.resourceServers.afterDelete)}:r==null?void 0:r.resourceServers,roles:o!=null&&o.roles?{...r==null?void 0:r.roles,afterCreate:u((O=r==null?void 0:r.roles)==null?void 0:O.afterCreate,o.roles.afterCreate),afterUpdate:u((j=r==null?void 0:r.roles)==null?void 0:j.afterUpdate,o.roles.afterUpdate),beforeDelete:u((q=r==null?void 0:r.roles)==null?void 0:q.beforeDelete,o.roles.beforeDelete),afterDelete:u((R=r==null?void 0:r.roles)==null?void 0:R.afterDelete,o.roles.afterDelete)}:r==null?void 0:r.roles,connections:o!=null&&o.connections?{...r==null?void 0:r.connections,afterCreate:u((Q=r==null?void 0:r.connections)==null?void 0:Q.afterCreate,o.connections.afterCreate),afterUpdate:u((J=r==null?void 0:r.connections)==null?void 0:J.afterUpdate,o.connections.afterUpdate),beforeDelete:u((X=r==null?void 0:r.connections)==null?void 0:X.beforeDelete,o.connections.beforeDelete),afterDelete:u((Y=r==null?void 0:r.connections)==null?void 0:Y.afterDelete,o.connections.afterDelete)}:r==null?void 0:r.connections,tenants:c?{...r==null?void 0:r.tenants,afterCreate:u((Z=r==null?void 0:r.tenants)==null?void 0:Z.afterCreate,c.afterCreate)}:r==null?void 0:r.tenants},m={...i,tenants:c?{...i.tenants,afterCreate:u((k=i.tenants)==null?void 0:k.afterCreate,c.afterCreate)}:i.tenants},f=N(s,m),w=P.init({...l,entityHooks:d,managementApiExtensions:[...l.managementApiExtensions||[],{path:"/tenants",router:f}]}),{app:g,managementApp:h,...v}=w,_=new ee.Hono;return _.onError((z,C)=>z instanceof S?z.getResponse():(console.error(z),C.json({message:"Internal Server Error"},500))),_.use("/api/v2/*",oe()),_.route("/",g),{app:_,managementApp:h,...v,multiTenancyConfig:s,multiTenancyHooks:i}}exports.createAccessControlHooks=te;exports.createAccessControlMiddleware=ce;exports.createDatabaseHooks=re;exports.createDatabaseMiddleware=de;exports.createMultiTenancy=ue;exports.createMultiTenancyHooks=F;exports.createMultiTenancyMiddleware=W;exports.createMultiTenancyPlugin=Ce;exports.createProtectSyncedMiddleware=oe;exports.createProvisioningHooks=ae;exports.createRuntimeFallbackAdapter=V;exports.createSettingsInheritanceAdapter=Ae;exports.createSubdomainMiddleware=le;exports.createSyncHooks=se;exports.createTenantsOpenAPIRouter=N;exports.init=Ie;exports.setupMultiTenancy=Se;exports.validateTenantAccess=ne;exports.withRuntimeFallback=ie;exports.withSettingsInheritance=Te;Object.keys(P).forEach(t=>{t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:()=>P[t]})});
@@ -38185,6 +38185,9 @@ export interface LabelProps {
38185
38185
  declare const Label: FC<PropsWithChildren<LabelProps>>;
38186
38186
  export declare const tailwindCss = "\n@font-face{font-display:swap;font-family:KHTeka;font-style:normal;font-weight:400;src:url(https://assets.sesamy.com/fonts/khteka/WOFF2/KHTeka-Regular.woff2) format(\"woff2\")}@font-face{font-display:swap;font-family:KHTeka;font-style:normal;font-weight:500;src:url(https://assets.sesamy.com/fonts/khteka/WOFF2/KHTeka-Medium.woff2) format(\"woff2\")}@font-face{font-display:swap;font-family:KHTeka;font-style:normal;font-weight:600;src:url(https://assets.sesamy.com/fonts/khteka/WOFF2/KHTeka-Bold.woff2) format(\"woff2\")}@font-face{font-family:uicon;src:url(https://login2.sesamy.com/_next/static/media/uicon.0b00e08a.woff2)}[class*=\" uicon-\"],[class^=uicon-]{font-family:uicon!important;font-size:inherit;font-style:normal;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}.uicon-apple:before{content:\"\\ea01\"}.uicon-arrow-down:before{content:\"\\ea02\"}.uicon-arrow-left:before{content:\"\\ea03\"}.uicon-arrow-right:before{content:\"\\ea04\"}.uicon-arrow-up:before{content:\"\\ea05\"}.uicon-facebook:before{content:\"\\ea06\"}.uicon-google:before{content:\"\\ea07\"}.uicon-info-bubble:before{content:\"\\ea08\"}.uicon-info:before{content:\"\\ea09\"}.uicon-sesamy:before{content:\"\\ea0a\"}.uicon-spinner-circle:before{content:\"\\ea0b\"}.uicon-spinner-inner:before{content:\"\\ea0c\"}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }\n\n/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #bfbcd7;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:KHTeka,Helvetica Neue,HelveticaNeue,TeX Gyre Heros,TeXGyreHeros,FreeSans,Nimbus Sans L,Liberation Sans,Arimo,Helvetica,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#4b4a58;opacity:1}input::placeholder,textarea::placeholder{color:#4b4a58;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}body,html{height:100%}body{--tw-bg-opacity:1;background-color:rgb(248 249 251/var(--tw-bg-opacity,1));font-size:1rem;letter-spacing:.0125rem;line-height:120%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (min-width:1280px){body{font-size:1.125rem;line-height:120%}}body:is(.dark *){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}button,input,optgroup,select,textarea{font-size:.875rem;letter-spacing:.0125rem;line-height:120%}@media (min-width:1280px){button,input,optgroup,select,textarea{font-size:1rem;line-height:120%}}h1{font-size:1.5rem;font-weight:500;line-height:120%}@media (min-width:1280px){h1{font-size:2rem;line-height:120%}}@media (min-width:640px){h1{font-size:3rem;letter-spacing:-.0625rem;line-height:100%}}@media (min-width:1280px){h1{font-size:3.5rem;letter-spacing:-.0625rem;line-height:100%}}h2{font-size:1.25rem;font-weight:500;line-height:120%}@media (min-width:1280px){h2{font-size:1.5rem;line-height:120%}}@media (min-width:640px){h2{font-size:2rem;letter-spacing:0;line-height:120%}}@media (min-width:1280px){h2{font-size:3rem;letter-spacing:-.0625rem;line-height:100%}}h3{font-size:1.125rem;font-weight:500;line-height:120%}@media (min-width:1280px){h3{font-size:1.25rem;line-height:120%}}@media (min-width:640px){h3{font-size:1.5rem;line-height:120%}}@media (min-width:1280px){h3{font-size:2rem;line-height:120%}}h4{font-size:1rem;font-weight:500;line-height:120%}@media (min-width:1280px){h4{font-size:1.125rem;line-height:120%}}@media (min-width:640px){h4{font-size:1.125rem;line-height:120%}}@media (min-width:1280px){h4{font-size:1.5rem;line-height:120%}}h5{font-size:.875rem;font-weight:500;line-height:120%}@media (min-width:1280px){h5{font-size:1rem;line-height:120%}}@media (min-width:640px){h5{font-size:1rem;line-height:120%}}@media (min-width:1280px){h5{font-size:1.125rem;line-height:120%}}h6{font-size:.75rem;font-weight:500;line-height:135%}@media (min-width:1280px){h6{font-size:.875rem;line-height:120%}}@media (min-width:640px){h6{font-size:.875rem;line-height:120%}}@media (min-width:1280px){h6{font-size:1rem;line-height:120%}}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1920px){.container{max-width:1920px}}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-0{left:0}.right-0{right:0}.right-2{right:.5rem}.top-0{top:0}.top-1\\/2{top:50%}.my-4{margin-bottom:1rem;margin-top:1rem}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-7{margin-bottom:1.75rem}.mb-8{margin-bottom:2rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-0\\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-8{margin-top:2rem}.line-clamp-1{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:1}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-9{height:2.25rem}.h-full{height:100%}.min-h-\\[calc\\(100vh-83px\\)\\]{min-height:calc(100vh - 83px)}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-5{width:1.25rem}.w-9{width:2.25rem}.w-\\[calc\\(100\\%-theme\\(space\\.2\\)-theme\\(space\\.2\\)\\)\\]{width:calc(100% - 1rem)}.w-auto{width:auto}.w-full{width:100%}.min-w-0{min-width:0}.max-w-\\[1295px\\]{max-width:1295px}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-y-1\\/2{--tw-translate-y:-50%}.-translate-y-1\\/2,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-col{flex-direction:column}.\\!flex-nowrap{flex-wrap:nowrap!important}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.\\!justify-between{justify-content:space-between!important}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-1\\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.375rem*var(--tw-space-y-reverse));margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.overflow-hidden,.truncate{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded-2xl{border-radius:1.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.625rem}.rounded-md{border-radius:.375rem}.rounded-r-lg{border-bottom-right-radius:.625rem;border-top-right-radius:.625rem}.border{border-width:1px}.border-y{border-top-width:1px}.border-b,.border-y{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-gray-100{--tw-border-opacity:1;border-color:rgb(248 249 251/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(191 188 215/var(--tw-border-opacity,1))}.border-gray-200\\/50{border-color:rgba(191,188,215,.5)}.border-gray-300{--tw-border-opacity:1;border-color:rgb(136 134 159/var(--tw-border-opacity,1))}.border-gray-500{--tw-border-opacity:1;border-color:rgb(59 57 70/var(--tw-border-opacity,1))}.border-red{--tw-border-opacity:1;border-color:rgb(252 90 90/var(--tw-border-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(248 249 251/var(--tw-bg-opacity,1))}.bg-gray-200\\/40{background-color:rgba(191,188,215,.4)}.bg-primary{background-color:var(--primary-color)}.bg-primaryHover{background-color:var(--primary-hover)}.bg-red\\/80{background-color:rgba(252,90,90,.8)}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-0{padding-left:0;padding-right:0}.px-10{padding-left:2.5rem;padding-right:2.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-10{padding-bottom:2.5rem;padding-top:2.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.pb-2{padding-bottom:.5rem}.pb-8{padding-bottom:2rem}.pl-12{padding-left:3rem}.pl-6{padding-left:1.5rem}.pr-12{padding-right:3rem}.pr-6{padding-right:1.5rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-2\\.5{padding-top:.625rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.indent-\\[5px\\]{text-indent:5px}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.\\!text-base{font-size:1rem!important;line-height:120%!important}.\\!text-xs{font-size:.75rem!important;line-height:135%!important}.text-2xl{font-size:1.5rem;line-height:120%}.text-3xl{font-size:2rem;line-height:120%}.text-base{font-size:1rem;line-height:120%}.text-lg{font-size:1.125rem;line-height:120%}.text-sm{font-size:.875rem;line-height:120%}.text-xl{font-size:1.25rem;line-height:120%}.text-xs{font-size:.75rem;line-height:135%}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.leading-\\[0\\]{line-height:0}.leading-none{line-height:1}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-\\[\\#B2B2B2\\]{--tw-text-opacity:1;color:rgb(178 178 178/var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-gray-200{--tw-text-opacity:1;color:rgb(191 188 215/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(136 134 159/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(75 74 88/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(59 57 70/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(30 30 39/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(20 20 26/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(8 8 14/var(--tw-text-opacity,1))}.text-green{--tw-text-opacity:1;color:rgb(54 191 118/var(--tw-text-opacity,1))}.text-primary{color:var(--primary-color)}.text-red{--tw-text-opacity:1;color:rgb(252 90 90/var(--tw-text-opacity,1))}.text-textOnPrimary{color:var(--text-on-primary)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.accent-\\[\\#4F2D7F\\]{accent-color:#4f2d7f}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-90{opacity:.9}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.ring-offset-white{--tw-ring-offset-color:#fff}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.row-up-left{align-content:flex-start;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start}.row-left{justify-content:flex-start}.row,.row-left{align-content:center;align-items:center;display:flex;flex-direction:row;flex-wrap:wrap}.row{justify-content:center}.column-left{align-items:flex-start}.column,.column-left{display:flex;flex-direction:column;justify-content:center}.column{align-items:center}@media (min-width:1280px){.text-5xl{font-size:5.125rem;letter-spacing:-.125rem;line-height:100%}.text-4xl{font-size:3.5rem}.text-3xl,.text-4xl{letter-spacing:-.0625rem;line-height:100%}.text-3xl{font-size:3rem}.text-2xl{font-size:2rem}.text-2xl,.text-xl{line-height:120%}.text-xl{font-size:1.5rem}.text-lg{font-size:1.25rem}.text-base,.text-lg{line-height:120%}.text-base{font-size:1.125rem}.text-sm{font-size:1rem}.text-sm,.text-xs{line-height:120%}.text-xs{font-size:.875rem}}:root{--primary-color:#7d68f4;--primary-hover:#9786f6;--text-on-primary:#fff}svg{transform:translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}*,:after,:before{text-underline-offset:4px}input[type=number],input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;-moz-appearance:textfield!important}.btn.is-loading{cursor:not-allowed;opacity:.4;pointer-events:none}.btn .btn-spinner,.btn.is-loading .btn-label{opacity:0;visibility:hidden}.btn.is-loading .btn-spinner{opacity:1;visibility:visible}[class*=\" uicon-\"],[class^=uicon-]{letter-spacing:0;line-height:100%}.file\\:border-0::file-selector-button{border-width:0}.file\\:text-sm::file-selector-button{font-size:.875rem;line-height:120%}.file\\:font-medium::file-selector-button{font-weight:500}.placeholder\\:normal-case::-moz-placeholder{text-transform:none}.placeholder\\:normal-case::placeholder{text-transform:none}.placeholder\\:text-gray-300::-moz-placeholder{--tw-text-opacity:1;color:rgb(136 134 159/var(--tw-text-opacity,1))}.placeholder\\:text-gray-300::placeholder{--tw-text-opacity:1;color:rgb(136 134 159/var(--tw-text-opacity,1))}.placeholder\\:text-gray-500::-moz-placeholder{--tw-text-opacity:1;color:rgb(59 57 70/var(--tw-text-opacity,1))}.placeholder\\:text-gray-500::placeholder{--tw-text-opacity:1;color:rgb(59 57 70/var(--tw-text-opacity,1))}.first\\:rounded-l-md:first-child{border-bottom-left-radius:.375rem;border-top-left-radius:.375rem}.first\\:border-l:first-child{border-left-width:1px}.last\\:rounded-r-md:last-child{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}.hover\\:bg-black\\/5:hover{background-color:rgba(0,0,0,.05)}.hover\\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(248 249 251/var(--tw-bg-opacity,1))}.hover\\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(191 188 215/var(--tw-bg-opacity,1))}.hover\\:bg-gray-200\\/75:hover{background-color:rgba(191,188,215,.75)}.hover\\:bg-primaryHover:hover{background-color:var(--primary-hover)}.hover\\:bg-red\\/90:hover{background-color:rgba(252,90,90,.9)}.hover\\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(30 30 39/var(--tw-text-opacity,1))}.hover\\:text-primaryHover:hover{color:var(--primary-hover)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-100:hover{opacity:1}.hover\\:brightness-90:hover{--tw-brightness:brightness(.9);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\\:z-10:focus{z-index:10}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\\:ring-1:focus,.focus\\:ring:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-primary:focus{--tw-ring-color:var(--primary-color)}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}.focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.group[open] .group-open\\:rotate-90{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.peer:disabled~.peer-disabled\\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\\:opacity-70{opacity:.7}.has-\\[\\:disabled\\]\\:opacity-50:has(:disabled){opacity:.5}.dark\\:border-gray-400:is(.dark *){--tw-border-opacity:1;border-color:rgb(75 74 88/var(--tw-border-opacity,1))}.dark\\:border-gray-500:is(.dark *){--tw-border-opacity:1;border-color:rgb(59 57 70/var(--tw-border-opacity,1))}.dark\\:border-gray-600:is(.dark *){--tw-border-opacity:1;border-color:rgb(40 40 52/var(--tw-border-opacity,1))}.dark\\:border-gray-700:is(.dark *){--tw-border-opacity:1;border-color:rgb(30 30 39/var(--tw-border-opacity,1))}.dark\\:bg-black:is(.dark *){--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.dark\\:bg-gray-600:is(.dark *){--tw-bg-opacity:1;background-color:rgb(40 40 52/var(--tw-bg-opacity,1))}.dark\\:bg-gray-700:is(.dark *){--tw-bg-opacity:1;background-color:rgb(30 30 39/var(--tw-bg-opacity,1))}.dark\\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(20 20 26/var(--tw-bg-opacity,1))}.dark\\:text-\\[\\#201a41\\]:is(.dark *){--tw-text-opacity:1;color:rgb(32 26 65/var(--tw-text-opacity,1))}.dark\\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(136 134 159/var(--tw-text-opacity,1))}.dark\\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(75 74 88/var(--tw-text-opacity,1))}.dark\\:text-white:is(.dark *){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.dark\\:ring-offset-gray-900:is(.dark *){--tw-ring-offset-color:#08080e}.dark\\:placeholder\\:text-gray-400:is(.dark *)::-moz-placeholder{--tw-text-opacity:1;color:rgb(75 74 88/var(--tw-text-opacity,1))}.dark\\:placeholder\\:text-gray-400:is(.dark *)::placeholder{--tw-text-opacity:1;color:rgb(75 74 88/var(--tw-text-opacity,1))}.dark\\:hover\\:bg-black\\/90:hover:is(.dark *){background-color:rgba(0,0,0,.9)}.dark\\:hover\\:bg-gray-700:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(30 30 39/var(--tw-bg-opacity,1))}.dark\\:hover\\:bg-gray-800:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(20 20 26/var(--tw-bg-opacity,1))}.dark\\:focus\\:ring-offset-gray-900:focus:is(.dark *){--tw-ring-offset-color:#08080e}@media (min-width:640px){.sm\\:absolute{position:absolute}.sm\\:left-4{left:1rem}.sm\\:top-1\\/2{top:50%}.sm\\:mt-4{margin-top:1rem}.sm\\:inline{display:inline}.sm\\:h-6{height:1.5rem}.sm\\:min-h-\\[700px\\]{min-height:700px}.sm\\:w-6{width:1.5rem}.sm\\:w-\\[calc\\(100\\%-theme\\(space\\.16\\)-theme\\(space\\.16\\)\\)\\]{width:calc(100% - 8rem)}.sm\\:w-auto{width:auto}.sm\\:w-full{width:100%}.sm\\:max-w-md{max-width:28rem}.sm\\:-translate-y-1\\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sm\\:flex-col{flex-direction:column}.sm\\:justify-normal{justify-content:normal}.sm\\:space-x-0>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(0px*(1 - var(--tw-space-x-reverse)));margin-right:calc(0px*var(--tw-space-x-reverse))}.sm\\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.sm\\:bg-fixed{background-attachment:fixed}.sm\\:bg-left-top{background-position:0 0}.sm\\:px-10{padding-left:2.5rem;padding-right:2.5rem}.sm\\:px-14{padding-left:3.5rem;padding-right:3.5rem}.sm\\:py-14{padding-bottom:3.5rem;padding-top:3.5rem}.sm\\:py-4{padding-bottom:1rem;padding-top:1rem}.sm\\:pt-16{padding-top:4rem}.sm\\:text-2xl{font-size:1.5rem;line-height:120%}.sm\\:text-base{font-size:1rem;line-height:120%}}@media (min-width:1280px){.md\\:min-w-\\[448px\\]{min-width:448px}.md\\:p-10{padding:2.5rem}.md\\:py-10{padding-bottom:2.5rem;padding-top:2.5rem}.md\\:pl-10{padding-left:2.5rem}.md\\:pl-20{padding-left:5rem}.md\\:pr-10{padding-right:2.5rem}.md\\:pr-20{padding-right:5rem}.md\\:text-3xl{font-size:2rem;line-height:120%}.md\\:text-base{font-size:1rem;line-height:120%}.md\\:text-sm{font-size:.875rem;line-height:120%}.md\\:text-xs{font-size:.75rem;line-height:135%}}@media (max-height:900px) and (min-width:640px){.short\\:static{position:static}.short\\:left-auto{left:auto}.short\\:top-auto{top:auto}.short\\:inline{display:inline}.short\\:hidden{display:none}.short\\:h-5{height:1.25rem}.short\\:min-h-\\[558px\\]{min-height:558px}.short\\:w-5{width:1.25rem}.short\\:flex-1{flex:1 1 0%}.short\\:translate-y-0{--tw-translate-y:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.short\\:flex-row{flex-direction:row}.short\\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.short\\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.short\\:px-0{padding-left:0;padding-right:0}.short\\:py-3{padding-bottom:.75rem;padding-top:.75rem}}.\\[\\&\\>\\*\\:last-child\\]\\:mb-0>:last-child{margin-bottom:0}.\\[\\&_h1\\]\\:mb-6 h1,.\\[\\&_h2\\]\\:mb-6 h2{margin-bottom:1.5rem}";
38187
38187
  export declare function injectTailwindCSS(): void;
38188
+ /**
38189
+ * @deprecated Use `RuntimeFallbackConfig` from `@authhero/multi-tenancy` instead.
38190
+ */
38188
38191
  export interface MainTenantAdapterConfig {
38189
38192
  mainTenantId?: string;
38190
38193
  mainClientId?: string;
@@ -38212,24 +38215,24 @@ export declare function createInMemoryCache(config?: InMemoryCacheConfig): Cache
38212
38215
  * This should be used when initializing the AuthHero application to enable
38213
38216
  * fallback to a main tenant for default configurations.
38214
38217
  *
38218
+ * @deprecated Use `withSettingsInheritance` or `createSettingsInheritanceAdapter`
38219
+ * from `@authhero/multi-tenancy` instead. This function will be removed in a future version.
38220
+ *
38215
38221
  * @param baseAdapters - The base data adapters to wrap
38216
38222
  * @param config - Configuration for main tenant fallback
38217
38223
  * @returns Wrapped data adapters with main tenant fallback functionality
38218
38224
  *
38219
38225
  * @example
38220
38226
  * ```typescript
38227
+ * // Old way (deprecated):
38221
38228
  * import { init, withMainTenantFallback } from "@authhero/authhero";
38222
- * import createAdapters from "@authhero/kysely";
38223
38229
  *
38224
- * const db = // ... your database connection
38225
- * const baseAdapters = createAdapters(db);
38226
- *
38227
- * const adapters = withMainTenantFallback(baseAdapters, {
38228
- * mainTenantId: "main",
38229
- * mainClientId: "main-client"
38230
+ * // New way:
38231
+ * import { withSettingsInheritance } from "@authhero/multi-tenancy";
38232
+ * const adapters = withSettingsInheritance(baseAdapters, {
38233
+ * controlPlaneTenantId: "main",
38234
+ * controlPlaneClientId: "main-client"
38230
38235
  * });
38231
- *
38232
- * const app = init({ dataAdapter: adapters });
38233
38236
  * ```
38234
38237
  */
38235
38238
  export declare function withMainTenantFallback(baseAdapters: DataAdapters, config: MainTenantAdapterConfig): DataAdapters;
@@ -53214,34 +53217,6 @@ export interface DatabaseIsolationConfig {
53214
53217
  */
53215
53218
  onDeprovision?: (tenantId: string) => Promise<void>;
53216
53219
  }
53217
- /**
53218
- * Configuration for tenant settings inheritance.
53219
- *
53220
- * This enables child tenants to inherit default settings from the control plane,
53221
- * reducing configuration overhead and ensuring consistency.
53222
- */
53223
- export interface SettingsInheritanceConfig {
53224
- /**
53225
- * If true, new tenants will inherit settings from the control plane
53226
- * as their default configuration.
53227
- * @default true
53228
- */
53229
- inheritFromControlPlane?: boolean;
53230
- /**
53231
- * Specific settings keys to inherit from the control plane.
53232
- * If not provided, all settings are inherited.
53233
- */
53234
- inheritedKeys?: (keyof Tenant$1)[];
53235
- /**
53236
- * Settings keys that should NOT be inherited (blacklist approach).
53237
- * Takes precedence over inheritedKeys.
53238
- */
53239
- excludedKeys?: (keyof Tenant$1)[];
53240
- /**
53241
- * Custom function to transform inherited settings before applying.
53242
- */
53243
- transformSettings?: (controlPlaneSettings: Partial<Tenant$1>, newTenantId: string) => Partial<Tenant$1>;
53244
- }
53245
53220
  /**
53246
53221
  * Configuration for subdomain-based tenant routing.
53247
53222
  *
@@ -53278,7 +53253,6 @@ export interface SubdomainRoutingConfig {
53278
53253
  *
53279
53254
  * - **accessControl**: Organization-based tenant access validation
53280
53255
  * - **databaseIsolation**: Per-tenant database instances
53281
- * - **settingsInheritance**: Inherit settings from control plane
53282
53256
  * - **subdomainRouting**: Route requests via subdomains
53283
53257
  */
53284
53258
  export interface MultiTenancyConfig {
@@ -53291,10 +53265,6 @@ export interface MultiTenancyConfig {
53291
53265
  * Per-tenant database isolation configuration.
53292
53266
  */
53293
53267
  databaseIsolation?: DatabaseIsolationConfig;
53294
- /**
53295
- * Settings inheritance configuration.
53296
- */
53297
- settingsInheritance?: SettingsInheritanceConfig;
53298
53268
  /**
53299
53269
  * Subdomain-based tenant routing configuration.
53300
53270
  */
@@ -53539,6 +53509,91 @@ export declare function createProtectSyncedMiddleware(): MiddlewareHandler<{
53539
53509
  Bindings: ProtectSystemBindings;
53540
53510
  Variables: ProtectSystemVariables;
53541
53511
  }>;
53512
+ /**
53513
+ * Configuration for runtime settings fallback from a control plane tenant.
53514
+ *
53515
+ * Runtime fallback provides default values at query time without copying sensitive data.
53516
+ */
53517
+ export interface RuntimeFallbackConfig {
53518
+ /**
53519
+ * The control plane tenant ID from which settings are inherited at runtime.
53520
+ * Child tenants will fall back to this tenant's configuration for
53521
+ * missing or default values (e.g., connection secrets, SMTP settings).
53522
+ */
53523
+ controlPlaneTenantId?: string;
53524
+ /**
53525
+ * The control plane client ID used for fallback client settings.
53526
+ * This client's configuration (web_origins, callbacks, etc.) will
53527
+ * be merged with child tenant clients at runtime.
53528
+ */
53529
+ controlPlaneClientId?: string;
53530
+ }
53531
+ /**
53532
+ * Creates a data adapter wrapper that provides runtime settings fallback from a control plane tenant.
53533
+ *
53534
+ * This adapter wraps the base adapters to provide fallback functionality where child tenants
53535
+ * can inherit default configurations from a control plane (main) tenant **at runtime**.
53536
+ * This is useful for:
53537
+ *
53538
+ * - **Default connection settings**: Inherit OAuth secrets, SMTP API keys, etc. without copying them
53539
+ * - **Client URL fallbacks**: Add control plane URLs to allowed origins, callbacks, etc.
53540
+ * - **Tenant property defaults**: Fall back to control plane values for missing tenant settings
53541
+ *
53542
+ * **Key difference from entity sync:**
53543
+ * - **Runtime fallback**: Values are merged at query time, sensitive data stays in control plane only
53544
+ * - **Entity sync**: Entities are copied to child tenants, needed for foreign key relationships
53545
+ *
53546
+ * @param baseAdapters - The base data adapters to wrap
53547
+ * @param config - Configuration for runtime settings fallback
53548
+ * @returns Wrapped data adapters with runtime fallback functionality
53549
+ *
53550
+ * @example
53551
+ * ```typescript
53552
+ * import { createRuntimeFallbackAdapter } from "@authhero/multi-tenancy";
53553
+ * import createAdapters from "@authhero/kysely";
53554
+ *
53555
+ * const db = // ... your database connection
53556
+ * const baseAdapters = createAdapters(db);
53557
+ *
53558
+ * const adapters = createRuntimeFallbackAdapter(baseAdapters, {
53559
+ * controlPlaneTenantId: "main",
53560
+ * controlPlaneClientId: "main-client"
53561
+ * });
53562
+ * ```
53563
+ */
53564
+ export declare function createRuntimeFallbackAdapter(baseAdapters: DataAdapters$1, config: RuntimeFallbackConfig): DataAdapters$1;
53565
+ /**
53566
+ * Helper function to wrap data adapters with runtime fallback from control plane.
53567
+ *
53568
+ * This is a convenience wrapper around `createRuntimeFallbackAdapter`.
53569
+ *
53570
+ * @param baseAdapters - The base data adapters to wrap
53571
+ * @param config - Configuration for runtime fallback
53572
+ * @returns Wrapped data adapters with runtime fallback functionality
53573
+ *
53574
+ * @example
53575
+ * ```typescript
53576
+ * import { withRuntimeFallback } from "@authhero/multi-tenancy";
53577
+ *
53578
+ * const adapters = withRuntimeFallback(baseAdapters, {
53579
+ * controlPlaneTenantId: "main",
53580
+ * controlPlaneClientId: "main-client"
53581
+ * });
53582
+ * ```
53583
+ */
53584
+ export declare function withRuntimeFallback(baseAdapters: DataAdapters$1, config: RuntimeFallbackConfig): DataAdapters$1;
53585
+ /**
53586
+ * @deprecated Use `RuntimeFallbackConfig` instead
53587
+ */
53588
+ export type SettingsInheritanceConfig = RuntimeFallbackConfig;
53589
+ /**
53590
+ * @deprecated Use `createRuntimeFallbackAdapter` instead
53591
+ */
53592
+ export declare const createSettingsInheritanceAdapter: typeof createRuntimeFallbackAdapter;
53593
+ /**
53594
+ * @deprecated Use `withRuntimeFallback` instead
53595
+ */
53596
+ export declare const withSettingsInheritance: typeof withRuntimeFallback;
53542
53597
  /**
53543
53598
  * Creates middleware for validating organization-based tenant access.
53544
53599
  *