@pol-studios/db 1.0.29 → 1.0.31

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.
@@ -1,4 +1,4 @@
1
- export { c as Profile, P as ProfileStatus, a as SetupAuthContext, S as SetupAuthContextProvider, b as SetupAuthContextProviderProps, s as setupAuthContext } from '../setupAuthContext-Kv-THH-h.js';
1
+ export { P as Profile, a as ProfileStatus, S as SetupAuthContext, b as SetupAuthContextProviderProps, s as setupAuthContext } from '../setupAuthContext-B76nbIP6.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as react from 'react';
4
4
  import { ReactNode } from 'react';
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  AuthProvider,
3
3
  PermissionProvider,
4
- SetupAuthContextProvider,
5
4
  UserMetadataProvider,
6
5
  entityPermissionContext,
7
6
  permissionContext,
@@ -12,8 +11,8 @@ import {
12
11
  useUserMetadataState,
13
12
  useUserMetadataValue,
14
13
  userMetadataContext
15
- } from "../chunk-HHQV2SST.js";
16
- import "../chunk-EKUDGIQZ.js";
14
+ } from "../chunk-WX4ABYIF.js";
15
+ import "../chunk-VGEMLNNM.js";
17
16
  import "../chunk-GC3TBUWE.js";
18
17
  import "../chunk-J4ZVCXZ4.js";
19
18
  import "../chunk-OQ7U6EQ3.js";
@@ -24,7 +23,6 @@ import "../chunk-P4UZ7IXC.js";
24
23
  export {
25
24
  AuthProvider,
26
25
  PermissionProvider,
27
- SetupAuthContextProvider,
28
26
  UserMetadataProvider,
29
27
  entityPermissionContext,
30
28
  permissionContext,
@@ -1,9 +1,9 @@
1
1
  import { User } from '@supabase/supabase-js';
2
- import { a as SetupAuthContext } from '../setupAuthContext-Kv-THH-h.js';
2
+ import { S as SetupAuthContext, E as EffectivePermission } from '../setupAuthContext-B76nbIP6.js';
3
3
  import { d as EntityType, a as EntityAction, b as EntityPermissionCheck } from '../EntityPermissions-DwFt4tUd.js';
4
4
  export { u as useSetUserMetadata, a as useUserMetadata, b as useUserMetadataState, c as useUserMetadataValue } from '../UserMetadataContext-DntmpK41.js';
5
- import 'react/jsx-runtime';
6
5
  import 'react';
6
+ import 'react/jsx-runtime';
7
7
  import '../useSupabase-DvWVuHHE.js';
8
8
  import '@supabase/supabase-js/dist/module/lib/types.js';
9
9
 
@@ -67,6 +67,7 @@ declare function useAuth(): Omit<SetupAuthContext, "user"> & {
67
67
  declare function useSetupAuth(): SetupAuthContext & {
68
68
  hasAccess: (access: string) => boolean;
69
69
  hasEntityAccess: (entityType: EntityType, entityId: number, action: EntityAction) => boolean;
70
+ effectivePermissions: EffectivePermission[];
70
71
  };
71
72
 
72
73
  /**
@@ -11,14 +11,14 @@ import {
11
11
  usePermissionLoading,
12
12
  usePermissionsBatch,
13
13
  useSetupAuth
14
- } from "../chunk-MA4XWGII.js";
14
+ } from "../chunk-5BLKZUKM.js";
15
15
  import {
16
16
  useSetUserMetadata,
17
17
  useUserMetadata,
18
18
  useUserMetadataState,
19
19
  useUserMetadataValue
20
- } from "../chunk-HHQV2SST.js";
21
- import "../chunk-EKUDGIQZ.js";
20
+ } from "../chunk-WX4ABYIF.js";
21
+ import "../chunk-VGEMLNNM.js";
22
22
  import "../chunk-GC3TBUWE.js";
23
23
  import "../chunk-J4ZVCXZ4.js";
24
24
  import "../chunk-OQ7U6EQ3.js";
@@ -1,11 +1,11 @@
1
1
  export { EntityWithPermission, useAuth, useCanCreate, useCanDelete, useCanEdit, useCanShare, useCanView, useInvalidatePermission, usePermission, usePermissionCheck, usePermissionLoading, usePermissionsBatch, useSetupAuth } from './hooks.js';
2
- export { c as Profile, P as ProfileStatus, a as SetupAuthContext, S as SetupAuthContextProvider, b as SetupAuthContextProviderProps, s as setupAuthContext } from '../setupAuthContext-Kv-THH-h.js';
2
+ export { P as Profile, a as ProfileStatus, S as SetupAuthContext, b as SetupAuthContextProviderProps, s as setupAuthContext } from '../setupAuthContext-B76nbIP6.js';
3
3
  export { AuthProvider, AuthProviderProps, EntityPermissionContextValue, PermissionContextValue, PermissionProvider, entityPermissionContext, permissionContext, usePermissions } from './context.js';
4
4
  export { U as UserMetadataContextType, e as UserMetadataInsert, f as UserMetadataProvider, g as UserMetadataRow, h as UserMetadataUpdate, u as useSetUserMetadata, a as useUserMetadata, b as useUserMetadataState, c as useUserMetadataValue, d as userMetadataContext } from '../UserMetadataContext-DntmpK41.js';
5
5
  export { hasAccess, hasAllAccess, hasAllEntityAccess, hasAnyAccess, hasAnyEntityAccess, hasEntityAccess, isEntityAccessDenied, isPermissionLoaded } from './guards.js';
6
6
  export { E as EntityAccessRecord, a as EntityAction, b as EntityPermissionCheck, c as EntityPermissionLevel, d as EntityType, P as PermissionEffect } from '../EntityPermissions-DwFt4tUd.js';
7
7
  import '@supabase/supabase-js';
8
- import 'react/jsx-runtime';
9
8
  import 'react';
9
+ import 'react/jsx-runtime';
10
10
  import '../useSupabase-DvWVuHHE.js';
11
11
  import '@supabase/supabase-js/dist/module/lib/types.js';
@@ -12,11 +12,10 @@ import {
12
12
  usePermissionLoading,
13
13
  usePermissionsBatch,
14
14
  useSetupAuth
15
- } from "../chunk-MA4XWGII.js";
15
+ } from "../chunk-5BLKZUKM.js";
16
16
  import {
17
17
  AuthProvider,
18
18
  PermissionProvider,
19
- SetupAuthContextProvider,
20
19
  UserMetadataProvider,
21
20
  entityPermissionContext,
22
21
  permissionContext,
@@ -27,8 +26,8 @@ import {
27
26
  useUserMetadataState,
28
27
  useUserMetadataValue,
29
28
  userMetadataContext
30
- } from "../chunk-HHQV2SST.js";
31
- import "../chunk-EKUDGIQZ.js";
29
+ } from "../chunk-WX4ABYIF.js";
30
+ import "../chunk-VGEMLNNM.js";
32
31
  import {
33
32
  hasAccess,
34
33
  hasAllAccess,
@@ -49,7 +48,6 @@ import "../chunk-P4UZ7IXC.js";
49
48
  export {
50
49
  AuthProvider,
51
50
  PermissionProvider,
52
- SetupAuthContextProvider,
53
51
  UserMetadataProvider,
54
52
  entityPermissionContext,
55
53
  hasAccess,
@@ -3,11 +3,11 @@ import {
3
3
  createAdapterRegistry,
4
4
  createSupabaseAdapter,
5
5
  stripSchemaPrefix
6
- } from "./chunk-7FY3PMXL.js";
6
+ } from "./chunk-O7SETNGD.js";
7
7
  import {
8
8
  DataLayerCoreContext,
9
9
  DataLayerStatusContext
10
- } from "./chunk-EKUDGIQZ.js";
10
+ } from "./chunk-VGEMLNNM.js";
11
11
  import {
12
12
  QueryExecutor,
13
13
  extractRelationNames,
@@ -5187,4 +5187,4 @@ object-assign/index.js:
5187
5187
  @license MIT
5188
5188
  *)
5189
5189
  */
5190
- //# sourceMappingURL=chunk-P72TCUKH.js.map
5190
+ //# sourceMappingURL=chunk-2NVSXZKQ.js.map
@@ -1,14 +1,13 @@
1
1
  import {
2
2
  permissionContext,
3
3
  setupAuthContext
4
- } from "./chunk-HHQV2SST.js";
4
+ } from "./chunk-WX4ABYIF.js";
5
5
  import {
6
6
  isUsable
7
7
  } from "./chunk-OQ7U6EQ3.js";
8
8
 
9
9
  // src/auth/hooks/useAuth.ts
10
- import { c as _c } from "react/compiler-runtime";
11
- import { useContext } from "react";
10
+ import { useCallback, useContext, useMemo } from "react";
12
11
  function useAuth() {
13
12
  const auth = useContext(setupAuthContext);
14
13
  if (isUsable(auth.user) === false) {
@@ -21,85 +20,49 @@ function useAuth() {
21
20
  }
22
21
  }
23
22
  function useSetupAuth() {
24
- const $ = _c(13);
25
23
  const auth = useContext(setupAuthContext);
26
24
  const entityPermissions = useContext(permissionContext);
27
- let t0;
28
- if ($[0] !== auth.access || $[1] !== auth.isArchived || $[2] !== auth.isSuspended) {
29
- t0 = (key) => {
30
- if (auth.isArchived || auth.isSuspended) {
31
- return false;
32
- }
33
- const accessGiven = auth.access;
34
- if (isUsable(accessGiven) === false) {
35
- return false;
36
- }
37
- if (accessGiven.includes("owner")) {
38
- return true;
39
- }
40
- if (accessGiven.includes(key)) {
41
- return true;
42
- }
43
- if (isUsable(key) === false) {
44
- return true;
45
- }
25
+ const hasAccess = useCallback((key) => {
26
+ if (auth.hasAccess) {
27
+ return auth.hasAccess(key);
28
+ }
29
+ if (auth.isArchived || auth.isSuspended) {
46
30
  return false;
47
- };
48
- $[0] = auth.access;
49
- $[1] = auth.isArchived;
50
- $[2] = auth.isSuspended;
51
- $[3] = t0;
52
- } else {
53
- t0 = $[3];
54
- }
55
- const hasAccess = t0;
56
- let t1;
57
- if ($[4] !== auth.access || $[5] !== auth.isArchived || $[6] !== auth.isSuspended || $[7] !== entityPermissions) {
58
- t1 = (entityType, entityId, action) => {
59
- if (auth.isArchived || auth.isSuspended) {
60
- return false;
61
- }
62
- if (!entityId || entityId <= 0 || !Number.isInteger(entityId)) {
63
- return false;
64
- }
65
- const accessGiven_0 = auth.access;
66
- if (isUsable(accessGiven_0) && accessGiven_0.includes("owner")) {
67
- return true;
68
- }
69
- if (!entityPermissions || typeof entityPermissions.checkPermission !== "function") {
70
- return false;
71
- }
72
- return entityPermissions.checkPermission(entityType, entityId, action);
73
- };
74
- $[4] = auth.access;
75
- $[5] = auth.isArchived;
76
- $[6] = auth.isSuspended;
77
- $[7] = entityPermissions;
78
- $[8] = t1;
79
- } else {
80
- t1 = $[8];
81
- }
82
- const hasEntityAccess = t1;
83
- let t2;
84
- if ($[9] !== auth || $[10] !== hasAccess || $[11] !== hasEntityAccess) {
85
- t2 = {
86
- hasAccess,
87
- hasEntityAccess,
88
- ...auth,
89
- user: auth.user
90
- };
91
- $[9] = auth;
92
- $[10] = hasAccess;
93
- $[11] = hasEntityAccess;
94
- $[12] = t2;
95
- } else {
96
- t2 = $[12];
97
- }
98
- return t2;
31
+ }
32
+ const accessGiven = auth.access;
33
+ if (isUsable(accessGiven) === false) return false;
34
+ if (accessGiven.includes("owner")) return true;
35
+ if (accessGiven.includes(key)) return true;
36
+ if (isUsable(key) === false) return true;
37
+ return false;
38
+ }, [auth.hasAccess, auth.access, auth.isArchived, auth.isSuspended]);
39
+ const hasEntityAccess = useCallback((entityType, entityId, action) => {
40
+ if (auth.isArchived || auth.isSuspended) {
41
+ return false;
42
+ }
43
+ if (!entityId || entityId <= 0 || !Number.isInteger(entityId)) {
44
+ return false;
45
+ }
46
+ const accessGiven_0 = auth.access;
47
+ if (isUsable(accessGiven_0) && accessGiven_0.includes("owner")) {
48
+ return true;
49
+ }
50
+ if (!entityPermissions || typeof entityPermissions.checkPermission !== "function") {
51
+ return false;
52
+ }
53
+ return entityPermissions.checkPermission(entityType, entityId, action);
54
+ }, [auth.access, auth.isArchived, auth.isSuspended, entityPermissions]);
55
+ return useMemo(() => ({
56
+ hasAccess,
57
+ hasEntityAccess,
58
+ ...auth,
59
+ user: auth.user,
60
+ effectivePermissions: auth.effectivePermissions || []
61
+ }), [hasAccess, hasEntityAccess, auth]);
99
62
  }
100
63
 
101
64
  // src/auth/hooks/usePermission.ts
102
- import { c as _c2 } from "react/compiler-runtime";
65
+ import { c as _c } from "react/compiler-runtime";
103
66
  import { useContext as useContext2, useEffect, useMemo as useMemo2 } from "react";
104
67
  function usePermissionContext() {
105
68
  const context = useContext2(permissionContext);
@@ -109,7 +72,7 @@ function usePermissionContext() {
109
72
  return context;
110
73
  }
111
74
  function usePermission(entityType, entityId) {
112
- const $ = _c2(5);
75
+ const $ = _c(5);
113
76
  const {
114
77
  getPermission
115
78
  } = usePermissionContext();
@@ -150,7 +113,7 @@ function usePermission(entityType, entityId) {
150
113
  return t0;
151
114
  }
152
115
  function usePermissionCheck(entityType, entityId, action) {
153
- const $ = _c2(5);
116
+ const $ = _c(5);
154
117
  const {
155
118
  checkPermission
156
119
  } = usePermissionContext();
@@ -244,4 +207,4 @@ export {
244
207
  useInvalidatePermission,
245
208
  usePermissionLoading
246
209
  };
247
- //# sourceMappingURL=chunk-MA4XWGII.js.map
210
+ //# sourceMappingURL=chunk-5BLKZUKM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/hooks/useAuth.ts","../src/auth/hooks/usePermission.ts"],"sourcesContent":["import { isUsable } from \"@pol-studios/utils\";\nimport { useCallback, useContext, useMemo } from \"react\";\nimport { User } from \"@supabase/supabase-js\";\nimport { SetupAuthContext, setupAuthContext, type EffectivePermission } from \"../context/AuthProvider\";\nimport { permissionContext } from \"../context/PermissionContext\";\nimport { EntityAction, EntityType } from \"../types/EntityPermissions\";\n\n// Re-export EffectivePermission type for consumers\nexport type { EffectivePermission };\n\n/**\n * Hook for authenticated users only.\n * Throws an error if the user is not authenticated.\n * Use useSetupAuth() if you need to handle unauthenticated users.\n *\n * @returns Auth context with guaranteed non-null user and hasAccess helper\n * @throws Error if user is not authenticated\n *\n * @example\n * ```tsx\n * function AuthenticatedComponent() {\n * const { user, hasAccess, profile } = useAuth();\n *\n * // user is guaranteed to be non-null\n * console.log(user.id);\n *\n * if (hasAccess('admin')) {\n * return <AdminDashboard />;\n * }\n *\n * return <UserDashboard />;\n * }\n * ```\n */\nexport function useAuth() {\n const auth = useContext(setupAuthContext);\n if (isUsable(auth.user) === false) {\n console.log({\n auth\n });\n throw new Error(\"User must not be null, use useSetupAuth() to use a nullable user.\");\n } else {\n return auth as any;\n }\n}\n\n/**\n * Hook for handling both authenticated and unauthenticated states.\n * Does not throw if user is not authenticated.\n *\n * @returns Auth context with possibly null user, hasAccess, and hasEntityAccess helpers\n *\n * @example\n * ```tsx\n * function FlexibleComponent() {\n * const { user, hasAccess, hasEntityAccess, isLoading } = useSetupAuth();\n *\n * if (isLoading) {\n * return <Spinner />;\n * }\n *\n * if (!user) {\n * return <LoginPrompt />;\n * }\n *\n * // Check global access\n * const isAdmin = hasAccess('admin');\n *\n * // Check entity-level access\n * const canEditProject = hasEntityAccess('Project', 123, 'edit');\n *\n * return <Dashboard />;\n * }\n * ```\n */\nexport function useSetupAuth(): SetupAuthContext & {\n hasAccess: (access: string) => boolean;\n hasEntityAccess: (entityType: EntityType, entityId: number, action: EntityAction) => boolean;\n effectivePermissions: EffectivePermission[];\n} {\n const auth = useContext(setupAuthContext);\n const entityPermissions = useContext(permissionContext);\n\n // Use the context's hasAccess which now includes effective permissions checking\n const hasAccess = useCallback((key: string) => {\n // Delegate to context hasAccess if available (includes effective permissions)\n if (auth.hasAccess) {\n return auth.hasAccess(key);\n }\n\n // Fallback for backward compatibility\n // Archived/suspended users have no access\n if (auth.isArchived || auth.isSuspended) {\n return false;\n }\n const accessGiven = auth.access;\n if (isUsable(accessGiven) === false) return false;\n if (accessGiven.includes(\"owner\")) return true;\n if (accessGiven.includes(key)) return true;\n if (isUsable(key) === false) return true;\n return false;\n }, [auth.hasAccess, auth.access, auth.isArchived, auth.isSuspended]);\n\n /**\n * Check if the current user has access to a specific entity.\n * Owners (users with 'owner' access key) bypass entity permissions entirely.\n * Otherwise, delegates to the PermissionContext for granular permission checks.\n *\n * @param entityType - 'Project' | 'Client' | 'ProjectDatabase'\n * @param entityId - The ID of the entity to check\n * @param action - 'view' | 'adminView' | 'edit' | 'create' | 'delete' | 'share'\n * @returns boolean - true if user has permission for the action on the entity\n */\n const hasEntityAccess = useCallback((entityType: EntityType, entityId: number, action: EntityAction): boolean => {\n // Archived/suspended users have no entity access\n if (auth.isArchived || auth.isSuspended) {\n return false;\n }\n\n // Validate entityId is a valid positive integer\n if (!entityId || entityId <= 0 || !Number.isInteger(entityId)) {\n return false;\n }\n\n // Owners bypass all entity permission checks\n const accessGiven_0 = auth.access;\n if (isUsable(accessGiven_0) && accessGiven_0.includes(\"owner\")) {\n return true;\n }\n\n // If PermissionContext is not available, deny access\n if (!entityPermissions || typeof entityPermissions.checkPermission !== \"function\") {\n return false;\n }\n\n // Delegate to PermissionContext\n return entityPermissions.checkPermission(entityType, entityId, action);\n }, [auth.access, auth.isArchived, auth.isSuspended, entityPermissions]);\n return useMemo(() => ({\n hasAccess,\n hasEntityAccess,\n ...auth,\n user: auth.user,\n effectivePermissions: auth.effectivePermissions || []\n }), [hasAccess, hasEntityAccess, auth]);\n}","import { c as _c } from \"react/compiler-runtime\";\nimport { useContext, useEffect, useMemo } from \"react\";\nimport { permissionContext } from \"../context/PermissionContext\";\nimport { EntityType, EntityAction, EntityPermissionCheck } from \"../types/EntityPermissions\";\n\n// Re-export types for convenience\nexport type { EntityType, EntityAction, EntityPermissionCheck };\n\n/**\n * Hook to get the full PermissionContext\n * @throws Error if used outside of PermissionProvider\n */\nfunction usePermissionContext() {\n const context = useContext(permissionContext);\n if (!context || Object.keys(context).length === 0) {\n throw new Error(\"usePermission hooks must be used within a PermissionProvider\");\n }\n return context;\n}\n\n/**\n * Hook to get full permission info for a single entity\n * @param entityType - 'Project' | 'Client' | 'ProjectDatabase'\n * @param entityId - The ID of the entity (can be undefined for loading states)\n * @returns EntityPermissionCheck with canView, canEdit, etc. and isLoading\n *\n * @example\n * ```tsx\n * function ProjectHeader({ projectId }: { projectId: number }) {\n * const permission = usePermission('Project', projectId);\n *\n * if (permission.isLoading) {\n * return <Spinner />;\n * }\n *\n * return (\n * <div>\n * {permission.canEdit && <EditButton />}\n * {permission.canDelete && <DeleteButton />}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermission(entityType, entityId) {\n const $ = _c(5);\n const {\n getPermission\n } = usePermissionContext();\n let t0;\n bb0: {\n if (entityId === undefined) {\n let t1;\n if ($[0] === Symbol.for(\"react.memo_cache_sentinel\")) {\n t1 = {\n canView: false,\n canAdminView: false,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: null,\n isLoading: true\n };\n $[0] = t1;\n } else {\n t1 = $[0];\n }\n t0 = t1;\n break bb0;\n }\n let t1;\n if ($[1] !== entityId || $[2] !== entityType || $[3] !== getPermission) {\n t1 = getPermission(entityType, entityId);\n $[1] = entityId;\n $[2] = entityType;\n $[3] = getPermission;\n $[4] = t1;\n } else {\n t1 = $[4];\n }\n t0 = t1;\n }\n return t0;\n}\n\n/**\n * Hook to check a single action permission\n * @param entityType - Entity type\n * @param entityId - Entity ID\n * @param action - 'view' | 'adminView' | 'edit' | 'create' | 'delete' | 'share'\n * @returns boolean - true if user has permission for action\n *\n * @example\n * ```tsx\n * function ProjectActions({ projectId }: { projectId: number }) {\n * const canEdit = usePermissionCheck('Project', projectId, 'edit');\n * const canDelete = usePermissionCheck('Project', projectId, 'delete');\n *\n * return (\n * <div>\n * <Button disabled={!canEdit}>Edit</Button>\n * <Button disabled={!canDelete}>Delete</Button>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermissionCheck(entityType, entityId, action) {\n const $ = _c(5);\n const {\n checkPermission\n } = usePermissionContext();\n let t0;\n bb0: {\n if (entityId === undefined) {\n t0 = false;\n break bb0;\n }\n let t1;\n if ($[0] !== action || $[1] !== checkPermission || $[2] !== entityId || $[3] !== entityType) {\n t1 = checkPermission(entityType, entityId, action);\n $[0] = action;\n $[1] = checkPermission;\n $[2] = entityId;\n $[3] = entityType;\n $[4] = t1;\n } else {\n t1 = $[4];\n }\n t0 = t1;\n }\n return t0;\n}\n\n/**\n * Result type for usePermissions batch hook\n */\nexport interface EntityWithPermission {\n type: EntityType;\n id: number;\n permission: EntityPermissionCheck;\n}\n\n/**\n * Hook for batch permission lookup - useful for lists\n * @param entities - Array of { type, id } objects\n * @returns Array of entities with their permissions attached\n *\n * This hook:\n * - Calls prefetchPermissions on mount and when entities change\n * - Returns memoized results\n * - Handles empty arrays gracefully\n *\n * @example\n * ```tsx\n * function ProjectList({ projects }: { projects: Array<{ id: number; name: string }> }) {\n * const entities = projects.map(p => ({ type: 'Project' as const, id: p.id }));\n * const entitiesWithPermissions = usePermissionsBatch(entities);\n *\n * return (\n * <ul>\n * {entitiesWithPermissions.map(({ id, permission }) => {\n * const project = projects.find(p => p.id === id);\n * return (\n * <li key={id}>\n * {project?.name}\n * {permission.canEdit && <EditIcon />}\n * </li>\n * );\n * })}\n * </ul>\n * );\n * }\n * ```\n */\nexport function usePermissionsBatch(entities: Array<{\n type: EntityType;\n id: number;\n}>): EntityWithPermission[] {\n const {\n getPermission,\n prefetchPermissions\n } = usePermissionContext();\n\n // Memoize the entities array to prevent unnecessary re-renders\n const entitiesKey = useMemo(() => entities.map(e => `${e.type}:${e.id}`).sort().join(\",\"), [entities]);\n\n // Prefetch permissions when entities change\n useEffect(() => {\n if (entities.length === 0) {\n return;\n }\n\n // Convert to the format expected by prefetchPermissions\n const entitiesToPrefetch = entities.map(e_0 => ({\n entityType: e_0.type,\n entityId: e_0.id\n }));\n prefetchPermissions(entitiesToPrefetch);\n }, [entities, entitiesKey, prefetchPermissions]);\n\n // Return memoized results\n return useMemo(() => {\n if (entities.length === 0) {\n return [];\n }\n return entities.map(entity => ({\n type: entity.type,\n id: entity.id,\n permission: getPermission(entity.type, entity.id)\n }));\n }, [getPermission, entitiesKey]);\n}\n\n/**\n * Simple boolean hook to check if user can view an entity\n * @param entityType - Entity type\n * @param entityId - Entity ID (can be undefined for loading states)\n * @returns boolean - true if user can view the entity\n *\n * @example\n * ```tsx\n * function ProjectPage({ projectId }: { projectId: number }) {\n * const canView = useCanView('Project', projectId);\n *\n * if (!canView) {\n * return <AccessDenied />;\n * }\n *\n * return <ProjectContent projectId={projectId} />;\n * }\n * ```\n */\nexport function useCanView(entityType, entityId) {\n return usePermissionCheck(entityType, entityId, \"view\");\n}\n\n/**\n * Simple boolean hook to check if user can edit an entity\n * @param entityType - Entity type\n * @param entityId - Entity ID (can be undefined for loading states)\n * @returns boolean - true if user can edit the entity\n *\n * @example\n * ```tsx\n * function ProjectEditor({ projectId }: { projectId: number }) {\n * const canEdit = useCanEdit('Project', projectId);\n *\n * return (\n * <form>\n * <input disabled={!canEdit} />\n * <button disabled={!canEdit}>Save</button>\n * </form>\n * );\n * }\n * ```\n */\nexport function useCanEdit(entityType, entityId) {\n return usePermissionCheck(entityType, entityId, \"edit\");\n}\n\n/**\n * Simple boolean hook to check if user can delete an entity\n * @param entityType - Entity type\n * @param entityId - Entity ID (can be undefined for loading states)\n * @returns boolean - true if user can delete the entity\n *\n * @example\n * ```tsx\n * function ProjectActions({ projectId }: { projectId: number }) {\n * const canDelete = useCanDelete('Project', projectId);\n *\n * return (\n * <Button\n * variant=\"destructive\"\n * disabled={!canDelete}\n * onClick={handleDelete}\n * >\n * Delete Project\n * </Button>\n * );\n * }\n * ```\n */\nexport function useCanDelete(entityType, entityId) {\n return usePermissionCheck(entityType, entityId, \"delete\");\n}\n\n/**\n * Simple boolean hook to check if user can share an entity\n * @param entityType - Entity type\n * @param entityId - Entity ID (can be undefined for loading states)\n * @returns boolean - true if user can share the entity\n *\n * @example\n * ```tsx\n * function ShareButton({ projectId }: { projectId: number }) {\n * const canShare = useCanShare('Project', projectId);\n *\n * if (!canShare) {\n * return null;\n * }\n *\n * return <Button onClick={openShareModal}>Share</Button>;\n * }\n * ```\n */\nexport function useCanShare(entityType, entityId) {\n return usePermissionCheck(entityType, entityId, \"share\");\n}\n\n/**\n * Simple boolean hook to check if user can create entities of a type\n * Note: For create permission, the entityId should be the parent entity ID\n * (e.g., for creating a ProjectDatabase, pass the Project ID)\n *\n * @param entityType - Entity type\n * @param entityId - Parent entity ID (can be undefined for loading states)\n * @returns boolean - true if user can create entities\n *\n * @example\n * ```tsx\n * function AddDatabaseButton({ projectId }: { projectId: number }) {\n * const canCreate = useCanCreate('ProjectDatabase', projectId);\n *\n * return (\n * <Button disabled={!canCreate} onClick={handleCreate}>\n * Add Database\n * </Button>\n * );\n * }\n * ```\n */\nexport function useCanCreate(entityType, entityId) {\n return usePermissionCheck(entityType, entityId, \"create\");\n}\n\n/**\n * Hook to invalidate permission cache for a specific entity\n * Useful after permission changes (e.g., after sharing an entity)\n *\n * @returns Function to invalidate permission for an entity\n *\n * @example\n * ```tsx\n * function ShareModal({ projectId }: { projectId: number }) {\n * const invalidatePermission = useInvalidatePermission();\n *\n * const handleShare = async (userId: string) => {\n * await shareProject(projectId, userId);\n * invalidatePermission('Project', projectId);\n * };\n *\n * return <ShareForm onShare={handleShare} />;\n * }\n * ```\n */\nexport function useInvalidatePermission() {\n const {\n invalidatePermission\n } = usePermissionContext();\n return invalidatePermission;\n}\n\n/**\n * Hook to get the loading state of the permission context\n * @returns boolean - true if permissions are being fetched\n *\n * @example\n * ```tsx\n * function PermissionAwareComponent() {\n * const isLoadingPermissions = usePermissionLoading();\n *\n * if (isLoadingPermissions) {\n * return <LoadingSpinner />;\n * }\n *\n * return <Content />;\n * }\n * ```\n */\nexport function usePermissionLoading() {\n const {\n isLoading\n } = usePermissionContext();\n return isLoading;\n}"],"mappings":"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","names":["useContext","useMemo","useContext","t1","useMemo"]}
@@ -3,13 +3,13 @@ import {
3
3
  } from "./chunk-SM73S2DY.js";
4
4
  import {
5
5
  useSetupAuth
6
- } from "./chunk-MA4XWGII.js";
6
+ } from "./chunk-5BLKZUKM.js";
7
7
  import {
8
8
  useDbQuery
9
- } from "./chunk-HHQV2SST.js";
9
+ } from "./chunk-WX4ABYIF.js";
10
10
  import {
11
11
  useDbUpsert
12
- } from "./chunk-EKUDGIQZ.js";
12
+ } from "./chunk-VGEMLNNM.js";
13
13
  import {
14
14
  delay,
15
15
  isNullOrWhitespace,
@@ -467,4 +467,4 @@ export {
467
467
  useSetUserMetadata,
468
468
  useUserMetadataState
469
469
  };
470
- //# sourceMappingURL=chunk-NGV7K5JD.js.map
470
+ //# sourceMappingURL=chunk-ADD5MIMK.js.map
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-7SCJNYTE.js";
7
7
  import {
8
8
  useDbQuery
9
- } from "./chunk-HHQV2SST.js";
9
+ } from "./chunk-WX4ABYIF.js";
10
10
  import {
11
11
  useDbUpsert
12
- } from "./chunk-EKUDGIQZ.js";
12
+ } from "./chunk-VGEMLNNM.js";
13
13
  import {
14
14
  getSupabaseUrl
15
15
  } from "./chunk-GC3TBUWE.js";
@@ -3388,4 +3388,4 @@ export {
3388
3388
  useApplyFeedback,
3389
3389
  useResolveFeedback
3390
3390
  };
3391
- //# sourceMappingURL=chunk-7FY3PMXL.js.map
3391
+ //# sourceMappingURL=chunk-O7SETNGD.js.map
@@ -1502,6 +1502,7 @@ try {
1502
1502
  }
1503
1503
  var failedUploadListeners = /* @__PURE__ */ new Set();
1504
1504
  var cachedFailedUploads = [];
1505
+ var EMPTY_FAILED_UPLOADS = [];
1505
1506
  function subscribeToFailedUploads(callback) {
1506
1507
  failedUploadListeners.add(callback);
1507
1508
  return () => {
@@ -1510,7 +1511,7 @@ function subscribeToFailedUploads(callback) {
1510
1511
  }
1511
1512
  function getFailedUploadsSnapshot() {
1512
1513
  if (!failedUploadStore) {
1513
- return [];
1514
+ return EMPTY_FAILED_UPLOADS;
1514
1515
  }
1515
1516
  const uploads = failedUploadStore.getAll();
1516
1517
  if (uploads.length !== cachedFailedUploads.length || uploads.some((u, i) => u.id !== cachedFailedUploads[i]?.id)) {
@@ -1661,7 +1662,7 @@ function _temp2() {
1661
1662
  notifyFailedUploadListeners();
1662
1663
  }
1663
1664
  function _temp() {
1664
- return [];
1665
+ return EMPTY_FAILED_UPLOADS;
1665
1666
  }
1666
1667
 
1667
1668
  // src/hooks/useOnlineStatus.ts
@@ -1713,4 +1714,4 @@ export {
1713
1714
  useSyncControl,
1714
1715
  useOnlineStatus
1715
1716
  };
1716
- //# sourceMappingURL=chunk-EKUDGIQZ.js.map
1717
+ //# sourceMappingURL=chunk-VGEMLNNM.js.map