@pol-studios/db 1.0.31 → 1.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/{DataLayerContext-Dc7nF2IG.d.ts → DataLayerContext-BwMk4VpG.d.ts} +92 -8
  2. package/dist/UserMetadataContext-QLIv-mfF.d.ts +171 -0
  3. package/dist/{UserMetadataContext-B8gVWGMl.d.ts → UserMetadataContext-pQb3A8_Q.d.ts} +1 -1
  4. package/dist/auth/context.d.ts +53 -5
  5. package/dist/auth/context.js +30 -8
  6. package/dist/auth/guards.d.ts +9 -9
  7. package/dist/auth/guards.js +2 -3
  8. package/dist/auth/hooks.d.ts +108 -4
  9. package/dist/auth/hooks.js +13 -9
  10. package/dist/auth/index.d.ts +6 -6
  11. package/dist/auth/index.js +45 -17
  12. package/dist/chunk-5HJLTYRA.js +355 -0
  13. package/dist/chunk-5HJLTYRA.js.map +1 -0
  14. package/dist/{chunk-WX4ABYIF.js → chunk-67HMVGV7.js} +292 -94
  15. package/dist/chunk-67HMVGV7.js.map +1 -0
  16. package/dist/chunk-6KN7KLEG.js +1 -0
  17. package/dist/{chunk-FZF26ZRB.js → chunk-7BGDQT5X.js} +29 -16
  18. package/dist/{chunk-FZF26ZRB.js.map → chunk-7BGDQT5X.js.map} +1 -1
  19. package/dist/{chunk-P4UZ7IXC.js → chunk-7D4SUZUM.js} +1 -5
  20. package/dist/{chunk-3PJTNH2L.js → chunk-AKIRHA4Q.js} +2 -2
  21. package/dist/{chunk-OQ7U6EQ3.js → chunk-AML2TLXJ.js} +3801 -3424
  22. package/dist/chunk-AML2TLXJ.js.map +1 -0
  23. package/dist/{chunk-5EFDS7SR.js → chunk-DMVUEJG2.js} +7 -2
  24. package/dist/chunk-DMVUEJG2.js.map +1 -0
  25. package/dist/{chunk-ADD5MIMK.js → chunk-FESQS4S5.js} +15 -15
  26. package/dist/{chunk-ADD5MIMK.js.map → chunk-FESQS4S5.js.map} +1 -1
  27. package/dist/{chunk-U5UNPBKB.js → chunk-FI6JAD5G.js} +3 -3
  28. package/dist/{chunk-TKWR5AAY.js → chunk-JOULSXOI.js} +2 -2
  29. package/dist/{chunk-HTJ2FQW5.js → chunk-LF3V3ERS.js} +13 -15
  30. package/dist/{chunk-HTJ2FQW5.js.map → chunk-LF3V3ERS.js.map} +1 -1
  31. package/dist/{chunk-5BLKZUKM.js → chunk-MREERKQU.js} +45 -14
  32. package/dist/chunk-MREERKQU.js.map +1 -0
  33. package/dist/{chunk-VGEMLNNM.js → chunk-NP34C3O3.js} +306 -704
  34. package/dist/chunk-NP34C3O3.js.map +1 -0
  35. package/dist/{chunk-CNIGRBRE.js → chunk-QJZUIAHA.js} +43 -19
  36. package/dist/{chunk-CNIGRBRE.js.map → chunk-QJZUIAHA.js.map} +1 -1
  37. package/dist/{chunk-HAWJTZCK.js → chunk-RT4O5H2E.js} +5 -7
  38. package/dist/chunk-RT4O5H2E.js.map +1 -0
  39. package/dist/{chunk-2NVSXZKQ.js → chunk-TN7QINPK.js} +74 -309
  40. package/dist/chunk-TN7QINPK.js.map +1 -0
  41. package/dist/chunk-UBHORKBS.js +215 -0
  42. package/dist/chunk-UBHORKBS.js.map +1 -0
  43. package/dist/{chunk-WVF7RUW5.js → chunk-WM25QE7E.js} +3 -3
  44. package/dist/{chunk-H6365JPC.js → chunk-YUX6RGLZ.js} +3 -3
  45. package/dist/{chunk-H6365JPC.js.map → chunk-YUX6RGLZ.js.map} +1 -1
  46. package/dist/{chunk-H3LNH2NT.js → chunk-Z456IHCB.js} +5 -9
  47. package/dist/{chunk-H3LNH2NT.js.map → chunk-Z456IHCB.js.map} +1 -1
  48. package/dist/{chunk-JAATANS3.js → chunk-ZCOFRJQD.js} +3 -3
  49. package/dist/{chunk-JAATANS3.js.map → chunk-ZCOFRJQD.js.map} +1 -1
  50. package/dist/client/index.d.ts +1 -1
  51. package/dist/client/index.js +2 -2
  52. package/dist/core/index.d.ts +54 -31
  53. package/dist/{executor-Br27YZvl.d.ts → executor-YJw4m7Q7.d.ts} +9 -1
  54. package/dist/gen/index.js +1 -1
  55. package/dist/hooks/index.d.ts +3 -22
  56. package/dist/hooks/index.js +12 -9
  57. package/dist/{index-CYFdO0iB.d.ts → index-lveh8qb0.d.ts} +1 -1
  58. package/dist/index.d.ts +38 -10
  59. package/dist/index.js +57 -36
  60. package/dist/index.native.d.ts +19 -13
  61. package/dist/index.native.js +64 -35
  62. package/dist/index.web.d.ts +18 -45
  63. package/dist/index.web.js +58 -49
  64. package/dist/index.web.js.map +1 -1
  65. package/dist/mutation/index.d.ts +2 -2
  66. package/dist/mutation/index.js +5 -5
  67. package/dist/parser/index.js +4 -4
  68. package/dist/powersync-bridge/index.d.ts +18 -3
  69. package/dist/powersync-bridge/index.js +2 -2
  70. package/dist/query/index.d.ts +1 -1
  71. package/dist/query/index.js +7 -8
  72. package/dist/realtime/index.js +7 -9
  73. package/dist/realtime/index.js.map +1 -1
  74. package/dist/types/index.d.ts +3 -3
  75. package/dist/types/index.js +6 -7
  76. package/dist/{useBatchUpsert-9OYjibLh.d.ts → useBatchUpsert-DAkiCNo3.d.ts} +1 -1
  77. package/dist/{useDbCount-Dk0yCKlT.d.ts → useDbCount-DWfYB2iu.d.ts} +16 -2
  78. package/dist/{useResolveFeedback-C1KucfdQ.d.ts → useResolveFeedback-CxLccZKK.d.ts} +197 -93
  79. package/dist/{useSupabase-DvWVuHHE.d.ts → useSupabase-DSZNeXnF.d.ts} +1 -1
  80. package/dist/with-auth/index.d.ts +2 -2
  81. package/dist/with-auth/index.js +46 -33
  82. package/dist/with-auth/index.js.map +1 -1
  83. package/package.json +18 -8
  84. package/dist/UserMetadataContext-DntmpK41.d.ts +0 -33
  85. package/dist/canvas-C4TBBDUL.node +0 -0
  86. package/dist/canvas-ZQNCL7JL.js +0 -1541
  87. package/dist/canvas-ZQNCL7JL.js.map +0 -1
  88. package/dist/chunk-2NVSXZKQ.js.map +0 -1
  89. package/dist/chunk-5BLKZUKM.js.map +0 -1
  90. package/dist/chunk-5EFDS7SR.js.map +0 -1
  91. package/dist/chunk-HAWJTZCK.js.map +0 -1
  92. package/dist/chunk-NSIAAYW3.js +0 -1
  93. package/dist/chunk-O7SETNGD.js +0 -3391
  94. package/dist/chunk-O7SETNGD.js.map +0 -1
  95. package/dist/chunk-OQ7U6EQ3.js.map +0 -1
  96. package/dist/chunk-VGEMLNNM.js.map +0 -1
  97. package/dist/chunk-WX4ABYIF.js.map +0 -1
  98. package/dist/dist-NDNRSNOG.js +0 -521
  99. package/dist/dist-NDNRSNOG.js.map +0 -1
  100. package/dist/pdf-PHXP7RHD.js +0 -20336
  101. package/dist/pdf-PHXP7RHD.js.map +0 -1
  102. /package/dist/{chunk-NSIAAYW3.js.map → chunk-6KN7KLEG.js.map} +0 -0
  103. /package/dist/{chunk-P4UZ7IXC.js.map → chunk-7D4SUZUM.js.map} +0 -0
  104. /package/dist/{chunk-3PJTNH2L.js.map → chunk-AKIRHA4Q.js.map} +0 -0
  105. /package/dist/{chunk-U5UNPBKB.js.map → chunk-FI6JAD5G.js.map} +0 -0
  106. /package/dist/{chunk-TKWR5AAY.js.map → chunk-JOULSXOI.js.map} +0 -0
  107. /package/dist/{chunk-WVF7RUW5.js.map → chunk-WM25QE7E.js.map} +0 -0
@@ -1,18 +1,16 @@
1
1
  import {
2
- useDbUpsert
3
- } from "./chunk-VGEMLNNM.js";
2
+ useDbQuery
3
+ } from "./chunk-UBHORKBS.js";
4
4
  import {
5
- isUsable,
6
- newUuid,
7
- omit
8
- } from "./chunk-OQ7U6EQ3.js";
9
- import {
10
- encode
11
- } from "./chunk-H6365JPC.js";
5
+ buildNormalizedQuery,
6
+ encode,
7
+ useQueriesForTableLoader,
8
+ useUpsertItem
9
+ } from "./chunk-YUX6RGLZ.js";
12
10
  import {
13
11
  typedSupabase,
14
12
  useSupabase
15
- } from "./chunk-5EFDS7SR.js";
13
+ } from "./chunk-DMVUEJG2.js";
16
14
 
17
15
  // src/errors/TimeoutError.ts
18
16
  var TIMEOUT_ERROR_MESSAGE = "Request timed out";
@@ -24,9 +22,10 @@ function isTimeoutError(error) {
24
22
 
25
23
  // src/useDbQuery.ts
26
24
  import { useMemo, useRef } from "react";
25
+ import { omit } from "@pol-studios/utils";
27
26
  import { useQuery } from "@tanstack/react-query";
28
27
  import { useDelayedValue } from "@pol-studios/hooks/state";
29
- function useDbQuery(query, config) {
28
+ function useDbQuery2(query, config) {
30
29
  const queryKey = encode(query, false);
31
30
  const queryKeyString = queryKey.join("-");
32
31
  const debouncedKeyString = useDelayedValue(queryKeyString, 50);
@@ -472,6 +471,7 @@ function usePermissions() {
472
471
  }
473
472
 
474
473
  // src/auth/context/AuthProvider.tsx
474
+ import { isUsable, newUuid } from "@pol-studios/utils";
475
475
  import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3, useState as useState2 } from "react";
476
476
  import { jsx as jsx2 } from "react/jsx-runtime";
477
477
  function getPermissionLevel(action) {
@@ -491,6 +491,9 @@ function getPermissionLevel(action) {
491
491
  }
492
492
  }
493
493
  var profileQuery = typedSupabase?.schema("core").from("Profile").select("*, UserAccess(accessKey), status").single();
494
+ function isNotExpired(expiresAt) {
495
+ return !expiresAt || new Date(expiresAt) > /* @__PURE__ */ new Date();
496
+ }
494
497
  function AuthProvider({
495
498
  children,
496
499
  enableEntityPermissions = false
@@ -577,40 +580,80 @@ function AuthProvider({
577
580
  setUserNeedsChange(false);
578
581
  });
579
582
  }, [userNeedsChange]);
580
- const profileRequest = useDbQuery(supabase.schema("core").from("Profile").select("*, UserAccess(accessKey), status").eq("id", currentUser?.id).limit(1).maybeSingle(), {
581
- enabled: isUsable(currentUser),
582
- crossOrganization: true
583
+ const {
584
+ data: profileData,
585
+ isLoading: profileLoading,
586
+ refetch: refetchProfile
587
+ } = useDbQuery("core.Profile", {
588
+ where: {
589
+ id: currentUser?.id
590
+ },
591
+ enabled: isUsable(currentUser)
583
592
  });
584
- const accessKeysRequest = useDbQuery(supabase.schema("core").rpc("get_user_access_keys", {
585
- user_id: currentUser?.id
586
- }), {
587
- enabled: isUsable(currentUser),
588
- crossOrganization: true
593
+ const profile = profileData?.[0] ?? null;
594
+ const {
595
+ data: directAccess,
596
+ isLoading: directAccessLoading,
597
+ refetch: refetchDirectAccess
598
+ } = useDbQuery("core.UserAccess", {
599
+ where: {
600
+ userId: currentUser?.id
601
+ },
602
+ enabled: isUsable(currentUser)
589
603
  });
590
- const effectivePermissionsRequest = useDbQuery(supabase.schema("core").rpc("get_user_effective_permissions", {
591
- user_id: currentUser?.id
592
- }), {
593
- enabled: isUsable(currentUser),
594
- crossOrganization: true
604
+ const {
605
+ data: userGroups,
606
+ isLoading: userGroupsLoading,
607
+ refetch: refetchUserGroups
608
+ } = useDbQuery("core.UserGroup", {
609
+ where: {
610
+ userId: currentUser?.id
611
+ },
612
+ enabled: isUsable(currentUser)
613
+ });
614
+ const {
615
+ data: groups,
616
+ isLoading: groupsLoading,
617
+ refetch: refetchGroups
618
+ } = useDbQuery("core.Group", {
619
+ where: {
620
+ isActive: 1
621
+ },
622
+ // PowerSync stores booleans as 0/1
623
+ enabled: isUsable(currentUser)
624
+ });
625
+ const groupIds = useMemo3(() => userGroups?.map((ug) => ug.groupId) ?? [], [userGroups]);
626
+ const groupsMap = useMemo3(() => new Map(groups?.map((g) => [g.id, g]) ?? []), [groups]);
627
+ const {
628
+ data: groupAccess,
629
+ isLoading: groupAccessLoading,
630
+ refetch: refetchGroupAccess
631
+ } = useDbQuery("core.GroupAccessKey", {
632
+ where: groupIds.length > 0 ? {
633
+ groupId: {
634
+ in: groupIds
635
+ }
636
+ } : void 0,
637
+ enabled: groupIds.length > 0
595
638
  });
596
- const refetchAccessKeys = useCallback2(() => {
597
- accessKeysRequest.refetch();
598
- }, [accessKeysRequest.refetch]);
599
- const refetchEffectivePermissions = useCallback2(() => {
600
- effectivePermissionsRequest.refetch();
601
- }, [effectivePermissionsRequest.refetch]);
639
+ const refetchAccessData = useCallback2(() => {
640
+ refetchDirectAccess();
641
+ refetchUserGroups();
642
+ refetchGroups();
643
+ refetchGroupAccess();
644
+ }, [refetchDirectAccess, refetchUserGroups, refetchGroups, refetchGroupAccess]);
602
645
  const userGroupIdsRef = useRef3(/* @__PURE__ */ new Set());
603
646
  useEffect2(() => {
604
- if (accessKeysRequest.data) {
605
- const groupIds = /* @__PURE__ */ new Set();
606
- for (const item of accessKeysRequest.data) {
607
- if (item.source === "group" && item.source_id) {
608
- groupIds.add(item.source_id);
647
+ if (userGroups) {
648
+ const groupIdSet = /* @__PURE__ */ new Set();
649
+ for (const ug_0 of userGroups) {
650
+ if (ug_0.groupId) {
651
+ groupIdSet.add(typeof ug_0.groupId === "number" ? ug_0.groupId : parseInt(ug_0.groupId, 10));
609
652
  }
610
653
  }
611
- userGroupIdsRef.current = groupIds;
654
+ userGroupIdsRef.current = groupIdSet;
612
655
  }
613
- }, [accessKeysRequest.data]);
656
+ }, [userGroups]);
614
657
  useEffect2(() => {
615
658
  if (!currentUser?.id) return;
616
659
  const channel = supabase.channel(`user-access-keys-${currentUser.id}`).on("postgres_changes", {
@@ -619,16 +662,14 @@ function AuthProvider({
619
662
  table: "UserAccess",
620
663
  filter: `userId=eq.${currentUser.id}`
621
664
  }, () => {
622
- refetchAccessKeys();
623
- refetchEffectivePermissions();
665
+ refetchAccessData();
624
666
  }).on("postgres_changes", {
625
667
  event: "*",
626
668
  schema: "core",
627
669
  table: "UserGroup",
628
670
  filter: `userId=eq.${currentUser.id}`
629
671
  }, () => {
630
- refetchAccessKeys();
631
- refetchEffectivePermissions();
672
+ refetchAccessData();
632
673
  }).on("postgres_changes", {
633
674
  event: "*",
634
675
  schema: "core",
@@ -636,8 +677,7 @@ function AuthProvider({
636
677
  }, (payload) => {
637
678
  const groupId = payload.new?.groupId || payload.old?.groupId;
638
679
  if (groupId && userGroupIdsRef.current.has(groupId)) {
639
- refetchAccessKeys();
640
- refetchEffectivePermissions();
680
+ refetchAccessData();
641
681
  }
642
682
  }).on("postgres_changes", {
643
683
  event: "UPDATE",
@@ -648,15 +688,14 @@ function AuthProvider({
648
688
  const newActive = payload_0.new?.isActive;
649
689
  const groupId_0 = payload_0.new?.id;
650
690
  if (oldActive !== newActive && groupId_0 && userGroupIdsRef.current.has(groupId_0)) {
651
- refetchAccessKeys();
652
- refetchEffectivePermissions();
691
+ refetchAccessData();
653
692
  }
654
693
  }).subscribe();
655
694
  return () => {
656
695
  channel.unsubscribe();
657
696
  supabase.removeChannel(channel);
658
697
  };
659
- }, [supabase, currentUser?.id, refetchAccessKeys, refetchEffectivePermissions]);
698
+ }, [supabase, currentUser?.id, refetchAccessData]);
660
699
  useEffect2(() => {
661
700
  if (!currentUser?.id) return;
662
701
  const profileChannel = supabase.channel(`profile-status-${currentUser.id}`).on("postgres_changes", {
@@ -670,40 +709,72 @@ function AuthProvider({
670
709
  if (oldStatus === "active" && (newStatus === "archived" || newStatus === "suspended")) {
671
710
  signOutAsync();
672
711
  }
673
- profileRequest.refetch();
712
+ refetchProfile();
674
713
  }).subscribe();
675
714
  return () => {
676
715
  profileChannel.unsubscribe();
677
716
  supabase.removeChannel(profileChannel);
678
717
  };
679
- }, [supabase, currentUser?.id, profileRequest.refetch]);
718
+ }, [supabase, currentUser?.id, refetchProfile]);
719
+ const allAccessKeys = useMemo3(() => {
720
+ const keys = [];
721
+ directAccess?.forEach((a) => {
722
+ if (isNotExpired(a.expiresAt)) {
723
+ keys.push({
724
+ accessKey: a.accessKey,
725
+ effect: a.effect ?? "allow",
726
+ source: "direct",
727
+ expiresAt: a.expiresAt
728
+ });
729
+ }
730
+ });
731
+ const activeGroupIds = new Set(userGroups?.filter((ug_1) => {
732
+ const group = groupsMap.get(ug_1.groupId);
733
+ return group?.isActive === 1 && isNotExpired(ug_1.expiresAt);
734
+ }).map((ug_2) => ug_2.groupId) ?? []);
735
+ groupAccess?.forEach((ga) => {
736
+ if (activeGroupIds.has(ga.groupId) && isNotExpired(ga.expiresAt)) {
737
+ keys.push({
738
+ accessKey: ga.accessKey,
739
+ effect: ga.effect ?? "allow",
740
+ source: "group",
741
+ expiresAt: ga.expiresAt
742
+ });
743
+ }
744
+ });
745
+ return keys;
746
+ }, [directAccess, userGroups, groupsMap, groupAccess]);
680
747
  const combinedAccess = useMemo3(() => {
681
- if (accessKeysRequest.data) {
682
- const uniqueKeys = /* @__PURE__ */ new Set();
683
- for (const item_0 of accessKeysRequest.data) {
684
- if (item_0.access_key) {
685
- uniqueKeys.add(item_0.access_key);
686
- }
748
+ const uniqueKeys = /* @__PURE__ */ new Set();
749
+ for (const item of allAccessKeys) {
750
+ if (item.accessKey && item.effect === "allow") {
751
+ uniqueKeys.add(item.accessKey);
687
752
  }
688
- return Array.from(uniqueKeys);
689
753
  }
690
- return profileRequest.data?.UserAccess?.map((x_3) => x_3.accessKey) || [];
691
- }, [accessKeysRequest.data, profileRequest.data?.UserAccess]);
754
+ return Array.from(uniqueKeys);
755
+ }, [allAccessKeys]);
692
756
  const effectivePermissions = useMemo3(() => {
693
- if (!effectivePermissionsRequest.data) {
694
- return [];
695
- }
696
- return effectivePermissionsRequest.data.map((item_1) => ({
697
- resourceType: item_1.resource_type,
698
- resourceId: item_1.resource_id,
699
- permission: item_1.permission,
700
- permissionLevel: item_1.permission_level,
701
- source: item_1.source,
702
- inheritedFrom: item_1.inherited_from,
703
- expiresAt: item_1.expires_at
704
- }));
705
- }, [effectivePermissionsRequest.data]);
706
- const profileStatus = profileRequest.data?.status;
757
+ const permissions = [];
758
+ for (const item_0 of allAccessKeys) {
759
+ if (item_0.effect !== "allow") continue;
760
+ const parts = item_0.accessKey.split(":");
761
+ if (parts.length === 3) {
762
+ const [resourceType, resourceId, permission] = parts;
763
+ const permissionLevel = getPermissionLevel(permission);
764
+ permissions.push({
765
+ resourceType,
766
+ resourceId,
767
+ permission,
768
+ permissionLevel,
769
+ source: item_0.source,
770
+ inheritedFrom: null,
771
+ expiresAt: item_0.expiresAt ?? null
772
+ });
773
+ }
774
+ }
775
+ return permissions;
776
+ }, [allAccessKeys]);
777
+ const profileStatus = profile?.status;
707
778
  const isArchived = profileStatus === "archived";
708
779
  const isSuspended = profileStatus === "suspended";
709
780
  const hasAccess = useCallback2((key) => {
@@ -712,12 +783,12 @@ function AuthProvider({
712
783
  }
713
784
  const accessGiven = combinedAccess;
714
785
  if (isUsable(accessGiven) === false) return false;
715
- if (accessGiven.includes("owner")) return true;
786
+ if (accessGiven.includes("*:*:*")) return true;
716
787
  if (accessGiven.includes(key)) return true;
717
788
  if (isUsable(key) === false) return true;
718
- const parts = key.split(":");
719
- if (parts.length === 3) {
720
- const [type, id_1, action_0] = parts;
789
+ const parts_0 = key.split(":");
790
+ if (parts_0.length === 3) {
791
+ const [type, id_1, action_0] = parts_0;
721
792
  const requiredLevel = getPermissionLevel(action_0);
722
793
  const hasPermission = effectivePermissions.some((p) => p.resourceType === type && p.resourceId === id_1 && p.permissionLevel >= requiredLevel);
723
794
  if (hasPermission) {
@@ -726,30 +797,149 @@ function AuthProvider({
726
797
  }
727
798
  return false;
728
799
  }, [combinedAccess, effectivePermissions, isArchived, isSuspended]);
800
+ const isAccessLoading = directAccessLoading || userGroupsLoading || groupsLoading || groupAccessLoading;
729
801
  const authStateWithLoading = useMemo3(() => ({
730
802
  hasAccess,
731
803
  user: currentUser,
732
- profile: profileRequest.data,
804
+ profile,
733
805
  access: combinedAccess,
734
806
  effectivePermissions,
735
807
  profileStatus,
736
808
  isArchived,
737
809
  isSuspended,
738
- isLoading: currentUser === null ? false : profileRequest.isLoading || accessKeysRequest.isLoading || effectivePermissionsRequest.isLoading || currentUser === void 0,
810
+ isLoading: currentUser === null ? false : profileLoading || isAccessLoading || currentUser === void 0,
739
811
  signInAsync,
740
812
  signOutAsync,
741
813
  onSignOut,
742
814
  removeOnSignOut,
743
815
  registerAsync,
744
816
  refreshAsync
745
- }), [profileRequest.data, profileRequest.isLoading, accessKeysRequest.data, accessKeysRequest.isLoading, effectivePermissionsRequest.isLoading, currentUser, combinedAccess, effectivePermissions, profileStatus, isArchived, isSuspended, hasAccess]);
817
+ }), [profile, profileLoading, isAccessLoading, currentUser, combinedAccess, effectivePermissions, profileStatus, isArchived, isSuspended, hasAccess]);
746
818
  const content = enableEntityPermissions ? /* @__PURE__ */ jsx2(PermissionProvider, { children }) : children;
747
819
  return /* @__PURE__ */ jsx2(setupAuthContext.Provider, { value: authStateWithLoading, children: content });
748
820
  }
749
821
 
750
822
  // src/auth/context/UserMetadataContext.tsx
751
- import { c as _c } from "react/compiler-runtime";
823
+ import { c as _c2 } from "react/compiler-runtime";
752
824
  import { createContext as createContext3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo4, useState as useState3, useCallback as useCallback3, useRef as useRef4 } from "react";
825
+
826
+ // src/useDbUpsert.ts
827
+ import { c as _c } from "react/compiler-runtime";
828
+ import { useMutation } from "@tanstack/react-query";
829
+ import { isUsable as isUsable2 } from "@pol-studios/utils";
830
+ import { omit as omit2 } from "@pol-studios/utils";
831
+ function useDbUpsert(relation, t0, query, mutationOption) {
832
+ const $ = _c(16);
833
+ let t1;
834
+ if ($[0] !== t0) {
835
+ t1 = t0 === void 0 ? ["id"] : t0;
836
+ $[0] = t0;
837
+ $[1] = t1;
838
+ } else {
839
+ t1 = $[1];
840
+ }
841
+ const primaryKeys = t1;
842
+ const tableName = typeof relation === "object" ? relation.table : relation;
843
+ const schemaName = typeof relation === "object" ? String(relation.schema) : "public";
844
+ const supabase = useSupabase();
845
+ let t2;
846
+ if ($[2] !== primaryKeys) {
847
+ t2 = primaryKeys.map(_temp);
848
+ $[2] = primaryKeys;
849
+ $[3] = t2;
850
+ } else {
851
+ t2 = $[3];
852
+ }
853
+ const primaryKeysAsStrings = t2;
854
+ const t3 = primaryKeysAsStrings;
855
+ const t4 = relation;
856
+ let t5;
857
+ if ($[4] !== t3 || $[5] !== t4) {
858
+ t5 = {
859
+ primaryKeys: t3,
860
+ table: t4,
861
+ schema: "public"
862
+ };
863
+ $[4] = t3;
864
+ $[5] = t4;
865
+ $[6] = t5;
866
+ } else {
867
+ t5 = $[6];
868
+ }
869
+ const upsertItem = useUpsertItem(t5);
870
+ const queriesForTable = useQueriesForTableLoader(tableName);
871
+ let t6;
872
+ if ($[7] !== primaryKeys || $[8] !== primaryKeysAsStrings || $[9] !== queriesForTable || $[10] !== query || $[11] !== schemaName || $[12] !== supabase || $[13] !== tableName || $[14] !== upsertItem) {
873
+ t6 = {
874
+ mutationFn: async (item) => {
875
+ let result = null;
876
+ const selectQuery = buildNormalizedQuery({
877
+ queriesForTable,
878
+ query
879
+ });
880
+ const insert = async function insert2() {
881
+ const keysToFilter = primaryKeys.filter((x) => isUsable2(item[x]) === false);
882
+ const keysToFilterAsStrings = keysToFilter.map(_temp2);
883
+ const response = await supabase.schema(schemaName).from(tableName).insert(omit2(item, keysToFilterAsStrings)).select(query).single();
884
+ if (response.error) {
885
+ throw response.error;
886
+ }
887
+ result = response.data;
888
+ if (result) {
889
+ upsertItem(result);
890
+ }
891
+ };
892
+ const isUpsertable = primaryKeys.every((x_0) => x_0 in item && isUsable2(item[x_0]));
893
+ if (isUpsertable) {
894
+ const query_0 = supabase.schema(schemaName).from(tableName).update(omit2(item, primaryKeysAsStrings));
895
+ primaryKeys.forEach((x_1) => {
896
+ query_0.eq(String(x_1), item[x_1]);
897
+ });
898
+ const queryResponse = await query_0.select(selectQuery?.selectQuery).single();
899
+ console.log("queryResponse", queryResponse, tableName);
900
+ if (queryResponse.status === 406) {
901
+ await insert();
902
+ } else {
903
+ if (queryResponse.error) {
904
+ throw queryResponse.error;
905
+ }
906
+ if (queryResponse.data) {
907
+ result = queryResponse.data;
908
+ if (result) {
909
+ upsertItem(result);
910
+ }
911
+ }
912
+ }
913
+ } else {
914
+ await insert();
915
+ }
916
+ return result;
917
+ }
918
+ };
919
+ $[7] = primaryKeys;
920
+ $[8] = primaryKeysAsStrings;
921
+ $[9] = queriesForTable;
922
+ $[10] = query;
923
+ $[11] = schemaName;
924
+ $[12] = supabase;
925
+ $[13] = tableName;
926
+ $[14] = upsertItem;
927
+ $[15] = t6;
928
+ } else {
929
+ t6 = $[15];
930
+ }
931
+ const mutation = useMutation(t6);
932
+ return mutation;
933
+ }
934
+ function _temp2(k_0) {
935
+ return String(k_0);
936
+ }
937
+ function _temp(k) {
938
+ return String(k);
939
+ }
940
+
941
+ // src/auth/context/UserMetadataContext.tsx
942
+ import { isUsable as isUsable3 } from "@pol-studios/utils";
753
943
  import { jsx as jsx3 } from "react/jsx-runtime";
754
944
  var UserMetadataQuery = {
755
945
  schema: "core",
@@ -766,17 +956,22 @@ function UserMetadataProvider({
766
956
  const [error, setError] = useState3(null);
767
957
  const setupAuth = useContext2(setupAuthContext);
768
958
  const userId = setupAuth?.user?.id;
769
- const metadataQuery = useDbQuery(supabase.schema("core").from("UserMetadata").select(UserMetadataQuery.defaultQuery).eq("userId", userId).order("key"), {
770
- enabled: isUsable(userId),
959
+ const metadataQuery = useDbQuery2(supabase.schema("core").from("UserMetadata").select(UserMetadataQuery.defaultQuery).eq("userId", userId).order("key"), {
960
+ enabled: isUsable3(userId),
771
961
  crossOrganization: true
772
962
  });
773
- const upsertMutation = useDbUpsert("UserMetadata", {
774
- invalidateTables: ["UserMetadata"]
775
- });
963
+ const upsertMutation = useDbUpsert(
964
+ {
965
+ table: "UserMetadata",
966
+ schema: "core"
967
+ },
968
+ ["userId", "key"]
969
+ // composite primary keys
970
+ );
776
971
  const upsertMutationRef = useRef4(upsertMutation);
777
972
  upsertMutationRef.current = upsertMutation;
778
973
  useEffect3(() => {
779
- if (metadataQuery.data) {
974
+ if (metadataQuery.data && Array.isArray(metadataQuery.data)) {
780
975
  const metadataMap = {};
781
976
  metadataQuery.data.forEach((item) => {
782
977
  metadataMap[item.key] = item.value;
@@ -789,6 +984,9 @@ function UserMetadataProvider({
789
984
  setIsLoading(false);
790
985
  } else if (metadataQuery.isLoading) {
791
986
  setIsLoading(true);
987
+ } else if (metadataQuery.data && !Array.isArray(metadataQuery.data)) {
988
+ setMetadataState({});
989
+ setIsLoading(false);
792
990
  }
793
991
  }, [metadataQuery.data, metadataQuery.error, metadataQuery.isLoading]);
794
992
  const setMetadata = useCallback3(async (key, value) => {
@@ -853,7 +1051,7 @@ function useUserMetadata() {
853
1051
  return context;
854
1052
  }
855
1053
  function useUserMetadataValue(key) {
856
- const $ = _c(3);
1054
+ const $ = _c2(3);
857
1055
  const {
858
1056
  getMetadata
859
1057
  } = useUserMetadata();
@@ -869,7 +1067,7 @@ function useUserMetadataValue(key) {
869
1067
  return t0;
870
1068
  }
871
1069
  function useSetUserMetadata() {
872
- const $ = _c(3);
1070
+ const $ = _c2(3);
873
1071
  const {
874
1072
  setMetadata,
875
1073
  removeMetadata
@@ -889,14 +1087,14 @@ function useSetUserMetadata() {
889
1087
  return t0;
890
1088
  }
891
1089
  function useUserMetadataState(key, defaultValue, options) {
892
- const $ = _c(11);
1090
+ const $ = _c2(11);
893
1091
  const {
894
1092
  metadata,
895
1093
  setMetadata,
896
1094
  isLoading
897
1095
  } = useUserMetadata();
898
- const serialize = options?.serialize ?? _temp;
899
- const deserialize = options?.deserialize ?? _temp2;
1096
+ const serialize = options?.serialize ?? _temp3;
1097
+ const deserialize = options?.deserialize ?? _temp22;
900
1098
  let t0;
901
1099
  bb0: {
902
1100
  const rawValue = metadata[key];
@@ -949,10 +1147,10 @@ function useUserMetadataState(key, defaultValue, options) {
949
1147
  }
950
1148
  return t2;
951
1149
  }
952
- function _temp2(value_0) {
1150
+ function _temp22(value_0) {
953
1151
  return JSON.parse(value_0);
954
1152
  }
955
- function _temp(value) {
1153
+ function _temp3(value) {
956
1154
  return JSON.stringify(value);
957
1155
  }
958
1156
 
@@ -960,7 +1158,7 @@ export {
960
1158
  TIMEOUT_ERROR_MESSAGE,
961
1159
  DEFAULT_QUERY_TIMEOUT,
962
1160
  isTimeoutError,
963
- useDbQuery,
1161
+ useDbQuery2 as useDbQuery,
964
1162
  setupAuthContext,
965
1163
  permissionContext,
966
1164
  entityPermissionContext,
@@ -974,4 +1172,4 @@ export {
974
1172
  useSetUserMetadata,
975
1173
  useUserMetadataState
976
1174
  };
977
- //# sourceMappingURL=chunk-WX4ABYIF.js.map
1175
+ //# sourceMappingURL=chunk-67HMVGV7.js.map