@calimero-network/mero-react 1.0.2 → 2.0.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.
package/dist/index.cjs CHANGED
@@ -3,6 +3,7 @@
3
3
  var react = require('react');
4
4
  var meroJs = require('@calimero-network/mero-js');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var reactDom = require('react-dom');
6
7
 
7
8
  // src/context/MeroContext.tsx
8
9
 
@@ -369,6 +370,544 @@ function useMero() {
369
370
  }
370
371
  return context;
371
372
  }
373
+ function isValidUrl(urlString) {
374
+ if (!urlString || urlString.trim() === "") {
375
+ return false;
376
+ }
377
+ try {
378
+ const urlToTest = urlString.startsWith("http://") || urlString.startsWith("https://") ? urlString : `https://${urlString}`;
379
+ const url = new URL(urlToTest);
380
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
381
+ return false;
382
+ }
383
+ if (!url.hostname) {
384
+ return false;
385
+ }
386
+ const hostname = url.hostname;
387
+ if (hostname === "localhost") {
388
+ return true;
389
+ }
390
+ const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
391
+ if (ipv4Regex.test(hostname)) {
392
+ const octets = hostname.split(".").map(Number);
393
+ return octets.every((octet) => octet >= 0 && octet <= 255);
394
+ }
395
+ const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
396
+ return domainRegex.test(hostname);
397
+ } catch {
398
+ return false;
399
+ }
400
+ }
401
+ var styles = {
402
+ overlay: {
403
+ position: "fixed",
404
+ top: 0,
405
+ left: 0,
406
+ right: 0,
407
+ bottom: 0,
408
+ backgroundColor: "rgba(0, 0, 0, 0.75)",
409
+ display: "flex",
410
+ alignItems: "center",
411
+ justifyContent: "center",
412
+ zIndex: 1e4,
413
+ padding: "1rem"
414
+ },
415
+ content: {
416
+ backgroundColor: "#1f2937",
417
+ borderRadius: "12px",
418
+ padding: "2rem",
419
+ maxWidth: "400px",
420
+ width: "100%",
421
+ position: "relative",
422
+ border: "1px solid #374151",
423
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)"
424
+ },
425
+ closeButton: {
426
+ position: "absolute",
427
+ top: "1rem",
428
+ right: "1rem",
429
+ background: "none",
430
+ border: "none",
431
+ fontSize: "1.5rem",
432
+ color: "#9ca3af",
433
+ cursor: "pointer",
434
+ padding: "0.25rem",
435
+ lineHeight: 1
436
+ },
437
+ header: {
438
+ display: "flex",
439
+ flexDirection: "column",
440
+ alignItems: "center",
441
+ gap: "0.75rem",
442
+ marginBottom: "1.5rem"
443
+ },
444
+ title: {
445
+ fontSize: "1.25rem",
446
+ fontWeight: 600,
447
+ color: "#f3f4f6",
448
+ margin: 0
449
+ },
450
+ info: {
451
+ color: "#9ca3af",
452
+ textAlign: "center",
453
+ marginBottom: "1.5rem",
454
+ fontSize: "0.875rem"
455
+ },
456
+ error: {
457
+ color: "#ef4444",
458
+ backgroundColor: "rgba(239, 68, 68, 0.1)",
459
+ border: "1px solid rgba(239, 68, 68, 0.3)",
460
+ borderRadius: "6px",
461
+ padding: "0.75rem",
462
+ marginBottom: "1rem",
463
+ fontSize: "0.875rem",
464
+ textAlign: "center"
465
+ },
466
+ radioGroup: {
467
+ display: "flex",
468
+ gap: "1rem",
469
+ marginBottom: "1rem",
470
+ justifyContent: "center"
471
+ },
472
+ radioLabel: {
473
+ display: "flex",
474
+ alignItems: "center",
475
+ gap: "0.5rem",
476
+ color: "#e5e7eb",
477
+ cursor: "pointer",
478
+ padding: "0.5rem 1rem",
479
+ borderRadius: "6px",
480
+ border: "1px solid #374151",
481
+ backgroundColor: "#111827",
482
+ transition: "all 0.2s"
483
+ },
484
+ radioLabelActive: {
485
+ borderColor: "#3b82f6",
486
+ backgroundColor: "rgba(59, 130, 246, 0.1)"
487
+ },
488
+ input: {
489
+ width: "100%",
490
+ padding: "0.75rem 1rem",
491
+ borderRadius: "6px",
492
+ border: "1px solid #374151",
493
+ backgroundColor: "#111827",
494
+ color: "#f3f4f6",
495
+ fontSize: "0.875rem",
496
+ outline: "none",
497
+ marginBottom: "1rem",
498
+ boxSizing: "border-box"
499
+ },
500
+ localInfo: {
501
+ color: "#9ca3af",
502
+ fontSize: "0.875rem",
503
+ textAlign: "center",
504
+ padding: "0.75rem",
505
+ backgroundColor: "#111827",
506
+ borderRadius: "6px",
507
+ marginBottom: "1rem"
508
+ },
509
+ buttonGroup: {
510
+ display: "flex",
511
+ justifyContent: "center"
512
+ },
513
+ button: {
514
+ padding: "0.75rem 2rem",
515
+ borderRadius: "6px",
516
+ border: "none",
517
+ fontSize: "0.875rem",
518
+ fontWeight: 600,
519
+ cursor: "pointer",
520
+ backgroundColor: "#3b82f6",
521
+ color: "white",
522
+ transition: "all 0.2s"
523
+ },
524
+ buttonDisabled: {
525
+ opacity: 0.5,
526
+ cursor: "not-allowed"
527
+ },
528
+ loading: {
529
+ display: "flex",
530
+ flexDirection: "column",
531
+ alignItems: "center",
532
+ gap: "1rem",
533
+ padding: "2rem",
534
+ color: "#9ca3af"
535
+ },
536
+ spinner: {
537
+ width: "2rem",
538
+ height: "2rem",
539
+ border: "3px solid #374151",
540
+ borderTopColor: "#3b82f6",
541
+ borderRadius: "50%",
542
+ animation: "spin 1s linear infinite"
543
+ }
544
+ };
545
+ function LoginModal({
546
+ onConnect,
547
+ onClose,
548
+ connectionType,
549
+ isOpen
550
+ }) {
551
+ const [nodeType, setNodeType] = react.useState("local");
552
+ const [nodeUrl, setNodeUrl2] = react.useState("");
553
+ const [isValid, setIsValid] = react.useState(true);
554
+ const [loading, setLoading] = react.useState(false);
555
+ const [error, setError] = react.useState(null);
556
+ const shouldShowLocal = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "local" /* Local */;
557
+ const shouldShowRemote = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "remote" /* Remote */;
558
+ const shouldShowRadioGroup = shouldShowLocal && shouldShowRemote;
559
+ react.useEffect(() => {
560
+ const savedUrl = localStorage.getItem("mero:node_url");
561
+ if (savedUrl) {
562
+ setNodeUrl2(savedUrl);
563
+ }
564
+ }, []);
565
+ react.useEffect(() => {
566
+ if (connectionType === "local" /* Local */) {
567
+ setNodeType("local");
568
+ } else if (connectionType === "remote" /* Remote */) {
569
+ setNodeType("remote");
570
+ }
571
+ }, [connectionType]);
572
+ react.useEffect(() => {
573
+ if (nodeType === "remote") {
574
+ setIsValid(isValidUrl(nodeUrl));
575
+ } else {
576
+ setIsValid(true);
577
+ }
578
+ }, [nodeUrl, nodeType]);
579
+ const handleConnect = react.useCallback(async () => {
580
+ if (!isValid) return;
581
+ setLoading(true);
582
+ setError(null);
583
+ const baseUrl = nodeType === "local" ? "http://node1.127.0.0.1.nip.io" : nodeUrl;
584
+ try {
585
+ const response = await fetch(
586
+ new URL("admin-api/is-authed", baseUrl).toString()
587
+ );
588
+ if (response.ok || response.status === 401) {
589
+ setLoading(false);
590
+ const normalizedUrl = baseUrl.replace(/\/+$/, "");
591
+ onConnect(normalizedUrl);
592
+ } else {
593
+ throw new Error(`Connection failed: ${response.statusText}`);
594
+ }
595
+ } catch (err) {
596
+ console.error("Connection failed:", err);
597
+ setError("Failed to connect. Please check the URL and try again.");
598
+ setLoading(false);
599
+ }
600
+ }, [isValid, nodeType, nodeUrl, onConnect]);
601
+ if (!isOpen) {
602
+ return null;
603
+ }
604
+ const modalContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
605
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
606
+ @keyframes spin {
607
+ to { transform: rotate(360deg); }
608
+ }
609
+ ` }),
610
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.content, onClick: (e) => e.stopPropagation(), children: [
611
+ /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles.closeButton, onClick: onClose, children: "\xD7" }),
612
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.header, children: [
613
+ /* @__PURE__ */ jsxRuntime.jsx(MeroLogo, {}),
614
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { style: styles.title, children: "Connect to Calimero" })
615
+ ] }),
616
+ loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.loading, children: [
617
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Connecting to node..." }),
618
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.spinner })
619
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
620
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.info, children: shouldShowRadioGroup ? "Select your Calimero node type to continue." : connectionType === "local" /* Local */ ? "Connect to your local Calimero node." : "Enter your remote Calimero node URL." }),
621
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.error, children: error }),
622
+ shouldShowRadioGroup && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.radioGroup, children: [
623
+ /* @__PURE__ */ jsxRuntime.jsxs(
624
+ "label",
625
+ {
626
+ style: {
627
+ ...styles.radioLabel,
628
+ ...nodeType === "local" ? styles.radioLabelActive : {}
629
+ },
630
+ onClick: () => setNodeType("local"),
631
+ children: [
632
+ /* @__PURE__ */ jsxRuntime.jsx(
633
+ "input",
634
+ {
635
+ type: "radio",
636
+ value: "local",
637
+ checked: nodeType === "local",
638
+ onChange: () => setNodeType("local"),
639
+ style: { display: "none" }
640
+ }
641
+ ),
642
+ "\u{1F3E0} Local"
643
+ ]
644
+ }
645
+ ),
646
+ /* @__PURE__ */ jsxRuntime.jsxs(
647
+ "label",
648
+ {
649
+ style: {
650
+ ...styles.radioLabel,
651
+ ...nodeType === "remote" ? styles.radioLabelActive : {}
652
+ },
653
+ onClick: () => setNodeType("remote"),
654
+ children: [
655
+ /* @__PURE__ */ jsxRuntime.jsx(
656
+ "input",
657
+ {
658
+ type: "radio",
659
+ value: "remote",
660
+ checked: nodeType === "remote",
661
+ onChange: () => setNodeType("remote"),
662
+ style: { display: "none" }
663
+ }
664
+ ),
665
+ "\u{1F310} Remote"
666
+ ]
667
+ }
668
+ )
669
+ ] }),
670
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: shouldShowRemote && nodeType === "remote" ? /* @__PURE__ */ jsxRuntime.jsx(
671
+ "input",
672
+ {
673
+ type: "text",
674
+ value: nodeUrl,
675
+ onChange: (e) => setNodeUrl2(e.target.value),
676
+ placeholder: "https://your-node-url.calimero.network",
677
+ style: styles.input,
678
+ onKeyDown: (e) => {
679
+ if (e.key === "Enter" && isValid) {
680
+ handleConnect();
681
+ }
682
+ }
683
+ }
684
+ ) : shouldShowLocal ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: styles.localInfo, children: [
685
+ "Using default local node: ",
686
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
687
+ /* @__PURE__ */ jsxRuntime.jsx("code", { style: { color: "#60a5fa" }, children: "http://node1.127.0.0.1.nip.io" })
688
+ ] }) : null }),
689
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.buttonGroup, children: /* @__PURE__ */ jsxRuntime.jsx(
690
+ "button",
691
+ {
692
+ onClick: handleConnect,
693
+ disabled: !isValid || loading,
694
+ style: {
695
+ ...styles.button,
696
+ ...!isValid || loading ? styles.buttonDisabled : {}
697
+ },
698
+ children: "Connect"
699
+ }
700
+ ) })
701
+ ] })
702
+ ] }) })
703
+ ] });
704
+ return reactDom.createPortal(modalContent, document.body);
705
+ }
706
+ function MeroLogo() {
707
+ return /* @__PURE__ */ jsxRuntime.jsx(
708
+ "svg",
709
+ {
710
+ width: "40",
711
+ height: "40",
712
+ viewBox: "0 0 24 24",
713
+ fill: "#3b82f6",
714
+ xmlns: "http://www.w3.org/2000/svg",
715
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" })
716
+ }
717
+ );
718
+ }
719
+ function ConnectButton({
720
+ connectionType = "remote-and-local" /* RemoteAndLocal */,
721
+ className,
722
+ style
723
+ }) {
724
+ const { isAuthenticated, connectToNode, logout, nodeUrl, isOnline } = useMero();
725
+ const [isDropdownOpen, setIsDropdownOpen] = react.useState(false);
726
+ const [isModalOpen, setIsModalOpen] = react.useState(false);
727
+ const dropdownRef = react.useRef(null);
728
+ react.useEffect(() => {
729
+ const handleClickOutside = (event) => {
730
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
731
+ setIsDropdownOpen(false);
732
+ }
733
+ };
734
+ document.addEventListener("mousedown", handleClickOutside);
735
+ return () => document.removeEventListener("mousedown", handleClickOutside);
736
+ }, []);
737
+ const dashboardUrl = react.useMemo(() => {
738
+ if (!isAuthenticated || !nodeUrl) return "#";
739
+ return new URL("admin-dashboard/", nodeUrl).toString();
740
+ }, [isAuthenticated, nodeUrl]);
741
+ const handleConnect = () => {
742
+ if (typeof connectionType === "object" && connectionType.type === "custom" /* Custom */) {
743
+ connectToNode(connectionType.url);
744
+ return;
745
+ }
746
+ setIsModalOpen(true);
747
+ };
748
+ const handleModalConnect = (url) => {
749
+ setIsModalOpen(false);
750
+ connectToNode(url);
751
+ };
752
+ if (isAuthenticated && !isOnline) {
753
+ return /* @__PURE__ */ jsxRuntime.jsxs(
754
+ "button",
755
+ {
756
+ className: `mero-connect-button mero-reconnecting ${className || ""}`,
757
+ style,
758
+ disabled: true,
759
+ children: [
760
+ /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
761
+ "Reconnecting..."
762
+ ]
763
+ }
764
+ );
765
+ }
766
+ if (isAuthenticated) {
767
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: "mero-connect-container", style: { position: "relative", display: "inline-block" }, children: [
768
+ /* @__PURE__ */ jsxRuntime.jsxs(
769
+ "button",
770
+ {
771
+ className: `mero-connect-button mero-connected ${className || ""}`,
772
+ style,
773
+ onClick: () => setIsDropdownOpen((prev) => !prev),
774
+ children: [
775
+ /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
776
+ "Connected"
777
+ ]
778
+ }
779
+ ),
780
+ isDropdownOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mero-dropdown", children: [
781
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mero-dropdown-info", title: nodeUrl || "", children: nodeUrl }),
782
+ /* @__PURE__ */ jsxRuntime.jsx(
783
+ "a",
784
+ {
785
+ href: dashboardUrl,
786
+ target: "_blank",
787
+ rel: "noopener noreferrer",
788
+ className: "mero-dropdown-item",
789
+ children: "Dashboard"
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsxRuntime.jsx(
793
+ "button",
794
+ {
795
+ className: "mero-dropdown-item",
796
+ onClick: () => {
797
+ setIsDropdownOpen(false);
798
+ logout();
799
+ },
800
+ children: "Log out"
801
+ }
802
+ )
803
+ ] })
804
+ ] });
805
+ }
806
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
807
+ /* @__PURE__ */ jsxRuntime.jsxs(
808
+ "button",
809
+ {
810
+ className: `mero-connect-button ${className || ""}`,
811
+ style,
812
+ onClick: handleConnect,
813
+ children: [
814
+ /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
815
+ "Connect"
816
+ ]
817
+ }
818
+ ),
819
+ /* @__PURE__ */ jsxRuntime.jsx(
820
+ LoginModal,
821
+ {
822
+ isOpen: isModalOpen,
823
+ onConnect: handleModalConnect,
824
+ onClose: () => setIsModalOpen(false),
825
+ connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType
826
+ }
827
+ )
828
+ ] });
829
+ }
830
+ function MeroLogo2() {
831
+ return /* @__PURE__ */ jsxRuntime.jsx(
832
+ "svg",
833
+ {
834
+ className: "mero-logo",
835
+ width: "24",
836
+ height: "24",
837
+ viewBox: "0 0 24 24",
838
+ fill: "currentColor",
839
+ xmlns: "http://www.w3.org/2000/svg",
840
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" })
841
+ }
842
+ );
843
+ }
844
+ function toError(err) {
845
+ return err instanceof Error ? err : new Error(String(err));
846
+ }
847
+ function mapApplicationContexts(contexts) {
848
+ return contexts.map((context) => ({
849
+ contextId: context.id,
850
+ applicationId: context.applicationId
851
+ }));
852
+ }
853
+ function useMountedRef() {
854
+ const mountedRef = react.useRef(true);
855
+ react.useEffect(() => {
856
+ mountedRef.current = true;
857
+ return () => {
858
+ mountedRef.current = false;
859
+ };
860
+ }, []);
861
+ return mountedRef;
862
+ }
863
+ function useAsyncMutation() {
864
+ const mountedRef = useMountedRef();
865
+ const [loading, setLoading] = react.useState(false);
866
+ const [error, setError] = react.useState(null);
867
+ const run = react.useCallback(
868
+ async (action) => {
869
+ if (mountedRef.current) {
870
+ setLoading(true);
871
+ setError(null);
872
+ }
873
+ try {
874
+ return await action();
875
+ } catch (err) {
876
+ const errorValue = toError(err);
877
+ if (mountedRef.current) {
878
+ setError(errorValue);
879
+ }
880
+ return null;
881
+ } finally {
882
+ if (mountedRef.current) {
883
+ setLoading(false);
884
+ }
885
+ }
886
+ },
887
+ [mountedRef]
888
+ );
889
+ return { loading, error, run, setError };
890
+ }
891
+ function sleep(ms) {
892
+ return new Promise((resolve) => {
893
+ setTimeout(resolve, ms);
894
+ });
895
+ }
896
+ function extractAliasContextId(value) {
897
+ if (typeof value === "string") {
898
+ return value;
899
+ }
900
+ if (!value || typeof value !== "object") {
901
+ return null;
902
+ }
903
+ if ("value" in value && typeof value.value === "string") {
904
+ return value.value;
905
+ }
906
+ if ("contextId" in value && typeof value.contextId === "string") {
907
+ return value.contextId;
908
+ }
909
+ return null;
910
+ }
372
911
  function useExecute(contextId, executorId) {
373
912
  const { mero } = useMero();
374
913
  const [loading, setLoading] = react.useState(false);
@@ -436,13 +975,7 @@ function useContexts(applicationId) {
436
975
  const [contexts, setContexts] = react.useState([]);
437
976
  const [loading, setLoading] = react.useState(false);
438
977
  const [error, setError] = react.useState(null);
439
- const mountedRef = react.useRef(true);
440
- react.useEffect(() => {
441
- mountedRef.current = true;
442
- return () => {
443
- mountedRef.current = false;
444
- };
445
- }, []);
978
+ const mountedRef = useMountedRef();
446
979
  const refetch = react.useCallback(async () => {
447
980
  if (!mero) return;
448
981
  if (mountedRef.current) {
@@ -450,17 +983,20 @@ function useContexts(applicationId) {
450
983
  setError(null);
451
984
  }
452
985
  try {
453
- const response = await mero.admin.getContexts();
454
- let list = (response.contexts ?? []).map((c) => ({ contextId: c.id, applicationId: c.applicationId }));
455
- if (applicationId) {
456
- list = list.filter((c) => c.applicationId === applicationId);
986
+ const response = applicationId ? await mero.admin.getContextsForApplication(applicationId) : await mero.admin.getContexts();
987
+ const list = mapApplicationContexts(response.contexts ?? []);
988
+ if (mountedRef.current) {
989
+ setContexts(list);
457
990
  }
458
- if (mountedRef.current) setContexts(list);
459
991
  } catch (err) {
460
- const e = err instanceof Error ? err : new Error(String(err));
461
- if (mountedRef.current) setError(e);
992
+ const errorValue = toError(err);
993
+ if (mountedRef.current) {
994
+ setError(errorValue);
995
+ }
462
996
  } finally {
463
- if (mountedRef.current) setLoading(false);
997
+ if (mountedRef.current) {
998
+ setLoading(false);
999
+ }
464
1000
  }
465
1001
  }, [mero, applicationId]);
466
1002
  react.useEffect(() => {
@@ -468,9 +1004,944 @@ function useContexts(applicationId) {
468
1004
  }, [refetch]);
469
1005
  return { contexts, loading, error, refetch };
470
1006
  }
1007
+ function useApplicationContexts(applicationId) {
1008
+ return useContexts(applicationId);
1009
+ }
1010
+ function useGroupMembers(groupId) {
1011
+ const { mero } = useMero();
1012
+ const [members, setMembers] = react.useState([]);
1013
+ const [selfIdentity, setSelfIdentity] = react.useState(null);
1014
+ const [loading, setLoading] = react.useState(false);
1015
+ const [error, setError] = react.useState(null);
1016
+ const mountedRef = useMountedRef();
1017
+ const refetch = react.useCallback(async () => {
1018
+ if (!mero || !groupId) {
1019
+ if (mountedRef.current) {
1020
+ setMembers([]);
1021
+ setSelfIdentity(null);
1022
+ setError(null);
1023
+ setLoading(false);
1024
+ }
1025
+ return;
1026
+ }
1027
+ if (mountedRef.current) {
1028
+ setLoading(true);
1029
+ setError(null);
1030
+ }
1031
+ try {
1032
+ const response = await mero.admin.listGroupMembers(groupId);
1033
+ if (mountedRef.current) {
1034
+ setMembers(response.data ?? []);
1035
+ setSelfIdentity(response.selfIdentity ?? null);
1036
+ }
1037
+ } catch (err) {
1038
+ const errorValue = toError(err);
1039
+ if (mountedRef.current) {
1040
+ setError(errorValue);
1041
+ }
1042
+ } finally {
1043
+ if (mountedRef.current) {
1044
+ setLoading(false);
1045
+ }
1046
+ }
1047
+ }, [groupId, mero, mountedRef]);
1048
+ react.useEffect(() => {
1049
+ void refetch();
1050
+ }, [refetch]);
1051
+ return { members, selfIdentity, loading, error, refetch };
1052
+ }
1053
+ function useGroupContexts(groupId) {
1054
+ const { mero } = useMero();
1055
+ const [contexts, setContexts] = react.useState([]);
1056
+ const [loading, setLoading] = react.useState(false);
1057
+ const [error, setError] = react.useState(null);
1058
+ const mountedRef = useMountedRef();
1059
+ const refetch = react.useCallback(async () => {
1060
+ if (!mero || !groupId) {
1061
+ if (mountedRef.current) {
1062
+ setContexts([]);
1063
+ setError(null);
1064
+ setLoading(false);
1065
+ }
1066
+ return;
1067
+ }
1068
+ if (mountedRef.current) {
1069
+ setLoading(true);
1070
+ setError(null);
1071
+ }
1072
+ try {
1073
+ const nextContexts = await mero.admin.listGroupContexts(groupId);
1074
+ if (mountedRef.current) {
1075
+ setContexts(nextContexts);
1076
+ }
1077
+ } catch (err) {
1078
+ const errorValue = toError(err);
1079
+ if (mountedRef.current) {
1080
+ setError(errorValue);
1081
+ }
1082
+ } finally {
1083
+ if (mountedRef.current) {
1084
+ setLoading(false);
1085
+ }
1086
+ }
1087
+ }, [groupId, mero, mountedRef]);
1088
+ react.useEffect(() => {
1089
+ void refetch();
1090
+ }, [refetch]);
1091
+ return { contexts, loading, error, refetch };
1092
+ }
1093
+ function useGroupInvitations() {
1094
+ const { mero } = useMero();
1095
+ const { loading, error, run } = useAsyncMutation();
1096
+ const createInvitation = react.useCallback(
1097
+ async (groupId, request) => {
1098
+ if (!mero) {
1099
+ return null;
1100
+ }
1101
+ return run(() => mero.admin.createGroupInvitation(groupId, request));
1102
+ },
1103
+ [mero, run]
1104
+ );
1105
+ return { createInvitation, loading, error };
1106
+ }
1107
+ function useJoinGroup() {
1108
+ const { mero } = useMero();
1109
+ const { loading, error, run } = useAsyncMutation();
1110
+ const joinGroup = react.useCallback(
1111
+ async (request) => {
1112
+ if (!mero) {
1113
+ return null;
1114
+ }
1115
+ return run(() => mero.admin.joinGroup(request));
1116
+ },
1117
+ [mero, run]
1118
+ );
1119
+ return { joinGroup, loading, error };
1120
+ }
1121
+ function useGroupCapabilities(groupId, memberId) {
1122
+ const { mero } = useMero();
1123
+ const [capabilities, setCapabilitiesState] = react.useState(null);
1124
+ const [loading, setLoading] = react.useState(false);
1125
+ const [error, setError] = react.useState(null);
1126
+ const mountedRef = useMountedRef();
1127
+ const refetch = react.useCallback(async () => {
1128
+ if (!mero || !groupId || !memberId) {
1129
+ if (mountedRef.current) {
1130
+ setCapabilitiesState(null);
1131
+ setError(null);
1132
+ setLoading(false);
1133
+ }
1134
+ return null;
1135
+ }
1136
+ if (mountedRef.current) {
1137
+ setLoading(true);
1138
+ setError(null);
1139
+ }
1140
+ try {
1141
+ const response = await mero.admin.getMemberCapabilities(groupId, memberId);
1142
+ if (mountedRef.current) {
1143
+ setCapabilitiesState(response.capabilities);
1144
+ }
1145
+ return response.capabilities;
1146
+ } catch (err) {
1147
+ const errorValue = toError(err);
1148
+ if (mountedRef.current) {
1149
+ setError(errorValue);
1150
+ }
1151
+ return null;
1152
+ } finally {
1153
+ if (mountedRef.current) {
1154
+ setLoading(false);
1155
+ }
1156
+ }
1157
+ }, [groupId, memberId, mero, mountedRef]);
1158
+ react.useEffect(() => {
1159
+ void refetch();
1160
+ }, [refetch]);
1161
+ const setCapabilities = react.useCallback(
1162
+ async (nextCapabilities) => {
1163
+ if (!mero || !groupId || !memberId) {
1164
+ return null;
1165
+ }
1166
+ if (mountedRef.current) {
1167
+ setLoading(true);
1168
+ setError(null);
1169
+ }
1170
+ try {
1171
+ await mero.admin.setMemberCapabilities(groupId, memberId, { capabilities: nextCapabilities });
1172
+ if (mountedRef.current) {
1173
+ setCapabilitiesState(nextCapabilities);
1174
+ }
1175
+ return nextCapabilities;
1176
+ } catch (err) {
1177
+ const errorValue = toError(err);
1178
+ if (mountedRef.current) {
1179
+ setError(errorValue);
1180
+ }
1181
+ return null;
1182
+ } finally {
1183
+ if (mountedRef.current) {
1184
+ setLoading(false);
1185
+ }
1186
+ }
1187
+ },
1188
+ [groupId, memberId, mero, mountedRef]
1189
+ );
1190
+ return { capabilities, loading, error, refetch, setCapabilities };
1191
+ }
1192
+ function useContextDiscovery(options) {
1193
+ const { mero } = useMero();
1194
+ const [context, setContext] = react.useState(null);
1195
+ const [loading, setLoading] = react.useState(false);
1196
+ const [error, setError] = react.useState(null);
1197
+ const mountedRef = useMountedRef();
1198
+ const knownContextIdsKey = JSON.stringify(options.knownContextIds ?? []);
1199
+ const discover = react.useCallback(async () => {
1200
+ if (!mero) {
1201
+ const notConnectedError = new Error("Not connected");
1202
+ if (mountedRef.current) {
1203
+ setError(notConnectedError);
1204
+ }
1205
+ return null;
1206
+ }
1207
+ const knownContextIds = new Set(options.knownContextIds ?? []);
1208
+ const pollIntervalMs = options.pollIntervalMs ?? 1e3;
1209
+ const timeoutMs = options.timeoutMs ?? 3e4;
1210
+ const deadline = Date.now() + timeoutMs;
1211
+ if (mountedRef.current) {
1212
+ setLoading(true);
1213
+ setError(null);
1214
+ }
1215
+ try {
1216
+ while (Date.now() <= deadline) {
1217
+ if (options.targetAlias) {
1218
+ const aliasMatch = extractAliasContextId(
1219
+ await mero.admin.lookupContextAlias(options.targetAlias)
1220
+ );
1221
+ if (aliasMatch && !knownContextIds.has(aliasMatch)) {
1222
+ const discoveredFromAlias = {
1223
+ contextId: aliasMatch,
1224
+ applicationId: options.applicationId
1225
+ };
1226
+ if (mountedRef.current) {
1227
+ setContext(discoveredFromAlias);
1228
+ }
1229
+ return discoveredFromAlias;
1230
+ }
1231
+ }
1232
+ const response = await mero.admin.getContextsForApplication(options.applicationId);
1233
+ const contexts = mapApplicationContexts(response.contexts ?? []);
1234
+ const discovered = contexts.find(
1235
+ (applicationContext) => !knownContextIds.has(applicationContext.contextId)
1236
+ );
1237
+ if (discovered) {
1238
+ if (mountedRef.current) {
1239
+ setContext(discovered);
1240
+ }
1241
+ return discovered;
1242
+ }
1243
+ if (Date.now() + pollIntervalMs > deadline) {
1244
+ break;
1245
+ }
1246
+ await sleep(pollIntervalMs);
1247
+ }
1248
+ const timeoutError = new Error(
1249
+ `Timed out discovering a context for application ${options.applicationId}`
1250
+ );
1251
+ if (mountedRef.current) {
1252
+ setContext(null);
1253
+ setError(timeoutError);
1254
+ }
1255
+ return null;
1256
+ } catch (err) {
1257
+ const errorValue = toError(err);
1258
+ if (mountedRef.current) {
1259
+ setContext(null);
1260
+ setError(errorValue);
1261
+ }
1262
+ return null;
1263
+ } finally {
1264
+ if (mountedRef.current) {
1265
+ setLoading(false);
1266
+ }
1267
+ }
1268
+ }, [
1269
+ knownContextIdsKey,
1270
+ mero,
1271
+ mountedRef,
1272
+ options.applicationId,
1273
+ options.knownContextIds,
1274
+ options.pollIntervalMs,
1275
+ options.targetAlias,
1276
+ options.timeoutMs
1277
+ ]);
1278
+ const reset = react.useCallback(() => {
1279
+ if (mountedRef.current) {
1280
+ setContext(null);
1281
+ setError(null);
1282
+ setLoading(false);
1283
+ }
1284
+ }, [mountedRef]);
1285
+ return { context, loading, error, discover, reset };
1286
+ }
1287
+ function useCreateContext() {
1288
+ const { mero } = useMero();
1289
+ const { loading, error, run } = useAsyncMutation();
1290
+ const createContext2 = react.useCallback(
1291
+ async (request) => {
1292
+ if (!mero) return null;
1293
+ return run(() => mero.admin.createContext(request));
1294
+ },
1295
+ [mero, run]
1296
+ );
1297
+ return { createContext: createContext2, loading, error };
1298
+ }
1299
+ function useDeleteContext() {
1300
+ const { mero } = useMero();
1301
+ const { loading, error, run } = useAsyncMutation();
1302
+ const deleteContext = react.useCallback(
1303
+ async (contextId) => {
1304
+ if (!mero) return null;
1305
+ return run(() => mero.admin.deleteContext(contextId));
1306
+ },
1307
+ [mero, run]
1308
+ );
1309
+ return { deleteContext, loading, error };
1310
+ }
1311
+ function useJoinContext() {
1312
+ const { mero } = useMero();
1313
+ const { loading, error, run } = useAsyncMutation();
1314
+ const joinContext = react.useCallback(
1315
+ async (contextId) => {
1316
+ if (!mero) return null;
1317
+ return run(() => mero.admin.joinContext(contextId));
1318
+ },
1319
+ [mero, run]
1320
+ );
1321
+ return { joinContext, loading, error };
1322
+ }
1323
+ function useContextGroup(contextId) {
1324
+ const { mero } = useMero();
1325
+ const [groupId, setGroupId] = react.useState(null);
1326
+ const [loading, setLoading] = react.useState(false);
1327
+ const [error, setError] = react.useState(null);
1328
+ const mountedRef = useMountedRef();
1329
+ const refetch = react.useCallback(async () => {
1330
+ if (!mero || !contextId) {
1331
+ if (mountedRef.current) {
1332
+ setGroupId(null);
1333
+ setError(null);
1334
+ setLoading(false);
1335
+ }
1336
+ return;
1337
+ }
1338
+ if (mountedRef.current) {
1339
+ setLoading(true);
1340
+ setError(null);
1341
+ }
1342
+ try {
1343
+ const result = await mero.admin.getContextGroup(contextId);
1344
+ if (mountedRef.current) {
1345
+ setGroupId(result);
1346
+ }
1347
+ } catch (err) {
1348
+ const errorValue = toError(err);
1349
+ if (mountedRef.current) {
1350
+ setError(errorValue);
1351
+ }
1352
+ } finally {
1353
+ if (mountedRef.current) {
1354
+ setLoading(false);
1355
+ }
1356
+ }
1357
+ }, [contextId, mero, mountedRef]);
1358
+ react.useEffect(() => {
1359
+ void refetch();
1360
+ }, [refetch]);
1361
+ return { groupId, loading, error, refetch };
1362
+ }
1363
+ function useGroupInfo(groupId) {
1364
+ const { mero } = useMero();
1365
+ const [groupInfo, setGroupInfo] = react.useState(null);
1366
+ const [loading, setLoading] = react.useState(false);
1367
+ const [error, setError] = react.useState(null);
1368
+ const mountedRef = useMountedRef();
1369
+ const refetch = react.useCallback(async () => {
1370
+ if (!mero || !groupId) {
1371
+ if (mountedRef.current) {
1372
+ setGroupInfo(null);
1373
+ setError(null);
1374
+ setLoading(false);
1375
+ }
1376
+ return;
1377
+ }
1378
+ if (mountedRef.current) {
1379
+ setLoading(true);
1380
+ setError(null);
1381
+ }
1382
+ try {
1383
+ const result = await mero.admin.getGroupInfo(groupId);
1384
+ if (mountedRef.current) {
1385
+ setGroupInfo(result);
1386
+ }
1387
+ } catch (err) {
1388
+ const errorValue = toError(err);
1389
+ if (mountedRef.current) {
1390
+ setError(errorValue);
1391
+ }
1392
+ } finally {
1393
+ if (mountedRef.current) {
1394
+ setLoading(false);
1395
+ }
1396
+ }
1397
+ }, [groupId, mero, mountedRef]);
1398
+ react.useEffect(() => {
1399
+ void refetch();
1400
+ }, [refetch]);
1401
+ return { groupInfo, loading, error, refetch };
1402
+ }
1403
+ function useDeleteGroup() {
1404
+ const { mero } = useMero();
1405
+ const { loading, error, run } = useAsyncMutation();
1406
+ const deleteGroup = react.useCallback(
1407
+ async (groupId, request) => {
1408
+ if (!mero) return null;
1409
+ return run(() => mero.admin.deleteGroup(groupId, request));
1410
+ },
1411
+ [mero, run]
1412
+ );
1413
+ return { deleteGroup, loading, error };
1414
+ }
1415
+ function useSyncGroup() {
1416
+ const { mero } = useMero();
1417
+ const { loading, error, run } = useAsyncMutation();
1418
+ const syncGroup = react.useCallback(
1419
+ async (groupId, request) => {
1420
+ if (!mero) return null;
1421
+ return run(() => mero.admin.syncGroup(groupId, request));
1422
+ },
1423
+ [mero, run]
1424
+ );
1425
+ return { syncGroup, loading, error };
1426
+ }
1427
+ function useAddGroupMembers() {
1428
+ const { mero } = useMero();
1429
+ const { loading, error, run } = useAsyncMutation();
1430
+ const addGroupMembers = react.useCallback(
1431
+ async (groupId, request) => {
1432
+ if (!mero) return null;
1433
+ return run(() => mero.admin.addGroupMembers(groupId, request));
1434
+ },
1435
+ [mero, run]
1436
+ );
1437
+ return { addGroupMembers, loading, error };
1438
+ }
1439
+ function useRemoveGroupMembers() {
1440
+ const { mero } = useMero();
1441
+ const { loading, error, run } = useAsyncMutation();
1442
+ const removeGroupMembers = react.useCallback(
1443
+ async (groupId, request) => {
1444
+ if (!mero) return null;
1445
+ return run(() => mero.admin.removeGroupMembers(groupId, request));
1446
+ },
1447
+ [mero, run]
1448
+ );
1449
+ return { removeGroupMembers, loading, error };
1450
+ }
1451
+ function useNamespaces() {
1452
+ const { mero } = useMero();
1453
+ const [namespaces, setNamespaces] = react.useState([]);
1454
+ const [loading, setLoading] = react.useState(false);
1455
+ const [error, setError] = react.useState(null);
1456
+ const mountedRef = useMountedRef();
1457
+ const refetch = react.useCallback(async () => {
1458
+ if (!mero) return;
1459
+ if (mountedRef.current) {
1460
+ setLoading(true);
1461
+ setError(null);
1462
+ }
1463
+ try {
1464
+ const result = await mero.admin.listNamespaces();
1465
+ if (mountedRef.current) {
1466
+ setNamespaces(result);
1467
+ }
1468
+ } catch (err) {
1469
+ const errorValue = toError(err);
1470
+ if (mountedRef.current) {
1471
+ setError(errorValue);
1472
+ }
1473
+ } finally {
1474
+ if (mountedRef.current) {
1475
+ setLoading(false);
1476
+ }
1477
+ }
1478
+ }, [mero, mountedRef]);
1479
+ react.useEffect(() => {
1480
+ void refetch();
1481
+ }, [refetch]);
1482
+ return { namespaces, loading, error, refetch };
1483
+ }
1484
+ function useNamespace(namespaceId) {
1485
+ const { mero } = useMero();
1486
+ const [namespace, setNamespace] = react.useState(null);
1487
+ const [loading, setLoading] = react.useState(false);
1488
+ const [error, setError] = react.useState(null);
1489
+ const mountedRef = useMountedRef();
1490
+ const refetch = react.useCallback(async () => {
1491
+ if (!mero || !namespaceId) {
1492
+ if (mountedRef.current) {
1493
+ setNamespace(null);
1494
+ setError(null);
1495
+ setLoading(false);
1496
+ }
1497
+ return;
1498
+ }
1499
+ if (mountedRef.current) {
1500
+ setLoading(true);
1501
+ setError(null);
1502
+ }
1503
+ try {
1504
+ const result = await mero.admin.getNamespace(namespaceId);
1505
+ if (mountedRef.current) {
1506
+ setNamespace(result);
1507
+ }
1508
+ } catch (err) {
1509
+ const errorValue = toError(err);
1510
+ if (mountedRef.current) {
1511
+ setError(errorValue);
1512
+ }
1513
+ } finally {
1514
+ if (mountedRef.current) {
1515
+ setLoading(false);
1516
+ }
1517
+ }
1518
+ }, [namespaceId, mero, mountedRef]);
1519
+ react.useEffect(() => {
1520
+ void refetch();
1521
+ }, [refetch]);
1522
+ return { namespace, loading, error, refetch };
1523
+ }
1524
+ function useNamespaceIdentity(namespaceId) {
1525
+ const { mero } = useMero();
1526
+ const [identity, setIdentity] = react.useState(null);
1527
+ const [loading, setLoading] = react.useState(false);
1528
+ const [error, setError] = react.useState(null);
1529
+ const mountedRef = useMountedRef();
1530
+ const refetch = react.useCallback(async () => {
1531
+ if (!mero || !namespaceId) {
1532
+ if (mountedRef.current) {
1533
+ setIdentity(null);
1534
+ setError(null);
1535
+ setLoading(false);
1536
+ }
1537
+ return;
1538
+ }
1539
+ if (mountedRef.current) {
1540
+ setLoading(true);
1541
+ setError(null);
1542
+ }
1543
+ try {
1544
+ const result = await mero.admin.getNamespaceIdentity(namespaceId);
1545
+ if (mountedRef.current) {
1546
+ setIdentity(result);
1547
+ }
1548
+ } catch (err) {
1549
+ const errorValue = toError(err);
1550
+ if (mountedRef.current) {
1551
+ setError(errorValue);
1552
+ }
1553
+ } finally {
1554
+ if (mountedRef.current) {
1555
+ setLoading(false);
1556
+ }
1557
+ }
1558
+ }, [namespaceId, mero, mountedRef]);
1559
+ react.useEffect(() => {
1560
+ void refetch();
1561
+ }, [refetch]);
1562
+ return { identity, loading, error, refetch };
1563
+ }
1564
+ function useNamespacesForApplication(applicationId) {
1565
+ const { mero } = useMero();
1566
+ const [namespaces, setNamespaces] = react.useState([]);
1567
+ const [loading, setLoading] = react.useState(false);
1568
+ const [error, setError] = react.useState(null);
1569
+ const mountedRef = useMountedRef();
1570
+ const refetch = react.useCallback(async () => {
1571
+ if (!mero || !applicationId) {
1572
+ if (mountedRef.current) {
1573
+ setNamespaces([]);
1574
+ setError(null);
1575
+ setLoading(false);
1576
+ }
1577
+ return;
1578
+ }
1579
+ if (mountedRef.current) {
1580
+ setLoading(true);
1581
+ setError(null);
1582
+ }
1583
+ try {
1584
+ const result = await mero.admin.listNamespacesForApplication(applicationId);
1585
+ if (mountedRef.current) {
1586
+ setNamespaces(result);
1587
+ }
1588
+ } catch (err) {
1589
+ const errorValue = toError(err);
1590
+ if (mountedRef.current) {
1591
+ setError(errorValue);
1592
+ }
1593
+ } finally {
1594
+ if (mountedRef.current) {
1595
+ setLoading(false);
1596
+ }
1597
+ }
1598
+ }, [applicationId, mero, mountedRef]);
1599
+ react.useEffect(() => {
1600
+ void refetch();
1601
+ }, [refetch]);
1602
+ return { namespaces, loading, error, refetch };
1603
+ }
1604
+ function useCreateNamespace() {
1605
+ const { mero } = useMero();
1606
+ const { loading, error, run } = useAsyncMutation();
1607
+ const createNamespace = react.useCallback(
1608
+ async (request) => {
1609
+ if (!mero) return null;
1610
+ return run(() => mero.admin.createNamespace(request));
1611
+ },
1612
+ [mero, run]
1613
+ );
1614
+ return { createNamespace, loading, error };
1615
+ }
1616
+ function useDeleteNamespace() {
1617
+ const { mero } = useMero();
1618
+ const { loading, error, run } = useAsyncMutation();
1619
+ const deleteNamespace = react.useCallback(
1620
+ async (namespaceId, request) => {
1621
+ if (!mero) return null;
1622
+ return run(() => mero.admin.deleteNamespace(namespaceId, request));
1623
+ },
1624
+ [mero, run]
1625
+ );
1626
+ return { deleteNamespace, loading, error };
1627
+ }
1628
+ function useCreateNamespaceInvitation() {
1629
+ const { mero } = useMero();
1630
+ const { loading, error, run } = useAsyncMutation();
1631
+ const createNamespaceInvitation = react.useCallback(
1632
+ async (namespaceId, request) => {
1633
+ if (!mero) return null;
1634
+ return run(() => mero.admin.createNamespaceInvitation(namespaceId, request));
1635
+ },
1636
+ [mero, run]
1637
+ );
1638
+ return { createNamespaceInvitation, loading, error };
1639
+ }
1640
+ function useJoinNamespace() {
1641
+ const { mero } = useMero();
1642
+ const { loading, error, run } = useAsyncMutation();
1643
+ const joinNamespace = react.useCallback(
1644
+ async (namespaceId, request) => {
1645
+ if (!mero) return null;
1646
+ return run(() => mero.admin.joinNamespace(namespaceId, request));
1647
+ },
1648
+ [mero, run]
1649
+ );
1650
+ return { joinNamespace, loading, error };
1651
+ }
1652
+ function useCreateGroupInNamespace() {
1653
+ const { mero } = useMero();
1654
+ const { loading, error, run } = useAsyncMutation();
1655
+ const createGroupInNamespace = react.useCallback(
1656
+ async (namespaceId, request) => {
1657
+ if (!mero) return null;
1658
+ return run(() => mero.admin.createGroupInNamespace(namespaceId, request));
1659
+ },
1660
+ [mero, run]
1661
+ );
1662
+ return { createGroupInNamespace, loading, error };
1663
+ }
1664
+ function useNamespaceGroups(namespaceId) {
1665
+ const { mero } = useMero();
1666
+ const [groups, setGroups] = react.useState([]);
1667
+ const [loading, setLoading] = react.useState(false);
1668
+ const [error, setError] = react.useState(null);
1669
+ const mountedRef = useMountedRef();
1670
+ const refetch = react.useCallback(async () => {
1671
+ if (!mero || !namespaceId) {
1672
+ if (mountedRef.current) {
1673
+ setGroups([]);
1674
+ setError(null);
1675
+ setLoading(false);
1676
+ }
1677
+ return;
1678
+ }
1679
+ if (mountedRef.current) {
1680
+ setLoading(true);
1681
+ setError(null);
1682
+ }
1683
+ try {
1684
+ const result = await mero.admin.listNamespaceGroups(namespaceId);
1685
+ if (mountedRef.current) {
1686
+ setGroups(result);
1687
+ }
1688
+ } catch (err) {
1689
+ const errorValue = toError(err);
1690
+ if (mountedRef.current) {
1691
+ setError(errorValue);
1692
+ }
1693
+ } finally {
1694
+ if (mountedRef.current) {
1695
+ setLoading(false);
1696
+ }
1697
+ }
1698
+ }, [namespaceId, mero, mountedRef]);
1699
+ react.useEffect(() => {
1700
+ void refetch();
1701
+ }, [refetch]);
1702
+ return { groups, loading, error, refetch };
1703
+ }
1704
+ function useUpdateMemberRole() {
1705
+ const { mero } = useMero();
1706
+ const { loading, error, run } = useAsyncMutation();
1707
+ const updateMemberRole = react.useCallback(
1708
+ async (groupId, identity, request) => {
1709
+ if (!mero) return null;
1710
+ return run(() => mero.admin.updateMemberRole(groupId, identity, request));
1711
+ },
1712
+ [mero, run]
1713
+ );
1714
+ return { updateMemberRole, loading, error };
1715
+ }
1716
+ function useSetDefaultCapabilities() {
1717
+ const { mero } = useMero();
1718
+ const { loading, error, run } = useAsyncMutation();
1719
+ const setDefaultCapabilities = react.useCallback(
1720
+ async (groupId, request) => {
1721
+ if (!mero) return null;
1722
+ return run(() => mero.admin.setDefaultCapabilities(groupId, request));
1723
+ },
1724
+ [mero, run]
1725
+ );
1726
+ return { setDefaultCapabilities, loading, error };
1727
+ }
1728
+ function useSetSubgroupVisibility() {
1729
+ const { mero } = useMero();
1730
+ const { loading, error, run } = useAsyncMutation();
1731
+ const setSubgroupVisibility = react.useCallback(
1732
+ async (groupId, request) => {
1733
+ if (!mero) return null;
1734
+ return run(() => mero.admin.setSubgroupVisibility(groupId, request));
1735
+ },
1736
+ [mero, run]
1737
+ );
1738
+ return { setSubgroupVisibility, loading, error };
1739
+ }
1740
+ function useSetTeeAdmissionPolicy() {
1741
+ const { mero } = useMero();
1742
+ const { loading, error, run } = useAsyncMutation();
1743
+ const setTeeAdmissionPolicy = react.useCallback(
1744
+ async (groupId, request) => {
1745
+ if (!mero) return null;
1746
+ return run(() => mero.admin.setTeeAdmissionPolicy(groupId, request));
1747
+ },
1748
+ [mero, run]
1749
+ );
1750
+ return { setTeeAdmissionPolicy, loading, error };
1751
+ }
1752
+ function useUpdateGroupSettings() {
1753
+ const { mero } = useMero();
1754
+ const { loading, error, run } = useAsyncMutation();
1755
+ const updateGroupSettings = react.useCallback(
1756
+ async (groupId, request) => {
1757
+ if (!mero) return null;
1758
+ return run(() => mero.admin.updateGroupSettings(groupId, request));
1759
+ },
1760
+ [mero, run]
1761
+ );
1762
+ return { updateGroupSettings, loading, error };
1763
+ }
1764
+ function useSetGroupAlias() {
1765
+ const { mero } = useMero();
1766
+ const { loading, error, run } = useAsyncMutation();
1767
+ const setGroupAlias = react.useCallback(
1768
+ async (groupId, request) => {
1769
+ if (!mero) return null;
1770
+ return run(() => mero.admin.setGroupAlias(groupId, request));
1771
+ },
1772
+ [mero, run]
1773
+ );
1774
+ return { setGroupAlias, loading, error };
1775
+ }
1776
+ function useSetMemberAlias() {
1777
+ const { mero } = useMero();
1778
+ const { loading, error, run } = useAsyncMutation();
1779
+ const setMemberAlias = react.useCallback(
1780
+ async (groupId, identity, request) => {
1781
+ if (!mero) return null;
1782
+ return run(() => mero.admin.setMemberAlias(groupId, identity, request));
1783
+ },
1784
+ [mero, run]
1785
+ );
1786
+ return { setMemberAlias, loading, error };
1787
+ }
1788
+ function useRegisterGroupSigningKey() {
1789
+ const { mero } = useMero();
1790
+ const { loading, error, run } = useAsyncMutation();
1791
+ const registerGroupSigningKey = react.useCallback(
1792
+ async (groupId, request) => {
1793
+ if (!mero) return null;
1794
+ return run(() => mero.admin.registerGroupSigningKey(groupId, request));
1795
+ },
1796
+ [mero, run]
1797
+ );
1798
+ return { registerGroupSigningKey, loading, error };
1799
+ }
1800
+ function useUpgradeGroup() {
1801
+ const { mero } = useMero();
1802
+ const { loading, error, run } = useAsyncMutation();
1803
+ const upgradeGroup = react.useCallback(
1804
+ async (groupId, request) => {
1805
+ if (!mero) return null;
1806
+ return run(() => mero.admin.upgradeGroup(groupId, request));
1807
+ },
1808
+ [mero, run]
1809
+ );
1810
+ return { upgradeGroup, loading, error };
1811
+ }
1812
+ function useGroupUpgradeStatus(groupId) {
1813
+ const { mero } = useMero();
1814
+ const [upgradeStatus, setUpgradeStatus] = react.useState(null);
1815
+ const [loading, setLoading] = react.useState(false);
1816
+ const [error, setError] = react.useState(null);
1817
+ const mountedRef = useMountedRef();
1818
+ const refetch = react.useCallback(async () => {
1819
+ if (!mero || !groupId) {
1820
+ if (mountedRef.current) {
1821
+ setUpgradeStatus(null);
1822
+ setError(null);
1823
+ setLoading(false);
1824
+ }
1825
+ return;
1826
+ }
1827
+ if (mountedRef.current) {
1828
+ setLoading(true);
1829
+ setError(null);
1830
+ }
1831
+ try {
1832
+ const result = await mero.admin.getGroupUpgradeStatus(groupId);
1833
+ if (mountedRef.current) {
1834
+ setUpgradeStatus(result);
1835
+ }
1836
+ } catch (err) {
1837
+ const errorValue = toError(err);
1838
+ if (mountedRef.current) {
1839
+ setError(errorValue);
1840
+ }
1841
+ } finally {
1842
+ if (mountedRef.current) {
1843
+ setLoading(false);
1844
+ }
1845
+ }
1846
+ }, [groupId, mero, mountedRef]);
1847
+ react.useEffect(() => {
1848
+ void refetch();
1849
+ }, [refetch]);
1850
+ return { upgradeStatus, loading, error, refetch };
1851
+ }
1852
+ function useRetryGroupUpgrade() {
1853
+ const { mero } = useMero();
1854
+ const { loading, error, run } = useAsyncMutation();
1855
+ const retryGroupUpgrade = react.useCallback(
1856
+ async (groupId, request) => {
1857
+ if (!mero) return null;
1858
+ return run(() => mero.admin.retryGroupUpgrade(groupId, request));
1859
+ },
1860
+ [mero, run]
1861
+ );
1862
+ return { retryGroupUpgrade, loading, error };
1863
+ }
1864
+ function useNestGroup() {
1865
+ const { mero } = useMero();
1866
+ const { loading, error, run } = useAsyncMutation();
1867
+ const nestGroup = react.useCallback(
1868
+ async (parentGroupId, request) => {
1869
+ if (!mero) return null;
1870
+ return run(() => mero.admin.nestGroup(parentGroupId, request));
1871
+ },
1872
+ [mero, run]
1873
+ );
1874
+ return { nestGroup, loading, error };
1875
+ }
1876
+ function useUnnestGroup() {
1877
+ const { mero } = useMero();
1878
+ const { loading, error, run } = useAsyncMutation();
1879
+ const unnestGroup = react.useCallback(
1880
+ async (parentGroupId, request) => {
1881
+ if (!mero) return null;
1882
+ return run(() => mero.admin.unnestGroup(parentGroupId, request));
1883
+ },
1884
+ [mero, run]
1885
+ );
1886
+ return { unnestGroup, loading, error };
1887
+ }
1888
+ function useSubgroups(groupId) {
1889
+ const { mero } = useMero();
1890
+ const [subgroups, setSubgroups] = react.useState([]);
1891
+ const [loading, setLoading] = react.useState(false);
1892
+ const [error, setError] = react.useState(null);
1893
+ const mountedRef = useMountedRef();
1894
+ const refetch = react.useCallback(async () => {
1895
+ if (!mero || !groupId) {
1896
+ if (mountedRef.current) {
1897
+ setSubgroups([]);
1898
+ setError(null);
1899
+ setLoading(false);
1900
+ }
1901
+ return;
1902
+ }
1903
+ if (mountedRef.current) {
1904
+ setLoading(true);
1905
+ setError(null);
1906
+ }
1907
+ try {
1908
+ const result = await mero.admin.listSubgroups(groupId);
1909
+ if (mountedRef.current) {
1910
+ setSubgroups(result);
1911
+ }
1912
+ } catch (err) {
1913
+ const errorValue = toError(err);
1914
+ if (mountedRef.current) {
1915
+ setError(errorValue);
1916
+ }
1917
+ } finally {
1918
+ if (mountedRef.current) {
1919
+ setLoading(false);
1920
+ }
1921
+ }
1922
+ }, [groupId, mero, mountedRef]);
1923
+ react.useEffect(() => {
1924
+ void refetch();
1925
+ }, [refetch]);
1926
+ return { subgroups, loading, error, refetch };
1927
+ }
1928
+ function useDetachContextFromGroup() {
1929
+ const { mero } = useMero();
1930
+ const { loading, error, run } = useAsyncMutation();
1931
+ const detachContextFromGroup = react.useCallback(
1932
+ async (groupId, contextId, request) => {
1933
+ if (!mero) return null;
1934
+ return run(() => mero.admin.detachContextFromGroup(groupId, contextId, request));
1935
+ },
1936
+ [mero, run]
1937
+ );
1938
+ return { detachContextFromGroup, loading, error };
1939
+ }
471
1940
 
472
1941
  exports.AppMode = AppMode;
1942
+ exports.ConnectButton = ConnectButton;
473
1943
  exports.ConnectionType = ConnectionType;
1944
+ exports.LoginModal = LoginModal;
474
1945
  exports.MeroContext = MeroContext;
475
1946
  exports.MeroProvider = MeroProvider;
476
1947
  exports.clearAllStorage = clearAllStorage;
@@ -487,10 +1958,51 @@ exports.setApplicationId = setApplicationId;
487
1958
  exports.setContextId = setContextId;
488
1959
  exports.setContextIdentity = setContextIdentity;
489
1960
  exports.setNodeUrl = setNodeUrl;
1961
+ exports.useAddGroupMembers = useAddGroupMembers;
1962
+ exports.useApplicationContexts = useApplicationContexts;
1963
+ exports.useContextDiscovery = useContextDiscovery;
1964
+ exports.useContextGroup = useContextGroup;
490
1965
  exports.useContexts = useContexts;
1966
+ exports.useCreateContext = useCreateContext;
1967
+ exports.useCreateGroupInNamespace = useCreateGroupInNamespace;
1968
+ exports.useCreateNamespace = useCreateNamespace;
1969
+ exports.useCreateNamespaceInvitation = useCreateNamespaceInvitation;
1970
+ exports.useDeleteContext = useDeleteContext;
1971
+ exports.useDeleteGroup = useDeleteGroup;
1972
+ exports.useDeleteNamespace = useDeleteNamespace;
1973
+ exports.useDetachContextFromGroup = useDetachContextFromGroup;
491
1974
  exports.useExecute = useExecute;
1975
+ exports.useGroupCapabilities = useGroupCapabilities;
1976
+ exports.useGroupContexts = useGroupContexts;
1977
+ exports.useGroupInfo = useGroupInfo;
1978
+ exports.useGroupInvitations = useGroupInvitations;
1979
+ exports.useGroupMembers = useGroupMembers;
1980
+ exports.useGroupUpgradeStatus = useGroupUpgradeStatus;
1981
+ exports.useJoinContext = useJoinContext;
1982
+ exports.useJoinGroup = useJoinGroup;
1983
+ exports.useJoinNamespace = useJoinNamespace;
492
1984
  exports.useMero = useMero;
1985
+ exports.useNamespace = useNamespace;
1986
+ exports.useNamespaceGroups = useNamespaceGroups;
1987
+ exports.useNamespaceIdentity = useNamespaceIdentity;
1988
+ exports.useNamespaces = useNamespaces;
1989
+ exports.useNamespacesForApplication = useNamespacesForApplication;
1990
+ exports.useNestGroup = useNestGroup;
1991
+ exports.useRegisterGroupSigningKey = useRegisterGroupSigningKey;
1992
+ exports.useRemoveGroupMembers = useRemoveGroupMembers;
1993
+ exports.useRetryGroupUpgrade = useRetryGroupUpgrade;
1994
+ exports.useSetDefaultCapabilities = useSetDefaultCapabilities;
1995
+ exports.useSetGroupAlias = useSetGroupAlias;
1996
+ exports.useSetMemberAlias = useSetMemberAlias;
1997
+ exports.useSetSubgroupVisibility = useSetSubgroupVisibility;
1998
+ exports.useSetTeeAdmissionPolicy = useSetTeeAdmissionPolicy;
1999
+ exports.useSubgroups = useSubgroups;
493
2000
  exports.useSubscription = useSubscription;
2001
+ exports.useSyncGroup = useSyncGroup;
2002
+ exports.useUnnestGroup = useUnnestGroup;
2003
+ exports.useUpdateGroupSettings = useUpdateGroupSettings;
2004
+ exports.useUpdateMemberRole = useUpdateMemberRole;
2005
+ exports.useUpgradeGroup = useUpgradeGroup;
494
2006
  Object.keys(meroJs).forEach(function (k) {
495
2007
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
496
2008
  enumerable: true,