suparisma 1.1.2 → 1.2.2

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/README.md CHANGED
@@ -16,6 +16,7 @@ A powerful, typesafe React hook generator for Supabase, driven by your Prisma sc
16
16
  - [Why Suparisma?](#why-suparisma)
17
17
  - [Features](#features)
18
18
  - [Installation](#installation)
19
+ - [React Native / Expo Setup](#react-native--expo-setup)
19
20
  - [Quick Start](#quick-start)
20
21
  - [Detailed Usage](#detailed-usage)
21
22
  - [Basic CRUD Operations](#basic-crud-operations)
@@ -26,6 +27,13 @@ A powerful, typesafe React hook generator for Supabase, driven by your Prisma sc
26
27
  - [Sorting Data](#sorting-data)
27
28
  - [Pagination](#pagination)
28
29
  - [Search Functionality](#search-functionality)
30
+ - [Enabling Search](#enabling-search)
31
+ - [Search Methods](#search-methods)
32
+ - [Basic Search Examples](#basic-search-examples)
33
+ - [JSON Field Search](#json-field-search)
34
+ - [Advanced Search Features](#advanced-search-features)
35
+ - [Real-World Search Examples](#real-world-search-examples)
36
+ - [Search Implementation Details](#search-implementation-details)
29
37
  - [Schema Annotations](#schema-annotations)
30
38
  - [Building UI Components](#building-ui-components)
31
39
  - [Table with Filtering, Sorting, and Pagination](#table-with-filtering-sorting-and-pagination)
@@ -53,7 +61,7 @@ Suparisma bridges this gap by:
53
61
  - Enabling easy **pagination, filtering, and search** on your data
54
62
  - Leveraging both **Prisma** and **Supabase** official SDKs
55
63
  - Respecting **Supabase's auth rules** for secure database access
56
- - Working seamlessly with any React environment (Next.js, Remix, Tanstack Router, etc.)
64
+ - Working seamlessly with any React environment (Next.js, Remix, Tanstack Router, React Native, etc.)
57
65
 
58
66
  ## Features
59
67
 
@@ -63,7 +71,7 @@ Suparisma bridges this gap by:
63
71
  - 🔍 **Full-text search** with configurable annotations *(currently under maintenance)*
64
72
  - 🔢 **Pagination and sorting** built into every hook
65
73
  - 🧩 **Prisma-like API** that feels familiar if you already use Prisma
66
- - 📱 **Works with any React framework** including Next.js, Remix, etc.
74
+ - 📱 **Works with any React framework** including Next.js, Remix, React Native, and Expo
67
75
  - 🛠️ **Simple CLI** to generate hooks with a single command
68
76
 
69
77
  ## Installation
@@ -79,6 +87,110 @@ yarn add suparisma
79
87
  pnpm install suparisma
80
88
  ```
81
89
 
90
+ ## React Native / Expo Setup
91
+
92
+ Suparisma fully supports React Native and Expo projects. Follow these additional steps for mobile development:
93
+
94
+ ### 1. Install Dependencies
95
+
96
+ ```bash
97
+ # Install Suparisma and required dependencies
98
+ pnpm install suparisma @supabase/supabase-js @react-native-async-storage/async-storage react-native-url-polyfill
99
+
100
+ # For UUID generation support (recommended)
101
+ pnpm install react-native-get-random-values
102
+ ```
103
+
104
+ ### 2. Add Polyfills
105
+
106
+ Add these imports at the very top of your app's entry point (e.g., `App.tsx` or `index.js`):
107
+
108
+ ```tsx
109
+ // App.tsx or index.js - Add these at the VERY TOP before any other imports
110
+ import 'react-native-get-random-values'; // Required for UUID generation
111
+ import 'react-native-url-polyfill/auto'; // Required for Supabase
112
+ ```
113
+
114
+ ### 3. Set Environment Variables
115
+
116
+ For **Expo** projects, use the `EXPO_PUBLIC_` prefix in your `.env` file:
117
+
118
+ ```bash
119
+ EXPO_PUBLIC_SUPABASE_URL="https://your-project.supabase.co"
120
+ EXPO_PUBLIC_SUPABASE_ANON_KEY="your-anon-key"
121
+ ```
122
+
123
+ For **bare React Native** projects, use `react-native-dotenv` or similar.
124
+
125
+ ### 4. Generate Hooks for React Native
126
+
127
+ Set the `SUPARISMA_PLATFORM` environment variable when generating:
128
+
129
+ ```bash
130
+ # Generate hooks for React Native / Expo
131
+ SUPARISMA_PLATFORM=react-native npx suparisma generate
132
+ ```
133
+
134
+ Or add it to your `package.json` scripts:
135
+
136
+ ```json
137
+ {
138
+ "scripts": {
139
+ "suparisma:generate": "SUPARISMA_PLATFORM=react-native npx suparisma generate"
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### 5. Use the Hooks
145
+
146
+ The hooks work exactly the same as in web projects:
147
+
148
+ ```tsx
149
+ import React from 'react';
150
+ import { View, Text, FlatList, TouchableOpacity } from 'react-native';
151
+ import useSuparisma from './src/suparisma/generated';
152
+
153
+ function ThingList() {
154
+ const {
155
+ data: things,
156
+ loading,
157
+ error,
158
+ create: createThing
159
+ } = useSuparisma.thing();
160
+
161
+ if (loading) return <Text>Loading...</Text>;
162
+ if (error) return <Text>Error: {error.message}</Text>;
163
+
164
+ return (
165
+ <View>
166
+ <FlatList
167
+ data={things}
168
+ keyExtractor={(item) => item.id}
169
+ renderItem={({ item }) => (
170
+ <Text>{item.name} (Number: {item.someNumber})</Text>
171
+ )}
172
+ />
173
+
174
+ <TouchableOpacity
175
+ onPress={() => createThing({
176
+ name: "New Thing",
177
+ someNumber: Math.floor(Math.random() * 100)
178
+ })}
179
+ >
180
+ <Text>Add Thing</Text>
181
+ </TouchableOpacity>
182
+ </View>
183
+ );
184
+ }
185
+ ```
186
+
187
+ ### Platform Detection
188
+
189
+ The generated Supabase client automatically configures itself for React Native with:
190
+ - **AsyncStorage** for auth persistence
191
+ - **Session detection** disabled (not applicable in mobile)
192
+ - **Auto refresh token** enabled
193
+
82
194
  ## Quick Start
83
195
 
84
196
  1. **Add a Prisma schema**: Ensure you have a valid `prisma/schema.prisma` file in your project
@@ -132,6 +244,7 @@ Note: you can adjust the prisma schema path and the generated files output path
132
244
  ```bash
133
245
  SUPARISMA_PRISMA_SCHEMA_PATH="./prisma/schema.prisma"
134
246
  SUPARISMA_OUTPUT_DIR="./src/suparisma/generated"
247
+ SUPARISMA_PLATFORM="web" # or "react-native" for React Native/Expo projects
135
248
  ```
136
249
  Also make sure to not change any of these generated files directly as **they will always be overwritten**
137
250
 
@@ -622,18 +735,430 @@ const { data, count } = useSuparisma.thing();
622
735
 
623
736
  ### Search Functionality
624
737
 
625
- > ⚠️ **MAINTENANCE NOTICE**: Search functionality is currently under maintenance and may not work as expected. We're working on improvements and will update the documentation once it's fully operational.
738
+ Suparisma provides powerful PostgreSQL full-text search capabilities with automatic RPC function generation and type-safe search methods. Search is enabled per field using annotations in your Prisma schema.
739
+
740
+ #### Enabling Search
741
+
742
+ Add search annotations to your Prisma schema fields:
743
+
744
+ ```prisma
745
+ model Post {
746
+ id String @id @default(uuid())
747
+ // @enableSearch - applies to the next field (inline)
748
+ title String
749
+ // @enableSearch - applies to the next field (standalone)
750
+ content String?
751
+ tags String[]
752
+
753
+ /// @enableSearch - applies to the NEXT field that comes after this comment
754
+ metadata Json?
755
+
756
+ createdAt DateTime @default(now())
757
+ updatedAt DateTime @updatedAt
758
+ }
759
+ ```
760
+
761
+ **Three ways to enable search:**
762
+
763
+ 1. **Inline comment**: `title String // @enableSearch`
764
+ 2. **Standalone comment**: Place `// @enableSearch` on a line above the field
765
+ 3. **Directive comment**: Place `/// @enableSearch` on a line, applies to the next field definition
766
+
767
+ #### Search Methods
768
+
769
+ Every searchable model provides comprehensive search functionality:
770
+
771
+ ```tsx
772
+ const {
773
+ data: posts,
774
+ search: searchPosts,
775
+ loading,
776
+ error
777
+ } = useSuparisma.post();
778
+
779
+ // The search object provides:
780
+ // - queries: SearchQuery[] // Current active search queries
781
+ // - loading: boolean // Search loading state
782
+ // - setQueries: (queries) => void // Set multiple search queries
783
+ // - addQuery: (query) => void // Add a single search query
784
+ // - removeQuery: (field) => void // Remove search by field
785
+ // - clearQueries: () => void // Clear all searches
786
+ // - searchMultiField: (value) => void // Search across all searchable fields
787
+ // - searchField: (field, value) => void // Search specific field
788
+ // - getCurrentSearchTerms: () => string[] // Get terms for highlighting
789
+ // - escapeRegex: (text) => string // Safely escape special characters
790
+ ```
791
+
792
+ #### Basic Search Examples
793
+
794
+ ```tsx
795
+ import useSuparisma from '../generated';
796
+
797
+ function PostSearch() {
798
+ const { data: posts, search: searchPosts } = useSuparisma.post();
799
+
800
+ return (
801
+ <div>
802
+ {/* Search in a specific field */}
803
+ <input
804
+ placeholder="Search titles..."
805
+ onChange={(e) => {
806
+ if (e.target.value.trim()) {
807
+ searchPosts.searchField("title", e.target.value);
808
+ } else {
809
+ searchPosts.clearQueries();
810
+ }
811
+ }}
812
+ />
813
+
814
+ {/* Search across all searchable fields */}
815
+ <input
816
+ placeholder="Search everywhere..."
817
+ onChange={(e) => {
818
+ if (e.target.value.trim()) {
819
+ searchPosts.searchMultiField(e.target.value);
820
+ } else {
821
+ searchPosts.clearQueries();
822
+ }
823
+ }}
824
+ />
825
+
826
+ {/* Display results */}
827
+ {posts?.map(post => (
828
+ <div key={post.id}>
829
+ <h3>{post.title}</h3>
830
+ <p>{post.content}</p>
831
+ </div>
832
+ ))}
833
+ </div>
834
+ );
835
+ }
836
+ ```
837
+
838
+ #### JSON Field Search
839
+
840
+ Suparisma supports full-text search on JSON fields when annotated with `/// @enableSearch`:
841
+
842
+ ```prisma
843
+ model Document {
844
+ id String @id @default(uuid())
845
+ title String // @enableSearch
846
+
847
+ /// @enableSearch - Enable search on the next JSON field
848
+ metadata Json? // Will be searchable as text
849
+
850
+ /// @enableSearch
851
+ content Json? // Complex JSON structures are converted to searchable text
852
+ }
853
+ ```
854
+
855
+ JSON fields are automatically converted to searchable text during indexing:
856
+
857
+ ```tsx
858
+ function DocumentSearch() {
859
+ const { data: documents, search } = useSuparisma.document();
860
+
861
+ return (
862
+ <div>
863
+ {/* Search within JSON metadata */}
864
+ <input
865
+ placeholder="Search metadata..."
866
+ onChange={(e) => {
867
+ if (e.target.value.trim()) {
868
+ search.searchField("metadata", e.target.value);
869
+ } else {
870
+ search.clearQueries();
871
+ }
872
+ }}
873
+ />
874
+
875
+ {/* Search across all fields including JSON */}
876
+ <input
877
+ placeholder="Search everything (including JSON)..."
878
+ onChange={(e) => {
879
+ if (e.target.value.trim()) {
880
+ search.searchMultiField(e.target.value);
881
+ } else {
882
+ search.clearQueries();
883
+ }
884
+ }}
885
+ />
886
+
887
+ {documents?.map(doc => (
888
+ <div key={doc.id}>
889
+ <h3>{doc.title}</h3>
890
+ <pre>{JSON.stringify(doc.metadata, null, 2)}</pre>
891
+ </div>
892
+ ))}
893
+ </div>
894
+ );
895
+ }
896
+ ```
897
+
898
+ **JSON Search Examples:**
899
+ ```tsx
900
+ // Search for documents with specific metadata values
901
+ search.searchField("metadata", "author"); // Finds JSON containing "author"
902
+ search.searchField("content", "typescript"); // Finds JSON containing "typescript"
903
+
904
+ // Multi-field search includes JSON fields
905
+ search.searchMultiField("react tutorial"); // Searches title, metadata, content
906
+ ```
626
907
 
627
- For fields annotated with `// @enableSearch`, you can use full-text search:
908
+ #### Advanced Search Features
628
909
 
910
+ **Multi-word Search with AND Logic**
629
911
  ```tsx
630
- // Search things by name
631
- const { data: searchResults } = useSuparisma.thing({
632
- search: {
633
- query: "cool",
634
- fields: ["name"]
912
+ // Searching "react typescript" finds posts containing BOTH words
913
+ searchPosts.searchField("title", "react typescript");
914
+ // Internally converts to: "react & typescript" for PostgreSQL
915
+ ```
916
+
917
+ **Search Highlighting**
918
+ ```tsx
919
+ function PostList() {
920
+ const { data: posts, search } = useSuparisma.post();
921
+
922
+ // Get current search terms for highlighting
923
+ const searchTerms = search.getCurrentSearchTerms();
924
+
925
+ const highlightText = (text: string, searchTerm: string) => {
926
+ if (!searchTerm) return text;
927
+
928
+ // Use the built-in regex escaping
929
+ const escapedTerm = search.escapeRegex(searchTerm);
930
+ const parts = text.split(new RegExp(`(${escapedTerm})`, 'gi'));
931
+
932
+ return parts.map((part, index) =>
933
+ part.toLowerCase() === searchTerm.toLowerCase() ? (
934
+ <mark key={index} className="bg-yellow-200">{part}</mark>
935
+ ) : part
936
+ );
937
+ };
938
+
939
+ return (
940
+ <div>
941
+ {posts?.map(post => (
942
+ <div key={post.id}>
943
+ <h3>
944
+ {searchTerms.length > 0
945
+ ? highlightText(post.title, searchTerms[0])
946
+ : post.title
947
+ }
948
+ </h3>
949
+ </div>
950
+ ))}
951
+ </div>
952
+ );
953
+ }
954
+ ```
955
+
956
+ **Multiple Search Queries**
957
+ ```tsx
958
+ // Search multiple fields simultaneously
959
+ search.setQueries([
960
+ { field: "title", value: "react" },
961
+ { field: "content", value: "tutorial" }
962
+ ]);
963
+
964
+ // Add individual searches
965
+ search.addQuery({ field: "title", value: "javascript" });
966
+ search.addQuery({ field: "tags", value: "frontend" });
967
+
968
+ // Remove specific search
969
+ search.removeQuery("title");
970
+ ```
971
+
972
+ **Search State Management**
973
+ ```tsx
974
+ function SearchComponent() {
975
+ const { search } = useSuparisma.post();
976
+
977
+ // Monitor search state
978
+ if (search.loading) {
979
+ return <div>Searching...</div>;
635
980
  }
636
- });
981
+
982
+ // Display active searches
983
+ if (search.queries.length > 0) {
984
+ return (
985
+ <div>
986
+ <p>Active searches:</p>
987
+ {search.queries.map((query, index) => (
988
+ <span key={index} className="tag">
989
+ {query.field}: "{query.value}"
990
+ <button onClick={() => search.removeQuery(query.field)}>
991
+ ×
992
+ </button>
993
+ </span>
994
+ ))}
995
+ <button onClick={search.clearQueries}>Clear All</button>
996
+ </div>
997
+ );
998
+ }
999
+
1000
+ return <div>No active searches</div>;
1001
+ }
1002
+ ```
1003
+
1004
+ #### Real-World Search Examples
1005
+
1006
+ **E-commerce Product Search**
1007
+ ```tsx
1008
+ function ProductSearch() {
1009
+ const { data: products, search } = useSuparisma.product();
1010
+ const [searchType, setSearchType] = useState<'name' | 'description' | 'multi'>('multi');
1011
+
1012
+ const handleSearch = (value: string) => {
1013
+ if (!value.trim()) {
1014
+ search.clearQueries();
1015
+ return;
1016
+ }
1017
+
1018
+ switch (searchType) {
1019
+ case 'name':
1020
+ search.searchField('name', value);
1021
+ break;
1022
+ case 'description':
1023
+ search.searchField('description', value);
1024
+ break;
1025
+ case 'multi':
1026
+ search.searchMultiField(value);
1027
+ break;
1028
+ }
1029
+ };
1030
+
1031
+ return (
1032
+ <div>
1033
+ {/* Search type selector */}
1034
+ <div className="search-controls">
1035
+ <select value={searchType} onChange={(e) => setSearchType(e.target.value)}>
1036
+ <option value="multi">Search All Fields</option>
1037
+ <option value="name">Product Name Only</option>
1038
+ <option value="description">Description Only</option>
1039
+ </select>
1040
+
1041
+ <input
1042
+ placeholder={`Search ${searchType === 'multi' ? 'products' : searchType}...`}
1043
+ onChange={(e) => handleSearch(e.target.value)}
1044
+ />
1045
+ </div>
1046
+
1047
+ {/* Results with highlighting */}
1048
+ <div className="results">
1049
+ {search.loading && <div>Searching...</div>}
1050
+ {products?.map(product => (
1051
+ <ProductCard key={product.id} product={product} />
1052
+ ))}
1053
+ </div>
1054
+ </div>
1055
+ );
1056
+ }
1057
+ ```
1058
+
1059
+ **Content Management Search**
1060
+ ```tsx
1061
+ function ArticleSearch() {
1062
+ const { data: articles, search } = useSuparisma.article();
1063
+ const [searchHistory, setSearchHistory] = useState<string[]>([]);
1064
+
1065
+ const performSearch = (term: string) => {
1066
+ if (term.trim()) {
1067
+ search.searchMultiField(term);
1068
+ // Add to history (avoid duplicates)
1069
+ setSearchHistory(prev =>
1070
+ [term, ...prev.filter(t => t !== term)].slice(0, 5)
1071
+ );
1072
+ } else {
1073
+ search.clearQueries();
1074
+ }
1075
+ };
1076
+
1077
+ return (
1078
+ <div>
1079
+ <div className="search-box">
1080
+ <input
1081
+ placeholder="Search articles..."
1082
+ onChange={(e) => performSearch(e.target.value)}
1083
+ onKeyDown={(e) => {
1084
+ if (e.key === 'Escape') {
1085
+ e.currentTarget.value = '';
1086
+ search.clearQueries();
1087
+ }
1088
+ }}
1089
+ />
1090
+
1091
+ {/* Search suggestions from history */}
1092
+ {searchHistory.length > 0 && (
1093
+ <div className="search-history">
1094
+ <small>Recent searches:</small>
1095
+ {searchHistory.map((term, index) => (
1096
+ <button
1097
+ key={index}
1098
+ onClick={() => performSearch(term)}
1099
+ className="suggestion"
1100
+ >
1101
+ {term}
1102
+ </button>
1103
+ ))}
1104
+ </div>
1105
+ )}
1106
+ </div>
1107
+
1108
+ {/* Search stats */}
1109
+ {search.queries.length > 0 && (
1110
+ <div className="search-stats">
1111
+ Found {articles?.length || 0} articles for "{search.getCurrentSearchTerms().join(', ')}"
1112
+ {search.loading && <span> (searching...)</span>}
1113
+ </div>
1114
+ )}
1115
+ </div>
1116
+ );
1117
+ }
1118
+ ```
1119
+
1120
+ #### Search Implementation Details
1121
+
1122
+ **PostgreSQL Full-Text Search**
1123
+ - Uses `to_tsvector` and `to_tsquery` for efficient full-text search
1124
+ - Automatically creates GIN indexes for searchable fields (recommended)
1125
+ - Supports partial matching with prefix search (`:*`)
1126
+ - Multi-word queries use AND logic (`&`) for better precision
1127
+
1128
+ **Generated RPC Functions**
1129
+ Suparisma automatically generates PostgreSQL RPC functions for search:
1130
+ - `search_{model}_by_{field}_prefix` - Single field search
1131
+ - `search_{model}_multi_field` - Multi-field search
1132
+
1133
+ **Performance Considerations**
1134
+ - Search queries are debounced (300ms) to prevent excessive API calls
1135
+ - Results are cached and updated via realtime subscriptions
1136
+ - Large datasets benefit from database-level GIN indexes:
1137
+
1138
+ ```sql
1139
+ -- Recommended indexes for better search performance
1140
+ CREATE INDEX IF NOT EXISTS idx_posts_title_gin
1141
+ ON posts USING gin(to_tsvector('english', title));
1142
+
1143
+ CREATE INDEX IF NOT EXISTS idx_posts_content_gin
1144
+ ON posts USING gin(to_tsvector('english', content));
1145
+ ```
1146
+
1147
+ **Error Handling**
1148
+ ```tsx
1149
+ function SearchWithErrorHandling() {
1150
+ const { data, search, error } = useSuparisma.post();
1151
+
1152
+ useEffect(() => {
1153
+ if (error) {
1154
+ console.error('Search error:', error);
1155
+ // Fallback to basic filtering
1156
+ search.clearQueries();
1157
+ }
1158
+ }, [error]);
1159
+
1160
+ // Component implementation...
1161
+ }
637
1162
  ```
638
1163
 
639
1164
  ## Schema Annotations
@@ -652,18 +1177,24 @@ model AuditLog {
652
1177
 
653
1178
  model Thing {
654
1179
  id String @id @default(uuid())
655
- name String? // @enableSearch - Enable full-text search for this field
656
- description String? // @enableSearch - Can add to multiple fields
1180
+ name String? // @enableSearch - Enable full-text search for this field (inline)
1181
+ // @enableSearch - Enable search for the field above (standalone)
1182
+ description String?
657
1183
  someNumber Int
1184
+
1185
+ /// @enableSearch - Enable search for the NEXT field that comes after this comment
1186
+ metadata Json?
658
1187
  }
659
1188
  ```
660
1189
 
661
1190
  Available annotations:
662
1191
 
663
- | Annotation | Description | Location |
664
- |------------|-------------|----------|
665
- | `@disableRealtime` | Disables real-time updates for this model | Model (before definition) |
666
- | `@enableSearch` | Enables full-text search on this field | Field (after definition) |
1192
+ | Annotation | Description | Location | Example |
1193
+ |------------|-------------|----------|---------|
1194
+ | `@disableRealtime` | Disables real-time updates for this model | Model (before definition) | `// @disableRealtime`<br>`model AuditLog { ... }` |
1195
+ | `// @enableSearch` | Enables full-text search (inline) | Field (after definition) | `name String // @enableSearch` |
1196
+ | `// @enableSearch` | Enables full-text search (standalone) | Line above field | `// @enableSearch`<br>`name String` |
1197
+ | `/// @enableSearch` | Enables full-text search (directive) | Applies to next field | `/// @enableSearch`<br>`metadata Json?` |
667
1198
 
668
1199
  ## Building UI Components
669
1200
 
@@ -866,10 +1397,13 @@ export default function ThingTable() {
866
1397
  |----------|----------|-------------|---------|
867
1398
  | `DATABASE_URL` | Yes | Postgres database URL used by Prisma | `postgresql://user:pass@host:port/db` |
868
1399
  | `DIRECT_URL` | Yes | Direct URL to Postgres DB for realtime setup | `postgresql://user:pass@host:port/db` |
869
- | `NEXT_PUBLIC_SUPABASE_URL` | Yes | Your Supabase project URL | `https://xyz.supabase.co` |
870
- | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Yes | Supabase anonymous key | `eyJh...` |
1400
+ | `NEXT_PUBLIC_SUPABASE_URL` | Yes (Web) | Your Supabase project URL (Next.js) | `https://xyz.supabase.co` |
1401
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Yes (Web) | Supabase anonymous key (Next.js) | `eyJh...` |
1402
+ | `EXPO_PUBLIC_SUPABASE_URL` | Yes (RN) | Your Supabase project URL (Expo) | `https://xyz.supabase.co` |
1403
+ | `EXPO_PUBLIC_SUPABASE_ANON_KEY` | Yes (RN) | Supabase anonymous key (Expo) | `eyJh...` |
871
1404
  | `SUPARISMA_OUTPUT_DIR` | No | Custom output directory | `src/lib/suparisma` |
872
1405
  | `SUPARISMA_PRISMA_SCHEMA_PATH` | No | Custom schema path | `db/schema.prisma` |
1406
+ | `SUPARISMA_PLATFORM` | No | Target platform: `web` or `react-native` | `react-native` |
873
1407
 
874
1408
  ### CLI Commands
875
1409
 
@@ -1039,6 +1573,12 @@ GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO anon;
1039
1573
  ALTER DEFAULT PRIVILEGES IN SCHEMA public
1040
1574
  GRANT USAGE, SELECT ON SEQUENCES TO anon;
1041
1575
  ```
1576
+
1577
+ You could also try debugging on a table, the following is NOT recommended but you can debug permissions given to anon, service_account and give all access to anon key to make sure that's not the issue:
1578
+ ```sql
1579
+ GRANT ALL ON TABLE "(tableName)" TO anon;
1580
+ GRANT ALL ON TABLE "(tableName)" TO authenticated;
1581
+ ```
1042
1582
 
1043
1583
  **"Unknown command: undefined"**
1044
1584