@eminuckan/spine 0.2.4 → 0.3.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/CODE_OF_CONDUCT.md +39 -0
  3. package/CONTRIBUTING.md +78 -0
  4. package/MAINTAINERS.md +43 -0
  5. package/README.md +66 -49
  6. package/ROADMAP.md +58 -0
  7. package/SECURITY.md +37 -0
  8. package/dist/access/evaluator.d.ts.map +1 -1
  9. package/dist/access/index.js +1 -1
  10. package/dist/access/types.d.ts +10 -2
  11. package/dist/access/types.d.ts.map +1 -1
  12. package/dist/{access-DlAqsVGQ.js → access-CGrsDMwu.js} +9 -7
  13. package/dist/access-CGrsDMwu.js.map +1 -0
  14. package/dist/api-client/api-config.server.d.ts +27 -0
  15. package/dist/api-client/api-config.server.d.ts.map +1 -1
  16. package/dist/api-client/error-codes.d.ts +6 -31
  17. package/dist/api-client/error-codes.d.ts.map +1 -1
  18. package/dist/api-client/index.js +2 -2
  19. package/dist/api-client/server.d.ts +1 -1
  20. package/dist/api-client/server.d.ts.map +1 -1
  21. package/dist/api-client/server.js +3 -3
  22. package/dist/{api-client-CZapXIF8.js → api-client-CgZUMukO.js} +9 -26
  23. package/dist/api-client-CgZUMukO.js.map +1 -0
  24. package/dist/auth/auth.server.d.ts.map +1 -1
  25. package/dist/auth/authorization-parameters.d.ts +5 -0
  26. package/dist/auth/authorization-parameters.d.ts.map +1 -0
  27. package/dist/auth/route-protection.server.d.ts +20 -4
  28. package/dist/auth/route-protection.server.d.ts.map +1 -1
  29. package/dist/auth/server.d.ts +1 -1
  30. package/dist/auth/server.d.ts.map +1 -1
  31. package/dist/auth/server.js +5 -5
  32. package/dist/auth/types.d.ts +24 -2
  33. package/dist/auth/types.d.ts.map +1 -1
  34. package/dist/{auth.server-B3ODGIX4.js → auth.server-D5oiz9aF.js} +62 -53
  35. package/dist/auth.server-D5oiz9aF.js.map +1 -0
  36. package/dist/{auth.server-wdKsjQsn.js → auth.server-lC94lmlx.js} +3 -3
  37. package/dist/identity/identity-context.server.d.ts +2 -0
  38. package/dist/identity/identity-context.server.d.ts.map +1 -1
  39. package/dist/identity/identity-store.d.ts +19 -2
  40. package/dist/identity/identity-store.d.ts.map +1 -1
  41. package/dist/identity/index.js +2 -2
  42. package/dist/identity/server.js +2 -2
  43. package/dist/identity/types.d.ts +3 -1
  44. package/dist/identity/types.d.ts.map +1 -1
  45. package/dist/{identity-yT2ijZF0.js → identity-C5un-xAs.js} +104 -60
  46. package/dist/identity-C5un-xAs.js.map +1 -0
  47. package/dist/index.js +8 -8
  48. package/dist/logging/index.js +1 -1
  49. package/dist/{logging-_h2mi3L9.js → logging-DviiAkLx.js} +2 -2
  50. package/dist/{logging-_h2mi3L9.js.map → logging-DviiAkLx.js.map} +1 -1
  51. package/dist/permissions/constants.d.ts +3 -0
  52. package/dist/permissions/constants.d.ts.map +1 -1
  53. package/dist/permissions/index.js +1 -1
  54. package/dist/permissions/permission-store.d.ts +1 -1
  55. package/dist/permissions/types.d.ts +1 -1
  56. package/dist/permissions/types.d.ts.map +1 -1
  57. package/dist/{permissions-OUK8Eql2.js → permissions-_n1hIG7Q.js} +6 -12
  58. package/dist/permissions-_n1hIG7Q.js.map +1 -0
  59. package/dist/query-client/types.d.ts +9 -9
  60. package/dist/query-client/types.d.ts.map +1 -1
  61. package/dist/query-client-Bh3TyB8W.js.map +1 -1
  62. package/dist/react-router/index.js +8 -8
  63. package/dist/react-router/server.js +14 -14
  64. package/dist/{redis-session-storage.server-D0-72FV-.js → redis-session-storage.server-v2VcpFsQ.js} +2 -2
  65. package/dist/{redis-session-storage.server-D0-72FV-.js.map → redis-session-storage.server-v2VcpFsQ.js.map} +1 -1
  66. package/dist/{server-B7JN86_0.js → server-B6PCxc-T.js} +31 -83
  67. package/dist/server-B6PCxc-T.js.map +1 -0
  68. package/dist/{server-DeBlxoaW.js → server-C96NMFBy.js} +17 -9
  69. package/dist/server-C96NMFBy.js.map +1 -0
  70. package/dist/{server-Ce9jQRdL.js → server-Ca-3DJf2.js} +44 -11
  71. package/dist/server-Ca-3DJf2.js.map +1 -0
  72. package/dist/{server-BmiuV28c.js → server-Dxsww9v9.js} +5 -4
  73. package/dist/server-Dxsww9v9.js.map +1 -0
  74. package/dist/server.js +14 -14
  75. package/dist/signalr/index.js +1 -1
  76. package/dist/signalr/types.d.ts +1 -1
  77. package/dist/{signalr-CSfCz1Ik.js → signalr-k-70VHKo.js} +3 -2
  78. package/dist/signalr-k-70VHKo.js.map +1 -0
  79. package/dist/tenant/index.js +2 -2
  80. package/dist/tenant/server.js +4 -4
  81. package/dist/tenant/tenant-context.d.ts +17 -1
  82. package/dist/tenant/tenant-context.d.ts.map +1 -1
  83. package/dist/tenant/tenant-cookie.server.d.ts.map +1 -1
  84. package/dist/tenant/tenant-store.d.ts +54 -9
  85. package/dist/tenant/tenant-store.d.ts.map +1 -1
  86. package/dist/tenant/tenant.server.d.ts +20 -1
  87. package/dist/tenant/tenant.server.d.ts.map +1 -1
  88. package/dist/tenant/types.d.ts +29 -9
  89. package/dist/tenant/types.d.ts.map +1 -1
  90. package/dist/tenant-DfLemb6n.js +384 -0
  91. package/dist/tenant-DfLemb6n.js.map +1 -0
  92. package/docs/adapters.md +87 -0
  93. package/docs/architecture.md +193 -0
  94. package/docs/backend-adaptation.md +249 -0
  95. package/docs/codex-for-oss-application.md +31 -0
  96. package/docs/codex-maintenance.md +47 -0
  97. package/docs/installation.md +213 -0
  98. package/docs/module-reference.md +207 -0
  99. package/docs/releasing.md +92 -0
  100. package/package.json +21 -3
  101. package/dist/access-DlAqsVGQ.js.map +0 -1
  102. package/dist/api-client-CZapXIF8.js.map +0 -1
  103. package/dist/auth.server-B3ODGIX4.js.map +0 -1
  104. package/dist/identity-yT2ijZF0.js.map +0 -1
  105. package/dist/permissions-OUK8Eql2.js.map +0 -1
  106. package/dist/server-B7JN86_0.js.map +0 -1
  107. package/dist/server-BmiuV28c.js.map +0 -1
  108. package/dist/server-Ce9jQRdL.js.map +0 -1
  109. package/dist/server-DeBlxoaW.js.map +0 -1
  110. package/dist/signalr-CSfCz1Ik.js.map +0 -1
  111. package/dist/tenant-BErqEENp.js +0 -256
  112. package/dist/tenant-BErqEENp.js.map +0 -1
@@ -1,256 +0,0 @@
1
- import { create } from "zustand";
2
- import { createContext, useContext, useEffect } from "react";
3
- import { jsx } from "react/jsx-runtime";
4
- import { devtools } from "zustand/middleware";
5
-
6
- //#region src/tenant/tenant-store.ts
7
- /**
8
- * Organization fetch endpoint (configurable)
9
- */
10
- let organizationEndpoint = "/api/organization/get";
11
- let tenantSwitchEndpoint = "/api/tenant/switch";
12
- /**
13
- * Configure tenant store endpoints
14
- */
15
- function configureTenantEndpoints(config) {
16
- if (config.organizationEndpoint) organizationEndpoint = config.organizationEndpoint;
17
- if (config.tenantSwitchEndpoint) tenantSwitchEndpoint = config.tenantSwitchEndpoint;
18
- }
19
- const useTenantStore = create()(devtools((set, get) => ({
20
- currentTenant: null,
21
- availableTenants: [],
22
- memberships: new Map(),
23
- organizations: new Map(),
24
- isLoading: false,
25
- isSwitching: false,
26
- setCurrentTenant: (tenantId) => set({ currentTenant: tenantId }),
27
- setAvailableTenants: (tenants) => {
28
- set({ availableTenants: tenants });
29
- const { organizations, fetchOrganization } = get();
30
- tenants.forEach((tenantId) => {
31
- if (!organizations.has(tenantId)) fetchOrganization(tenantId);
32
- });
33
- },
34
- setMemberships: (memberships) => {
35
- const membershipMap = new Map();
36
- memberships.forEach((membership) => {
37
- membershipMap.set(membership.tenantId, membership);
38
- });
39
- set({ memberships: membershipMap });
40
- },
41
- setOrganization: (tenantId, data) => set((state) => ({ organizations: new Map(state.organizations).set(tenantId, data) })),
42
- addOrganization: (tenantId, data) => {
43
- set((state) => {
44
- const newOrganizations = new Map(state.organizations);
45
- newOrganizations.set(tenantId, data);
46
- return { organizations: newOrganizations };
47
- });
48
- },
49
- setLoading: (loading) => set({ isLoading: loading }),
50
- setSwitching: (switching) => set({ isSwitching: switching }),
51
- fetchOrganization: async (tenantId) => {
52
- try {
53
- const response = await fetch(`${organizationEndpoint}/${tenantId}`);
54
- if (response.ok) {
55
- const result = await response.json();
56
- if (result.success && result.data) get().setOrganization(tenantId, result.data);
57
- }
58
- } catch (error) {
59
- console.error("Failed to fetch organization data for tenant:", tenantId, error);
60
- }
61
- },
62
- switchTenant: async (tenantId) => {
63
- const { availableTenants } = get();
64
- if (!availableTenants.includes(tenantId)) {
65
- console.error("Tenant not available:", tenantId);
66
- return;
67
- }
68
- set({ isSwitching: true });
69
- try {
70
- const response = await fetch(tenantSwitchEndpoint, {
71
- method: "POST",
72
- headers: { "Content-Type": "application/json" },
73
- body: JSON.stringify({ tenantId })
74
- });
75
- if (response.ok) {
76
- const result = await response.json();
77
- if (result.success) {
78
- set({ currentTenant: tenantId });
79
- const { organizations, fetchOrganization } = get();
80
- if (!organizations.has(tenantId)) await fetchOrganization(tenantId);
81
- window.location.reload();
82
- }
83
- }
84
- } catch (error) {
85
- console.error("Failed to switch tenant:", error);
86
- set({ isSwitching: false });
87
- }
88
- },
89
- getMembership: (tenantId) => {
90
- const { memberships } = get();
91
- return memberships.get(tenantId) || null;
92
- },
93
- getCurrentMembership: () => {
94
- const { currentTenant, memberships } = get();
95
- if (!currentTenant) return null;
96
- return memberships.get(currentTenant) || null;
97
- },
98
- getTenantName: (tenantId) => {
99
- const { memberships, organizations } = get();
100
- const membership = memberships.get(tenantId);
101
- if (membership?.tenantName) return membership.tenantName;
102
- if (membership?.organizationName) return membership.organizationName;
103
- return organizations.get(tenantId)?.name || tenantId;
104
- },
105
- getOrganization: (tenantId) => {
106
- const { organizations } = get();
107
- return organizations.get(tenantId) || null;
108
- },
109
- getCurrentOrganization: () => {
110
- const { currentTenant, organizations } = get();
111
- if (!currentTenant) return null;
112
- return organizations.get(currentTenant) || null;
113
- }
114
- }), { name: "TenantStore" }));
115
- /**
116
- * Initialize store with server data
117
- */
118
- function initializeTenantStore(currentTenant, availableTenants, memberships) {
119
- const store = useTenantStore.getState();
120
- store.setCurrentTenant(currentTenant);
121
- store.setAvailableTenants(availableTenants);
122
- if (memberships) store.setMemberships(memberships);
123
- }
124
-
125
- //#endregion
126
- //#region src/tenant/tenant-context.tsx
127
- const TenantContext = createContext(null);
128
- function TenantProvider({ children, initialTenant = null, initialTenants = [], initialMemberships = [], onTenantChange }) {
129
- const currentTenant = useTenantStore((state) => state.currentTenant);
130
- const availableTenants = useTenantStore((state) => state.availableTenants);
131
- const memberships = useTenantStore((state) => state.memberships);
132
- const organizations = useTenantStore((state) => state.organizations);
133
- const isLoading = useTenantStore((state) => state.isLoading || state.isSwitching);
134
- const currentOrganization = useTenantStore((state) => state.getCurrentOrganization());
135
- const currentMembership = useTenantStore((state) => state.getCurrentMembership());
136
- const setCurrentTenant = useTenantStore((state) => state.setCurrentTenant);
137
- const setAvailableTenants = useTenantStore((state) => state.setAvailableTenants);
138
- const setMemberships = useTenantStore((state) => state.setMemberships);
139
- const switchTenantAction = useTenantStore((state) => state.switchTenant);
140
- const fetchOrganization = useTenantStore((state) => state.fetchOrganization);
141
- const getOrganization = useTenantStore((state) => state.getOrganization);
142
- const getMembership = useTenantStore((state) => state.getMembership);
143
- const getTenantName = useTenantStore((state) => state.getTenantName);
144
- useEffect(() => {
145
- if (initialTenant) setCurrentTenant(initialTenant);
146
- if (initialTenants.length > 0) setAvailableTenants(initialTenants);
147
- if (initialMemberships.length > 0) setMemberships(initialMemberships);
148
- }, [
149
- initialTenant,
150
- initialTenants.join(","),
151
- initialMemberships.map((membership) => membership.tenantId).join(","),
152
- setCurrentTenant,
153
- setAvailableTenants,
154
- setMemberships
155
- ]);
156
- useEffect(() => {
157
- const getCookieTenant = () => {
158
- const cookies = document.cookie.split(";");
159
- const tenantCookie = cookies.find((cookie) => cookie.trim().startsWith("__active-org="));
160
- if (tenantCookie) {
161
- const value$1 = tenantCookie.split("=")[1];
162
- return decodeURIComponent(value$1);
163
- }
164
- return null;
165
- };
166
- if (!currentTenant) {
167
- const cookieTenant = getCookieTenant();
168
- if (cookieTenant && availableTenants.includes(cookieTenant)) setCurrentTenant(cookieTenant);
169
- }
170
- }, [
171
- currentTenant,
172
- availableTenants,
173
- setCurrentTenant
174
- ]);
175
- const switchTenant = (tenantId) => {
176
- switchTenantAction(tenantId).then(() => {
177
- if (onTenantChange) onTenantChange();
178
- });
179
- };
180
- const refreshTenants = () => {
181
- console.log("Tenant refresh requested - should be handled by identity context");
182
- };
183
- const refreshOrganization = () => {
184
- if (currentTenant) fetchOrganization(currentTenant);
185
- };
186
- useEffect(() => {
187
- if (currentTenant && !currentOrganization) refreshOrganization();
188
- }, [currentTenant, currentOrganization]);
189
- const value = {
190
- currentTenant,
191
- availableTenants,
192
- memberships,
193
- currentOrganization,
194
- currentMembership,
195
- organizations,
196
- isLoading,
197
- switchTenant,
198
- refreshTenants,
199
- refreshOrganization,
200
- getOrganization,
201
- getMembership,
202
- getTenantName
203
- };
204
- return /* @__PURE__ */ jsx(TenantContext.Provider, {
205
- value,
206
- children
207
- });
208
- }
209
- /**
210
- * Hook for using tenant context
211
- */
212
- function useTenant() {
213
- const context = useContext(TenantContext);
214
- if (!context) throw new Error("useTenant must be used within a TenantProvider");
215
- return context;
216
- }
217
- /**
218
- * Hook for current tenant only
219
- */
220
- function useCurrentTenant() {
221
- const { currentTenant } = useTenant();
222
- return currentTenant;
223
- }
224
- /**
225
- * Hook for tenant switching
226
- */
227
- function useTenantSwitcher() {
228
- const { switchTenant, isLoading, availableTenants } = useTenant();
229
- return {
230
- switchTenant,
231
- isLoading,
232
- availableTenants
233
- };
234
- }
235
- /**
236
- * Hook for current organization
237
- */
238
- function useCurrentOrganization() {
239
- const { currentOrganization } = useTenant();
240
- return currentOrganization;
241
- }
242
- /**
243
- * Hook for organization operations
244
- */
245
- function useOrganization() {
246
- const { currentOrganization, refreshOrganization, isLoading } = useTenant();
247
- return {
248
- organization: currentOrganization,
249
- refreshOrganization,
250
- isLoading
251
- };
252
- }
253
-
254
- //#endregion
255
- export { TenantProvider, configureTenantEndpoints, initializeTenantStore, useCurrentOrganization, useCurrentTenant, useOrganization, useTenant, useTenantStore, useTenantSwitcher };
256
- //# sourceMappingURL=tenant-BErqEENp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tenant-BErqEENp.js","names":["config: {\n organizationEndpoint?: string;\n tenantSwitchEndpoint?: string;\n}","currentTenant: string | null","availableTenants: string[]","memberships?: TenantMembership[]","value","tenantId: string","value: TenantContextType"],"sources":["../src/tenant/tenant-store.ts","../src/tenant/tenant-context.tsx"],"sourcesContent":["/**\n * Tenant Store (Zustand)\n * \n * Client-side state management for tenant and organization data.\n */\n\nimport { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\nimport type { OrganizationData, TenantMembership } from './types';\n\ninterface TenantState {\n // State\n currentTenant: string | null;\n availableTenants: string[];\n memberships: Map<string, TenantMembership>;\n organizations: Map<string, OrganizationData>;\n isLoading: boolean;\n isSwitching: boolean;\n\n // Actions\n setCurrentTenant: (tenantId: string | null) => void;\n setAvailableTenants: (tenants: string[]) => void;\n setMemberships: (memberships: TenantMembership[]) => void;\n setOrganization: (tenantId: string, data: OrganizationData) => void;\n addOrganization: (tenantId: string, data: OrganizationData) => void;\n setLoading: (loading: boolean) => void;\n setSwitching: (switching: boolean) => void;\n\n // Async actions\n fetchOrganization: (tenantId: string) => Promise<void>;\n switchTenant: (tenantId: string) => Promise<void>;\n\n // Getters\n getMembership: (tenantId: string) => TenantMembership | null;\n getCurrentMembership: () => TenantMembership | null;\n getTenantName: (tenantId: string) => string;\n getOrganization: (tenantId: string) => OrganizationData | null;\n getCurrentOrganization: () => OrganizationData | null;\n}\n\n/**\n * Organization fetch endpoint (configurable)\n */\nlet organizationEndpoint = '/api/organization/get';\nlet tenantSwitchEndpoint = '/api/tenant/switch';\n\n/**\n * Configure tenant store endpoints\n */\nexport function configureTenantEndpoints(config: {\n organizationEndpoint?: string;\n tenantSwitchEndpoint?: string;\n}) {\n if (config.organizationEndpoint) {\n organizationEndpoint = config.organizationEndpoint;\n }\n if (config.tenantSwitchEndpoint) {\n tenantSwitchEndpoint = config.tenantSwitchEndpoint;\n }\n}\n\nexport const useTenantStore = create<TenantState>()(\n devtools(\n (set, get) => ({\n // Initial state\n currentTenant: null,\n availableTenants: [],\n memberships: new Map(),\n organizations: new Map(),\n isLoading: false,\n isSwitching: false,\n\n // Setters\n setCurrentTenant: (tenantId) => set({ currentTenant: tenantId }),\n\n setAvailableTenants: (tenants) => {\n set({ availableTenants: tenants });\n\n // Fetch organization data for all tenants\n const { organizations, fetchOrganization } = get();\n tenants.forEach((tenantId) => {\n if (!organizations.has(tenantId)) {\n fetchOrganization(tenantId);\n }\n });\n },\n\n setMemberships: (memberships) => {\n const membershipMap = new Map<string, TenantMembership>();\n memberships.forEach((membership) => {\n membershipMap.set(membership.tenantId, membership);\n });\n set({ memberships: membershipMap });\n },\n\n setOrganization: (tenantId, data) =>\n set((state) => ({\n organizations: new Map(state.organizations).set(tenantId, data),\n })),\n\n addOrganization: (tenantId, data) => {\n set((state) => {\n const newOrganizations = new Map(state.organizations);\n newOrganizations.set(tenantId, data);\n return { organizations: newOrganizations };\n });\n },\n\n setLoading: (loading) => set({ isLoading: loading }),\n setSwitching: (switching) => set({ isSwitching: switching }),\n\n // Async actions\n fetchOrganization: async (tenantId) => {\n try {\n const response = await fetch(`${organizationEndpoint}/${tenantId}`);\n if (response.ok) {\n const result = await response.json();\n if (result.success && result.data) {\n get().setOrganization(tenantId, result.data);\n }\n }\n } catch (error) {\n console.error('Failed to fetch organization data for tenant:', tenantId, error);\n }\n },\n\n switchTenant: async (tenantId) => {\n const { availableTenants } = get();\n\n if (!availableTenants.includes(tenantId)) {\n console.error('Tenant not available:', tenantId);\n return;\n }\n\n set({ isSwitching: true });\n\n try {\n const response = await fetch(tenantSwitchEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ tenantId }),\n });\n\n if (response.ok) {\n const result = await response.json();\n if (result.success) {\n set({ currentTenant: tenantId });\n\n // Fetch organization data if not already loaded\n const { organizations, fetchOrganization } = get();\n if (!organizations.has(tenantId)) {\n await fetchOrganization(tenantId);\n }\n\n // Reload the page to refresh all data with new tenant context\n window.location.reload();\n }\n }\n } catch (error) {\n console.error('Failed to switch tenant:', error);\n set({ isSwitching: false });\n }\n },\n\n // Getters\n getMembership: (tenantId) => {\n const { memberships } = get();\n return memberships.get(tenantId) || null;\n },\n\n getCurrentMembership: () => {\n const { currentTenant, memberships } = get();\n if (!currentTenant) return null;\n return memberships.get(currentTenant) || null;\n },\n\n getTenantName: (tenantId) => {\n const { memberships, organizations } = get();\n const membership = memberships.get(tenantId);\n if (membership?.tenantName) {\n return membership.tenantName;\n }\n if (membership?.organizationName) {\n return membership.organizationName;\n }\n return organizations.get(tenantId)?.name || tenantId;\n },\n\n getOrganization: (tenantId) => {\n const { organizations } = get();\n return organizations.get(tenantId) || null;\n },\n\n getCurrentOrganization: () => {\n const { currentTenant, organizations } = get();\n if (!currentTenant) return null;\n return organizations.get(currentTenant) || null;\n },\n }),\n { name: 'TenantStore' }\n )\n);\n\n/**\n * Initialize store with server data\n */\nexport function initializeTenantStore(\n currentTenant: string | null,\n availableTenants: string[],\n memberships?: TenantMembership[]\n) {\n const store = useTenantStore.getState();\n store.setCurrentTenant(currentTenant);\n store.setAvailableTenants(availableTenants);\n if (memberships) {\n store.setMemberships(memberships);\n }\n}\n","/**\n * Tenant Context Provider\n * \n * React context for tenant management.\n */\n\nimport { createContext, useContext, useEffect, type ReactNode } from 'react';\nimport { useTenantStore } from './tenant-store';\nimport type { OrganizationData, TenantContextType, TenantMembership } from './types';\n\nconst TenantContext = createContext<TenantContextType | null>(null);\n\ninterface TenantProviderProps {\n children: ReactNode;\n initialTenant?: string | null;\n initialTenants?: string[];\n initialMemberships?: TenantMembership[];\n onTenantChange?: () => void;\n}\n\nexport function TenantProvider({\n children,\n initialTenant = null,\n initialTenants = [],\n initialMemberships = [],\n onTenantChange,\n}: TenantProviderProps) {\n const currentTenant = useTenantStore((state) => state.currentTenant);\n const availableTenants = useTenantStore((state) => state.availableTenants);\n const memberships = useTenantStore((state) => state.memberships);\n const organizations = useTenantStore((state) => state.organizations);\n const isLoading = useTenantStore((state) => state.isLoading || state.isSwitching);\n const currentOrganization = useTenantStore((state) => state.getCurrentOrganization());\n const currentMembership = useTenantStore((state) => state.getCurrentMembership());\n\n const setCurrentTenant = useTenantStore((state) => state.setCurrentTenant);\n const setAvailableTenants = useTenantStore((state) => state.setAvailableTenants);\n const setMemberships = useTenantStore((state) => state.setMemberships);\n const switchTenantAction = useTenantStore((state) => state.switchTenant);\n const fetchOrganization = useTenantStore((state) => state.fetchOrganization);\n const getOrganization = useTenantStore((state) => state.getOrganization);\n const getMembership = useTenantStore((state) => state.getMembership);\n const getTenantName = useTenantStore((state) => state.getTenantName);\n\n // Initialize store with initial values\n useEffect(() => {\n if (initialTenant) {\n setCurrentTenant(initialTenant);\n }\n if (initialTenants.length > 0) {\n setAvailableTenants(initialTenants);\n }\n if (initialMemberships.length > 0) {\n setMemberships(initialMemberships);\n }\n }, [\n initialTenant,\n initialTenants.join(','),\n initialMemberships.map((membership) => membership.tenantId).join(','),\n setCurrentTenant,\n setAvailableTenants,\n setMemberships,\n ]);\n\n // Read tenant from cookie (client-side)\n useEffect(() => {\n const getCookieTenant = () => {\n const cookies = document.cookie.split(';');\n const tenantCookie = cookies.find((cookie) =>\n cookie.trim().startsWith('__active-org=')\n );\n\n if (tenantCookie) {\n const value = tenantCookie.split('=')[1];\n return decodeURIComponent(value);\n }\n\n return null;\n };\n\n if (!currentTenant) {\n const cookieTenant = getCookieTenant();\n if (cookieTenant && availableTenants.includes(cookieTenant)) {\n setCurrentTenant(cookieTenant);\n }\n }\n }, [currentTenant, availableTenants, setCurrentTenant]);\n\n // Switch tenant handler\n const switchTenant = (tenantId: string) => {\n switchTenantAction(tenantId).then(() => {\n if (onTenantChange) {\n onTenantChange();\n }\n });\n };\n\n // Refresh tenants (handled by identity context)\n const refreshTenants = () => {\n console.log('Tenant refresh requested - should be handled by identity context');\n };\n\n // Refresh organization\n const refreshOrganization = () => {\n if (currentTenant) {\n fetchOrganization(currentTenant);\n }\n };\n\n // Load organization data when tenant is set\n useEffect(() => {\n if (currentTenant && !currentOrganization) {\n refreshOrganization();\n }\n }, [currentTenant, currentOrganization]);\n\n const value: TenantContextType = {\n currentTenant,\n availableTenants,\n memberships,\n currentOrganization,\n currentMembership,\n organizations,\n isLoading,\n switchTenant,\n refreshTenants,\n refreshOrganization,\n getOrganization,\n getMembership,\n getTenantName,\n };\n\n return (\n <TenantContext.Provider value={value}>\n {children}\n </TenantContext.Provider>\n );\n}\n\n/**\n * Hook for using tenant context\n */\nexport function useTenant(): TenantContextType {\n const context = useContext(TenantContext);\n\n if (!context) {\n throw new Error('useTenant must be used within a TenantProvider');\n }\n\n return context;\n}\n\n/**\n * Hook for current tenant only\n */\nexport function useCurrentTenant(): string | null {\n const { currentTenant } = useTenant();\n return currentTenant;\n}\n\n/**\n * Hook for tenant switching\n */\nexport function useTenantSwitcher() {\n const { switchTenant, isLoading, availableTenants } = useTenant();\n return { switchTenant, isLoading, availableTenants };\n}\n\n/**\n * Hook for current organization\n */\nexport function useCurrentOrganization(): OrganizationData | null {\n const { currentOrganization } = useTenant();\n return currentOrganization;\n}\n\n/**\n * Hook for organization operations\n */\nexport function useOrganization() {\n const { currentOrganization, refreshOrganization, isLoading } = useTenant();\n\n return {\n organization: currentOrganization,\n refreshOrganization,\n isLoading,\n };\n}\n"],"mappings":"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"}