@pol-studios/db 1.0.0 → 1.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.
Files changed (45) hide show
  1. package/README.md +434 -0
  2. package/dist/EntityPermissions-DwFt4tUd.d.ts +35 -0
  3. package/dist/FilterConfig-Bt2Ek74z.d.ts +99 -0
  4. package/dist/UserMetadataContext-CeUdM6kV.d.ts +89 -0
  5. package/dist/auth/context.d.ts +47 -0
  6. package/dist/auth/context.js +12791 -0
  7. package/dist/auth/context.js.map +1 -0
  8. package/dist/auth/guards.d.ts +180 -0
  9. package/dist/auth/guards.js +7651 -0
  10. package/dist/auth/guards.js.map +1 -0
  11. package/dist/auth/hooks.d.ts +312 -0
  12. package/dist/auth/hooks.js +10600 -0
  13. package/dist/auth/hooks.js.map +1 -0
  14. package/dist/auth/index.d.ts +10 -0
  15. package/dist/auth/index.js +13035 -0
  16. package/dist/auth/index.js.map +1 -0
  17. package/dist/client/index.d.ts +16 -0
  18. package/dist/core/index.d.ts +508 -0
  19. package/dist/executor-CB4KHyYG.d.ts +507 -0
  20. package/dist/gen/index.d.ts +1099 -0
  21. package/dist/hooks/index.d.ts +6 -0
  22. package/dist/index-CMhJjgef.d.ts +1815 -0
  23. package/dist/index-DNv49L9u.d.ts +8780 -0
  24. package/dist/index.d.ts +1486 -0
  25. package/dist/index.js +10320 -7124
  26. package/dist/index.js.map +1 -1
  27. package/dist/mutation/index.d.ts +58 -0
  28. package/dist/mutation/index.js +4581 -76
  29. package/dist/mutation/index.js.map +1 -1
  30. package/dist/parser/index.d.ts +366 -0
  31. package/dist/parser/index.js +26 -26
  32. package/dist/parser/index.js.map +1 -1
  33. package/dist/query/index.d.ts +723 -0
  34. package/dist/query/index.js +13124 -10324
  35. package/dist/query/index.js.map +1 -1
  36. package/dist/realtime/index.d.ts +44 -0
  37. package/dist/realtime/index.js +13217 -9297
  38. package/dist/realtime/index.js.map +1 -1
  39. package/dist/select-query-parser-CGI40aOg.d.ts +352 -0
  40. package/dist/types/index.d.ts +6 -0
  41. package/dist/types-DjuX1XHy.d.ts +62 -0
  42. package/dist/useBatchUpsert-BHaIk9ID.d.ts +24 -0
  43. package/dist/useDbQuery-C-TL8jY1.d.ts +19 -0
  44. package/dist/useSupabase-DO9kQv2O.d.ts +27 -0
  45. package/package.json +28 -15
package/README.md ADDED
@@ -0,0 +1,434 @@
1
+ # @pol-studios/db
2
+
3
+ > Database layer for React applications with Supabase and PowerSync support
4
+
5
+ A comprehensive database abstraction layer supporting both Supabase (V2 hooks) and PowerSync (V3 hooks) for offline-first applications. Provides React Query integration, realtime subscriptions, mutation hooks, and storage utilities.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add @pol-studios/db
11
+ ```
12
+
13
+ ## Peer Dependencies
14
+
15
+ ```bash
16
+ # Required
17
+ pnpm add react @supabase/supabase-js @tanstack/react-query @pol-studios/auth @pol-studios/hooks
18
+
19
+ # Optional (for React Native / offline-first)
20
+ pnpm add @powersync/react-native @react-native-community/netinfo react-native
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```tsx
26
+ import { SupabaseProvider, useDbQuery, useDbInsert, useDbUpdate, useDbDelete } from "@pol-studios/db";
27
+
28
+ // Wrap your app with the provider
29
+ function App() {
30
+ return (
31
+ <SupabaseProvider url={SUPABASE_URL} anonKey={SUPABASE_ANON_KEY}>
32
+ <QueryClientProvider client={queryClient}>
33
+ <MyApp />
34
+ </QueryClientProvider>
35
+ </SupabaseProvider>
36
+ );
37
+ }
38
+
39
+ // Query data
40
+ function ProjectList() {
41
+ const { data, isLoading } = useDbQuery("projects", {
42
+ select: "*",
43
+ order: { column: "created_at", ascending: false },
44
+ });
45
+
46
+ if (isLoading) return <Loading />;
47
+ return <List items={data} />;
48
+ }
49
+
50
+ // Mutations
51
+ function CreateProject() {
52
+ const insert = useDbInsert("projects");
53
+ const update = useDbUpdate("projects");
54
+ const remove = useDbDelete("projects");
55
+
56
+ const handleCreate = () => {
57
+ insert.mutate({ name: "New Project", status: "active" });
58
+ };
59
+
60
+ const handleUpdate = (id, data) => {
61
+ update.mutate({ id, ...data });
62
+ };
63
+
64
+ const handleDelete = (id) => {
65
+ remove.mutate({ id });
66
+ };
67
+ }
68
+ ```
69
+
70
+ ## Subpath Exports
71
+
72
+ | Path | Description |
73
+ |------|-------------|
74
+ | `@pol-studios/db` | All exports combined |
75
+ | `@pol-studios/db/client` | Supabase client utilities |
76
+ | `@pol-studios/db/core` | Core types and configuration |
77
+ | `@pol-studios/db/query` | Query system utilities |
78
+ | `@pol-studios/db/mutation` | Mutation hooks (batch operations) |
79
+ | `@pol-studios/db/realtime` | Realtime subscription utilities |
80
+ | `@pol-studios/db/parser` | Query parser utilities |
81
+ | `@pol-studios/db/hooks` | V3 hooks (PowerSync) |
82
+ | `@pol-studios/db/types` | TypeScript type definitions |
83
+ | `@pol-studios/db/gen` | Generated entity configurations |
84
+
85
+ ## API Reference
86
+
87
+ ### V2 Hooks (Supabase-based)
88
+
89
+ ```tsx
90
+ import {
91
+ // Query hooks
92
+ useDbQuery,
93
+ useDbInfiniteQuery,
94
+ useDbAdvanceQuery,
95
+ useDbPartialQuery,
96
+ useDbRealtimeQuery,
97
+
98
+ // Mutation hooks
99
+ useDbInsert,
100
+ useDbUpdate,
101
+ useDbDelete,
102
+ useDbUpsert,
103
+ useDbMultiUpsert,
104
+ useDbMultiDelete,
105
+
106
+ // Batch mutations
107
+ useBatchUpsert,
108
+ useBatchDelete,
109
+ } from "@pol-studios/db";
110
+
111
+ // Basic query
112
+ const { data } = useDbQuery("projects", {
113
+ select: "id, name, status",
114
+ filter: { status: "active" },
115
+ order: { column: "name" },
116
+ limit: 10,
117
+ });
118
+
119
+ // Infinite scroll query
120
+ const { data, fetchNextPage, hasNextPage } = useDbInfiniteQuery("projects", {
121
+ select: "*",
122
+ pageSize: 20,
123
+ });
124
+
125
+ // Advanced query with joins
126
+ const { data } = useDbAdvanceQuery("projects", {
127
+ select: "*, tasks(*), owner:profiles(*)",
128
+ filter: { archived: false },
129
+ });
130
+
131
+ // Realtime query (auto-updates on changes)
132
+ const { data } = useDbRealtimeQuery("projects", {
133
+ select: "*",
134
+ filter: { team_id: teamId },
135
+ });
136
+
137
+ // Insert with automatic cache invalidation
138
+ const { mutate: insert } = useDbInsert("projects");
139
+ insert({ name: "New Project" });
140
+
141
+ // Update
142
+ const { mutate: update } = useDbUpdate("projects");
143
+ update({ id: projectId, name: "Updated Name" });
144
+
145
+ // Upsert
146
+ const { mutate: upsert } = useDbUpsert("projects");
147
+ upsert({ id: projectId, name: "Name" }); // Insert or update
148
+
149
+ // Batch operations
150
+ const { mutate: batchUpsert } = useBatchUpsert("projects");
151
+ batchUpsert(projectsArray);
152
+ ```
153
+
154
+ ### V3 Hooks (PowerSync / Offline-first)
155
+
156
+ ```tsx
157
+ import {
158
+ // V3 Query hooks
159
+ useDbQueryV3,
160
+ useDbQueryById,
161
+ useDbInfiniteQueryV3,
162
+ useDbCountV3,
163
+ useAdvanceQuery,
164
+
165
+ // V3 Mutation hooks
166
+ useDbInsertV3,
167
+ useDbUpdateV3,
168
+ useDbDeleteV3,
169
+ useDbUpsertV3,
170
+
171
+ // Sync utilities
172
+ useSyncStatus,
173
+ useSyncControl,
174
+ useOnlineStatus,
175
+ useDataLayer,
176
+ } from "@pol-studios/db";
177
+
178
+ // V3 queries work offline with PowerSync
179
+ const { data } = useDbQueryV3("projects", {
180
+ where: { status: "active" },
181
+ orderBy: { created_at: "desc" },
182
+ });
183
+
184
+ // Get single item by ID
185
+ const { data: project } = useDbQueryById("projects", projectId);
186
+
187
+ // Count query
188
+ const { data: count } = useDbCountV3("projects", {
189
+ where: { status: "active" },
190
+ });
191
+
192
+ // Sync status
193
+ const { isSyncing, lastSyncTime, pendingChanges } = useSyncStatus();
194
+
195
+ // Control sync
196
+ const { startSync, stopSync, forceSync } = useSyncControl();
197
+
198
+ // Online status
199
+ const isOnline = useOnlineStatus();
200
+ ```
201
+
202
+ ### Supabase Client
203
+
204
+ ```tsx
205
+ import {
206
+ useSupabase,
207
+ SupabaseProvider,
208
+ createNewSupabaseClient,
209
+ typedSupabase,
210
+ onSupabaseInitialized,
211
+ setDefaultOptions,
212
+ } from "@pol-studios/db";
213
+
214
+ // Get typed Supabase client
215
+ const supabase = useSupabase();
216
+
217
+ // Direct client creation
218
+ const client = createNewSupabaseClient(url, key);
219
+
220
+ // Typed client for specific database schema
221
+ const typed = typedSupabase(client);
222
+
223
+ // Initialize callback
224
+ onSupabaseInitialized((client) => {
225
+ console.log("Supabase ready");
226
+ });
227
+ ```
228
+
229
+ ### Realtime Subscriptions
230
+
231
+ ```tsx
232
+ import { useDbRealtime, useLiveChangesIndicator, useLiveChangeTracking } from "@pol-studios/db";
233
+
234
+ // Subscribe to table changes
235
+ useDbRealtime("projects", {
236
+ event: "INSERT",
237
+ filter: `team_id=eq.${teamId}`,
238
+ callback: (payload) => {
239
+ console.log("New project:", payload.new);
240
+ },
241
+ });
242
+
243
+ // Track live changes indicator
244
+ const { hasChanges, changeCount } = useLiveChangesIndicator("projects");
245
+
246
+ // Track specific changes
247
+ const { changes, clearChanges } = useLiveChangeTracking("projects", projectId);
248
+ ```
249
+
250
+ ### Storage
251
+
252
+ ```tsx
253
+ import {
254
+ useStorageUrl,
255
+ useStoragePath,
256
+ useStorageUpload,
257
+ useStorageUploadWithEntity,
258
+ useDbUpload,
259
+ } from "@pol-studios/db";
260
+
261
+ // Get public URL for storage path
262
+ const url = useStorageUrl("avatars", "user-123.png");
263
+
264
+ // Generate storage path
265
+ const path = useStoragePath("documents", { entityId, fileName });
266
+
267
+ // Upload file
268
+ const { upload, isUploading, progress } = useStorageUpload("documents");
269
+ await upload(file);
270
+
271
+ // Upload with entity association
272
+ const { upload } = useStorageUploadWithEntity("attachments", {
273
+ entityType: "project",
274
+ entityId: projectId,
275
+ });
276
+ ```
277
+
278
+ ### Utility Hooks
279
+
280
+ ```tsx
281
+ import {
282
+ useAI,
283
+ useReceiptAI,
284
+ useServerAvailability,
285
+ useSearchQuery,
286
+ useAutosaveState,
287
+ useBackgroundTask,
288
+ useToastError,
289
+ useLatestOperationLog,
290
+ useConsent,
291
+ useAccountDeletion,
292
+ useUserStatus,
293
+ useDataExport,
294
+ } from "@pol-studios/db";
295
+
296
+ // AI integration
297
+ const { generate, isLoading } = useAI();
298
+
299
+ // Receipt AI processing
300
+ const { processReceipt } = useReceiptAI();
301
+
302
+ // Server availability check
303
+ const isAvailable = useServerAvailability();
304
+
305
+ // Search with debounce
306
+ const { results, search } = useSearchQuery("projects", { debounce: 300 });
307
+
308
+ // Autosave state
309
+ const [value, setValue, { isDirty, isSaving }] = useAutosaveState(initial, saveFn);
310
+
311
+ // Background task
312
+ const { run, isRunning, progress } = useBackgroundTask(asyncFn);
313
+
314
+ // Error toast integration
315
+ const showError = useToastError();
316
+ ```
317
+
318
+ ### Edge Functions
319
+
320
+ ```tsx
321
+ import { useSupabaseFunction } from "@pol-studios/db";
322
+
323
+ // Call Supabase Edge Functions
324
+ const { invoke, isLoading, data, error } = useSupabaseFunction("process-data");
325
+ await invoke({ input: "value" });
326
+ ```
327
+
328
+ ### Data Layer Provider (V3)
329
+
330
+ ```tsx
331
+ import { DataLayerProvider, useDataLayer } from "@pol-studios/db";
332
+
333
+ // Wrap app for offline-first support
334
+ <DataLayerProvider config={dataLayerConfig}>
335
+ <App />
336
+ </DataLayerProvider>
337
+
338
+ // Access data layer
339
+ const { adapter, isReady, syncStatus } = useDataLayer();
340
+ ```
341
+
342
+ ## TypeScript Types
343
+
344
+ ```tsx
345
+ import type {
346
+ // Database types
347
+ DatabaseTypes,
348
+ TableNames,
349
+ PublicTableNames,
350
+ SchemaNames,
351
+ SchemaTableNames,
352
+
353
+ // Query types
354
+ QueryOptions,
355
+ QueryResult,
356
+ QuerySingleResult,
357
+ WhereClause,
358
+ WhereOperators,
359
+ OrderBy,
360
+
361
+ // Mutation types
362
+ MutationResult,
363
+ MutationHookResult,
364
+ DeleteMutationResult,
365
+ ExtractRow,
366
+ ExtractInsert,
367
+ ExtractUpdate,
368
+
369
+ // V3 types
370
+ DataLayerConfig,
371
+ DataAdapter,
372
+ SyncStatus,
373
+ SyncMode,
374
+ SyncScope,
375
+ SyncControl,
376
+ ConnectionConfig,
377
+
378
+ // Strategy types
379
+ SupabaseStrategy,
380
+ PowerSyncStrategy,
381
+ HybridStrategy,
382
+ CachedStrategy,
383
+ AutoStrategy,
384
+ TableStrategy,
385
+
386
+ // Schema types
387
+ DatabaseSchema,
388
+ TableSchema,
389
+ ColumnInfo,
390
+ ColumnType,
391
+ RelationshipInfo,
392
+ RelationshipType,
393
+
394
+ // Supabase types
395
+ TypedSupabaseClient,
396
+ SupabaseDatabaseTypes,
397
+ UserSessionId,
398
+ } from "@pol-studios/db";
399
+ ```
400
+
401
+ ## Network Utilities
402
+
403
+ ```tsx
404
+ import {
405
+ getOnlineStatus,
406
+ getOnlineStatusSync,
407
+ initializeNetworkMonitoring,
408
+ subscribeToNetworkChanges,
409
+ isReactNative,
410
+ } from "@pol-studios/db";
411
+
412
+ // Check online status
413
+ const isOnline = await getOnlineStatus();
414
+ const isOnlineSync = getOnlineStatusSync();
415
+
416
+ // Initialize network monitoring
417
+ initializeNetworkMonitoring();
418
+
419
+ // Subscribe to network changes
420
+ const unsubscribe = subscribeToNetworkChanges((isOnline) => {
421
+ console.log("Network:", isOnline ? "online" : "offline");
422
+ });
423
+ ```
424
+
425
+ ## Related Packages
426
+
427
+ - [@pol-studios/auth](../auth) - Authentication (required peer dependency)
428
+ - [@pol-studios/hooks](../hooks) - React hooks (required peer dependency)
429
+ - [@pol-studios/utils](../utils) - Utility functions
430
+ - [@pol-studios/features](../features) - Feature modules (uses db)
431
+
432
+ ## License
433
+
434
+ UNLICENSED
@@ -0,0 +1,35 @@
1
+ type EntityType = 'Project' | 'Client' | 'ProjectDatabase';
2
+ type EntityPermissionLevel = 'ReadOnly' | 'AdminReadOnly' | 'ReadWrite' | 'Admin';
3
+ type PermissionEffect = 'allow' | 'deny';
4
+ type EntityAction = 'view' | 'adminView' | 'edit' | 'create' | 'delete' | 'share';
5
+ interface EntityPermissionCheck {
6
+ canView: boolean;
7
+ canAdminView: boolean;
8
+ canEdit: boolean;
9
+ canCreate: boolean;
10
+ canDelete: boolean;
11
+ canShare: boolean;
12
+ permissionLevel: EntityPermissionLevel | null;
13
+ isLoading: boolean;
14
+ /** Whether access was explicitly denied */
15
+ isDenied?: boolean;
16
+ }
17
+ interface EntityAccessRecord {
18
+ id: number;
19
+ userId: string;
20
+ entityType: EntityType;
21
+ entityId: number;
22
+ permission: EntityPermissionLevel;
23
+ /** Permission effect - 'allow' grants access, 'deny' explicitly blocks */
24
+ effect: PermissionEffect;
25
+ inheritedFromClientId?: number | null;
26
+ inheritFromProject?: boolean;
27
+ /** User ID who granted this permission */
28
+ grantedBy?: string | null;
29
+ /** ISO timestamp when permission was granted */
30
+ grantedAt?: string;
31
+ /** ISO timestamp when permission expires, null for never */
32
+ expiresAt?: string | null;
33
+ }
34
+
35
+ export type { EntityAccessRecord as E, PermissionEffect as P, EntityAction as a, EntityPermissionCheck as b, EntityPermissionLevel as c, EntityType as d };
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Unified Filter Configuration Type
3
+ *
4
+ * This is the canonical type for filter configuration across the codebase.
5
+ * Replaces both ValueOption and SimpleFilterConfig.
6
+ */
7
+ type PropertyType = "string" | "number" | "boolean" | "date";
8
+ type ValueForPropertyType<T extends PropertyType> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "date" ? Date : never;
9
+ interface TableInfo {
10
+ tableName: string;
11
+ schemaName?: string;
12
+ outputProperty?: string;
13
+ innerProperty: string;
14
+ innerCast?: string;
15
+ }
16
+ interface SortConfig {
17
+ isSortable?: boolean;
18
+ properties?: string[];
19
+ }
20
+ interface FilterConfigOption<PT extends PropertyType = PropertyType> {
21
+ display: string;
22
+ value: ValueForPropertyType<PT>;
23
+ }
24
+ /**
25
+ * Simple filter clause for WHERE conditions
26
+ * Used in edge function query building
27
+ */
28
+ interface WhereFilter {
29
+ id: string;
30
+ field: string;
31
+ op: string;
32
+ value: string | number | string[] | number[] | boolean | null;
33
+ not?: boolean;
34
+ }
35
+ /**
36
+ * WhereClause can be either:
37
+ * - string: For edge function format like "tagId.eq.5"
38
+ * - WhereFilter: For complex filter objects
39
+ */
40
+ type WhereClause = string | WhereFilter;
41
+ /**
42
+ * Unified FilterConfig - the canonical filter configuration type
43
+ *
44
+ * Uses `field` with dot notation for relationships.
45
+ * Examples: "name", "locationId.name", "locationId.tags.value"
46
+ */
47
+ interface FilterConfig<EntityType = unknown, PT extends PropertyType = PropertyType> {
48
+ /**
49
+ * Field path using dot notation for relationships
50
+ * Examples: "name", "locationId.name", "locationId.tags.value"
51
+ */
52
+ field?: string;
53
+ /** The property name on the entity */
54
+ property?: keyof EntityType | string;
55
+ /** Display label shown in UI */
56
+ display: string;
57
+ /**
58
+ * Data type of the field. Can be inferred from schema when using `field`.
59
+ */
60
+ propertyType?: PT;
61
+ /** Whether this field is searchable via text search (default: true for strings) */
62
+ searchable?: boolean;
63
+ /** Additional WHERE clause for relationship filtering */
64
+ where?: WhereClause;
65
+ /** Relationship configuration for many-to-one joins */
66
+ manyToOneTableInfo?: TableInfo & {
67
+ innerTable?: TableInfo[];
68
+ };
69
+ /** Predefined dropdown options */
70
+ options?: FilterConfigOption<PT>[];
71
+ /** Sort configuration for this field */
72
+ sortOptions?: SortConfig;
73
+ /** Mark as metadata field (custom columns) */
74
+ isMetadata?: boolean;
75
+ /** Hide behind "Show More Filters" button */
76
+ advanced?: boolean;
77
+ /** Show in "Recommended" section */
78
+ recommended?: boolean;
79
+ /** Custom render function for display in filter dropdown */
80
+ renderOption?: (option: FilterConfig<EntityType, PT>) => string;
81
+ }
82
+ /**
83
+ * Group of filter configs for organizing filters in UI
84
+ * Note: Named "Group" to avoid conflict with FilterGroup (AND/OR query groups)
85
+ */
86
+ interface Group {
87
+ /** Title displayed for the group (used as 'label' in some contexts) */
88
+ title: string;
89
+ /** Optional nesting level for UI rendering */
90
+ level?: number;
91
+ /** Hide entire group by default behind "Show More Filters" button */
92
+ advanced?: boolean;
93
+ /** Show this group in the "Recommended" section at the top of the filter dropdown */
94
+ recommended?: boolean;
95
+ /** Child filter configs or nested groups */
96
+ children: (FilterConfig | Group)[];
97
+ }
98
+
99
+ export type { FilterConfigOption as F, Group as G, PropertyType as P, SortConfig as S, TableInfo as T, ValueForPropertyType as V, WhereFilter as W, FilterConfig as a, WhereClause as b };
@@ -0,0 +1,89 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ReactNode } from 'react';
4
+ import { User, SignUpWithPasswordCredentials, AuthTokenResponsePassword } from '@supabase/supabase-js';
5
+ import { D as Database } from './useSupabase-DO9kQv2O.js';
6
+
7
+ type ProfileStatus = "active" | "archived" | "suspended";
8
+ interface SetupAuthContext {
9
+ user?: User | null | undefined;
10
+ isLoading: boolean;
11
+ profile: Profile | null | undefined;
12
+ access: string[];
13
+ /** Whether the profile is archived */
14
+ isArchived: boolean;
15
+ /** Whether the profile is suspended */
16
+ isSuspended: boolean;
17
+ /** The profile status (active, archived, suspended) */
18
+ profileStatus: ProfileStatus | undefined;
19
+ registerAsync: (register: SignUpWithPasswordCredentials) => Promise<any>;
20
+ signInAsync: (username: string, password: string) => Promise<AuthTokenResponsePassword>;
21
+ signOutAsync: () => Promise<any>;
22
+ refreshAsync: () => Promise<void>;
23
+ onSignOut: (action: () => any) => string;
24
+ removeOnSignOut: (id: string) => any;
25
+ hasAccess?: (key: string) => boolean;
26
+ }
27
+ interface Profile {
28
+ id: string;
29
+ email?: string;
30
+ fullName?: string;
31
+ status?: ProfileStatus;
32
+ UserAccess?: Array<{
33
+ accessKey: string;
34
+ }>;
35
+ [key: string]: any;
36
+ }
37
+ declare const setupAuthContext: react.Context<SetupAuthContext>;
38
+ /**
39
+ * Props for SetupAuthContextProvider
40
+ * A simpler provider that takes pre-computed auth state
41
+ */
42
+ interface SetupAuthContextProviderProps {
43
+ children: ReactNode;
44
+ auth: SetupAuthContext;
45
+ }
46
+ /**
47
+ * Simple provider that takes auth state and provides it via context.
48
+ * Use this when you already have the auth state and just need to provide it to children.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * const auth = useSetupAuth();
53
+ * return (
54
+ * <SetupAuthContextProvider auth={auth}>
55
+ * <MyComponent />
56
+ * </SetupAuthContextProvider>
57
+ * );
58
+ * ```
59
+ */
60
+ declare function SetupAuthContextProvider({ children, auth, }: SetupAuthContextProviderProps): react_jsx_runtime.JSX.Element;
61
+
62
+ type UserMetadataRow = Database["core"]["Tables"]["UserMetadata"]["Row"];
63
+ type UserMetadataInsert = Database["core"]["Tables"]["UserMetadata"]["Insert"];
64
+ type UserMetadataUpdate = Database["core"]["Tables"]["UserMetadata"]["Update"];
65
+ interface UserMetadataContextType {
66
+ metadata: Record<string, string>;
67
+ isLoading: boolean;
68
+ error: Error | null;
69
+ setMetadata: (key: string, value: string) => Promise<void>;
70
+ getMetadata: (key: string) => string | undefined;
71
+ removeMetadata: (key: string) => Promise<void>;
72
+ refreshMetadata: () => Promise<void>;
73
+ }
74
+ declare const userMetadataContext: react.Context<UserMetadataContextType>;
75
+ declare function UserMetadataProvider({ children }: {
76
+ children: ReactNode;
77
+ }): react_jsx_runtime.JSX.Element;
78
+ declare function useUserMetadata(): UserMetadataContextType;
79
+ declare function useUserMetadataValue(key: string): string | undefined;
80
+ declare function useSetUserMetadata(): {
81
+ setMetadata: (key: string, value: string) => Promise<void>;
82
+ removeMetadata: (key: string) => Promise<void>;
83
+ };
84
+ declare function useUserMetadataState<T>(key: string, defaultValue: T, options?: {
85
+ serialize?: (value: T) => string;
86
+ deserialize?: (value: string) => T;
87
+ }): [T, (value: T) => Promise<void>, boolean];
88
+
89
+ export { type ProfileStatus as P, SetupAuthContextProvider as S, type UserMetadataContextType as U, type SetupAuthContext as a, type SetupAuthContextProviderProps as b, type Profile as c, useUserMetadata as d, useUserMetadataState as e, useUserMetadataValue as f, userMetadataContext as g, type UserMetadataInsert as h, UserMetadataProvider as i, type UserMetadataRow as j, type UserMetadataUpdate as k, setupAuthContext as s, useSetUserMetadata as u };
@@ -0,0 +1,47 @@
1
+ export { c as Profile, P as ProfileStatus, a as SetupAuthContext, S as SetupAuthContextProvider, b as SetupAuthContextProviderProps, U as UserMetadataContextType, h as UserMetadataInsert, i as UserMetadataProvider, j as UserMetadataRow, k as UserMetadataUpdate, s as setupAuthContext, u as useSetUserMetadata, d as useUserMetadata, e as useUserMetadataState, f as useUserMetadataValue, g as userMetadataContext } from '../UserMetadataContext-CeUdM6kV.js';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+ import { d as EntityType, b as EntityPermissionCheck, a as EntityAction } from '../EntityPermissions-DwFt4tUd.js';
6
+ import '@supabase/supabase-js';
7
+ import '../useSupabase-DO9kQv2O.js';
8
+ import '@supabase/supabase-js/dist/module/lib/types.js';
9
+
10
+ interface AuthProviderProps {
11
+ children: ReactNode;
12
+ /**
13
+ * Enable entity-level permissions system (Project, Client, ProjectDatabase access control).
14
+ * When enabled, wraps children with PermissionProvider.
15
+ * @default false
16
+ */
17
+ enableEntityPermissions?: boolean;
18
+ }
19
+ declare function AuthProvider({ children, enableEntityPermissions, }: AuthProviderProps): react_jsx_runtime.JSX.Element;
20
+
21
+ interface EntityIdentifier {
22
+ entityType: EntityType;
23
+ entityId: number;
24
+ }
25
+ interface PermissionContextValue {
26
+ getPermission: (entityType: EntityType, entityId: number) => EntityPermissionCheck;
27
+ checkPermission: (entityType: EntityType, entityId: number, action: EntityAction) => boolean;
28
+ prefetchPermissions: (entities: EntityIdentifier[]) => Promise<void>;
29
+ invalidatePermission: (entityType: EntityType, entityId: number) => void;
30
+ isLoading: boolean;
31
+ }
32
+ /**
33
+ * @deprecated Use permissionContext instead
34
+ */
35
+ interface EntityPermissionContextValue extends PermissionContextValue {
36
+ }
37
+ declare const permissionContext: react.Context<PermissionContextValue>;
38
+ /**
39
+ * @deprecated Use permissionContext instead
40
+ */
41
+ declare const entityPermissionContext: react.Context<PermissionContextValue>;
42
+ declare function PermissionProvider({ children }: {
43
+ children: ReactNode;
44
+ }): react_jsx_runtime.JSX.Element;
45
+ declare function usePermissions(): PermissionContextValue;
46
+
47
+ export { AuthProvider, type AuthProviderProps, type EntityPermissionContextValue, type PermissionContextValue, PermissionProvider, entityPermissionContext, permissionContext, usePermissions };