@prabhask5/stellar-engine 1.1.6 → 1.1.8

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 (265) hide show
  1. package/README.md +68 -25
  2. package/dist/actions/remoteChange.d.ts +143 -18
  3. package/dist/actions/remoteChange.d.ts.map +1 -1
  4. package/dist/actions/remoteChange.js +182 -58
  5. package/dist/actions/remoteChange.js.map +1 -1
  6. package/dist/actions/truncateTooltip.d.ts +56 -0
  7. package/dist/actions/truncateTooltip.d.ts.map +1 -0
  8. package/dist/actions/truncateTooltip.js +312 -0
  9. package/dist/actions/truncateTooltip.js.map +1 -0
  10. package/dist/auth/admin.d.ts +40 -3
  11. package/dist/auth/admin.d.ts.map +1 -1
  12. package/dist/auth/admin.js +45 -5
  13. package/dist/auth/admin.js.map +1 -1
  14. package/dist/auth/crypto.d.ts +55 -5
  15. package/dist/auth/crypto.d.ts.map +1 -1
  16. package/dist/auth/crypto.js +58 -5
  17. package/dist/auth/crypto.js.map +1 -1
  18. package/dist/auth/deviceVerification.d.ts +236 -20
  19. package/dist/auth/deviceVerification.d.ts.map +1 -1
  20. package/dist/auth/deviceVerification.js +293 -40
  21. package/dist/auth/deviceVerification.js.map +1 -1
  22. package/dist/auth/displayUtils.d.ts +98 -0
  23. package/dist/auth/displayUtils.d.ts.map +1 -0
  24. package/dist/auth/displayUtils.js +133 -0
  25. package/dist/auth/displayUtils.js.map +1 -0
  26. package/dist/auth/loginGuard.d.ts +108 -14
  27. package/dist/auth/loginGuard.d.ts.map +1 -1
  28. package/dist/auth/loginGuard.js +153 -31
  29. package/dist/auth/loginGuard.js.map +1 -1
  30. package/dist/auth/offlineCredentials.d.ts +132 -15
  31. package/dist/auth/offlineCredentials.d.ts.map +1 -1
  32. package/dist/auth/offlineCredentials.js +167 -23
  33. package/dist/auth/offlineCredentials.js.map +1 -1
  34. package/dist/auth/offlineLogin.d.ts +96 -10
  35. package/dist/auth/offlineLogin.d.ts.map +1 -1
  36. package/dist/auth/offlineLogin.js +82 -15
  37. package/dist/auth/offlineLogin.js.map +1 -1
  38. package/dist/auth/offlineSession.d.ts +83 -9
  39. package/dist/auth/offlineSession.d.ts.map +1 -1
  40. package/dist/auth/offlineSession.js +104 -13
  41. package/dist/auth/offlineSession.js.map +1 -1
  42. package/dist/auth/resolveAuthState.d.ts +70 -8
  43. package/dist/auth/resolveAuthState.d.ts.map +1 -1
  44. package/dist/auth/resolveAuthState.js +142 -46
  45. package/dist/auth/resolveAuthState.js.map +1 -1
  46. package/dist/auth/singleUser.d.ts +390 -37
  47. package/dist/auth/singleUser.d.ts.map +1 -1
  48. package/dist/auth/singleUser.js +505 -133
  49. package/dist/auth/singleUser.js.map +1 -1
  50. package/dist/bin/install-pwa.d.ts +25 -0
  51. package/dist/bin/install-pwa.d.ts.map +1 -0
  52. package/dist/bin/install-pwa.js +2197 -0
  53. package/dist/bin/install-pwa.js.map +1 -0
  54. package/dist/config.d.ts +132 -12
  55. package/dist/config.d.ts.map +1 -1
  56. package/dist/config.js +87 -9
  57. package/dist/config.js.map +1 -1
  58. package/dist/conflicts.d.ts +246 -23
  59. package/dist/conflicts.d.ts.map +1 -1
  60. package/dist/conflicts.js +495 -46
  61. package/dist/conflicts.js.map +1 -1
  62. package/dist/data.d.ts +338 -18
  63. package/dist/data.d.ts.map +1 -1
  64. package/dist/data.js +385 -34
  65. package/dist/data.js.map +1 -1
  66. package/dist/database.d.ts +72 -14
  67. package/dist/database.d.ts.map +1 -1
  68. package/dist/database.js +120 -29
  69. package/dist/database.js.map +1 -1
  70. package/dist/debug.d.ts +77 -1
  71. package/dist/debug.d.ts.map +1 -1
  72. package/dist/debug.js +88 -1
  73. package/dist/debug.js.map +1 -1
  74. package/dist/deviceId.d.ts +38 -7
  75. package/dist/deviceId.d.ts.map +1 -1
  76. package/dist/deviceId.js +68 -10
  77. package/dist/deviceId.js.map +1 -1
  78. package/dist/engine.d.ts +175 -3
  79. package/dist/engine.d.ts.map +1 -1
  80. package/dist/engine.js +831 -110
  81. package/dist/engine.js.map +1 -1
  82. package/dist/entries/actions.d.ts +14 -0
  83. package/dist/entries/actions.d.ts.map +1 -1
  84. package/dist/entries/actions.js +27 -1
  85. package/dist/entries/actions.js.map +1 -1
  86. package/dist/entries/auth.d.ts +16 -0
  87. package/dist/entries/auth.d.ts.map +1 -1
  88. package/dist/entries/auth.js +73 -1
  89. package/dist/entries/auth.js.map +1 -1
  90. package/dist/entries/config.d.ts +12 -0
  91. package/dist/entries/config.d.ts.map +1 -1
  92. package/dist/entries/config.js +18 -1
  93. package/dist/entries/config.js.map +1 -1
  94. package/dist/entries/kit.d.ts +21 -9
  95. package/dist/entries/kit.d.ts.map +1 -1
  96. package/dist/entries/kit.js +57 -8
  97. package/dist/entries/kit.js.map +1 -1
  98. package/dist/entries/stores.d.ts +11 -0
  99. package/dist/entries/stores.d.ts.map +1 -1
  100. package/dist/entries/stores.js +43 -2
  101. package/dist/entries/stores.js.map +1 -1
  102. package/dist/entries/types.d.ts +11 -1
  103. package/dist/entries/types.d.ts.map +1 -1
  104. package/dist/entries/types.js +10 -0
  105. package/dist/entries/types.js.map +1 -1
  106. package/dist/entries/utils.d.ts +7 -1
  107. package/dist/entries/utils.d.ts.map +1 -1
  108. package/dist/entries/utils.js +23 -2
  109. package/dist/entries/utils.js.map +1 -1
  110. package/dist/entries/vite.d.ts +20 -0
  111. package/dist/entries/vite.d.ts.map +1 -0
  112. package/dist/entries/vite.js +26 -0
  113. package/dist/entries/vite.js.map +1 -0
  114. package/dist/index.d.ts +33 -2
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +176 -21
  117. package/dist/index.js.map +1 -1
  118. package/dist/kit/auth.d.ts +80 -0
  119. package/dist/kit/auth.d.ts.map +1 -0
  120. package/dist/kit/auth.js +72 -0
  121. package/dist/kit/auth.js.map +1 -0
  122. package/dist/kit/confirm.d.ts +111 -0
  123. package/dist/kit/confirm.d.ts.map +1 -0
  124. package/dist/kit/confirm.js +169 -0
  125. package/dist/kit/confirm.js.map +1 -0
  126. package/dist/kit/loads.d.ts +189 -0
  127. package/dist/kit/loads.d.ts.map +1 -0
  128. package/dist/kit/loads.js +205 -0
  129. package/dist/kit/loads.js.map +1 -0
  130. package/dist/kit/server.d.ts +175 -0
  131. package/dist/kit/server.d.ts.map +1 -0
  132. package/dist/kit/server.js +297 -0
  133. package/dist/kit/server.js.map +1 -0
  134. package/dist/kit/sw.d.ts +176 -0
  135. package/dist/kit/sw.d.ts.map +1 -0
  136. package/dist/kit/sw.js +320 -0
  137. package/dist/kit/sw.js.map +1 -0
  138. package/dist/queue.d.ts +274 -0
  139. package/dist/queue.d.ts.map +1 -1
  140. package/dist/queue.js +556 -38
  141. package/dist/queue.js.map +1 -1
  142. package/dist/realtime.d.ts +241 -27
  143. package/dist/realtime.d.ts.map +1 -1
  144. package/dist/realtime.js +633 -109
  145. package/dist/realtime.js.map +1 -1
  146. package/dist/runtime/runtimeConfig.d.ts +91 -16
  147. package/dist/runtime/runtimeConfig.d.ts.map +1 -1
  148. package/dist/runtime/runtimeConfig.js +146 -19
  149. package/dist/runtime/runtimeConfig.js.map +1 -1
  150. package/dist/stores/authState.d.ts +150 -11
  151. package/dist/stores/authState.d.ts.map +1 -1
  152. package/dist/stores/authState.js +169 -17
  153. package/dist/stores/authState.js.map +1 -1
  154. package/dist/stores/network.d.ts +39 -0
  155. package/dist/stores/network.d.ts.map +1 -1
  156. package/dist/stores/network.js +169 -16
  157. package/dist/stores/network.js.map +1 -1
  158. package/dist/stores/remoteChanges.d.ts +327 -52
  159. package/dist/stores/remoteChanges.d.ts.map +1 -1
  160. package/dist/stores/remoteChanges.js +337 -75
  161. package/dist/stores/remoteChanges.js.map +1 -1
  162. package/dist/stores/sync.d.ts +130 -0
  163. package/dist/stores/sync.d.ts.map +1 -1
  164. package/dist/stores/sync.js +167 -7
  165. package/dist/stores/sync.js.map +1 -1
  166. package/dist/supabase/auth.d.ts +326 -19
  167. package/dist/supabase/auth.d.ts.map +1 -1
  168. package/dist/supabase/auth.js +374 -26
  169. package/dist/supabase/auth.js.map +1 -1
  170. package/dist/supabase/client.d.ts +79 -6
  171. package/dist/supabase/client.d.ts.map +1 -1
  172. package/dist/supabase/client.js +158 -15
  173. package/dist/supabase/client.js.map +1 -1
  174. package/dist/supabase/validate.d.ts +101 -7
  175. package/dist/supabase/validate.d.ts.map +1 -1
  176. package/dist/supabase/validate.js +117 -8
  177. package/dist/supabase/validate.js.map +1 -1
  178. package/dist/sw/build/vite-plugin.d.ts +74 -0
  179. package/dist/sw/build/vite-plugin.d.ts.map +1 -0
  180. package/dist/sw/build/vite-plugin.js +183 -0
  181. package/dist/sw/build/vite-plugin.js.map +1 -0
  182. package/dist/sw/sw.js +669 -0
  183. package/dist/types.d.ts +150 -45
  184. package/dist/types.d.ts.map +1 -1
  185. package/dist/types.js +12 -10
  186. package/dist/types.js.map +1 -1
  187. package/dist/utils.d.ts +55 -13
  188. package/dist/utils.d.ts.map +1 -1
  189. package/dist/utils.js +83 -22
  190. package/dist/utils.js.map +1 -1
  191. package/package.json +20 -22
  192. package/src/components/DeferredChangesBanner.svelte +477 -0
  193. package/src/components/SyncStatus.svelte +1732 -0
  194. package/dist/crdt/awareness.d.ts +0 -54
  195. package/dist/crdt/awareness.d.ts.map +0 -1
  196. package/dist/crdt/awareness.js +0 -219
  197. package/dist/crdt/awareness.js.map +0 -1
  198. package/dist/crdt/doc.d.ts +0 -56
  199. package/dist/crdt/doc.d.ts.map +0 -1
  200. package/dist/crdt/doc.js +0 -130
  201. package/dist/crdt/doc.js.map +0 -1
  202. package/dist/crdt/index.d.ts +0 -15
  203. package/dist/crdt/index.d.ts.map +0 -1
  204. package/dist/crdt/index.js +0 -20
  205. package/dist/crdt/index.js.map +0 -1
  206. package/dist/crdt/offline.d.ts +0 -91
  207. package/dist/crdt/offline.d.ts.map +0 -1
  208. package/dist/crdt/offline.js +0 -353
  209. package/dist/crdt/offline.js.map +0 -1
  210. package/dist/crdt/sync.d.ts +0 -58
  211. package/dist/crdt/sync.d.ts.map +0 -1
  212. package/dist/crdt/sync.js +0 -399
  213. package/dist/crdt/sync.js.map +0 -1
  214. package/dist/crdt/types.d.ts +0 -62
  215. package/dist/crdt/types.d.ts.map +0 -1
  216. package/dist/crdt/types.js +0 -7
  217. package/dist/crdt/types.js.map +0 -1
  218. package/dist/email/sendEmail.d.ts +0 -31
  219. package/dist/email/sendEmail.d.ts.map +0 -1
  220. package/dist/email/sendEmail.js +0 -39
  221. package/dist/email/sendEmail.js.map +0 -1
  222. package/dist/email/validateSmtp.d.ts +0 -18
  223. package/dist/email/validateSmtp.d.ts.map +0 -1
  224. package/dist/email/validateSmtp.js +0 -33
  225. package/dist/email/validateSmtp.js.map +0 -1
  226. package/dist/entries/crdt.d.ts +0 -3
  227. package/dist/entries/crdt.d.ts.map +0 -1
  228. package/dist/entries/crdt.js +0 -13
  229. package/dist/entries/crdt.js.map +0 -1
  230. package/dist/entries/email.d.ts +0 -4
  231. package/dist/entries/email.d.ts.map +0 -1
  232. package/dist/entries/email.js +0 -4
  233. package/dist/entries/email.js.map +0 -1
  234. package/dist/kit/authPresets.d.ts +0 -28
  235. package/dist/kit/authPresets.d.ts.map +0 -1
  236. package/dist/kit/authPresets.js +0 -23
  237. package/dist/kit/authPresets.js.map +0 -1
  238. package/dist/kit/configEndpoint.d.ts +0 -18
  239. package/dist/kit/configEndpoint.d.ts.map +0 -1
  240. package/dist/kit/configEndpoint.js +0 -27
  241. package/dist/kit/configEndpoint.js.map +0 -1
  242. package/dist/kit/deployEndpoint.d.ts +0 -22
  243. package/dist/kit/deployEndpoint.d.ts.map +0 -1
  244. package/dist/kit/deployEndpoint.js +0 -79
  245. package/dist/kit/deployEndpoint.js.map +0 -1
  246. package/dist/kit/layoutLoad.d.ts +0 -23
  247. package/dist/kit/layoutLoad.d.ts.map +0 -1
  248. package/dist/kit/layoutLoad.js +0 -41
  249. package/dist/kit/layoutLoad.js.map +0 -1
  250. package/dist/kit/protectedLoad.d.ts +0 -16
  251. package/dist/kit/protectedLoad.d.ts.map +0 -1
  252. package/dist/kit/protectedLoad.js +0 -28
  253. package/dist/kit/protectedLoad.js.map +0 -1
  254. package/dist/kit/setupLoad.d.ts +0 -11
  255. package/dist/kit/setupLoad.d.ts.map +0 -1
  256. package/dist/kit/setupLoad.js +0 -28
  257. package/dist/kit/setupLoad.js.map +0 -1
  258. package/dist/kit/validateEndpoint.d.ts +0 -9
  259. package/dist/kit/validateEndpoint.d.ts.map +0 -1
  260. package/dist/kit/validateEndpoint.js +0 -25
  261. package/dist/kit/validateEndpoint.js.map +0 -1
  262. package/dist/kit/vercelApi.d.ts +0 -6
  263. package/dist/kit/vercelApi.d.ts.map +0 -1
  264. package/dist/kit/vercelApi.js +0 -48
  265. package/dist/kit/vercelApi.js.map +0 -1
@@ -1,15 +1,88 @@
1
1
  /**
2
- * Supabase Client - Lazy Initialization via Proxy
2
+ * @fileoverview Supabase Client Lazy Initialization via ES Proxy
3
3
  *
4
- * Uses runtime config instead of build-time $env/static/public.
5
- * The Proxy pattern preserves the exact same API surface.
4
+ * This module exports a single `supabase` constant that looks and behaves
5
+ * exactly like a `SupabaseClient` instance, but is actually an ES `Proxy`
6
+ * that defers client creation until the **first property access**. This
7
+ * "lazy singleton" pattern solves a critical bootstrapping problem:
8
+ *
9
+ * The Supabase URL and anon key are loaded at **runtime** (via
10
+ * `getConfig()` from `../runtime/runtimeConfig`), not at build time.
11
+ * Modules that `import { supabase }` at the top level would otherwise
12
+ * crash because the config has not been initialized yet when the import
13
+ * executes.
14
+ *
15
+ * How the Proxy pattern works:
16
+ * 1. `supabase` is exported as `new Proxy({} as SupabaseClient, handler)`.
17
+ * 2. The handler's `get` trap intercepts every property access (e.g.
18
+ * `supabase.auth`, `supabase.from(...)`).
19
+ * 3. On first access, `getOrCreateClient()` reads the runtime config and
20
+ * calls `createClient(url, key, options)` to build the real client.
21
+ * 4. The real client is cached in a module-level `realClient` variable;
22
+ * subsequent accesses reuse it (standard singleton).
23
+ * 5. Function values are `.bind(client)` to preserve `this` context.
24
+ *
25
+ * Additional responsibilities:
26
+ * - **Corrupted session cleanup**: Before the client is created, any
27
+ * malformed `sb-*` entries in localStorage are detected and removed to
28
+ * prevent "can't access property 'hash'" runtime errors.
29
+ * - **Unhandled rejection handler**: A global listener catches Supabase
30
+ * auth errors that escape normal error handling, clears storage, and
31
+ * performs a single guarded page reload to recover.
32
+ * - **iOS PWA detection**: The client sends a custom `x-client-info`
33
+ * header indicating whether it is running as a standalone PWA on iOS,
34
+ * which helps with server-side debugging of session eviction issues.
35
+ *
36
+ * Security considerations:
37
+ * - The anon key is a **public** key (safe to include in client bundles).
38
+ * - PKCE flow is used instead of the implicit flow for stronger OAuth
39
+ * security and better compatibility with PWA environments.
40
+ * - Session persistence uses localStorage; the module proactively scrubs
41
+ * corrupted entries to prevent denial-of-service via bad local state.
42
+ *
43
+ * @module supabase/client
6
44
  */
7
45
  import { type SupabaseClient } from '@supabase/supabase-js';
46
+ /**
47
+ * Override the storage key prefix used by the Supabase client.
48
+ *
49
+ * Must be called **before** the first access to the `supabase` export,
50
+ * since the prefix is baked into the client options at creation time.
51
+ *
52
+ * @param prefix - The new prefix string (e.g. the app's name).
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * _setClientPrefix('myapp');
57
+ * // Later accesses will use storageKey 'myapp-auth'
58
+ * ```
59
+ */
8
60
  export declare function _setClientPrefix(prefix: string): void;
9
61
  /**
10
- * Proxy-based lazy singleton.
11
- * Delegates all property access to the real SupabaseClient,
12
- * which is created on first access using getConfig().
62
+ * The public Supabase client — a Proxy-based lazy singleton.
63
+ *
64
+ * **Why a Proxy?**
65
+ * The Supabase URL and anon key are not available at import time (they come
66
+ * from a runtime config that is loaded asynchronously). A Proxy lets every
67
+ * module `import { supabase }` at the top level without worrying about
68
+ * initialization order. The real client is created transparently on first
69
+ * property access.
70
+ *
71
+ * **How it works:**
72
+ * - The `get` trap intercepts every property read (e.g. `supabase.auth`,
73
+ * `supabase.from`).
74
+ * - It calls `getOrCreateClient()` to ensure the real client exists.
75
+ * - It forwards the property access via `Reflect.get`.
76
+ * - Function values are `.bind(client)` to keep `this` correct when the
77
+ * caller destructures methods (e.g. `const { from } = supabase`).
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { supabase } from './client';
82
+ *
83
+ * // Works immediately — the Proxy defers creation until this line runs:
84
+ * const { data } = await supabase.from('users').select('*');
85
+ * ```
13
86
  */
14
87
  export declare const supabase: SupabaseClient;
15
88
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM1E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,QAE9C;AAqJD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,cASrB,CAAC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe1E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,QAE9C;AAwND;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,QAAQ,EAAE,cASrB,CAAC"}
@@ -1,18 +1,92 @@
1
1
  /**
2
- * Supabase Client - Lazy Initialization via Proxy
2
+ * @fileoverview Supabase Client Lazy Initialization via ES Proxy
3
3
  *
4
- * Uses runtime config instead of build-time $env/static/public.
5
- * The Proxy pattern preserves the exact same API surface.
4
+ * This module exports a single `supabase` constant that looks and behaves
5
+ * exactly like a `SupabaseClient` instance, but is actually an ES `Proxy`
6
+ * that defers client creation until the **first property access**. This
7
+ * "lazy singleton" pattern solves a critical bootstrapping problem:
8
+ *
9
+ * The Supabase URL and anon key are loaded at **runtime** (via
10
+ * `getConfig()` from `../runtime/runtimeConfig`), not at build time.
11
+ * Modules that `import { supabase }` at the top level would otherwise
12
+ * crash because the config has not been initialized yet when the import
13
+ * executes.
14
+ *
15
+ * How the Proxy pattern works:
16
+ * 1. `supabase` is exported as `new Proxy({} as SupabaseClient, handler)`.
17
+ * 2. The handler's `get` trap intercepts every property access (e.g.
18
+ * `supabase.auth`, `supabase.from(...)`).
19
+ * 3. On first access, `getOrCreateClient()` reads the runtime config and
20
+ * calls `createClient(url, key, options)` to build the real client.
21
+ * 4. The real client is cached in a module-level `realClient` variable;
22
+ * subsequent accesses reuse it (standard singleton).
23
+ * 5. Function values are `.bind(client)` to preserve `this` context.
24
+ *
25
+ * Additional responsibilities:
26
+ * - **Corrupted session cleanup**: Before the client is created, any
27
+ * malformed `sb-*` entries in localStorage are detected and removed to
28
+ * prevent "can't access property 'hash'" runtime errors.
29
+ * - **Unhandled rejection handler**: A global listener catches Supabase
30
+ * auth errors that escape normal error handling, clears storage, and
31
+ * performs a single guarded page reload to recover.
32
+ * - **iOS PWA detection**: The client sends a custom `x-client-info`
33
+ * header indicating whether it is running as a standalone PWA on iOS,
34
+ * which helps with server-side debugging of session eviction issues.
35
+ *
36
+ * Security considerations:
37
+ * - The anon key is a **public** key (safe to include in client bundles).
38
+ * - PKCE flow is used instead of the implicit flow for stronger OAuth
39
+ * security and better compatibility with PWA environments.
40
+ * - Session persistence uses localStorage; the module proactively scrubs
41
+ * corrupted entries to prevent denial-of-service via bad local state.
42
+ *
43
+ * @module supabase/client
6
44
  */
7
45
  import { createClient } from '@supabase/supabase-js';
8
46
  import { getConfig } from '../runtime/runtimeConfig';
9
47
  import { debugLog, debugWarn, debugError } from '../debug';
48
+ // =============================================================================
49
+ // SECTION: Client Prefix Configuration
50
+ // =============================================================================
51
+ /**
52
+ * Prefix used for the Supabase `storageKey` and custom headers.
53
+ * Defaults to `'stellar'`; can be overridden by the host application
54
+ * via {@link _setClientPrefix} before the client is first accessed.
55
+ */
10
56
  let _prefix = 'stellar';
57
+ /**
58
+ * Override the storage key prefix used by the Supabase client.
59
+ *
60
+ * Must be called **before** the first access to the `supabase` export,
61
+ * since the prefix is baked into the client options at creation time.
62
+ *
63
+ * @param prefix - The new prefix string (e.g. the app's name).
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * _setClientPrefix('myapp');
68
+ * // Later accesses will use storageKey 'myapp-auth'
69
+ * ```
70
+ */
11
71
  export function _setClientPrefix(prefix) {
12
72
  _prefix = prefix;
13
73
  }
14
- // Clear corrupted Supabase auth data from localStorage if it exists
15
- // This prevents "can't access property 'hash'" errors during initialization
74
+ // =============================================================================
75
+ // SECTION: Corrupted Session Cleanup
76
+ // =============================================================================
77
+ /**
78
+ * Scan localStorage for corrupted Supabase auth entries and remove them.
79
+ *
80
+ * Supabase stores session data under keys prefixed with `sb-`. If the
81
+ * browser was closed mid-write, or if a bug produced malformed JSON, these
82
+ * entries can cause runtime errors like "can't access property 'hash' of
83
+ * undefined" on the next page load.
84
+ *
85
+ * This function runs **once** at module evaluation time (before the client
86
+ * is created) and acts as a defensive self-healing mechanism.
87
+ *
88
+ * @internal
89
+ */
16
90
  function clearCorruptedAuthData() {
17
91
  if (typeof localStorage === 'undefined')
18
92
  return;
@@ -41,7 +115,9 @@ function clearCorruptedAuthData() {
41
115
  }
42
116
  }
43
117
  catch {
44
- // JSON parse failed - data is corrupted
118
+ /* JSON.parse failed the stored value is not valid JSON, which
119
+ means the data was partially written or otherwise corrupted.
120
+ Removing it is the safest recovery action. */
45
121
  debugWarn('[Auth] Clearing malformed session data:', key);
46
122
  localStorage.removeItem(key);
47
123
  }
@@ -52,7 +128,13 @@ function clearCorruptedAuthData() {
52
128
  debugError('[Auth] Error checking localStorage:', e);
53
129
  }
54
130
  }
55
- // Add global handler for unhandled Supabase auth errors
131
+ // =============================================================================
132
+ // SECTION: Global Error Recovery
133
+ // =============================================================================
134
+ /* Register a global unhandled-rejection handler that catches Supabase auth
135
+ errors which escape normal try/catch boundaries. This is a last-resort
136
+ recovery mechanism: clear the corrupted storage and reload once. A
137
+ sessionStorage flag (`__stellar_auth_reload`) guards against reload loops. */
56
138
  if (typeof window !== 'undefined') {
57
139
  // Clear reload guard on successful startup (app loaded without crashing)
58
140
  try {
@@ -73,7 +155,8 @@ if (typeof window !== 'undefined') {
73
155
  try {
74
156
  const keys = Object.keys(localStorage).filter((k) => k.startsWith('sb-'));
75
157
  keys.forEach((k) => localStorage.removeItem(k));
76
- // Guard against reload loop: only reload once per session
158
+ /* Guard against reload loop: only reload once per browser session.
159
+ Without this guard, a persistent error could cause infinite reloads. */
77
160
  if (!sessionStorage.getItem('__stellar_auth_reload')) {
78
161
  sessionStorage.setItem('__stellar_auth_reload', '1');
79
162
  window.location.reload();
@@ -86,17 +169,51 @@ if (typeof window !== 'undefined') {
86
169
  }
87
170
  });
88
171
  }
89
- // Run cleanup before creating client
172
+ // =============================================================================
173
+ // SECTION: Module-Level Initialization
174
+ // =============================================================================
175
+ /* Run the corruption cleanup synchronously at module load time, before any
176
+ code can attempt to read the (potentially corrupted) session data. */
90
177
  clearCorruptedAuthData();
91
- // Detect if running as iOS PWA (standalone mode)
178
+ /**
179
+ * Detect if the app is running as an iOS PWA (standalone mode).
180
+ *
181
+ * iOS PWAs have unique session-persistence challenges: Safari's
182
+ * Intelligent Tracking Prevention (ITP) and aggressive localStorage
183
+ * eviction can cause sessions to disappear unexpectedly. Knowing we are
184
+ * in this environment lets us log more aggressively and send a custom
185
+ * header for server-side debugging.
186
+ */
92
187
  const isIOSPWA = typeof window !== 'undefined' &&
93
188
  // @ts-expect-error - navigator.standalone is iOS-specific
94
189
  (window.navigator.standalone === true || window.matchMedia('(display-mode: standalone)').matches);
95
190
  if (isIOSPWA) {
96
191
  debugLog('[Auth] Running as iOS PWA - using enhanced auth persistence');
97
192
  }
98
- // Lazy singleton: actual client is created on first access
193
+ // =============================================================================
194
+ // SECTION: Lazy Singleton Client
195
+ // =============================================================================
196
+ /** The cached SupabaseClient instance, created on first access. */
99
197
  let realClient = null;
198
+ /**
199
+ * Create (or return the cached) SupabaseClient instance.
200
+ *
201
+ * On first invocation this reads the runtime config, constructs the client
202
+ * with appropriate auth options, and wires up an `onAuthStateChange`
203
+ * listener for debug logging. Subsequent calls return the cached instance.
204
+ *
205
+ * Client configuration highlights:
206
+ * - `persistSession: true` — sessions survive page reloads via localStorage.
207
+ * - `autoRefreshToken: true` — the SDK refreshes tokens before they expire.
208
+ * - `flowType: 'pkce'` — PKCE is more secure than the implicit flow and
209
+ * works better with PWA and mobile browser environments.
210
+ * - `storageKey: '{prefix}-auth'` — namespaced to avoid collisions when
211
+ * multiple Supabase-backed apps share the same origin.
212
+ *
213
+ * @returns The fully-initialized `SupabaseClient`.
214
+ *
215
+ * @internal Called exclusively by the Proxy `get` trap below.
216
+ */
100
217
  function getOrCreateClient() {
101
218
  if (realClient)
102
219
  return realClient;
@@ -130,7 +247,9 @@ function getOrCreateClient() {
130
247
  if (typeof window !== 'undefined') {
131
248
  realClient.auth.onAuthStateChange((event, session) => {
132
249
  debugLog(`[Auth] State change: ${event}`, session ? `User: ${session.user?.id}` : 'No session');
133
- // If session is lost unexpectedly, this helps identify the issue
250
+ /* iOS PWAs can lose sessions silently when Safari evicts localStorage.
251
+ Logging SIGNED_OUT events specifically for PWAs makes this visible
252
+ in remote debugging tools. */
134
253
  if (event === 'SIGNED_OUT' && isIOSPWA) {
135
254
  debugWarn('[Auth] Signed out on iOS PWA - session may have been evicted');
136
255
  }
@@ -141,10 +260,34 @@ function getOrCreateClient() {
141
260
  }
142
261
  return realClient;
143
262
  }
263
+ // =============================================================================
264
+ // SECTION: Proxy Export
265
+ // =============================================================================
144
266
  /**
145
- * Proxy-based lazy singleton.
146
- * Delegates all property access to the real SupabaseClient,
147
- * which is created on first access using getConfig().
267
+ * The public Supabase client — a Proxy-based lazy singleton.
268
+ *
269
+ * **Why a Proxy?**
270
+ * The Supabase URL and anon key are not available at import time (they come
271
+ * from a runtime config that is loaded asynchronously). A Proxy lets every
272
+ * module `import { supabase }` at the top level without worrying about
273
+ * initialization order. The real client is created transparently on first
274
+ * property access.
275
+ *
276
+ * **How it works:**
277
+ * - The `get` trap intercepts every property read (e.g. `supabase.auth`,
278
+ * `supabase.from`).
279
+ * - It calls `getOrCreateClient()` to ensure the real client exists.
280
+ * - It forwards the property access via `Reflect.get`.
281
+ * - Function values are `.bind(client)` to keep `this` correct when the
282
+ * caller destructures methods (e.g. `const { from } = supabase`).
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * import { supabase } from './client';
287
+ *
288
+ * // Works immediately — the Proxy defers creation until this line runs:
289
+ * const { data } = await supabase.from('users').select('*');
290
+ * ```
148
291
  */
149
292
  export const supabase = new Proxy({}, {
150
293
  get(_target, prop, receiver) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,114 @@
1
1
  /**
2
- * Supabase Validation
2
+ * @fileoverview Supabase Validation Module
3
3
  *
4
- * 1. Credential validation: Tests connectivity using provided credentials (setup flows).
5
- * 2. Schema validation: Verifies that all configured Supabase tables exist and are accessible.
4
+ * Provides two complementary validation capabilities:
5
+ *
6
+ * 1. **Credential validation** (`validateSupabaseCredentials`):
7
+ * Tests that a given Supabase URL and anon key are well-formed and can
8
+ * reach the Supabase REST API. Used during setup / onboarding flows
9
+ * where the user manually enters their project credentials.
10
+ *
11
+ * 2. **Schema validation** (`validateSchema`):
12
+ * Verifies that every table declared in the engine config actually exists
13
+ * in the Supabase project and is accessible under the current RLS policies.
14
+ * This is a "smoke test" that catches misconfiguration early, before the
15
+ * sync engine attempts real reads/writes and produces cryptic errors.
16
+ *
17
+ * Security considerations:
18
+ * - Credential validation creates a **temporary** `SupabaseClient` scoped
19
+ * to the function call; it does not leak into the module-level singleton.
20
+ * - Schema validation queries use `LIMIT 0`, so no user data is fetched —
21
+ * the query only confirms that the table exists and RLS allows access.
22
+ * - Error messages are deliberately generic to avoid leaking internal
23
+ * database structure to end users; detailed errors go to `debugError`.
24
+ *
25
+ * Integration patterns:
26
+ * - Called from setup wizards, admin panels, and health-check utilities.
27
+ * - `validateSchema` uses the shared `supabase` proxy from `./client.ts`,
28
+ * so it benefits from the same lazy-init and session management.
29
+ *
30
+ * @module supabase/validate
31
+ */
32
+ /**
33
+ * Validate Supabase credentials by attempting a lightweight API call.
34
+ *
35
+ * This function is designed for **setup flows** where a user provides their
36
+ * Supabase URL and anon key and the app needs to verify them before saving.
37
+ *
38
+ * Validation steps:
39
+ * 1. Parse the URL to ensure it is syntactically valid.
40
+ * 2. Create a disposable `SupabaseClient` with the provided credentials.
41
+ * 3. Issue a `SELECT id FROM <testTable> LIMIT 1` query.
42
+ * 4. Interpret the response:
43
+ * - Success or "relation does not exist" => credentials are valid (the
44
+ * API responded, so URL + key are correct; the table simply may not
45
+ * have been created yet).
46
+ * - "Invalid API key" / PGRST301 => credentials are wrong.
47
+ * - Network error => Supabase is unreachable.
48
+ *
49
+ * @param url - The Supabase project URL (e.g. `https://xyz.supabase.co`).
50
+ * @param anonKey - The project's anonymous (public) API key.
51
+ * @param testTable - Optional table name to query. Defaults to `'_health_check'`.
52
+ * Using a table that does not exist is fine — we only care
53
+ * whether the API responds, not whether the table is present.
54
+ * @returns An object with `valid: true` on success, or `valid: false` plus an
55
+ * `error` message describing what went wrong.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const result = await validateSupabaseCredentials(
60
+ * 'https://abc.supabase.co',
61
+ * 'eyJhbGci...',
62
+ * 'profiles'
63
+ * );
64
+ * if (!result.valid) {
65
+ * showError(result.error);
66
+ * }
67
+ * ```
68
+ *
69
+ * @see {@link validateSchema} — for post-setup table existence checks
6
70
  */
7
71
  export declare function validateSupabaseCredentials(url: string, anonKey: string, testTable?: string): Promise<{
8
72
  valid: boolean;
9
73
  error?: string;
10
74
  }>;
11
75
  /**
12
- * Validates that all configured Supabase tables exist and are accessible.
76
+ * Validate that all tables declared in the engine configuration exist in
77
+ * Supabase and are accessible under the current RLS policies.
78
+ *
79
+ * For each table the function executes:
80
+ * ```sql
81
+ * SELECT id FROM <table> LIMIT 0
82
+ * ```
83
+ * This returns **zero rows** (no data egress, minimal latency) but still
84
+ * exercises the full PostgREST pipeline — table lookup, RLS policy
85
+ * evaluation, and column resolution. If any of these steps fail, the table
86
+ * is flagged.
87
+ *
88
+ * When device verification is enabled in the engine config, the
89
+ * `trusted_devices` table is automatically appended to the check list.
90
+ *
91
+ * Error categorization:
92
+ * - **Missing table**: The relation does not exist in the database.
93
+ * - **Permission denied (42501)**: The table exists but RLS or grants
94
+ * prevent the anon role from reading it.
95
+ * - **Other**: Any unexpected PostgREST or network error.
96
+ *
97
+ * @returns An object containing:
98
+ * - `valid` — `true` when all tables pass, `false` otherwise.
99
+ * - `missingTables` — names of tables that do not exist at all.
100
+ * - `errors` — human-readable descriptions of every issue found.
13
101
  *
14
- * Fires `SELECT id FROM <table> LIMIT 0` per table — returns zero rows (no data egress)
15
- * but validates the table exists and RLS allows access.
102
+ * @example
103
+ * ```ts
104
+ * const { valid, missingTables, errors } = await validateSchema();
105
+ * if (!valid) {
106
+ * console.error('Schema issues:', errors);
107
+ * // Prompt user to run migrations or fix RLS policies
108
+ * }
109
+ * ```
16
110
  *
17
- * If device verification is enabled, also validates the `trusted_devices` table.
111
+ * @see {@link validateSupabaseCredentials} for pre-setup credential checks
18
112
  */
19
113
  export declare function validateSchema(): Promise<{
20
114
  valid: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/supabase/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqC7C;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CA4CD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/supabase/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAWH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0C7C;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CAiDD"}
@@ -1,13 +1,80 @@
1
1
  /**
2
- * Supabase Validation
2
+ * @fileoverview Supabase Validation Module
3
3
  *
4
- * 1. Credential validation: Tests connectivity using provided credentials (setup flows).
5
- * 2. Schema validation: Verifies that all configured Supabase tables exist and are accessible.
4
+ * Provides two complementary validation capabilities:
5
+ *
6
+ * 1. **Credential validation** (`validateSupabaseCredentials`):
7
+ * Tests that a given Supabase URL and anon key are well-formed and can
8
+ * reach the Supabase REST API. Used during setup / onboarding flows
9
+ * where the user manually enters their project credentials.
10
+ *
11
+ * 2. **Schema validation** (`validateSchema`):
12
+ * Verifies that every table declared in the engine config actually exists
13
+ * in the Supabase project and is accessible under the current RLS policies.
14
+ * This is a "smoke test" that catches misconfiguration early, before the
15
+ * sync engine attempts real reads/writes and produces cryptic errors.
16
+ *
17
+ * Security considerations:
18
+ * - Credential validation creates a **temporary** `SupabaseClient` scoped
19
+ * to the function call; it does not leak into the module-level singleton.
20
+ * - Schema validation queries use `LIMIT 0`, so no user data is fetched —
21
+ * the query only confirms that the table exists and RLS allows access.
22
+ * - Error messages are deliberately generic to avoid leaking internal
23
+ * database structure to end users; detailed errors go to `debugError`.
24
+ *
25
+ * Integration patterns:
26
+ * - Called from setup wizards, admin panels, and health-check utilities.
27
+ * - `validateSchema` uses the shared `supabase` proxy from `./client.ts`,
28
+ * so it benefits from the same lazy-init and session management.
29
+ *
30
+ * @module supabase/validate
6
31
  */
7
32
  import { createClient } from '@supabase/supabase-js';
8
33
  import { getEngineConfig } from '../config';
9
34
  import { supabase } from './client';
10
35
  import { debugError, debugLog } from '../debug';
36
+ // =============================================================================
37
+ // SECTION: Credential Validation
38
+ // =============================================================================
39
+ /**
40
+ * Validate Supabase credentials by attempting a lightweight API call.
41
+ *
42
+ * This function is designed for **setup flows** where a user provides their
43
+ * Supabase URL and anon key and the app needs to verify them before saving.
44
+ *
45
+ * Validation steps:
46
+ * 1. Parse the URL to ensure it is syntactically valid.
47
+ * 2. Create a disposable `SupabaseClient` with the provided credentials.
48
+ * 3. Issue a `SELECT id FROM <testTable> LIMIT 1` query.
49
+ * 4. Interpret the response:
50
+ * - Success or "relation does not exist" => credentials are valid (the
51
+ * API responded, so URL + key are correct; the table simply may not
52
+ * have been created yet).
53
+ * - "Invalid API key" / PGRST301 => credentials are wrong.
54
+ * - Network error => Supabase is unreachable.
55
+ *
56
+ * @param url - The Supabase project URL (e.g. `https://xyz.supabase.co`).
57
+ * @param anonKey - The project's anonymous (public) API key.
58
+ * @param testTable - Optional table name to query. Defaults to `'_health_check'`.
59
+ * Using a table that does not exist is fine — we only care
60
+ * whether the API responds, not whether the table is present.
61
+ * @returns An object with `valid: true` on success, or `valid: false` plus an
62
+ * `error` message describing what went wrong.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const result = await validateSupabaseCredentials(
67
+ * 'https://abc.supabase.co',
68
+ * 'eyJhbGci...',
69
+ * 'profiles'
70
+ * );
71
+ * if (!result.valid) {
72
+ * showError(result.error);
73
+ * }
74
+ * ```
75
+ *
76
+ * @see {@link validateSchema} — for post-setup table existence checks
77
+ */
11
78
  export async function validateSupabaseCredentials(url, anonKey, testTable) {
12
79
  try {
13
80
  new URL(url);
@@ -16,6 +83,9 @@ export async function validateSupabaseCredentials(url, anonKey, testTable) {
16
83
  return { valid: false, error: 'Invalid Supabase URL format' };
17
84
  }
18
85
  try {
86
+ /* Create a throwaway client scoped to this validation call. We
87
+ intentionally do NOT reuse the module-level singleton because the
88
+ credentials being tested may differ from the app's active config. */
19
89
  const tempClient = createClient(url, anonKey);
20
90
  // Test REST API reachability by attempting a simple query
21
91
  const { error } = await tempClient
@@ -30,7 +100,9 @@ export async function validateSupabaseCredentials(url, anonKey, testTable) {
30
100
  error: 'Invalid Supabase credentials. Check your URL and Anon Key.'
31
101
  };
32
102
  }
33
- // Table doesn't exist but API is reachable credentials work, schema not set up yet
103
+ /* Table doesn't exist but the API respondedthis means the URL and
104
+ anon key are correct; the schema just hasn't been set up yet. We
105
+ treat this as a successful credential validation. */
34
106
  if (error.message?.includes('relation') && error.message?.includes('does not exist')) {
35
107
  return { valid: true };
36
108
  }
@@ -44,13 +116,46 @@ export async function validateSupabaseCredentials(url, anonKey, testTable) {
44
116
  return { valid: false, error: `Could not connect to Supabase: ${message}` };
45
117
  }
46
118
  }
119
+ // =============================================================================
120
+ // SECTION: Schema Validation
121
+ // =============================================================================
47
122
  /**
48
- * Validates that all configured Supabase tables exist and are accessible.
123
+ * Validate that all tables declared in the engine configuration exist in
124
+ * Supabase and are accessible under the current RLS policies.
125
+ *
126
+ * For each table the function executes:
127
+ * ```sql
128
+ * SELECT id FROM <table> LIMIT 0
129
+ * ```
130
+ * This returns **zero rows** (no data egress, minimal latency) but still
131
+ * exercises the full PostgREST pipeline — table lookup, RLS policy
132
+ * evaluation, and column resolution. If any of these steps fail, the table
133
+ * is flagged.
134
+ *
135
+ * When device verification is enabled in the engine config, the
136
+ * `trusted_devices` table is automatically appended to the check list.
137
+ *
138
+ * Error categorization:
139
+ * - **Missing table**: The relation does not exist in the database.
140
+ * - **Permission denied (42501)**: The table exists but RLS or grants
141
+ * prevent the anon role from reading it.
142
+ * - **Other**: Any unexpected PostgREST or network error.
143
+ *
144
+ * @returns An object containing:
145
+ * - `valid` — `true` when all tables pass, `false` otherwise.
146
+ * - `missingTables` — names of tables that do not exist at all.
147
+ * - `errors` — human-readable descriptions of every issue found.
49
148
  *
50
- * Fires `SELECT id FROM <table> LIMIT 0` per table — returns zero rows (no data egress)
51
- * but validates the table exists and RLS allows access.
149
+ * @example
150
+ * ```ts
151
+ * const { valid, missingTables, errors } = await validateSchema();
152
+ * if (!valid) {
153
+ * console.error('Schema issues:', errors);
154
+ * // Prompt user to run migrations or fix RLS policies
155
+ * }
156
+ * ```
52
157
  *
53
- * If device verification is enabled, also validates the `trusted_devices` table.
158
+ * @see {@link validateSupabaseCredentials} for pre-setup credential checks
54
159
  */
55
160
  export async function validateSchema() {
56
161
  const config = getEngineConfig();
@@ -59,10 +164,14 @@ export async function validateSchema() {
59
164
  if (config.auth?.deviceVerification?.enabled) {
60
165
  tableNames.push('trusted_devices');
61
166
  }
167
+ /** Tables whose relation does not exist in the database at all. */
62
168
  const missingTables = [];
169
+ /** Human-readable error descriptions for all issues encountered. */
63
170
  const errors = [];
64
171
  for (const tableName of tableNames) {
65
172
  try {
173
+ /* SELECT id LIMIT 0 — validates table existence and RLS access
174
+ without fetching any actual data rows. */
66
175
  const { error } = await supabase.from(tableName).select('id').limit(0);
67
176
  if (error) {
68
177
  if (error.message?.includes('relation') && error.message?.includes('does not exist')) {