@eminuckan/spine 0.2.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 (99) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/LICENSE +21 -0
  3. package/README.md +425 -0
  4. package/dist/api-client/index.d.ts +3 -0
  5. package/dist/api-client/index.js +4 -0
  6. package/dist/api-client/server.d.ts +4 -0
  7. package/dist/api-client/server.js +5 -0
  8. package/dist/api-client-Ftxqm3Ep.js +212 -0
  9. package/dist/api-client-Ftxqm3Ep.js.map +1 -0
  10. package/dist/auth/index.d.ts +2 -0
  11. package/dist/auth/index.js +0 -0
  12. package/dist/auth/server.d.ts +3 -0
  13. package/dist/auth/server.js +6 -0
  14. package/dist/auth.server-C979TR6W.js +724 -0
  15. package/dist/auth.server-C979TR6W.js.map +1 -0
  16. package/dist/auth.server-DU-x2LPA.js +5 -0
  17. package/dist/identity/index.d.ts +4 -0
  18. package/dist/identity/index.js +3 -0
  19. package/dist/identity/server.d.ts +4 -0
  20. package/dist/identity/server.js +4 -0
  21. package/dist/identity-CFa1txoj.js +235 -0
  22. package/dist/identity-CFa1txoj.js.map +1 -0
  23. package/dist/index-BIJOC8Fb.d.ts +272 -0
  24. package/dist/index-BIJOC8Fb.d.ts.map +1 -0
  25. package/dist/index-Bt9XE6gj.d.ts +104 -0
  26. package/dist/index-Bt9XE6gj.d.ts.map +1 -0
  27. package/dist/index-C2hGpzGr.d.ts +74 -0
  28. package/dist/index-C2hGpzGr.d.ts.map +1 -0
  29. package/dist/index-CfQsb3l_.d.ts +170 -0
  30. package/dist/index-CfQsb3l_.d.ts.map +1 -0
  31. package/dist/index-D6RK_5vm.d.ts +199 -0
  32. package/dist/index-D6RK_5vm.d.ts.map +1 -0
  33. package/dist/index-DrttYPAj.d.ts +30 -0
  34. package/dist/index-DrttYPAj.d.ts.map +1 -0
  35. package/dist/index-geY2ynnN.d.ts +141 -0
  36. package/dist/index-geY2ynnN.d.ts.map +1 -0
  37. package/dist/index-kr8Wk7v5.d.ts +1 -0
  38. package/dist/index.d.ts +12 -0
  39. package/dist/index.js +10 -0
  40. package/dist/logging/index.d.ts +3 -0
  41. package/dist/logging/index.js +3 -0
  42. package/dist/logging-_h2mi3L9.js +118 -0
  43. package/dist/logging-_h2mi3L9.js.map +1 -0
  44. package/dist/permissions/index.d.ts +2 -0
  45. package/dist/permissions/index.js +3 -0
  46. package/dist/permissions-D5ScGGnd.js +281 -0
  47. package/dist/permissions-D5ScGGnd.js.map +1 -0
  48. package/dist/query-client/index.d.ts +2 -0
  49. package/dist/query-client/index.js +3 -0
  50. package/dist/query-client-DRPQIKHX.js +174 -0
  51. package/dist/query-client-DRPQIKHX.js.map +1 -0
  52. package/dist/react-router/index.d.ts +12 -0
  53. package/dist/react-router/index.js +10 -0
  54. package/dist/react-router/server.d.ts +18 -0
  55. package/dist/react-router/server.js +17 -0
  56. package/dist/redis-session-storage.server-DhufyPjd.js +250 -0
  57. package/dist/redis-session-storage.server-DhufyPjd.js.map +1 -0
  58. package/dist/server-BoeUiXSh.d.ts +40 -0
  59. package/dist/server-BoeUiXSh.d.ts.map +1 -0
  60. package/dist/server-C-DiVP9e.js +185 -0
  61. package/dist/server-C-DiVP9e.js.map +1 -0
  62. package/dist/server-CLbksnvg.d.ts +144 -0
  63. package/dist/server-CLbksnvg.d.ts.map +1 -0
  64. package/dist/server-CNp6gjFE.js +78 -0
  65. package/dist/server-CNp6gjFE.js.map +1 -0
  66. package/dist/server-CXGaRaiS.d.ts +256 -0
  67. package/dist/server-CXGaRaiS.d.ts.map +1 -0
  68. package/dist/server-CiSbg-9C.js +352 -0
  69. package/dist/server-CiSbg-9C.js.map +1 -0
  70. package/dist/server-DLgH3FRR.js +312 -0
  71. package/dist/server-DLgH3FRR.js.map +1 -0
  72. package/dist/server-DazqdM63.d.ts +93 -0
  73. package/dist/server-DazqdM63.d.ts.map +1 -0
  74. package/dist/server-iWm3oeCM.js +145 -0
  75. package/dist/server-iWm3oeCM.js.map +1 -0
  76. package/dist/server-zEKMDpP7.d.ts +80 -0
  77. package/dist/server-zEKMDpP7.d.ts.map +1 -0
  78. package/dist/server.d.ts +18 -0
  79. package/dist/server.js +17 -0
  80. package/dist/signalr/index.d.ts +4 -0
  81. package/dist/signalr/index.js +3 -0
  82. package/dist/signalr-BJGcXc0m.js +274 -0
  83. package/dist/signalr-BJGcXc0m.js.map +1 -0
  84. package/dist/src-D7mh9MKA.js +0 -0
  85. package/dist/tenant/index.d.ts +3 -0
  86. package/dist/tenant/index.js +3 -0
  87. package/dist/tenant/server.d.ts +3 -0
  88. package/dist/tenant/server.js +5 -0
  89. package/dist/tenant-C6KPaSCX.js +256 -0
  90. package/dist/tenant-C6KPaSCX.js.map +1 -0
  91. package/dist/types-BTjFzIhv.d.ts +31 -0
  92. package/dist/types-BTjFzIhv.d.ts.map +1 -0
  93. package/dist/types-DoIfDhl6.d.ts +55 -0
  94. package/dist/types-DoIfDhl6.d.ts.map +1 -0
  95. package/dist/types-DufLRY7A.d.ts +164 -0
  96. package/dist/types-DufLRY7A.d.ts.map +1 -0
  97. package/dist/types-uDrDMkCq.d.ts +93 -0
  98. package/dist/types-uDrDMkCq.d.ts.map +1 -0
  99. package/package.json +147 -0
@@ -0,0 +1,256 @@
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-C6KPaSCX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-C6KPaSCX.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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"}
@@ -0,0 +1,31 @@
1
+ //#region src/logging/types.d.ts
2
+ /**
3
+ * Logging Types
4
+ */
5
+ declare enum LogLevel {
6
+ DEBUG = "debug",
7
+ INFO = "info",
8
+ WARN = "warn",
9
+ ERROR = "error",
10
+ }
11
+ interface LogContext {
12
+ [key: string]: unknown;
13
+ }
14
+ interface LogEntry {
15
+ timestamp: string;
16
+ level: LogLevel;
17
+ message: string;
18
+ context?: LogContext;
19
+ error?: Error;
20
+ }
21
+ interface LoggerConfig {
22
+ minLevel: LogLevel;
23
+ enableConsole: boolean;
24
+ enableRemote: boolean;
25
+ remoteEndpoint?: string;
26
+ serviceName?: string;
27
+ } //#endregion
28
+
29
+ //# sourceMappingURL=types.d.ts.map
30
+ export { LogContext, LogEntry, LogLevel as LogLevel$1, LoggerConfig };
31
+ //# sourceMappingURL=types-BTjFzIhv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-BTjFzIhv.d.ts","names":[],"sources":["../src/logging/types.ts"],"sourcesContent":null,"mappings":";;;;aAIY,QAAA;EAAA,KAAA,GAAA,OAAQ;EAOH,IAAA,GAAA,MAAU;EAIV,IAAA,GAAA,MAAQ;EAAA,KAAA,GAAA,OAAA;;AAIb,UARK,UAAA,CAQL;EAAU,CAAA,GACZ,EAAA,MAAA,CAAA,EAAA,OAAA;AAAK;AAGE,UARA,QAAA,CAQY;;SANpB;;YAEG;UACF;;UAGO,YAAA;YACL"}
@@ -0,0 +1,55 @@
1
+ //#region src/tenant/types.d.ts
2
+ /**
3
+ * Tenant Types
4
+ */
5
+ interface TenantInfo {
6
+ id: string;
7
+ name?: string;
8
+ role?: string;
9
+ }
10
+ interface TenantMembership {
11
+ tenantId: string;
12
+ tenantName?: string;
13
+ tenantSlug?: string | null;
14
+ organizationName?: string;
15
+ role?: string;
16
+ roles?: string[];
17
+ ownerUserId?: string | null;
18
+ isOwner?: boolean;
19
+ }
20
+ interface OrganizationBranding {
21
+ logoUrl?: string | null;
22
+ themePrimary?: string | null;
23
+ themeMode?: string | null;
24
+ emailBranding?: string | null;
25
+ }
26
+ interface OrganizationData {
27
+ organizationId: string;
28
+ name: string;
29
+ slug?: string | null;
30
+ timeZone?: string | null;
31
+ currency?: string | null;
32
+ branding?: OrganizationBranding | null;
33
+ ownerUserId?: string | null;
34
+ ownerAssignedAtUtc?: string | null;
35
+ defaultOperatingAccountId?: string | null;
36
+ }
37
+ interface TenantContextType {
38
+ currentTenant: string | null;
39
+ availableTenants: string[];
40
+ memberships: Map<string, TenantMembership>;
41
+ currentOrganization: OrganizationData | null;
42
+ currentMembership: TenantMembership | null;
43
+ organizations: Map<string, OrganizationData>;
44
+ isLoading: boolean;
45
+ switchTenant: (tenantId: string) => void;
46
+ refreshTenants: () => void;
47
+ refreshOrganization: () => void;
48
+ getOrganization: (tenantId: string) => OrganizationData | null;
49
+ getMembership: (tenantId: string) => TenantMembership | null;
50
+ getTenantName: (tenantId: string) => string;
51
+ } //#endregion
52
+
53
+ //# sourceMappingURL=types.d.ts.map
54
+ export { OrganizationBranding, OrganizationData, TenantContextType, TenantInfo, TenantMembership };
55
+ //# sourceMappingURL=types-DoIfDhl6.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DoIfDhl6.d.ts","names":[],"sources":["../src/tenant/types.ts"],"sourcesContent":null,"mappings":";;;;UAIiB,UAAA;EAAA,EAAA,EAAA,MAAA;EAMA,IAAA,CAAA,EAAA,MAAA;EAWA,IAAA,CAAA,EAAA,MAAA;AAOjB;AAYiB,UA9BA,gBAAA,CA8BiB;EAAA,QAAA,EAAA,MAAA;EAAA,UAGP,CAAA,EAAA,MAAA;EAAgB,UAA5B,CAAA,EAAA,MAAA,GAAA,IAAA;EAAG,gBACK,CAAA,EAAA,MAAA;EAAgB,IAClB,CAAA,EAAA,MAAA;EAAgB,KACR,CAAA,EAAA,MAAA,EAAA;EAAgB,WAA5B,CAAA,EAAA,MAAA,GAAA,IAAA;EAAG,OAKqB,CAAA,EAAA,OAAA;;AACc,UA/BtC,oBAAA,CA+BsC;;;;;;UAxBtC,gBAAA;;;;;;aAMJ;;;;;UAMI,iBAAA;;;eAGF,YAAY;uBACJ;qBACF;iBACJ,YAAY;;;;;yCAKY;uCACF"}
@@ -0,0 +1,164 @@
1
+ //#region src/auth/types.d.ts
2
+ /**
3
+ * Auth Types
4
+ */
5
+ /**
6
+ * Application Type
7
+ * Determines logout behavior and error handling
8
+ */
9
+ type ApplicationType = 'no-landing-page' | 'landing-page' | 'dashboard' | 'tenant-app' | 'custom';
10
+ /**
11
+ * OAuth Configuration
12
+ */
13
+ interface AuthConfig {
14
+ authority: string;
15
+ clientId: string;
16
+ clientSecret?: string;
17
+ redirectUri: string;
18
+ postLogoutRedirectUri?: string;
19
+ scope: string;
20
+ /**
21
+ * Application type - determines logout behavior
22
+ * - 'no-landing-page': No landing page, defaults to full SSO logout
23
+ * - 'landing-page': Has a landing page, defaults to app-specific logout
24
+ * - 'dashboard': Legacy alias for 'no-landing-page'
25
+ * - 'tenant-app': Legacy alias for 'landing-page'
26
+ * - 'custom': Use explicit ssoLogout setting
27
+ * @default 'custom'
28
+ */
29
+ applicationType?: ApplicationType;
30
+ /**
31
+ * Whether to perform full SSO logout (clear identity cookie) or app-specific logout
32
+ * - true: Full logout - clears identity cookie, revokes all tokens
33
+ * - false: App-specific logout - keeps identity cookie, revokes only this app's tokens
34
+ *
35
+ * If not set, determined by applicationType:
36
+ * - 'no-landing-page': true (full logout)
37
+ * - 'landing-page': false (app-specific)
38
+ * - 'dashboard': true (legacy alias)
39
+ * - 'tenant-app': false (legacy alias)
40
+ * - 'custom': false (default)
41
+ */
42
+ ssoLogout?: boolean;
43
+ /**
44
+ * Whether the application has a landing page
45
+ * - true: Has landing page - OAuth errors redirect to home, user sees landing
46
+ * - false: No landing page - Must handle OAuth errors specially to avoid loops
47
+ *
48
+ * If not set, determined by applicationType:
49
+ * - 'no-landing-page': false
50
+ * - 'landing-page': true
51
+ * - 'dashboard': false (legacy alias)
52
+ * - 'tenant-app': true (legacy alias)
53
+ * - 'custom': true (default)
54
+ */
55
+ hasLandingPage?: boolean;
56
+ }
57
+ /**
58
+ * Configurable claim mapping for adapting auth/session extraction
59
+ * to different identity providers and backend conventions.
60
+ */
61
+ interface AuthClaimMapping {
62
+ subject?: string[];
63
+ name?: string[];
64
+ email?: string[];
65
+ givenName?: string[];
66
+ familyName?: string[];
67
+ picture?: string[];
68
+ locale?: string[];
69
+ zoneinfo?: string[];
70
+ updatedAt?: string[];
71
+ tenantIds?: string[];
72
+ tenantRoles?: string[];
73
+ permissions?: string[];
74
+ isOnboarded?: string[];
75
+ }
76
+ /**
77
+ * User Info from OAuth provider
78
+ */
79
+ interface UserInfo {
80
+ sub: string;
81
+ name?: string;
82
+ email?: string;
83
+ givenName?: string;
84
+ familyName?: string;
85
+ picture?: string;
86
+ locale?: string;
87
+ zoneinfo?: string;
88
+ updated_at?: number;
89
+ [key: string]: unknown;
90
+ }
91
+ /**
92
+ * OAuth State for PKCE flow
93
+ */
94
+ interface OAuthState {
95
+ state: string;
96
+ codeVerifier: string;
97
+ nonce?: string;
98
+ returnUrl?: string;
99
+ createdAt: number;
100
+ }
101
+ /**
102
+ * Session Data stored in Redis
103
+ */
104
+ interface SessionData {
105
+ userId?: string;
106
+ accessToken?: string;
107
+ refreshToken?: string;
108
+ idToken?: string;
109
+ expiresAt?: number;
110
+ user?: UserInfo;
111
+ lastActivity?: number;
112
+ }
113
+ /**
114
+ * Session Flash Data for temporary messages
115
+ */
116
+ interface SessionFlashData {
117
+ error: string;
118
+ success: string;
119
+ }
120
+ /**
121
+ * Token refresh result
122
+ */
123
+ interface TokenRefreshResult {
124
+ success: boolean;
125
+ newAccessToken?: string;
126
+ tokens?: {
127
+ access_token: string;
128
+ refresh_token?: string;
129
+ id_token?: string;
130
+ expires_in?: number;
131
+ };
132
+ error?: string;
133
+ shouldLogout?: boolean;
134
+ }
135
+ /**
136
+ * Route protection levels
137
+ */
138
+ type ProtectionLevel = 'public' | 'auth' | 'onboarding-required' | 'subscription-required';
139
+ /**
140
+ * Protected route loader function type
141
+ */
142
+ type ProtectedLoaderFn<T> = (user?: UserInfo) => Promise<T> | T;
143
+ /**
144
+ * Login options
145
+ */
146
+ interface LoginOptions {
147
+ /** Return URL after successful login */
148
+ returnUrl?: string;
149
+ /** OAuth prompt parameter (none, login, consent, select_account) */
150
+ prompt?: 'none' | 'login' | 'consent' | 'select_account';
151
+ }
152
+ /**
153
+ * Auth error information from OAuth callback
154
+ */
155
+ interface AuthError {
156
+ /** Error code (e.g., 'access_denied', 'login_required') */
157
+ error: string;
158
+ /** Human-readable error description */
159
+ description?: string;
160
+ } //#endregion
161
+
162
+ //# sourceMappingURL=types.d.ts.map
163
+ export { ApplicationType, AuthClaimMapping, AuthConfig, AuthError, LoginOptions, OAuthState, ProtectedLoaderFn, ProtectionLevel, SessionData, SessionFlashData, TokenRefreshResult as TokenRefreshResult$1, UserInfo };
164
+ //# sourceMappingURL=types-DufLRY7A.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DufLRY7A.d.ts","names":[],"sources":["../src/auth/types.ts"],"sourcesContent":null,"mappings":";;;;;;;;KAQY,eAAA;AAAZ;;;UAUiB,UAAA;EAAA,SAAA,EAAA,MAAU;;;;;EAoDV,KAAA,EAAA,MAAA;;;;AAmBjB;;;;AAgBA;;oBAtEoB;;AAiFpB;;;;AAaA;;;;AAQA;;;;EAgBY;;;;AASZ;;;;;;AAAsE;;;;AAKtE;;;;AAUiB,UA3GA,gBAAA,CA2GS;;;;;;;;;;;;;;;;;;UAxFT,QAAA;;;;;;;;;;;;;;;UAgBA,UAAA;;;;;;;;;;UAWA,WAAA;;;;;;SAMR;;;;;;UAOQ,gBAAA;;;;;;;UAQA,kBAAA;;;;;;;;;;;;;;;KAgBL,eAAA;;;;KASA,+BAA+B,aAAa,QAAQ,KAAK;;;;UAKpD,YAAA;;;;;;;;;UAUA,SAAA"}
@@ -0,0 +1,93 @@
1
+ import { TenantMembership } from "./types-DoIfDhl6.js";
2
+
3
+ //#region src/identity/types.d.ts
4
+ /**
5
+ * Address data for user profile
6
+ */
7
+
8
+ /**
9
+ * Address data for user profile
10
+ */
11
+ interface AddressData {
12
+ addressId?: string;
13
+ type?: string;
14
+ line1: string;
15
+ line2?: string | null;
16
+ city: string;
17
+ state: string;
18
+ postalCode: string;
19
+ country: string;
20
+ isPrimary?: boolean;
21
+ attention?: string | null;
22
+ region?: string | null;
23
+ }
24
+ /**
25
+ * Core identity context data
26
+ *
27
+ * This interface is designed to be flexible and work with various backend implementations.
28
+ * Only the fields your backend returns need to be populated.
29
+ */
30
+ interface IdentityContextData {
31
+ /** Unique user identifier */
32
+ userId?: string;
33
+ /** User's email address */
34
+ email?: string;
35
+ /** User's first name */
36
+ firstName?: string | null;
37
+ /** User's last name */
38
+ lastName?: string | null;
39
+ /** User's display name (computed or custom) */
40
+ displayName?: string | null;
41
+ /** URL to user's profile image/avatar */
42
+ profileImageUrl?: string | null;
43
+ /** User's phone number */
44
+ phoneNumber?: string | null;
45
+ /** User's timezone (e.g., "America/New_York") */
46
+ timeZone?: string;
47
+ /** User's preferred locale (e.g., "en-US") */
48
+ locale?: string;
49
+ /** User's addresses */
50
+ addresses?: AddressData[];
51
+ /** Whether user has any tenant membership */
52
+ hasAnyMembership?: boolean;
53
+ /** Whether user owns any tenant */
54
+ hasOwnerMembership?: boolean;
55
+ /** List of tenant IDs user belongs to */
56
+ tenants?: string[];
57
+ /** Currently active tenant ID */
58
+ currentTenant?: string;
59
+ /** Detailed membership information */
60
+ memberships?: TenantMembership[];
61
+ /** Whether user has completed onboarding */
62
+ isOnboarded?: boolean;
63
+ /** Whether user has an active subscription */
64
+ hasSubscription?: boolean;
65
+ /** Whether user's email is verified */
66
+ emailVerified?: boolean;
67
+ /** Whether 2FA is enabled */
68
+ twoFactorEnabled?: boolean;
69
+ /** User's permissions (for current tenant or global) */
70
+ permissions?: string[];
71
+ /** User's global roles */
72
+ globalRoles?: string[];
73
+ /** Version number for cache invalidation */
74
+ contextVersion?: number;
75
+ /** Loading state indicator */
76
+ isLoading?: boolean;
77
+ /** Last time context was updated */
78
+ lastUpdated?: Date;
79
+ /** Additional custom data from backend */
80
+ metadata?: Record<string, unknown>;
81
+ }
82
+ interface IdentityContextChangedEvent {
83
+ reason: string;
84
+ tenantId?: string;
85
+ triggeredByUserId?: string;
86
+ contextVersion: number;
87
+ timestamp: string;
88
+ }
89
+ type IdentityContextChangeHandler = (event: IdentityContextChangedEvent) => void; //#endregion
90
+
91
+ //# sourceMappingURL=types.d.ts.map
92
+ export { AddressData, IdentityContextChangeHandler, IdentityContextChangedEvent, IdentityContextData };
93
+ //# sourceMappingURL=types-uDrDMkCq.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-uDrDMkCq.d.ts","names":[],"sources":["../src/identity/types.ts"],"sourcesContent":null,"mappings":";;;;;;;;;;UAciB,WAAA;;EAoBA,IAAA,CAAA,EAAA,MAAA;EAAmB,KAAA,EAAA,MAAA;EAAA,KAuBtB,CAAA,EAAA,MAAA,GAAA,IAAA;EAAW,IAYT,EAAA,MAAA;EAAgB,KAwBhB,EAAA,MAAA;EAAI,UAIP,EAAA,MAAA;EAAM,OAAA,EAAA,MAAA;EAGF,SAAA,CAAA,EAAA,OAAA;EAQL,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;;UA1EK,mBAAA;;;;;;;;;;;;;;;;;;;;cAuBH;;;;;;;;;;gBAYE;;;;;;;;;;;;;;;;;;gBAwBA;;aAIH;;UAGI,2BAAA;;;;;;;KAQL,4BAAA,WAAuC"}