@elevasis/ui 1.2.1 → 1.3.1

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 (59) hide show
  1. package/dist/CoreAuthKitInner-3J4RVQO6.js +43 -0
  2. package/dist/api/index.d.ts +32 -18
  3. package/dist/api/index.js +4 -2
  4. package/dist/auth/context.d.ts +23 -5
  5. package/dist/auth/index.d.ts +119 -30
  6. package/dist/auth/index.js +6 -3
  7. package/dist/chunk-2JBWPFHF.js +108 -0
  8. package/dist/chunk-4VGWQ5AN.js +91 -0
  9. package/dist/chunk-72HOBFMP.js +87 -0
  10. package/dist/{chunk-WNWKOCGJ.js → chunk-A3MCANC6.js} +296 -2
  11. package/dist/{chunk-JKERRYVS.js → chunk-BLO4SISK.js} +7 -3
  12. package/dist/chunk-DD3CCMCZ.js +15 -0
  13. package/dist/chunk-FWZJH3TL.js +13 -0
  14. package/dist/{chunk-GEFB5YIR.js → chunk-JBFFCZI4.js} +1 -1
  15. package/dist/chunk-JGJSZ3UE.js +47 -0
  16. package/dist/{chunk-7AI5ZYJ4.js → chunk-JVAZHVNV.js} +2 -94
  17. package/dist/{chunk-ZGHDPDTF.js → chunk-JYSYHVLU.js} +3 -3
  18. package/dist/{chunk-5UWFGBFM.js → chunk-L2CM2CUA.js} +16 -4
  19. package/dist/chunk-NEK6JKPW.js +75 -0
  20. package/dist/{chunk-J3FALDQE.js → chunk-NXHL23JW.js} +7 -13
  21. package/dist/{chunk-OUHGHTE7.js → chunk-O3PY6B6E.js} +3 -2
  22. package/dist/{chunk-YULUKCS6.js → chunk-PVVQTENF.js} +1 -1
  23. package/dist/chunk-TIRMFDM4.js +33 -0
  24. package/dist/{chunk-PYL4XW6H.js → chunk-TMFCNFLW.js} +1 -1
  25. package/dist/{chunk-S66I2PYB.js → chunk-TN3PU2WK.js} +1 -1
  26. package/dist/chunk-TYV5NJV2.js +1 -0
  27. package/dist/{chunk-B64YDSAY.js → chunk-TZPAA4RC.js} +54 -97
  28. package/dist/chunk-UMXDDEAG.js +148 -0
  29. package/dist/chunk-XLV6LYN2.js +157 -0
  30. package/dist/components/command-queue/index.js +6 -4
  31. package/dist/components/index.js +9 -7
  32. package/dist/components/notifications/index.js +4 -3
  33. package/dist/display/index.js +3 -2
  34. package/dist/hooks/index.d.ts +2630 -3
  35. package/dist/hooks/index.js +9 -5
  36. package/dist/hooks/published.d.ts +2630 -3
  37. package/dist/hooks/published.js +7 -3
  38. package/dist/index.d.ts +759 -164
  39. package/dist/index.js +24 -18
  40. package/dist/initialization/index.d.ts +49 -1
  41. package/dist/initialization/index.js +5 -2
  42. package/dist/organization/index.d.ts +61 -2
  43. package/dist/organization/index.js +5 -2
  44. package/dist/profile/index.d.ts +30 -2
  45. package/dist/profile/index.js +2 -1
  46. package/dist/provider/index.d.ts +116 -43
  47. package/dist/provider/index.js +10 -6
  48. package/dist/provider/published.d.ts +88 -28
  49. package/dist/provider/published.js +9 -4
  50. package/dist/supabase/index.js +2 -47
  51. package/dist/utils/index.js +2 -1
  52. package/package.json +15 -2
  53. package/dist/CoreAuthKitInner-KM72EYJS.js +0 -19
  54. package/dist/chunk-GDV44UWF.js +0 -138
  55. package/dist/chunk-HBRMWW6V.js +0 -43
  56. package/dist/chunk-NIAVTSMB.js +0 -21
  57. package/dist/chunk-QSVZP2NU.js +0 -214
  58. package/dist/chunk-ZQVPUAGR.js +0 -89
  59. /package/dist/{chunk-Q47SPRY7.js → chunk-RNP5R5I3.js} +0 -0
@@ -1,7 +1,6 @@
1
+ import { useNotificationAdapter } from './chunk-TIRMFDM4.js';
1
2
  import { useElevasisServices } from './chunk-KA7LO7U5.js';
2
- import { showApiErrorNotification } from './chunk-7AI5ZYJ4.js';
3
3
  import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
4
- import { notifications } from '@mantine/notifications';
5
4
 
6
5
  function useCommandQueue({
7
6
  status,
@@ -82,6 +81,7 @@ function useSubmitAction() {
82
81
  function useDeleteTask() {
83
82
  const { apiRequest } = useElevasisServices();
84
83
  const queryClient = useQueryClient();
84
+ const notify = useNotificationAdapter();
85
85
  return useMutation({
86
86
  mutationFn: async (taskId) => {
87
87
  await apiRequest(`/command-queue/${taskId}`, {
@@ -95,20 +95,13 @@ function useDeleteTask() {
95
95
  for (const [queryKey, data] of queries) {
96
96
  previousData.set(queryKey, data);
97
97
  if (data) {
98
- queryClient.setQueryData(
99
- queryKey,
100
- (old) => old?.filter((task) => task.id !== taskId)
101
- );
98
+ queryClient.setQueryData(queryKey, (old) => old?.filter((task) => task.id !== taskId));
102
99
  }
103
100
  }
104
101
  return { previousData };
105
102
  },
106
103
  onSuccess: () => {
107
- notifications.show({
108
- title: "Task Deleted",
109
- message: "Task has been removed",
110
- color: "green"
111
- });
104
+ notify.success("Task Deleted", "Task has been removed");
112
105
  queryClient.invalidateQueries({ queryKey: ["command-queue"] });
113
106
  },
114
107
  onError: (error, _taskId, context) => {
@@ -117,7 +110,7 @@ function useDeleteTask() {
117
110
  queryClient.setQueryData(queryKey, data);
118
111
  }
119
112
  }
120
- showApiErrorNotification(error);
113
+ notify.apiError(error);
121
114
  }
122
115
  });
123
116
  }
@@ -146,6 +139,7 @@ function useCommandQueueTotals({
146
139
  function usePatchTask() {
147
140
  const { apiRequest } = useElevasisServices();
148
141
  const queryClient = useQueryClient();
142
+ const notify = useNotificationAdapter();
149
143
  return useMutation({
150
144
  mutationFn: async ({ taskId, params }) => {
151
145
  const response = await apiRequest(`/command-queue/${taskId}`, {
@@ -168,7 +162,7 @@ function usePatchTask() {
168
162
  );
169
163
  },
170
164
  onError: (error) => {
171
- showApiErrorNotification(error);
165
+ notify.apiError(error);
172
166
  }
173
167
  });
174
168
  }
@@ -1,6 +1,7 @@
1
1
  import { StyledMarkdown } from './chunk-3KMDHCAR.js';
2
2
  import { ResourceStatusColors } from './chunk-YZ6GTZXL.js';
3
- import { getErrorInfo, getErrorTitle, getResourceIcon } from './chunk-7AI5ZYJ4.js';
3
+ import { getResourceIcon } from './chunk-JVAZHVNV.js';
4
+ import { getErrorInfo, getErrorTitle } from './chunk-4VGWQ5AN.js';
4
5
  import { useAuthContext } from './chunk-7PLEQFHO.js';
5
6
  import { useRouterContext } from './chunk-Q7DJKLEN.js';
6
7
  import { Alert, Text, Code, Group, Badge, Collapse, ScrollArea, Center, Stack, Title, Button, UnstyledButton, Box, ThemeIcon, Card, Skeleton, Paper, Loader, Select, Grid, Space } from '@mantine/core';
@@ -101,7 +102,7 @@ function CollapsibleSection({
101
102
  function EmptyState({ icon: Icon, title, description, action, py = "xl" }) {
102
103
  return /* @__PURE__ */ jsx(Center, { py, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "xs", children: [
103
104
  /* @__PURE__ */ jsx(Icon, { size: 48, style: { opacity: 0.5 } }),
104
- /* @__PURE__ */ jsx(Title, { order: 3, children: title }),
105
+ /* @__PURE__ */ jsx(Title, { order: 4, children: title }),
105
106
  description && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", ta: "center", children: description }),
106
107
  action && /* @__PURE__ */ jsx(Button, { variant: "light", onClick: action.onClick, leftSection: action.icon, mt: "sm", children: action.label })
107
108
  ] }) });
@@ -1,4 +1,4 @@
1
- import { useUserProfile } from './chunk-5UWFGBFM.js';
1
+ import { useUserProfile } from './chunk-L2CM2CUA.js';
2
2
  import { useAuthContext } from './chunk-7PLEQFHO.js';
3
3
  import { useMemo, useCallback } from 'react';
4
4
 
@@ -0,0 +1,33 @@
1
+ import { getErrorInfo, getErrorTitle, formatErrorMessage } from './chunk-4VGWQ5AN.js';
2
+ import { createContext, useContext } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ var consoleAdapter = {
6
+ success(title, message) {
7
+ console.log(`[Notification][Success] ${title}: ${message}`);
8
+ },
9
+ error(title, message) {
10
+ console.warn(`[Notification][Error] ${title}: ${message}`);
11
+ },
12
+ info(title, message) {
13
+ console.log(`[Notification][Info] ${title}: ${message}`);
14
+ },
15
+ warning(title, message) {
16
+ console.warn(`[Notification][Warning] ${title}: ${message}`);
17
+ },
18
+ apiError(error) {
19
+ const { message, code, requestId, fields, retryAfter } = getErrorInfo(error);
20
+ const title = getErrorTitle(code);
21
+ const formatted = formatErrorMessage(message, requestId, fields, retryAfter);
22
+ console.warn(`[Notification][API Error] ${title}: ${formatted}`);
23
+ }
24
+ };
25
+ var NotificationContext = createContext(consoleAdapter);
26
+ function NotificationProvider({ adapter, children }) {
27
+ return /* @__PURE__ */ jsx(NotificationContext.Provider, { value: adapter, children });
28
+ }
29
+ function useNotificationAdapter() {
30
+ return useContext(NotificationContext);
31
+ }
32
+
33
+ export { NotificationProvider, useNotificationAdapter };
@@ -1,4 +1,4 @@
1
- import { useMarkAsRead, useMarkAllAsRead, useNotificationCount, useNotifications } from './chunk-JKERRYVS.js';
1
+ import { useMarkAsRead, useMarkAllAsRead, useNotificationCount, useNotifications } from './chunk-BLO4SISK.js';
2
2
  import { UnstyledButton, Group, Box, Stack, Text, Center, Loader, Button, Divider, ScrollArea, Popover, Tooltip, Indicator, ActionIcon } from '@mantine/core';
3
3
  import { IconCircle, IconCircleFilled, IconBell } from '@tabler/icons-react';
4
4
  import { formatDistanceToNow } from 'date-fns';
@@ -1,4 +1,4 @@
1
- import { CustomModal } from './chunk-ZGHDPDTF.js';
1
+ import { CustomModal } from './chunk-JYSYHVLU.js';
2
2
  import { StyledMarkdown } from './chunk-3KMDHCAR.js';
3
3
  import { memo, useState, useCallback, cloneElement, useRef, useEffect, useMemo } from 'react';
4
4
  import { Stack, Group, Text, Tooltip, ActionIcon, Paper, Textarea, Box, Collapse, Center, Space, Button, Title, TextInput, Alert, Badge, Progress, Loader } from '@mantine/core';
@@ -0,0 +1 @@
1
+
@@ -1,14 +1,10 @@
1
- import { ApiClientProvider, createUseApiClient } from './chunk-GDV44UWF.js';
2
- import { ElevasisServiceProvider } from './chunk-KA7LO7U5.js';
3
- import { WorkOSAuthBridge } from './chunk-NIAVTSMB.js';
4
- import { OAuthProvider } from './chunk-QSVZP2NU.js';
5
- import { useAuthContext } from './chunk-7PLEQFHO.js';
6
- import { useMemo, useEffect, useRef } from 'react';
1
+ import { ElevasisCoreProvider } from './chunk-72HOBFMP.js';
2
+ import { getErrorInfo, formatErrorMessage, getErrorTitle } from './chunk-4VGWQ5AN.js';
3
+ import { useMemo, useEffect } from 'react';
7
4
  import { Tooltip, Text, Tabs, Table, Stack, SimpleGrid, Select, Combobox, SegmentedControl, ScrollArea, Paper, Popover, Notification, Modal, Menu, Input, HoverCard, Group, Grid, Flex, Code, Divider, Card, Button, Accordion, createTheme, mergeThemeOverrides, MantineProvider } from '@mantine/core';
8
- import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
9
- import { AuthKitProvider } from '@workos-inc/authkit-react';
10
5
  import '@mantine/core/styles.css';
11
6
  import '@mantine/notifications/styles.css';
7
+ import { notifications } from '@mantine/notifications';
12
8
  import { jsx } from 'react/jsx-runtime';
13
9
 
14
10
  var DEFAULT_SIZE = "sm";
@@ -1366,32 +1362,56 @@ function createCssVariablesResolver(tokens, preset) {
1366
1362
  dark: { ...darkShades, ...darkDefaults, ...flat, ...dark }
1367
1363
  });
1368
1364
  }
1369
- var defaultQueryClient = null;
1370
- function getDefaultQueryClient() {
1371
- if (!defaultQueryClient) {
1372
- defaultQueryClient = new QueryClient({
1373
- defaultOptions: { queries: { retry: 1 } }
1365
+ var mantineNotificationAdapter = {
1366
+ success(title, message) {
1367
+ notifications.show({
1368
+ title,
1369
+ message,
1370
+ autoClose: 5e3,
1371
+ color: "green",
1372
+ position: "top-right"
1373
+ });
1374
+ },
1375
+ error(title, message) {
1376
+ notifications.show({
1377
+ title,
1378
+ message,
1379
+ autoClose: 5e3,
1380
+ color: "red",
1381
+ position: "top-right"
1382
+ });
1383
+ },
1384
+ info(title, message) {
1385
+ notifications.show({
1386
+ title,
1387
+ message,
1388
+ autoClose: 5e3,
1389
+ color: "blue",
1390
+ position: "top-right"
1391
+ });
1392
+ },
1393
+ warning(title, message) {
1394
+ notifications.show({
1395
+ title,
1396
+ message,
1397
+ autoClose: 5e3,
1398
+ color: "orange",
1399
+ position: "top-right"
1400
+ });
1401
+ },
1402
+ apiError(error) {
1403
+ const { message, code, requestId, fields, retryAfter } = getErrorInfo(error);
1404
+ const hasFields = fields && Object.keys(fields).length > 0;
1405
+ notifications.show({
1406
+ title: getErrorTitle(code),
1407
+ message: formatErrorMessage(message, requestId, fields, retryAfter),
1408
+ autoClose: retryAfter ? retryAfter * 1e3 : hasFields ? 8e3 : 5e3,
1409
+ color: "red",
1410
+ position: "top-right"
1374
1411
  });
1375
1412
  }
1376
- return defaultQueryClient;
1377
- }
1378
- var defaultUseOrganizations = () => ({ isInitializing: false, isOrgRefreshing: false });
1379
- function ElevasisUIProvider({
1380
- auth,
1381
- theme,
1382
- organizationId = null,
1383
- queryClient,
1384
- apiUrl,
1385
- onError,
1386
- isOrganizationReady,
1387
- children
1388
- }) {
1389
- if (auth.mode === "apiKey") {
1390
- throw new Error(
1391
- `ElevasisUIProvider: auth mode 'apiKey' is not yet implemented. Only 'authkit' and 'oauth' modes are supported.`
1392
- );
1393
- }
1394
- const resolvedQueryClient = queryClient ?? getDefaultQueryClient();
1413
+ };
1414
+ function ElevasisUIProvider({ theme, children, ...coreProps }) {
1395
1415
  const resolvedColorScheme = theme?.colorScheme ?? "dark";
1396
1416
  const preset = useMemo(() => getPreset(theme?.preset ?? "default"), [theme?.preset]);
1397
1417
  useEffect(() => {
@@ -1426,79 +1446,16 @@ function ElevasisUIProvider({
1426
1446
  () => createCssVariablesResolver(theme?.tokens, theme?.preset),
1427
1447
  [theme?.tokens, theme?.preset]
1428
1448
  );
1429
- const content = apiUrl ? /* @__PURE__ */ jsx(
1430
- ServiceBridge,
1431
- {
1432
- apiUrl,
1433
- organizationId,
1434
- isOrganizationReady,
1435
- onError,
1436
- children
1437
- }
1438
- ) : children;
1439
- const AuthInner = auth.mode === "authkit" ? /* @__PURE__ */ jsx(AuthKitInner, { auth, children: content }) : /* @__PURE__ */ jsx(OAuthInner, { auth, children: content });
1440
1449
  return /* @__PURE__ */ jsx(
1441
1450
  MantineProvider,
1442
1451
  {
1443
1452
  theme: resolvedTheme,
1444
1453
  defaultColorScheme: resolvedColorScheme,
1445
1454
  cssVariablesResolver,
1446
- children: /* @__PURE__ */ jsx(QueryClientProvider, { client: resolvedQueryClient, children: AuthInner })
1447
- }
1448
- );
1449
- }
1450
- function AuthKitInner({ auth, children }) {
1451
- return /* @__PURE__ */ jsx(
1452
- AuthKitProvider,
1453
- {
1454
- clientId: auth.clientId,
1455
- apiHostname: auth.apiHostname ?? "api.workos.com",
1456
- redirectUri: auth.redirectUri,
1457
- devMode: auth.devMode ?? false,
1458
- children: /* @__PURE__ */ jsx(WorkOSAuthBridge, { children })
1459
- }
1460
- );
1461
- }
1462
- function OAuthInner({ auth, children }) {
1463
- return /* @__PURE__ */ jsx(OAuthProvider, { config: auth, children });
1464
- }
1465
- function ServiceBridge({
1466
- apiUrl,
1467
- organizationId,
1468
- isOrganizationReady,
1469
- onError,
1470
- children
1471
- }) {
1472
- const { getAccessToken } = useAuthContext();
1473
- return /* @__PURE__ */ jsx(
1474
- ApiClientProvider,
1475
- {
1476
- getAccessToken,
1477
- organizationId,
1478
- isOrganizationReady: isOrganizationReady ?? !!organizationId,
1479
- onError,
1480
- children: /* @__PURE__ */ jsx(ServiceBridgeInner, { apiUrl, organizationId, isOrganizationReady, children })
1481
- }
1482
- );
1483
- }
1484
- function ServiceBridgeInner({
1485
- apiUrl,
1486
- organizationId,
1487
- isOrganizationReady,
1488
- children
1489
- }) {
1490
- const useApiClient = useRef(createUseApiClient(defaultUseOrganizations, apiUrl)).current;
1491
- const { apiRequest } = useApiClient();
1492
- return /* @__PURE__ */ jsx(
1493
- ElevasisServiceProvider,
1494
- {
1495
- apiRequest,
1496
- organizationId,
1497
- isReady: isOrganizationReady ?? !!organizationId,
1498
- children
1455
+ children: /* @__PURE__ */ jsx(ElevasisCoreProvider, { notifications: mantineNotificationAdapter, ...coreProps, children })
1499
1456
  }
1500
1457
  );
1501
1458
  }
1502
1459
  var ElevasisProvider = ElevasisUIProvider;
1503
1460
 
1504
- export { ElevasisProvider, ElevasisUIProvider, createCssVariablesResolver, generateShades, getPreset, mantineThemeOverride };
1461
+ export { ElevasisProvider, ElevasisUIProvider, createCssVariablesResolver, generateShades, getPreset, mantineNotificationAdapter, mantineThemeOverride };
@@ -0,0 +1,148 @@
1
+ import { useProfile } from './chunk-L2CM2CUA.js';
2
+ import { OrganizationContext } from './chunk-DD3CCMCZ.js';
3
+ import { useElevasisServices } from './chunk-KA7LO7U5.js';
4
+ import { useAuthContext } from './chunk-7PLEQFHO.js';
5
+ import { useState, useRef, useEffect, useCallback, createElement } from 'react';
6
+ import { useQueryClient } from '@tanstack/react-query';
7
+
8
+ function OrganizationProvider({ children }) {
9
+ const { user, organizationId: workosOrgId } = useAuthContext();
10
+ const { apiRequest } = useElevasisServices();
11
+ const { profile } = useProfile();
12
+ const queryClient = useQueryClient();
13
+ const [memberships, setMemberships] = useState([]);
14
+ const [currentWorkOSOrganizationId, setCurrentWorkOSOrganizationId] = useState(null);
15
+ const [currentSupabaseOrganizationId, setCurrentSupabaseOrganizationId] = useState(null);
16
+ const [currentMembership, setCurrentMembership] = useState(null);
17
+ const [isInitializing, setIsInitializing] = useState(true);
18
+ const [isOrgRefreshing, setIsOrgRefreshing] = useState(false);
19
+ const [error, setError] = useState(null);
20
+ const hasInitializedRef = useRef(false);
21
+ const [profileLoaded, setProfileLoaded] = useState(false);
22
+ useEffect(() => {
23
+ if (profile !== void 0 && profile !== null) {
24
+ setProfileLoaded(true);
25
+ }
26
+ }, [profile]);
27
+ useEffect(() => {
28
+ if (!user) {
29
+ setMemberships([]);
30
+ setCurrentWorkOSOrganizationId(null);
31
+ setCurrentSupabaseOrganizationId(null);
32
+ setCurrentMembership(null);
33
+ setIsInitializing(false);
34
+ setIsOrgRefreshing(false);
35
+ setError(null);
36
+ hasInitializedRef.current = false;
37
+ setProfileLoaded(false);
38
+ }
39
+ }, [user]);
40
+ const applyMembership = useCallback((membership) => {
41
+ setCurrentMembership(membership);
42
+ setCurrentSupabaseOrganizationId(membership?.organization?.id ?? null);
43
+ setCurrentWorkOSOrganizationId(membership?.organization?.workos_org_id ?? null);
44
+ }, []);
45
+ const selectOrganization = useCallback(
46
+ (data) => {
47
+ let selected = null;
48
+ if (profile?.last_visited_org) {
49
+ selected = data.find((m) => m.organizationId === profile.last_visited_org) ?? null;
50
+ }
51
+ if (!selected && workosOrgId) {
52
+ selected = data.find((m) => m.organization?.workos_org_id === workosOrgId) ?? null;
53
+ }
54
+ if (!selected && data.length > 0) {
55
+ selected = data[0];
56
+ }
57
+ if (selected) {
58
+ applyMembership(selected);
59
+ }
60
+ },
61
+ [profile?.last_visited_org, workosOrgId, applyMembership]
62
+ );
63
+ const fetchAndInitialize = useCallback(async () => {
64
+ if (!user?.id || !profileLoaded) return;
65
+ setError(null);
66
+ if (memberships.length === 0) {
67
+ setIsInitializing(true);
68
+ } else {
69
+ setIsOrgRefreshing(true);
70
+ }
71
+ try {
72
+ const data = await apiRequest("/memberships/my-memberships");
73
+ if (!Array.isArray(data)) {
74
+ throw new Error("Invalid memberships response");
75
+ }
76
+ setMemberships(data);
77
+ if (data.length === 0) {
78
+ setError("No organization memberships found. Please contact your administrator or try refreshing the page.");
79
+ hasInitializedRef.current = true;
80
+ return;
81
+ }
82
+ if (!currentWorkOSOrganizationId) {
83
+ selectOrganization(data);
84
+ } else {
85
+ const stillPresent = data.find((m) => m.organization?.workos_org_id === currentWorkOSOrganizationId);
86
+ if (!stillPresent) {
87
+ applyMembership(data[0] ?? null);
88
+ } else if (stillPresent.id !== currentMembership?.id) {
89
+ applyMembership(stillPresent);
90
+ }
91
+ }
92
+ hasInitializedRef.current = true;
93
+ } catch (err) {
94
+ setError(err instanceof Error ? err.message : "Failed to load organizations");
95
+ } finally {
96
+ setIsInitializing(false);
97
+ setIsOrgRefreshing(false);
98
+ }
99
+ }, [
100
+ user?.id,
101
+ profileLoaded,
102
+ memberships.length,
103
+ apiRequest,
104
+ currentWorkOSOrganizationId,
105
+ currentMembership?.id,
106
+ selectOrganization,
107
+ applyMembership
108
+ ]);
109
+ useEffect(() => {
110
+ if (!user?.id || !profileLoaded || hasInitializedRef.current) return;
111
+ fetchAndInitialize();
112
+ }, [user?.id, profileLoaded, fetchAndInitialize]);
113
+ const switchOrganization = useCallback(
114
+ (workosOrgId2) => {
115
+ const target = memberships.find((m) => m.organization?.workos_org_id === workosOrgId2);
116
+ if (!target) return;
117
+ applyMembership(target);
118
+ void queryClient.invalidateQueries();
119
+ void apiRequest("/users/me", {
120
+ method: "PATCH",
121
+ headers: { "Content-Type": "application/json" },
122
+ body: JSON.stringify({ last_visited_org: target.organizationId })
123
+ }).catch((err) => {
124
+ console.warn("Failed to persist last_visited_org preference:", err);
125
+ });
126
+ },
127
+ [memberships, applyMembership, queryClient, apiRequest]
128
+ );
129
+ const retry = useCallback(async () => {
130
+ hasInitializedRef.current = false;
131
+ setError(null);
132
+ await fetchAndInitialize();
133
+ }, [fetchAndInitialize]);
134
+ const value = {
135
+ currentWorkOSOrganizationId,
136
+ currentSupabaseOrganizationId,
137
+ currentMembership,
138
+ memberships,
139
+ isInitializing,
140
+ isOrgRefreshing,
141
+ error,
142
+ switchOrganization,
143
+ retry
144
+ };
145
+ return createElement(OrganizationContext.Provider, { value }, children);
146
+ }
147
+
148
+ export { OrganizationProvider };
@@ -0,0 +1,157 @@
1
+ import { APIClientError } from './chunk-4VGWQ5AN.js';
2
+ import { OrganizationContext } from './chunk-DD3CCMCZ.js';
3
+ import { createContext, useContext, useMemo, useCallback } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var ApiClientContext = createContext(null);
7
+ function useApiClientContext() {
8
+ const context = useContext(ApiClientContext);
9
+ if (!context) {
10
+ throw new Error("useApiClient must be used within ApiClientProvider");
11
+ }
12
+ return context;
13
+ }
14
+ function ApiClientProvider({
15
+ children,
16
+ getAccessToken,
17
+ organizationId = null,
18
+ getOrganizationId: getOrganizationIdProp,
19
+ isOrganizationReady,
20
+ onError
21
+ }) {
22
+ const getOrganizationId = useMemo(
23
+ () => getOrganizationIdProp ?? (() => organizationId ?? null),
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ [getOrganizationIdProp, organizationId]
26
+ );
27
+ const value = useMemo(
28
+ () => ({
29
+ getAccessToken,
30
+ organizationId: organizationId ?? null,
31
+ isOrganizationReady,
32
+ getOrganizationId,
33
+ onError
34
+ }),
35
+ [getAccessToken, organizationId, isOrganizationReady, getOrganizationId, onError]
36
+ );
37
+ return /* @__PURE__ */ jsx(ApiClientContext.Provider, { value, children });
38
+ }
39
+
40
+ // ../core/src/platform/constants/http.ts
41
+ var HTTP_HEADERS = {
42
+ /**
43
+ * Organization context header
44
+ * Note: Node.js normalizes all headers to lowercase, so we use lowercase consistently
45
+ */
46
+ WORKOS_ORGANIZATION_ID: "workos-organization-id",
47
+ AGENT_ORGANIZATION: "x-agent-organization",
48
+ AGENT_MODE: "x-agent-mode"
49
+ };
50
+
51
+ // src/api/hooks/useApiClient.ts
52
+ var DEFAULT_TIMEOUT_MS = 6e4;
53
+ function buildApiRequest(getAccessToken, getOrganizationId, apiUrl, handleResponseError) {
54
+ return async function apiRequest(endpoint, options = {}) {
55
+ try {
56
+ const token = await getAccessToken();
57
+ const organizationId = getOrganizationId();
58
+ const headers = {
59
+ ...options.body ? { "Content-Type": "application/json" } : {},
60
+ ...token ? { Authorization: `Bearer ${token}` } : {},
61
+ ...organizationId && { [HTTP_HEADERS.WORKOS_ORGANIZATION_ID]: organizationId },
62
+ ...options.headers
63
+ };
64
+ const timeoutSignal = AbortSignal.timeout(DEFAULT_TIMEOUT_MS);
65
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
66
+ const response = await fetch(`${apiUrl}/api${endpoint}`, {
67
+ ...options,
68
+ headers,
69
+ signal
70
+ });
71
+ if (!response.ok) {
72
+ await handleResponseError(endpoint, response, options);
73
+ }
74
+ if (response.status === 204) {
75
+ return void 0;
76
+ }
77
+ const data = await response.json();
78
+ return data;
79
+ } catch (error) {
80
+ if (error instanceof Error && error.message.includes("No access token")) {
81
+ const headers = {
82
+ ...options.body ? { "Content-Type": "application/json" } : {},
83
+ ...options.headers
84
+ };
85
+ const fallbackTimeoutSignal = AbortSignal.timeout(DEFAULT_TIMEOUT_MS);
86
+ const fallbackSignal = options.signal ? AbortSignal.any([options.signal, fallbackTimeoutSignal]) : fallbackTimeoutSignal;
87
+ const response = await fetch(`${apiUrl}/api${endpoint}`, {
88
+ ...options,
89
+ headers,
90
+ signal: fallbackSignal
91
+ });
92
+ if (!response.ok) {
93
+ await handleResponseError(endpoint, response, options);
94
+ }
95
+ if (response.status === 204) {
96
+ return void 0;
97
+ }
98
+ return response.json();
99
+ }
100
+ throw error;
101
+ }
102
+ };
103
+ }
104
+ function useApiClient(apiUrl) {
105
+ const { getAccessToken, getOrganizationId, isOrganizationReady: contextOrgReady, onError } = useApiClientContext();
106
+ const orgCtx = useContext(OrganizationContext);
107
+ const orgReady = orgCtx ? !!orgCtx.currentWorkOSOrganizationId && !orgCtx.isInitializing && !orgCtx.isOrgRefreshing : contextOrgReady;
108
+ const orgInitializing = orgCtx ? orgCtx.isInitializing || orgCtx.isOrgRefreshing : false;
109
+ const handleResponseError = useCallback(
110
+ async (endpoint, response, options) => {
111
+ const errorData = await response.json().catch(() => ({
112
+ error: `HTTP ${response.status}`,
113
+ code: "INTERNAL_SERVER_ERROR"
114
+ }));
115
+ if (response.status >= 500 && onError) {
116
+ onError(endpoint, new Error(errorData.error), {
117
+ method: options.method || "GET",
118
+ statusCode: response.status,
119
+ requestId: errorData.requestId
120
+ });
121
+ }
122
+ throw new APIClientError(
123
+ errorData.error,
124
+ errorData.code,
125
+ response.status,
126
+ errorData.requestId,
127
+ errorData.fields,
128
+ errorData.retryAfter
129
+ );
130
+ },
131
+ [onError]
132
+ );
133
+ const apiRequest = useCallback(
134
+ (endpoint, options = {}) => buildApiRequest(getAccessToken, getOrganizationId, apiUrl, handleResponseError)(endpoint, options),
135
+ [getAccessToken, getOrganizationId, apiUrl, handleResponseError]
136
+ );
137
+ const deferredApiRequest = useCallback(
138
+ async (endpoint, options = {}) => {
139
+ if (orgInitializing) {
140
+ throw new Error("Organization context is still initializing. Please wait.");
141
+ }
142
+ if (!orgReady) {
143
+ throw new Error("No organization selected. Please select an organization.");
144
+ }
145
+ return apiRequest(endpoint, options);
146
+ },
147
+ [apiRequest, orgInitializing, orgReady]
148
+ );
149
+ return {
150
+ apiRequest,
151
+ deferredApiRequest,
152
+ isOrganizationReady: orgReady,
153
+ isInitializing: orgInitializing
154
+ };
155
+ }
156
+
157
+ export { ApiClientProvider, useApiClient, useApiClientContext };
@@ -1,10 +1,12 @@
1
- export { ActionModal, TaskCard, getIcon, iconMap } from '../../chunk-ZGHDPDTF.js';
2
- import '../../chunk-J3FALDQE.js';
1
+ export { ActionModal, TaskCard, getIcon, iconMap } from '../../chunk-JYSYHVLU.js';
2
+ import '../../chunk-NXHL23JW.js';
3
3
  export { FormFieldRenderer } from '../../chunk-PSLKGOBZ.js';
4
- import '../../chunk-OUHGHTE7.js';
4
+ import '../../chunk-O3PY6B6E.js';
5
5
  import '../../chunk-3KMDHCAR.js';
6
6
  import '../../chunk-YZ6GTZXL.js';
7
+ import '../../chunk-TIRMFDM4.js';
8
+ import '../../chunk-JVAZHVNV.js';
9
+ import '../../chunk-4VGWQ5AN.js';
7
10
  import '../../chunk-KA7LO7U5.js';
8
- import '../../chunk-7AI5ZYJ4.js';
9
11
  import '../../chunk-7PLEQFHO.js';
10
12
  import '../../chunk-Q7DJKLEN.js';
@@ -1,18 +1,20 @@
1
- export { ChatHeader, ChatInputArea, ChatInterface, ChatSidebar, ConfirmationInputModal, ConfirmationModal, MessageBubble } from '../chunk-S66I2PYB.js';
1
+ export { ChatHeader, ChatInputArea, ChatInterface, ChatSidebar, ConfirmationInputModal, ConfirmationModal, MessageBubble } from '../chunk-TN3PU2WK.js';
2
2
  export { ExecutionLogsTable, ResourceHealthChart, getHealthColor } from '../chunk-NE36BUGQ.js';
3
3
  import '../chunk-W7ZBF5AA.js';
4
- export { ActionModal, CustomModal, TaskCard, getIcon, iconMap } from '../chunk-ZGHDPDTF.js';
5
- import '../chunk-J3FALDQE.js';
4
+ export { ActionModal, CustomModal, TaskCard, getIcon, iconMap } from '../chunk-JYSYHVLU.js';
5
+ import '../chunk-NXHL23JW.js';
6
6
  export { FormFieldRenderer } from '../chunk-PSLKGOBZ.js';
7
- export { NotificationBell, NotificationItem, NotificationList, NotificationPanel } from '../chunk-PYL4XW6H.js';
8
- import '../chunk-JKERRYVS.js';
7
+ export { NotificationBell, NotificationItem, NotificationList, NotificationPanel } from '../chunk-TMFCNFLW.js';
8
+ import '../chunk-BLO4SISK.js';
9
9
  export { AgentDefinitionDisplay, CollapsibleJsonSection, ConfigCard, ContractDisplay, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, ResourceDefinitionSection, ToolsListDisplay, WorkflowDefinitionDisplay, useNewKnowledgeMapLayout } from '../chunk-OXVOHOP3.js';
10
10
  import '../chunk-6BJOYF6E.js';
11
11
  import '../chunk-HUWJXLLF.js';
12
- export { APIErrorAlert, CollapsibleSection, ContextViewer, CustomSelector, DetailCardSkeleton, EmptyState, JsonViewer, ListSkeleton, NavigationButton, PageNotFound, PageTitleCaption, ResourceCard, StatCard, StatCardSkeleton, StatsCardSkeleton, TabCountBadge, TimeRangeSelector, TrendIndicator, catalogItemToResourceDefinition } from '../chunk-OUHGHTE7.js';
12
+ export { APIErrorAlert, CollapsibleSection, ContextViewer, CustomSelector, DetailCardSkeleton, EmptyState, JsonViewer, ListSkeleton, NavigationButton, PageNotFound, PageTitleCaption, ResourceCard, StatCard, StatCardSkeleton, StatsCardSkeleton, TabCountBadge, TimeRangeSelector, TrendIndicator, catalogItemToResourceDefinition } from '../chunk-O3PY6B6E.js';
13
13
  export { StyledMarkdown } from '../chunk-3KMDHCAR.js';
14
14
  import '../chunk-YZ6GTZXL.js';
15
+ import '../chunk-TIRMFDM4.js';
16
+ import '../chunk-JVAZHVNV.js';
17
+ import '../chunk-4VGWQ5AN.js';
15
18
  import '../chunk-KA7LO7U5.js';
16
- import '../chunk-7AI5ZYJ4.js';
17
19
  import '../chunk-7PLEQFHO.js';
18
20
  import '../chunk-Q7DJKLEN.js';