@calimero-network/mero-react 1.0.0-beta.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,26 @@
1
1
  import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
2
- import { MeroJs } from '@calimero-network/mero-js';
3
- export { MeroJs } from '@calimero-network/mero-js';
2
+ import { parseAuthCallback, MeroJs, buildAuthLoginUrl, LocalStorageTokenStore } from '@calimero-network/mero-js';
3
+ export * from '@calimero-network/mero-js';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { createPortal } from 'react-dom';
6
6
 
7
7
  // src/context/MeroContext.tsx
8
8
 
9
+ // src/types.ts
10
+ var AppMode = /* @__PURE__ */ ((AppMode2) => {
11
+ AppMode2["SingleContext"] = "single-context";
12
+ AppMode2["MultiContext"] = "multi-context";
13
+ AppMode2["Admin"] = "admin";
14
+ return AppMode2;
15
+ })(AppMode || {});
16
+ var ConnectionType = /* @__PURE__ */ ((ConnectionType2) => {
17
+ ConnectionType2["RemoteAndLocal"] = "remote-and-local";
18
+ ConnectionType2["Remote"] = "remote";
19
+ ConnectionType2["Local"] = "local";
20
+ ConnectionType2["Custom"] = "custom";
21
+ return ConnectionType2;
22
+ })(ConnectionType || {});
23
+
9
24
  // src/storage/index.ts
10
25
  var STORAGE_KEYS = {
11
26
  ACCESS_TOKEN: "mero:access_token",
@@ -13,20 +28,25 @@ var STORAGE_KEYS = {
13
28
  EXPIRES_AT: "mero:expires_at",
14
29
  NODE_URL: "mero:node_url",
15
30
  APPLICATION_ID: "mero:application_id",
16
- CONTEXT_ID: "mero:context_id"
31
+ CONTEXT_ID: "mero:context_id",
32
+ CONTEXT_IDENTITY: "mero:context_identity"
17
33
  };
34
+ var _storageAvailable = null;
18
35
  function isLocalStorageAvailable() {
36
+ if (_storageAvailable !== null) return _storageAvailable;
19
37
  try {
20
38
  if (typeof window === "undefined" || !window.localStorage) {
39
+ _storageAvailable = false;
21
40
  return false;
22
41
  }
23
42
  const testKey = "__mero_test__";
24
43
  localStorage.setItem(testKey, "test");
25
44
  localStorage.removeItem(testKey);
26
- return true;
45
+ _storageAvailable = true;
27
46
  } catch {
28
- return false;
47
+ _storageAvailable = false;
29
48
  }
49
+ return _storageAvailable;
30
50
  }
31
51
  var localStorageTokenStorage = {
32
52
  async get() {
@@ -107,46 +127,37 @@ function setContextId(id) {
107
127
  if (!isLocalStorageAvailable()) return;
108
128
  localStorage.setItem(STORAGE_KEYS.CONTEXT_ID, id);
109
129
  }
130
+ function clearContextId() {
131
+ if (!isLocalStorageAvailable()) return;
132
+ localStorage.removeItem(STORAGE_KEYS.CONTEXT_ID);
133
+ }
134
+ function getContextIdentity() {
135
+ if (!isLocalStorageAvailable()) return null;
136
+ return localStorage.getItem(STORAGE_KEYS.CONTEXT_IDENTITY);
137
+ }
138
+ function setContextIdentity(id) {
139
+ if (!isLocalStorageAvailable()) return;
140
+ localStorage.setItem(STORAGE_KEYS.CONTEXT_IDENTITY, id);
141
+ }
142
+ function clearContextIdentity() {
143
+ if (!isLocalStorageAvailable()) return;
144
+ localStorage.removeItem(STORAGE_KEYS.CONTEXT_IDENTITY);
145
+ }
110
146
  function clearAllStorage() {
111
147
  if (!isLocalStorageAvailable()) return;
112
148
  Object.values(STORAGE_KEYS).forEach((key) => {
113
149
  localStorage.removeItem(key);
114
150
  });
115
151
  }
116
-
117
- // src/types.ts
118
- var AppMode = /* @__PURE__ */ ((AppMode2) => {
119
- AppMode2["SingleContext"] = "single-context";
120
- AppMode2["MultiContext"] = "multi-context";
121
- AppMode2["Admin"] = "admin";
122
- return AppMode2;
123
- })(AppMode || {});
124
- var ConnectionType = /* @__PURE__ */ ((ConnectionType2) => {
125
- ConnectionType2["RemoteAndLocal"] = "remote-and-local";
126
- ConnectionType2["Remote"] = "remote";
127
- ConnectionType2["Local"] = "local";
128
- ConnectionType2["Custom"] = "custom";
129
- return ConnectionType2;
130
- })(ConnectionType || {});
131
- var EventStreamMode = /* @__PURE__ */ ((EventStreamMode2) => {
132
- EventStreamMode2["WebSocket"] = "websocket";
133
- EventStreamMode2["SSE"] = "sse";
134
- return EventStreamMode2;
135
- })(EventStreamMode || {});
136
- var defaultContextValue = {
137
- mero: null,
138
- isAuthenticated: false,
139
- isOnline: true,
140
- nodeUrl: null,
141
- applicationId: null,
142
- contextId: null,
143
- connectToNode: () => {
144
- },
145
- logout: () => {
146
- },
147
- isLoading: true
148
- };
149
- var MeroContext = createContext(defaultContextValue);
152
+ var MeroContext = createContext(null);
153
+ var isBrowser = typeof window !== "undefined";
154
+ var _tokenStore = null;
155
+ function getTokenStore() {
156
+ if (!_tokenStore) {
157
+ _tokenStore = new LocalStorageTokenStore();
158
+ }
159
+ return _tokenStore;
160
+ }
150
161
  function getPermissionsForMode(mode) {
151
162
  switch (mode) {
152
163
  case "single-context" /* SingleContext */:
@@ -159,27 +170,20 @@ function getPermissionsForMode(mode) {
159
170
  throw new Error(`Unsupported application mode: ${mode}`);
160
171
  }
161
172
  }
162
- function redirectToAuthLogin(params) {
163
- const authParams = new URLSearchParams();
164
- authParams.append("callback-url", params.callbackUrl);
165
- authParams.append("permissions", params.permissions.join(","));
166
- authParams.append("mode", params.mode);
167
- if (params.packageName) {
168
- authParams.append("package-name", params.packageName);
169
- if (params.packageVersion) {
170
- authParams.append("package-version", params.packageVersion);
171
- }
172
- if (params.registryUrl) {
173
- authParams.append("registry-url", params.registryUrl);
174
- }
175
- } else if (params.applicationId) {
176
- authParams.append("application-id", params.applicationId);
177
- }
178
- if (params.applicationPath) {
179
- authParams.append("application-path", params.applicationPath);
173
+ function parseJwtExpiry(token) {
174
+ try {
175
+ const parts = token.split(".");
176
+ if (parts.length === 3) {
177
+ let b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
178
+ while (b64.length % 4) b64 += "=";
179
+ const payload = JSON.parse(atob(b64));
180
+ if (payload.exp && payload.exp > 0) {
181
+ return payload.exp * 1e3;
182
+ }
183
+ }
184
+ } catch {
180
185
  }
181
- authParams.append("app-url", params.nodeUrl);
182
- window.location.href = `${params.nodeUrl}/auth/login?${authParams.toString()}`;
186
+ return Date.now() + 36e5;
183
187
  }
184
188
  function MeroProvider({
185
189
  children,
@@ -187,8 +191,6 @@ function MeroProvider({
187
191
  packageName,
188
192
  packageVersion,
189
193
  registryUrl,
190
- applicationId: propApplicationId,
191
- applicationPath,
192
194
  timeoutMs = 3e4
193
195
  }) {
194
196
  const [mero, setMero] = useState(null);
@@ -197,15 +199,23 @@ function MeroProvider({
197
199
  const [isLoading, setIsLoading] = useState(true);
198
200
  const [nodeUrl, setNodeUrlState] = useState(() => getNodeUrl());
199
201
  const [applicationId, setApplicationIdState] = useState(
200
- () => getApplicationId() || propApplicationId || null
202
+ () => getApplicationId() || null
201
203
  );
202
204
  const [contextId, setContextIdState] = useState(() => getContextId());
205
+ const [contextIdentity, setContextIdentityState] = useState(() => getContextIdentity());
203
206
  const meroRef = useRef(null);
207
+ const callbackRef = useRef(void 0);
208
+ if (callbackRef.current === void 0 && isBrowser) {
209
+ callbackRef.current = parseAuthCallback(window.location.href);
210
+ }
204
211
  const createMeroInstance = useCallback(
205
212
  (url) => {
213
+ if (meroRef.current) {
214
+ meroRef.current.close();
215
+ }
206
216
  const instance = new MeroJs({
207
217
  baseUrl: url,
208
- tokenStorage: localStorageTokenStorage,
218
+ tokenStore: getTokenStore(),
209
219
  timeoutMs
210
220
  });
211
221
  meroRef.current = instance;
@@ -215,127 +225,35 @@ function MeroProvider({
215
225
  );
216
226
  const checkAuth = useCallback(async (instance) => {
217
227
  try {
218
- await instance.admin.contexts.listContexts();
228
+ await instance.admin.getContexts();
219
229
  return true;
220
230
  } catch {
221
231
  return false;
222
232
  }
223
233
  }, []);
224
- const processAuthCallback = useCallback(() => {
225
- const url = new URL(window.location.href);
226
- const rawHash = url.hash;
227
- const hash = rawHash.slice(1);
228
- console.log("========== AUTH CALLBACK DEBUG ==========");
229
- console.log("Raw URL:", window.location.href);
230
- console.log("Raw hash:", rawHash);
231
- console.log("Hash (without #):", hash);
232
- if (!hash) {
233
- console.log("No hash found, skipping auth callback");
234
- console.log("==========================================");
235
- return false;
236
- }
237
- const params = new URLSearchParams(hash);
238
- console.log("All hash params:");
239
- for (const [key, value] of params.entries()) {
240
- console.log(` ${key}: ${value.substring(0, 50)}${value.length > 50 ? "..." : ""}`);
241
- }
242
- console.log("==========================================");
243
- const accessToken = params.get("access_token");
244
- const refreshToken = params.get("refresh_token");
245
- const appId = params.get("application_id") || params.get("applicationId") || params.get("app_id");
246
- const ctxId = params.get("context_id") || params.get("contextId") || params.get("context");
247
- const expiresIn = params.get("expires_in");
248
- const nodeUrlParam = params.get("node_url") || params.get("nodeUrl") || params.get("node");
249
- if (!accessToken || !refreshToken) return false;
250
- if (nodeUrlParam) {
251
- const decodedNodeUrl = decodeURIComponent(nodeUrlParam);
252
- setNodeUrl(decodedNodeUrl);
253
- setNodeUrlState(decodedNodeUrl);
254
- console.log("[mero-react] SSO: Node URL from hash params:", decodedNodeUrl);
255
- }
256
- try {
257
- const decodedAccess = decodeURIComponent(accessToken);
258
- const decodedRefresh = decodeURIComponent(refreshToken);
259
- let expiresAt = Date.now() + 36e5;
260
- if (expiresIn) {
261
- expiresAt = Date.now() + parseInt(expiresIn, 10) * 1e3;
262
- } else {
263
- try {
264
- const parts = decodedAccess.split(".");
265
- if (parts.length === 3) {
266
- const payload = JSON.parse(atob(parts[1]));
267
- if (payload.exp) {
268
- expiresAt = payload.exp * 1e3;
269
- }
270
- }
271
- } catch {
272
- }
273
- }
274
- localStorageTokenStorage.set({
275
- access_token: decodedAccess,
276
- refresh_token: decodedRefresh,
277
- expires_at: expiresAt
278
- });
279
- if (appId) {
280
- setApplicationId(appId);
281
- setApplicationIdState(appId);
282
- }
283
- if (ctxId) {
284
- setContextId(ctxId);
285
- setContextIdState(ctxId);
286
- }
287
- params.delete("access_token");
288
- params.delete("refresh_token");
289
- params.delete("application_id");
290
- params.delete("applicationId");
291
- params.delete("app_id");
292
- params.delete("context_id");
293
- params.delete("contextId");
294
- params.delete("context");
295
- params.delete("expires_in");
296
- params.delete("node_url");
297
- params.delete("nodeUrl");
298
- params.delete("node");
299
- const newHash = params.toString();
300
- url.hash = newHash ? `#${newHash}` : "";
301
- window.history.replaceState({}, document.title, url.toString());
302
- console.log("[mero-react] Stored contextId:", ctxId, "applicationId:", appId);
303
- return true;
304
- } catch (e) {
305
- console.error("[mero-react] Failed to process auth callback:", e);
306
- return false;
307
- }
308
- }, []);
309
234
  const connectToNode = useCallback(
310
235
  (url) => {
236
+ if (!isBrowser) return;
311
237
  setNodeUrl(url);
312
238
  setNodeUrlState(url);
313
239
  const callbackUrl = new URL(window.location.href);
314
- if (callbackUrl.hash) {
315
- const hashParams = new URLSearchParams(callbackUrl.hash.substring(1));
316
- hashParams.delete("access_token");
317
- hashParams.delete("refresh_token");
318
- hashParams.delete("application_id");
319
- callbackUrl.hash = hashParams.toString() ? `#${hashParams.toString()}` : "";
320
- }
321
- const permissions = getPermissionsForMode(mode);
322
- redirectToAuthLogin({
323
- nodeUrl: url,
240
+ callbackUrl.hash = "";
241
+ const loginUrl = buildAuthLoginUrl(url, {
324
242
  callbackUrl: callbackUrl.toString(),
325
- permissions,
243
+ permissions: getPermissionsForMode(mode),
326
244
  mode,
327
245
  packageName,
328
246
  packageVersion,
329
- registryUrl,
330
- applicationId: propApplicationId,
331
- applicationPath
247
+ registryUrl
332
248
  });
249
+ window.location.href = loginUrl;
333
250
  },
334
- [mode, packageName, packageVersion, registryUrl, propApplicationId, applicationPath]
251
+ [mode, packageName, packageVersion, registryUrl]
335
252
  );
336
- const logout = useCallback(async () => {
253
+ const logout = useCallback(() => {
337
254
  if (meroRef.current) {
338
- await meroRef.current.clearToken();
255
+ meroRef.current.clearToken();
256
+ meroRef.current.close();
339
257
  }
340
258
  clearAllStorage();
341
259
  setMero(null);
@@ -343,56 +261,90 @@ function MeroProvider({
343
261
  setNodeUrlState(null);
344
262
  setApplicationIdState(null);
345
263
  setContextIdState(null);
264
+ setContextIdentityState(null);
346
265
  meroRef.current = null;
347
266
  }, []);
348
267
  useEffect(() => {
268
+ let active = true;
349
269
  const init = async () => {
350
- console.log("[mero-react] Init starting...");
351
- console.log("[mero-react] Current URL:", window.location.href);
352
- console.log("[mero-react] Stored nodeUrl:", getNodeUrl());
353
- console.log("[mero-react] Stored contextId:", getContextId());
354
- console.log("[mero-react] Stored applicationId:", getApplicationId());
355
- const hasCallback = processAuthCallback();
356
- console.log("[mero-react] hasCallback:", hasCallback);
357
- const savedUrl = getNodeUrl();
270
+ const callback = callbackRef.current;
271
+ if (callback) {
272
+ getTokenStore().setTokens({
273
+ access_token: callback.accessToken,
274
+ refresh_token: callback.refreshToken,
275
+ expires_at: parseJwtExpiry(callback.accessToken)
276
+ });
277
+ if (callback.applicationId) {
278
+ setApplicationId(callback.applicationId);
279
+ if (active) setApplicationIdState(callback.applicationId);
280
+ }
281
+ if (callback.contextId) {
282
+ setContextId(callback.contextId);
283
+ if (active) setContextIdState(callback.contextId);
284
+ }
285
+ if (callback.contextIdentity) {
286
+ setContextIdentity(callback.contextIdentity);
287
+ if (active) setContextIdentityState(callback.contextIdentity);
288
+ }
289
+ if (callback.nodeUrl) {
290
+ setNodeUrl(callback.nodeUrl);
291
+ if (active) setNodeUrlState(callback.nodeUrl);
292
+ }
293
+ if (isBrowser) {
294
+ window.history.replaceState({}, "", window.location.pathname + window.location.search);
295
+ }
296
+ callbackRef.current = null;
297
+ }
298
+ const savedUrl = callback?.nodeUrl || getNodeUrl();
358
299
  if (!savedUrl) {
359
- setIsLoading(false);
300
+ if (active) setIsLoading(false);
360
301
  return;
361
302
  }
362
303
  const instance = createMeroInstance(savedUrl);
363
- await instance.init();
364
304
  const authed = await checkAuth(instance);
305
+ if (!active) return;
365
306
  if (authed) {
366
307
  setMero(instance);
367
308
  setIsAuthenticated(true);
368
309
  setIsOnline(true);
369
- } else if (hasCallback) {
310
+ } else if (callback) {
370
311
  setMero(instance);
371
- setIsAuthenticated(false);
372
312
  }
373
313
  setIsLoading(false);
374
314
  };
375
- init();
376
- }, [createMeroInstance, checkAuth, processAuthCallback]);
315
+ init().catch((err) => {
316
+ console.error("[MeroProvider] Initialization failed:", err);
317
+ if (active) setIsLoading(false);
318
+ });
319
+ return () => {
320
+ active = false;
321
+ };
322
+ }, [createMeroInstance, checkAuth]);
377
323
  useEffect(() => {
378
324
  if (!isAuthenticated || !meroRef.current) return;
379
- const interval = setInterval(async () => {
380
- const instance = meroRef.current;
381
- if (!instance) return;
382
- const healthy = await checkAuth(instance);
383
- if (!healthy && isOnline) {
384
- setIsOnline(false);
385
- } else if (healthy && !isOnline) {
386
- setIsOnline(true);
325
+ let active = true;
326
+ const sse = meroRef.current.events;
327
+ const onConnect = () => {
328
+ if (active) setIsOnline(true);
329
+ };
330
+ const onError = (err) => {
331
+ if (!active) return;
332
+ setIsOnline(false);
333
+ if (err.message.includes("401")) {
334
+ logout();
387
335
  }
388
- }, 5e3);
389
- return () => clearInterval(interval);
390
- }, [isAuthenticated, isOnline, checkAuth]);
391
- useEffect(() => {
392
- if (propApplicationId && !applicationId) {
393
- setApplicationIdState(propApplicationId);
394
- }
395
- }, [propApplicationId, applicationId]);
336
+ };
337
+ sse.on("connect", onConnect);
338
+ sse.on("error", onError);
339
+ sse.connect().catch(() => {
340
+ if (active) setIsOnline(false);
341
+ });
342
+ return () => {
343
+ active = false;
344
+ sse.off("connect", onConnect);
345
+ sse.off("error", onError);
346
+ };
347
+ }, [isAuthenticated, mero]);
396
348
  const contextValue = useMemo(
397
349
  () => ({
398
350
  mero,
@@ -401,17 +353,18 @@ function MeroProvider({
401
353
  nodeUrl,
402
354
  applicationId,
403
355
  contextId,
356
+ contextIdentity,
404
357
  connectToNode,
405
358
  logout,
406
359
  isLoading
407
360
  }),
408
- [mero, isAuthenticated, isOnline, nodeUrl, applicationId, contextId, connectToNode, logout, isLoading]
361
+ [mero, isAuthenticated, isOnline, nodeUrl, applicationId, contextId, contextIdentity, connectToNode, logout, isLoading]
409
362
  );
410
363
  return /* @__PURE__ */ jsx(MeroContext.Provider, { value: contextValue, children });
411
364
  }
412
365
  function useMero() {
413
366
  const context = useContext(MeroContext);
414
- if (context === void 0) {
367
+ if (!context) {
415
368
  throw new Error("useMero must be used within a MeroProvider");
416
369
  }
417
370
  return context;
@@ -887,7 +840,1103 @@ function MeroLogo2() {
887
840
  }
888
841
  );
889
842
  }
843
+ function toError(err) {
844
+ return err instanceof Error ? err : new Error(String(err));
845
+ }
846
+ function mapApplicationContexts(contexts) {
847
+ return contexts.map((context) => ({
848
+ contextId: context.id,
849
+ applicationId: context.applicationId
850
+ }));
851
+ }
852
+ function useMountedRef() {
853
+ const mountedRef = useRef(true);
854
+ useEffect(() => {
855
+ mountedRef.current = true;
856
+ return () => {
857
+ mountedRef.current = false;
858
+ };
859
+ }, []);
860
+ return mountedRef;
861
+ }
862
+ function useAsyncMutation() {
863
+ const mountedRef = useMountedRef();
864
+ const [loading, setLoading] = useState(false);
865
+ const [error, setError] = useState(null);
866
+ const run = useCallback(
867
+ async (action) => {
868
+ if (mountedRef.current) {
869
+ setLoading(true);
870
+ setError(null);
871
+ }
872
+ try {
873
+ return await action();
874
+ } catch (err) {
875
+ const errorValue = toError(err);
876
+ if (mountedRef.current) {
877
+ setError(errorValue);
878
+ }
879
+ return null;
880
+ } finally {
881
+ if (mountedRef.current) {
882
+ setLoading(false);
883
+ }
884
+ }
885
+ },
886
+ [mountedRef]
887
+ );
888
+ return { loading, error, run, setError };
889
+ }
890
+ function sleep(ms) {
891
+ return new Promise((resolve) => {
892
+ setTimeout(resolve, ms);
893
+ });
894
+ }
895
+ function extractAliasContextId(value) {
896
+ if (typeof value === "string") {
897
+ return value;
898
+ }
899
+ if (!value || typeof value !== "object") {
900
+ return null;
901
+ }
902
+ if ("value" in value && typeof value.value === "string") {
903
+ return value.value;
904
+ }
905
+ if ("contextId" in value && typeof value.contextId === "string") {
906
+ return value.contextId;
907
+ }
908
+ return null;
909
+ }
910
+ function useExecute(contextId, executorId) {
911
+ const { mero } = useMero();
912
+ const [loading, setLoading] = useState(false);
913
+ const [error, setError] = useState(null);
914
+ const mountedRef = useRef(true);
915
+ useEffect(() => {
916
+ mountedRef.current = true;
917
+ return () => {
918
+ mountedRef.current = false;
919
+ };
920
+ }, []);
921
+ const execute = useCallback(
922
+ async (method, params) => {
923
+ if (!mero || !contextId || !executorId) {
924
+ if (mountedRef.current) setError(new Error("Not connected"));
925
+ return null;
926
+ }
927
+ if (mountedRef.current) {
928
+ setLoading(true);
929
+ setError(null);
930
+ }
931
+ try {
932
+ const result = await mero.rpc.execute({
933
+ contextId,
934
+ method,
935
+ argsJson: params,
936
+ executorPublicKey: executorId
937
+ });
938
+ return result;
939
+ } catch (err) {
940
+ const e = err instanceof Error ? err : new Error(String(err));
941
+ if (mountedRef.current) setError(e);
942
+ return null;
943
+ } finally {
944
+ if (mountedRef.current) setLoading(false);
945
+ }
946
+ },
947
+ [mero, contextId, executorId]
948
+ );
949
+ return { execute, loading, error };
950
+ }
951
+ function useSubscription(contextIds, callback) {
952
+ const { mero } = useMero();
953
+ const callbackRef = useRef(callback);
954
+ callbackRef.current = callback;
955
+ const contextIdsKey = JSON.stringify(contextIds);
956
+ useEffect(() => {
957
+ if (!mero || contextIds.length === 0) return;
958
+ const sse = mero.events;
959
+ const handler = (event) => {
960
+ callbackRef.current(event);
961
+ };
962
+ sse.on("event", handler);
963
+ sse.connect().catch(() => {
964
+ });
965
+ sse.subscribe(contextIds).catch(() => {
966
+ });
967
+ return () => {
968
+ sse.off("event", handler);
969
+ };
970
+ }, [mero, contextIdsKey]);
971
+ }
972
+ function useContexts(applicationId) {
973
+ const { mero } = useMero();
974
+ const [contexts, setContexts] = useState([]);
975
+ const [loading, setLoading] = useState(false);
976
+ const [error, setError] = useState(null);
977
+ const mountedRef = useMountedRef();
978
+ const refetch = useCallback(async () => {
979
+ if (!mero) return;
980
+ if (mountedRef.current) {
981
+ setLoading(true);
982
+ setError(null);
983
+ }
984
+ try {
985
+ const response = applicationId ? await mero.admin.getContextsForApplication(applicationId) : await mero.admin.getContexts();
986
+ const list = mapApplicationContexts(response.contexts ?? []);
987
+ if (mountedRef.current) {
988
+ setContexts(list);
989
+ }
990
+ } catch (err) {
991
+ const errorValue = toError(err);
992
+ if (mountedRef.current) {
993
+ setError(errorValue);
994
+ }
995
+ } finally {
996
+ if (mountedRef.current) {
997
+ setLoading(false);
998
+ }
999
+ }
1000
+ }, [mero, applicationId]);
1001
+ useEffect(() => {
1002
+ void refetch();
1003
+ }, [refetch]);
1004
+ return { contexts, loading, error, refetch };
1005
+ }
1006
+ function useApplicationContexts(applicationId) {
1007
+ return useContexts(applicationId);
1008
+ }
1009
+ function useGroupMembers(groupId) {
1010
+ const { mero } = useMero();
1011
+ const [members, setMembers] = useState([]);
1012
+ const [selfIdentity, setSelfIdentity] = useState(null);
1013
+ const [loading, setLoading] = useState(false);
1014
+ const [error, setError] = useState(null);
1015
+ const mountedRef = useMountedRef();
1016
+ const refetch = useCallback(async () => {
1017
+ if (!mero || !groupId) {
1018
+ if (mountedRef.current) {
1019
+ setMembers([]);
1020
+ setSelfIdentity(null);
1021
+ setError(null);
1022
+ setLoading(false);
1023
+ }
1024
+ return;
1025
+ }
1026
+ if (mountedRef.current) {
1027
+ setLoading(true);
1028
+ setError(null);
1029
+ }
1030
+ try {
1031
+ const response = await mero.admin.listGroupMembers(groupId);
1032
+ if (mountedRef.current) {
1033
+ setMembers(response.data ?? []);
1034
+ setSelfIdentity(response.selfIdentity ?? null);
1035
+ }
1036
+ } catch (err) {
1037
+ const errorValue = toError(err);
1038
+ if (mountedRef.current) {
1039
+ setError(errorValue);
1040
+ }
1041
+ } finally {
1042
+ if (mountedRef.current) {
1043
+ setLoading(false);
1044
+ }
1045
+ }
1046
+ }, [groupId, mero, mountedRef]);
1047
+ useEffect(() => {
1048
+ void refetch();
1049
+ }, [refetch]);
1050
+ return { members, selfIdentity, loading, error, refetch };
1051
+ }
1052
+ function useGroupContexts(groupId) {
1053
+ const { mero } = useMero();
1054
+ const [contexts, setContexts] = useState([]);
1055
+ const [loading, setLoading] = useState(false);
1056
+ const [error, setError] = useState(null);
1057
+ const mountedRef = useMountedRef();
1058
+ const refetch = useCallback(async () => {
1059
+ if (!mero || !groupId) {
1060
+ if (mountedRef.current) {
1061
+ setContexts([]);
1062
+ setError(null);
1063
+ setLoading(false);
1064
+ }
1065
+ return;
1066
+ }
1067
+ if (mountedRef.current) {
1068
+ setLoading(true);
1069
+ setError(null);
1070
+ }
1071
+ try {
1072
+ const nextContexts = await mero.admin.listGroupContexts(groupId);
1073
+ if (mountedRef.current) {
1074
+ setContexts(nextContexts);
1075
+ }
1076
+ } catch (err) {
1077
+ const errorValue = toError(err);
1078
+ if (mountedRef.current) {
1079
+ setError(errorValue);
1080
+ }
1081
+ } finally {
1082
+ if (mountedRef.current) {
1083
+ setLoading(false);
1084
+ }
1085
+ }
1086
+ }, [groupId, mero, mountedRef]);
1087
+ useEffect(() => {
1088
+ void refetch();
1089
+ }, [refetch]);
1090
+ return { contexts, loading, error, refetch };
1091
+ }
1092
+ function useGroupInvitations() {
1093
+ const { mero } = useMero();
1094
+ const { loading, error, run } = useAsyncMutation();
1095
+ const createInvitation = useCallback(
1096
+ async (groupId, request) => {
1097
+ if (!mero) {
1098
+ return null;
1099
+ }
1100
+ return run(() => mero.admin.createGroupInvitation(groupId, request));
1101
+ },
1102
+ [mero, run]
1103
+ );
1104
+ return { createInvitation, loading, error };
1105
+ }
1106
+ function useJoinGroup() {
1107
+ const { mero } = useMero();
1108
+ const { loading, error, run } = useAsyncMutation();
1109
+ const joinGroup = useCallback(
1110
+ async (request) => {
1111
+ if (!mero) {
1112
+ return null;
1113
+ }
1114
+ return run(() => mero.admin.joinGroup(request));
1115
+ },
1116
+ [mero, run]
1117
+ );
1118
+ return { joinGroup, loading, error };
1119
+ }
1120
+ function useGroupCapabilities(groupId, memberId) {
1121
+ const { mero } = useMero();
1122
+ const [capabilities, setCapabilitiesState] = useState(null);
1123
+ const [loading, setLoading] = useState(false);
1124
+ const [error, setError] = useState(null);
1125
+ const mountedRef = useMountedRef();
1126
+ const refetch = useCallback(async () => {
1127
+ if (!mero || !groupId || !memberId) {
1128
+ if (mountedRef.current) {
1129
+ setCapabilitiesState(null);
1130
+ setError(null);
1131
+ setLoading(false);
1132
+ }
1133
+ return null;
1134
+ }
1135
+ if (mountedRef.current) {
1136
+ setLoading(true);
1137
+ setError(null);
1138
+ }
1139
+ try {
1140
+ const response = await mero.admin.getMemberCapabilities(groupId, memberId);
1141
+ if (mountedRef.current) {
1142
+ setCapabilitiesState(response.capabilities);
1143
+ }
1144
+ return response.capabilities;
1145
+ } catch (err) {
1146
+ const errorValue = toError(err);
1147
+ if (mountedRef.current) {
1148
+ setError(errorValue);
1149
+ }
1150
+ return null;
1151
+ } finally {
1152
+ if (mountedRef.current) {
1153
+ setLoading(false);
1154
+ }
1155
+ }
1156
+ }, [groupId, memberId, mero, mountedRef]);
1157
+ useEffect(() => {
1158
+ void refetch();
1159
+ }, [refetch]);
1160
+ const setCapabilities = useCallback(
1161
+ async (nextCapabilities) => {
1162
+ if (!mero || !groupId || !memberId) {
1163
+ return null;
1164
+ }
1165
+ if (mountedRef.current) {
1166
+ setLoading(true);
1167
+ setError(null);
1168
+ }
1169
+ try {
1170
+ await mero.admin.setMemberCapabilities(groupId, memberId, { capabilities: nextCapabilities });
1171
+ if (mountedRef.current) {
1172
+ setCapabilitiesState(nextCapabilities);
1173
+ }
1174
+ return nextCapabilities;
1175
+ } catch (err) {
1176
+ const errorValue = toError(err);
1177
+ if (mountedRef.current) {
1178
+ setError(errorValue);
1179
+ }
1180
+ return null;
1181
+ } finally {
1182
+ if (mountedRef.current) {
1183
+ setLoading(false);
1184
+ }
1185
+ }
1186
+ },
1187
+ [groupId, memberId, mero, mountedRef]
1188
+ );
1189
+ return { capabilities, loading, error, refetch, setCapabilities };
1190
+ }
1191
+ function useContextDiscovery(options) {
1192
+ const { mero } = useMero();
1193
+ const [context, setContext] = useState(null);
1194
+ const [loading, setLoading] = useState(false);
1195
+ const [error, setError] = useState(null);
1196
+ const mountedRef = useMountedRef();
1197
+ const knownContextIdsKey = JSON.stringify(options.knownContextIds ?? []);
1198
+ const discover = useCallback(async () => {
1199
+ if (!mero) {
1200
+ const notConnectedError = new Error("Not connected");
1201
+ if (mountedRef.current) {
1202
+ setError(notConnectedError);
1203
+ }
1204
+ return null;
1205
+ }
1206
+ const knownContextIds = new Set(options.knownContextIds ?? []);
1207
+ const pollIntervalMs = options.pollIntervalMs ?? 1e3;
1208
+ const timeoutMs = options.timeoutMs ?? 3e4;
1209
+ const deadline = Date.now() + timeoutMs;
1210
+ if (mountedRef.current) {
1211
+ setLoading(true);
1212
+ setError(null);
1213
+ }
1214
+ try {
1215
+ while (Date.now() <= deadline) {
1216
+ if (options.targetAlias) {
1217
+ const aliasMatch = extractAliasContextId(
1218
+ await mero.admin.lookupContextAlias(options.targetAlias)
1219
+ );
1220
+ if (aliasMatch && !knownContextIds.has(aliasMatch)) {
1221
+ const discoveredFromAlias = {
1222
+ contextId: aliasMatch,
1223
+ applicationId: options.applicationId
1224
+ };
1225
+ if (mountedRef.current) {
1226
+ setContext(discoveredFromAlias);
1227
+ }
1228
+ return discoveredFromAlias;
1229
+ }
1230
+ }
1231
+ const response = await mero.admin.getContextsForApplication(options.applicationId);
1232
+ const contexts = mapApplicationContexts(response.contexts ?? []);
1233
+ const discovered = contexts.find(
1234
+ (applicationContext) => !knownContextIds.has(applicationContext.contextId)
1235
+ );
1236
+ if (discovered) {
1237
+ if (mountedRef.current) {
1238
+ setContext(discovered);
1239
+ }
1240
+ return discovered;
1241
+ }
1242
+ if (Date.now() + pollIntervalMs > deadline) {
1243
+ break;
1244
+ }
1245
+ await sleep(pollIntervalMs);
1246
+ }
1247
+ const timeoutError = new Error(
1248
+ `Timed out discovering a context for application ${options.applicationId}`
1249
+ );
1250
+ if (mountedRef.current) {
1251
+ setContext(null);
1252
+ setError(timeoutError);
1253
+ }
1254
+ return null;
1255
+ } catch (err) {
1256
+ const errorValue = toError(err);
1257
+ if (mountedRef.current) {
1258
+ setContext(null);
1259
+ setError(errorValue);
1260
+ }
1261
+ return null;
1262
+ } finally {
1263
+ if (mountedRef.current) {
1264
+ setLoading(false);
1265
+ }
1266
+ }
1267
+ }, [
1268
+ knownContextIdsKey,
1269
+ mero,
1270
+ mountedRef,
1271
+ options.applicationId,
1272
+ options.knownContextIds,
1273
+ options.pollIntervalMs,
1274
+ options.targetAlias,
1275
+ options.timeoutMs
1276
+ ]);
1277
+ const reset = useCallback(() => {
1278
+ if (mountedRef.current) {
1279
+ setContext(null);
1280
+ setError(null);
1281
+ setLoading(false);
1282
+ }
1283
+ }, [mountedRef]);
1284
+ return { context, loading, error, discover, reset };
1285
+ }
1286
+ function useCreateContext() {
1287
+ const { mero } = useMero();
1288
+ const { loading, error, run } = useAsyncMutation();
1289
+ const createContext2 = useCallback(
1290
+ async (request) => {
1291
+ if (!mero) return null;
1292
+ return run(() => mero.admin.createContext(request));
1293
+ },
1294
+ [mero, run]
1295
+ );
1296
+ return { createContext: createContext2, loading, error };
1297
+ }
1298
+ function useDeleteContext() {
1299
+ const { mero } = useMero();
1300
+ const { loading, error, run } = useAsyncMutation();
1301
+ const deleteContext = useCallback(
1302
+ async (contextId) => {
1303
+ if (!mero) return null;
1304
+ return run(() => mero.admin.deleteContext(contextId));
1305
+ },
1306
+ [mero, run]
1307
+ );
1308
+ return { deleteContext, loading, error };
1309
+ }
1310
+ function useJoinContext() {
1311
+ const { mero } = useMero();
1312
+ const { loading, error, run } = useAsyncMutation();
1313
+ const joinContext = useCallback(
1314
+ async (contextId) => {
1315
+ if (!mero) return null;
1316
+ return run(() => mero.admin.joinContext(contextId));
1317
+ },
1318
+ [mero, run]
1319
+ );
1320
+ return { joinContext, loading, error };
1321
+ }
1322
+ function useContextGroup(contextId) {
1323
+ const { mero } = useMero();
1324
+ const [groupId, setGroupId] = useState(null);
1325
+ const [loading, setLoading] = useState(false);
1326
+ const [error, setError] = useState(null);
1327
+ const mountedRef = useMountedRef();
1328
+ const refetch = useCallback(async () => {
1329
+ if (!mero || !contextId) {
1330
+ if (mountedRef.current) {
1331
+ setGroupId(null);
1332
+ setError(null);
1333
+ setLoading(false);
1334
+ }
1335
+ return;
1336
+ }
1337
+ if (mountedRef.current) {
1338
+ setLoading(true);
1339
+ setError(null);
1340
+ }
1341
+ try {
1342
+ const result = await mero.admin.getContextGroup(contextId);
1343
+ if (mountedRef.current) {
1344
+ setGroupId(result);
1345
+ }
1346
+ } catch (err) {
1347
+ const errorValue = toError(err);
1348
+ if (mountedRef.current) {
1349
+ setError(errorValue);
1350
+ }
1351
+ } finally {
1352
+ if (mountedRef.current) {
1353
+ setLoading(false);
1354
+ }
1355
+ }
1356
+ }, [contextId, mero, mountedRef]);
1357
+ useEffect(() => {
1358
+ void refetch();
1359
+ }, [refetch]);
1360
+ return { groupId, loading, error, refetch };
1361
+ }
1362
+ function useGroupInfo(groupId) {
1363
+ const { mero } = useMero();
1364
+ const [groupInfo, setGroupInfo] = useState(null);
1365
+ const [loading, setLoading] = useState(false);
1366
+ const [error, setError] = useState(null);
1367
+ const mountedRef = useMountedRef();
1368
+ const refetch = useCallback(async () => {
1369
+ if (!mero || !groupId) {
1370
+ if (mountedRef.current) {
1371
+ setGroupInfo(null);
1372
+ setError(null);
1373
+ setLoading(false);
1374
+ }
1375
+ return;
1376
+ }
1377
+ if (mountedRef.current) {
1378
+ setLoading(true);
1379
+ setError(null);
1380
+ }
1381
+ try {
1382
+ const result = await mero.admin.getGroupInfo(groupId);
1383
+ if (mountedRef.current) {
1384
+ setGroupInfo(result);
1385
+ }
1386
+ } catch (err) {
1387
+ const errorValue = toError(err);
1388
+ if (mountedRef.current) {
1389
+ setError(errorValue);
1390
+ }
1391
+ } finally {
1392
+ if (mountedRef.current) {
1393
+ setLoading(false);
1394
+ }
1395
+ }
1396
+ }, [groupId, mero, mountedRef]);
1397
+ useEffect(() => {
1398
+ void refetch();
1399
+ }, [refetch]);
1400
+ return { groupInfo, loading, error, refetch };
1401
+ }
1402
+ function useDeleteGroup() {
1403
+ const { mero } = useMero();
1404
+ const { loading, error, run } = useAsyncMutation();
1405
+ const deleteGroup = useCallback(
1406
+ async (groupId, request) => {
1407
+ if (!mero) return null;
1408
+ return run(() => mero.admin.deleteGroup(groupId, request));
1409
+ },
1410
+ [mero, run]
1411
+ );
1412
+ return { deleteGroup, loading, error };
1413
+ }
1414
+ function useSyncGroup() {
1415
+ const { mero } = useMero();
1416
+ const { loading, error, run } = useAsyncMutation();
1417
+ const syncGroup = useCallback(
1418
+ async (groupId, request) => {
1419
+ if (!mero) return null;
1420
+ return run(() => mero.admin.syncGroup(groupId, request));
1421
+ },
1422
+ [mero, run]
1423
+ );
1424
+ return { syncGroup, loading, error };
1425
+ }
1426
+ function useAddGroupMembers() {
1427
+ const { mero } = useMero();
1428
+ const { loading, error, run } = useAsyncMutation();
1429
+ const addGroupMembers = useCallback(
1430
+ async (groupId, request) => {
1431
+ if (!mero) return null;
1432
+ return run(() => mero.admin.addGroupMembers(groupId, request));
1433
+ },
1434
+ [mero, run]
1435
+ );
1436
+ return { addGroupMembers, loading, error };
1437
+ }
1438
+ function useRemoveGroupMembers() {
1439
+ const { mero } = useMero();
1440
+ const { loading, error, run } = useAsyncMutation();
1441
+ const removeGroupMembers = useCallback(
1442
+ async (groupId, request) => {
1443
+ if (!mero) return null;
1444
+ return run(() => mero.admin.removeGroupMembers(groupId, request));
1445
+ },
1446
+ [mero, run]
1447
+ );
1448
+ return { removeGroupMembers, loading, error };
1449
+ }
1450
+ function useNamespaces() {
1451
+ const { mero } = useMero();
1452
+ const [namespaces, setNamespaces] = useState([]);
1453
+ const [loading, setLoading] = useState(false);
1454
+ const [error, setError] = useState(null);
1455
+ const mountedRef = useMountedRef();
1456
+ const refetch = useCallback(async () => {
1457
+ if (!mero) return;
1458
+ if (mountedRef.current) {
1459
+ setLoading(true);
1460
+ setError(null);
1461
+ }
1462
+ try {
1463
+ const result = await mero.admin.listNamespaces();
1464
+ if (mountedRef.current) {
1465
+ setNamespaces(result);
1466
+ }
1467
+ } catch (err) {
1468
+ const errorValue = toError(err);
1469
+ if (mountedRef.current) {
1470
+ setError(errorValue);
1471
+ }
1472
+ } finally {
1473
+ if (mountedRef.current) {
1474
+ setLoading(false);
1475
+ }
1476
+ }
1477
+ }, [mero, mountedRef]);
1478
+ useEffect(() => {
1479
+ void refetch();
1480
+ }, [refetch]);
1481
+ return { namespaces, loading, error, refetch };
1482
+ }
1483
+ function useNamespace(namespaceId) {
1484
+ const { mero } = useMero();
1485
+ const [namespace, setNamespace] = useState(null);
1486
+ const [loading, setLoading] = useState(false);
1487
+ const [error, setError] = useState(null);
1488
+ const mountedRef = useMountedRef();
1489
+ const refetch = useCallback(async () => {
1490
+ if (!mero || !namespaceId) {
1491
+ if (mountedRef.current) {
1492
+ setNamespace(null);
1493
+ setError(null);
1494
+ setLoading(false);
1495
+ }
1496
+ return;
1497
+ }
1498
+ if (mountedRef.current) {
1499
+ setLoading(true);
1500
+ setError(null);
1501
+ }
1502
+ try {
1503
+ const result = await mero.admin.getNamespace(namespaceId);
1504
+ if (mountedRef.current) {
1505
+ setNamespace(result);
1506
+ }
1507
+ } catch (err) {
1508
+ const errorValue = toError(err);
1509
+ if (mountedRef.current) {
1510
+ setError(errorValue);
1511
+ }
1512
+ } finally {
1513
+ if (mountedRef.current) {
1514
+ setLoading(false);
1515
+ }
1516
+ }
1517
+ }, [namespaceId, mero, mountedRef]);
1518
+ useEffect(() => {
1519
+ void refetch();
1520
+ }, [refetch]);
1521
+ return { namespace, loading, error, refetch };
1522
+ }
1523
+ function useNamespaceIdentity(namespaceId) {
1524
+ const { mero } = useMero();
1525
+ const [identity, setIdentity] = useState(null);
1526
+ const [loading, setLoading] = useState(false);
1527
+ const [error, setError] = useState(null);
1528
+ const mountedRef = useMountedRef();
1529
+ const refetch = useCallback(async () => {
1530
+ if (!mero || !namespaceId) {
1531
+ if (mountedRef.current) {
1532
+ setIdentity(null);
1533
+ setError(null);
1534
+ setLoading(false);
1535
+ }
1536
+ return;
1537
+ }
1538
+ if (mountedRef.current) {
1539
+ setLoading(true);
1540
+ setError(null);
1541
+ }
1542
+ try {
1543
+ const result = await mero.admin.getNamespaceIdentity(namespaceId);
1544
+ if (mountedRef.current) {
1545
+ setIdentity(result);
1546
+ }
1547
+ } catch (err) {
1548
+ const errorValue = toError(err);
1549
+ if (mountedRef.current) {
1550
+ setError(errorValue);
1551
+ }
1552
+ } finally {
1553
+ if (mountedRef.current) {
1554
+ setLoading(false);
1555
+ }
1556
+ }
1557
+ }, [namespaceId, mero, mountedRef]);
1558
+ useEffect(() => {
1559
+ void refetch();
1560
+ }, [refetch]);
1561
+ return { identity, loading, error, refetch };
1562
+ }
1563
+ function useNamespacesForApplication(applicationId) {
1564
+ const { mero } = useMero();
1565
+ const [namespaces, setNamespaces] = useState([]);
1566
+ const [loading, setLoading] = useState(false);
1567
+ const [error, setError] = useState(null);
1568
+ const mountedRef = useMountedRef();
1569
+ const refetch = useCallback(async () => {
1570
+ if (!mero || !applicationId) {
1571
+ if (mountedRef.current) {
1572
+ setNamespaces([]);
1573
+ setError(null);
1574
+ setLoading(false);
1575
+ }
1576
+ return;
1577
+ }
1578
+ if (mountedRef.current) {
1579
+ setLoading(true);
1580
+ setError(null);
1581
+ }
1582
+ try {
1583
+ const result = await mero.admin.listNamespacesForApplication(applicationId);
1584
+ if (mountedRef.current) {
1585
+ setNamespaces(result);
1586
+ }
1587
+ } catch (err) {
1588
+ const errorValue = toError(err);
1589
+ if (mountedRef.current) {
1590
+ setError(errorValue);
1591
+ }
1592
+ } finally {
1593
+ if (mountedRef.current) {
1594
+ setLoading(false);
1595
+ }
1596
+ }
1597
+ }, [applicationId, mero, mountedRef]);
1598
+ useEffect(() => {
1599
+ void refetch();
1600
+ }, [refetch]);
1601
+ return { namespaces, loading, error, refetch };
1602
+ }
1603
+ function useCreateNamespace() {
1604
+ const { mero } = useMero();
1605
+ const { loading, error, run } = useAsyncMutation();
1606
+ const createNamespace = useCallback(
1607
+ async (request) => {
1608
+ if (!mero) return null;
1609
+ return run(() => mero.admin.createNamespace(request));
1610
+ },
1611
+ [mero, run]
1612
+ );
1613
+ return { createNamespace, loading, error };
1614
+ }
1615
+ function useDeleteNamespace() {
1616
+ const { mero } = useMero();
1617
+ const { loading, error, run } = useAsyncMutation();
1618
+ const deleteNamespace = useCallback(
1619
+ async (namespaceId, request) => {
1620
+ if (!mero) return null;
1621
+ return run(() => mero.admin.deleteNamespace(namespaceId, request));
1622
+ },
1623
+ [mero, run]
1624
+ );
1625
+ return { deleteNamespace, loading, error };
1626
+ }
1627
+ function useCreateNamespaceInvitation() {
1628
+ const { mero } = useMero();
1629
+ const { loading, error, run } = useAsyncMutation();
1630
+ const createNamespaceInvitation = useCallback(
1631
+ async (namespaceId, request) => {
1632
+ if (!mero) return null;
1633
+ return run(() => mero.admin.createNamespaceInvitation(namespaceId, request));
1634
+ },
1635
+ [mero, run]
1636
+ );
1637
+ return { createNamespaceInvitation, loading, error };
1638
+ }
1639
+ function useJoinNamespace() {
1640
+ const { mero } = useMero();
1641
+ const { loading, error, run } = useAsyncMutation();
1642
+ const joinNamespace = useCallback(
1643
+ async (namespaceId, request) => {
1644
+ if (!mero) return null;
1645
+ return run(() => mero.admin.joinNamespace(namespaceId, request));
1646
+ },
1647
+ [mero, run]
1648
+ );
1649
+ return { joinNamespace, loading, error };
1650
+ }
1651
+ function useCreateGroupInNamespace() {
1652
+ const { mero } = useMero();
1653
+ const { loading, error, run } = useAsyncMutation();
1654
+ const createGroupInNamespace = useCallback(
1655
+ async (namespaceId, request) => {
1656
+ if (!mero) return null;
1657
+ return run(() => mero.admin.createGroupInNamespace(namespaceId, request));
1658
+ },
1659
+ [mero, run]
1660
+ );
1661
+ return { createGroupInNamespace, loading, error };
1662
+ }
1663
+ function useNamespaceGroups(namespaceId) {
1664
+ const { mero } = useMero();
1665
+ const [groups, setGroups] = useState([]);
1666
+ const [loading, setLoading] = useState(false);
1667
+ const [error, setError] = useState(null);
1668
+ const mountedRef = useMountedRef();
1669
+ const refetch = useCallback(async () => {
1670
+ if (!mero || !namespaceId) {
1671
+ if (mountedRef.current) {
1672
+ setGroups([]);
1673
+ setError(null);
1674
+ setLoading(false);
1675
+ }
1676
+ return;
1677
+ }
1678
+ if (mountedRef.current) {
1679
+ setLoading(true);
1680
+ setError(null);
1681
+ }
1682
+ try {
1683
+ const result = await mero.admin.listNamespaceGroups(namespaceId);
1684
+ if (mountedRef.current) {
1685
+ setGroups(result);
1686
+ }
1687
+ } catch (err) {
1688
+ const errorValue = toError(err);
1689
+ if (mountedRef.current) {
1690
+ setError(errorValue);
1691
+ }
1692
+ } finally {
1693
+ if (mountedRef.current) {
1694
+ setLoading(false);
1695
+ }
1696
+ }
1697
+ }, [namespaceId, mero, mountedRef]);
1698
+ useEffect(() => {
1699
+ void refetch();
1700
+ }, [refetch]);
1701
+ return { groups, loading, error, refetch };
1702
+ }
1703
+ function useUpdateMemberRole() {
1704
+ const { mero } = useMero();
1705
+ const { loading, error, run } = useAsyncMutation();
1706
+ const updateMemberRole = useCallback(
1707
+ async (groupId, identity, request) => {
1708
+ if (!mero) return null;
1709
+ return run(() => mero.admin.updateMemberRole(groupId, identity, request));
1710
+ },
1711
+ [mero, run]
1712
+ );
1713
+ return { updateMemberRole, loading, error };
1714
+ }
1715
+ function useSetDefaultCapabilities() {
1716
+ const { mero } = useMero();
1717
+ const { loading, error, run } = useAsyncMutation();
1718
+ const setDefaultCapabilities = useCallback(
1719
+ async (groupId, request) => {
1720
+ if (!mero) return null;
1721
+ return run(() => mero.admin.setDefaultCapabilities(groupId, request));
1722
+ },
1723
+ [mero, run]
1724
+ );
1725
+ return { setDefaultCapabilities, loading, error };
1726
+ }
1727
+ function useSetDefaultVisibility() {
1728
+ const { mero } = useMero();
1729
+ const { loading, error, run } = useAsyncMutation();
1730
+ const setDefaultVisibility = useCallback(
1731
+ async (groupId, request) => {
1732
+ if (!mero) return null;
1733
+ return run(() => mero.admin.setDefaultVisibility(groupId, request));
1734
+ },
1735
+ [mero, run]
1736
+ );
1737
+ return { setDefaultVisibility, loading, error };
1738
+ }
1739
+ function useSetTeeAdmissionPolicy() {
1740
+ const { mero } = useMero();
1741
+ const { loading, error, run } = useAsyncMutation();
1742
+ const setTeeAdmissionPolicy = useCallback(
1743
+ async (groupId, request) => {
1744
+ if (!mero) return null;
1745
+ return run(() => mero.admin.setTeeAdmissionPolicy(groupId, request));
1746
+ },
1747
+ [mero, run]
1748
+ );
1749
+ return { setTeeAdmissionPolicy, loading, error };
1750
+ }
1751
+ function useUpdateGroupSettings() {
1752
+ const { mero } = useMero();
1753
+ const { loading, error, run } = useAsyncMutation();
1754
+ const updateGroupSettings = useCallback(
1755
+ async (groupId, request) => {
1756
+ if (!mero) return null;
1757
+ return run(() => mero.admin.updateGroupSettings(groupId, request));
1758
+ },
1759
+ [mero, run]
1760
+ );
1761
+ return { updateGroupSettings, loading, error };
1762
+ }
1763
+ function useSetGroupAlias() {
1764
+ const { mero } = useMero();
1765
+ const { loading, error, run } = useAsyncMutation();
1766
+ const setGroupAlias = useCallback(
1767
+ async (groupId, request) => {
1768
+ if (!mero) return null;
1769
+ return run(() => mero.admin.setGroupAlias(groupId, request));
1770
+ },
1771
+ [mero, run]
1772
+ );
1773
+ return { setGroupAlias, loading, error };
1774
+ }
1775
+ function useSetMemberAlias() {
1776
+ const { mero } = useMero();
1777
+ const { loading, error, run } = useAsyncMutation();
1778
+ const setMemberAlias = useCallback(
1779
+ async (groupId, identity, request) => {
1780
+ if (!mero) return null;
1781
+ return run(() => mero.admin.setMemberAlias(groupId, identity, request));
1782
+ },
1783
+ [mero, run]
1784
+ );
1785
+ return { setMemberAlias, loading, error };
1786
+ }
1787
+ function useRegisterGroupSigningKey() {
1788
+ const { mero } = useMero();
1789
+ const { loading, error, run } = useAsyncMutation();
1790
+ const registerGroupSigningKey = useCallback(
1791
+ async (groupId, request) => {
1792
+ if (!mero) return null;
1793
+ return run(() => mero.admin.registerGroupSigningKey(groupId, request));
1794
+ },
1795
+ [mero, run]
1796
+ );
1797
+ return { registerGroupSigningKey, loading, error };
1798
+ }
1799
+ function useUpgradeGroup() {
1800
+ const { mero } = useMero();
1801
+ const { loading, error, run } = useAsyncMutation();
1802
+ const upgradeGroup = useCallback(
1803
+ async (groupId, request) => {
1804
+ if (!mero) return null;
1805
+ return run(() => mero.admin.upgradeGroup(groupId, request));
1806
+ },
1807
+ [mero, run]
1808
+ );
1809
+ return { upgradeGroup, loading, error };
1810
+ }
1811
+ function useGroupUpgradeStatus(groupId) {
1812
+ const { mero } = useMero();
1813
+ const [upgradeStatus, setUpgradeStatus] = useState(null);
1814
+ const [loading, setLoading] = useState(false);
1815
+ const [error, setError] = useState(null);
1816
+ const mountedRef = useMountedRef();
1817
+ const refetch = useCallback(async () => {
1818
+ if (!mero || !groupId) {
1819
+ if (mountedRef.current) {
1820
+ setUpgradeStatus(null);
1821
+ setError(null);
1822
+ setLoading(false);
1823
+ }
1824
+ return;
1825
+ }
1826
+ if (mountedRef.current) {
1827
+ setLoading(true);
1828
+ setError(null);
1829
+ }
1830
+ try {
1831
+ const result = await mero.admin.getGroupUpgradeStatus(groupId);
1832
+ if (mountedRef.current) {
1833
+ setUpgradeStatus(result);
1834
+ }
1835
+ } catch (err) {
1836
+ const errorValue = toError(err);
1837
+ if (mountedRef.current) {
1838
+ setError(errorValue);
1839
+ }
1840
+ } finally {
1841
+ if (mountedRef.current) {
1842
+ setLoading(false);
1843
+ }
1844
+ }
1845
+ }, [groupId, mero, mountedRef]);
1846
+ useEffect(() => {
1847
+ void refetch();
1848
+ }, [refetch]);
1849
+ return { upgradeStatus, loading, error, refetch };
1850
+ }
1851
+ function useRetryGroupUpgrade() {
1852
+ const { mero } = useMero();
1853
+ const { loading, error, run } = useAsyncMutation();
1854
+ const retryGroupUpgrade = useCallback(
1855
+ async (groupId, request) => {
1856
+ if (!mero) return null;
1857
+ return run(() => mero.admin.retryGroupUpgrade(groupId, request));
1858
+ },
1859
+ [mero, run]
1860
+ );
1861
+ return { retryGroupUpgrade, loading, error };
1862
+ }
1863
+ function useNestGroup() {
1864
+ const { mero } = useMero();
1865
+ const { loading, error, run } = useAsyncMutation();
1866
+ const nestGroup = useCallback(
1867
+ async (parentGroupId, request) => {
1868
+ if (!mero) return null;
1869
+ return run(() => mero.admin.nestGroup(parentGroupId, request));
1870
+ },
1871
+ [mero, run]
1872
+ );
1873
+ return { nestGroup, loading, error };
1874
+ }
1875
+ function useUnnestGroup() {
1876
+ const { mero } = useMero();
1877
+ const { loading, error, run } = useAsyncMutation();
1878
+ const unnestGroup = useCallback(
1879
+ async (parentGroupId, request) => {
1880
+ if (!mero) return null;
1881
+ return run(() => mero.admin.unnestGroup(parentGroupId, request));
1882
+ },
1883
+ [mero, run]
1884
+ );
1885
+ return { unnestGroup, loading, error };
1886
+ }
1887
+ function useSubgroups(groupId) {
1888
+ const { mero } = useMero();
1889
+ const [subgroups, setSubgroups] = useState([]);
1890
+ const [loading, setLoading] = useState(false);
1891
+ const [error, setError] = useState(null);
1892
+ const mountedRef = useMountedRef();
1893
+ const refetch = useCallback(async () => {
1894
+ if (!mero || !groupId) {
1895
+ if (mountedRef.current) {
1896
+ setSubgroups([]);
1897
+ setError(null);
1898
+ setLoading(false);
1899
+ }
1900
+ return;
1901
+ }
1902
+ if (mountedRef.current) {
1903
+ setLoading(true);
1904
+ setError(null);
1905
+ }
1906
+ try {
1907
+ const result = await mero.admin.listSubgroups(groupId);
1908
+ if (mountedRef.current) {
1909
+ setSubgroups(result);
1910
+ }
1911
+ } catch (err) {
1912
+ const errorValue = toError(err);
1913
+ if (mountedRef.current) {
1914
+ setError(errorValue);
1915
+ }
1916
+ } finally {
1917
+ if (mountedRef.current) {
1918
+ setLoading(false);
1919
+ }
1920
+ }
1921
+ }, [groupId, mero, mountedRef]);
1922
+ useEffect(() => {
1923
+ void refetch();
1924
+ }, [refetch]);
1925
+ return { subgroups, loading, error, refetch };
1926
+ }
1927
+ function useDetachContextFromGroup() {
1928
+ const { mero } = useMero();
1929
+ const { loading, error, run } = useAsyncMutation();
1930
+ const detachContextFromGroup = useCallback(
1931
+ async (groupId, contextId, request) => {
1932
+ if (!mero) return null;
1933
+ return run(() => mero.admin.detachContextFromGroup(groupId, contextId, request));
1934
+ },
1935
+ [mero, run]
1936
+ );
1937
+ return { detachContextFromGroup, loading, error };
1938
+ }
890
1939
 
891
- export { AppMode, ConnectButton, ConnectionType, EventStreamMode, LoginModal, MeroContext, MeroProvider, clearAllStorage, clearApplicationId, clearNodeUrl, getApplicationId, getNodeUrl, localStorageTokenStorage, setApplicationId, setNodeUrl, useMero };
1940
+ export { AppMode, ConnectButton, ConnectionType, LoginModal, MeroContext, MeroProvider, clearAllStorage, clearApplicationId, clearContextId, clearContextIdentity, clearNodeUrl, getApplicationId, getContextId, getContextIdentity, getNodeUrl, localStorageTokenStorage, setApplicationId, setContextId, setContextIdentity, setNodeUrl, useAddGroupMembers, useApplicationContexts, useContextDiscovery, useContextGroup, useContexts, useCreateContext, useCreateGroupInNamespace, useCreateNamespace, useCreateNamespaceInvitation, useDeleteContext, useDeleteGroup, useDeleteNamespace, useDetachContextFromGroup, useExecute, useGroupCapabilities, useGroupContexts, useGroupInfo, useGroupInvitations, useGroupMembers, useGroupUpgradeStatus, useJoinContext, useJoinGroup, useJoinNamespace, useMero, useNamespace, useNamespaceGroups, useNamespaceIdentity, useNamespaces, useNamespacesForApplication, useNestGroup, useRegisterGroupSigningKey, useRemoveGroupMembers, useRetryGroupUpgrade, useSetDefaultCapabilities, useSetDefaultVisibility, useSetGroupAlias, useSetMemberAlias, useSetTeeAdmissionPolicy, useSubgroups, useSubscription, useSyncGroup, useUnnestGroup, useUpdateGroupSettings, useUpdateMemberRole, useUpgradeGroup };
892
1941
  //# sourceMappingURL=index.js.map
893
1942
  //# sourceMappingURL=index.js.map