@uncaughtdev/supabase 0.1.0
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/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/index.d.mts +98 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Uncaught Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @uncaughtdev/supabase
|
|
2
|
+
|
|
3
|
+
Supabase client wrapper for [Uncaught](https://github.com/AjeeshDevops/uncaught) error monitoring.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @uncaughtdev/supabase
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { wrapSupabase } from '@uncaughtdev/supabase';
|
|
15
|
+
import { createClient } from '@supabase/supabase-js';
|
|
16
|
+
|
|
17
|
+
const supabase = wrapSupabase(createClient(url, key));
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## What's included
|
|
21
|
+
|
|
22
|
+
- Deep Proxy wrapper — intercepts all Supabase operations
|
|
23
|
+
- Query chain tracking (`.from().select().eq()` etc.)
|
|
24
|
+
- Error parsing (Postgrest, Auth, Functions, Storage)
|
|
25
|
+
- RLS violation explainer with human-readable messages
|
|
26
|
+
|
|
27
|
+
## License
|
|
28
|
+
|
|
29
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring which Supabase subsystems are tracked by the proxy.
|
|
3
|
+
*/
|
|
4
|
+
interface WrapSupabaseOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Track database queries (.from().select/.insert/.update/.upsert/.delete).
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
trackQueries?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Track authentication operations (.auth.signUp, .auth.signIn*, etc.).
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
trackAuth?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Track edge function invocations (.functions.invoke).
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
trackFunctions?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Track storage operations (.storage.from().upload/.download/.remove, etc.).
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
trackStorage?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Track realtime channel subscriptions and messages.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
trackRealtime?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A single step in a Supabase query builder chain.
|
|
33
|
+
* Records the method name and the arguments passed to it.
|
|
34
|
+
*/
|
|
35
|
+
interface QueryChainStep {
|
|
36
|
+
method: string;
|
|
37
|
+
args: unknown[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Represents a fully-tracked Supabase query with all chain steps
|
|
41
|
+
* and metadata extracted from the builder chain.
|
|
42
|
+
*/
|
|
43
|
+
interface TrackedQuery {
|
|
44
|
+
/** The table name extracted from .from('table'). */
|
|
45
|
+
table: string;
|
|
46
|
+
/** The primary operation type (select, insert, update, upsert, delete, rpc). */
|
|
47
|
+
operation: string;
|
|
48
|
+
/** All method calls in the chain, in order. */
|
|
49
|
+
chain: QueryChainStep[];
|
|
50
|
+
/** Human-readable string representation of the full query chain. */
|
|
51
|
+
humanReadable: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Structured parse result from a Supabase error.
|
|
55
|
+
*/
|
|
56
|
+
interface ParsedSupabaseError {
|
|
57
|
+
/** High-level category: 'postgrest' | 'auth' | 'functions' | 'storage' | 'unknown'. */
|
|
58
|
+
errorType: string;
|
|
59
|
+
/** The specific error code (e.g. '42501', 'PGRST116', 'AuthApiError'). */
|
|
60
|
+
errorCode: string;
|
|
61
|
+
/** The raw error message. */
|
|
62
|
+
message: string;
|
|
63
|
+
/** Human-readable explanation with actionable guidance. */
|
|
64
|
+
humanExplanation: string;
|
|
65
|
+
/** Suggested UncaughtEvent category for grouping. */
|
|
66
|
+
suggestedCategory: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Wrap a Supabase client with transparent error interception.
|
|
71
|
+
*
|
|
72
|
+
* The returned client has the exact same type and behavior as the original.
|
|
73
|
+
* All Supabase operations work identically — the wrapper only observes
|
|
74
|
+
* results and captures errors through the @uncaughtdev/core client.
|
|
75
|
+
*
|
|
76
|
+
* @param client - A SupabaseClient instance from `createClient()`.
|
|
77
|
+
* @param options - Optional configuration for which subsystems to track.
|
|
78
|
+
* By default, queries, auth, and functions are tracked.
|
|
79
|
+
* Storage and realtime are opt-in.
|
|
80
|
+
* @returns The same client, wrapped with transparent error interception.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { createClient } from '@supabase/supabase-js';
|
|
85
|
+
* import { initUncaught } from '@uncaughtdev/core';
|
|
86
|
+
* import { wrapSupabase } from '@uncaughtdev/supabase';
|
|
87
|
+
*
|
|
88
|
+
* initUncaught({ projectKey: 'my-project' });
|
|
89
|
+
*
|
|
90
|
+
* const supabase = wrapSupabase(
|
|
91
|
+
* createClient(SUPABASE_URL, SUPABASE_ANON_KEY),
|
|
92
|
+
* { trackQueries: true, trackAuth: true, trackFunctions: true }
|
|
93
|
+
* );
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function wrapSupabase<T>(client: T, options?: WrapSupabaseOptions): T;
|
|
97
|
+
|
|
98
|
+
export { type ParsedSupabaseError, type QueryChainStep, type TrackedQuery, type WrapSupabaseOptions, wrapSupabase };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring which Supabase subsystems are tracked by the proxy.
|
|
3
|
+
*/
|
|
4
|
+
interface WrapSupabaseOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Track database queries (.from().select/.insert/.update/.upsert/.delete).
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
trackQueries?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Track authentication operations (.auth.signUp, .auth.signIn*, etc.).
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
trackAuth?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Track edge function invocations (.functions.invoke).
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
trackFunctions?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Track storage operations (.storage.from().upload/.download/.remove, etc.).
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
trackStorage?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Track realtime channel subscriptions and messages.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
trackRealtime?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A single step in a Supabase query builder chain.
|
|
33
|
+
* Records the method name and the arguments passed to it.
|
|
34
|
+
*/
|
|
35
|
+
interface QueryChainStep {
|
|
36
|
+
method: string;
|
|
37
|
+
args: unknown[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Represents a fully-tracked Supabase query with all chain steps
|
|
41
|
+
* and metadata extracted from the builder chain.
|
|
42
|
+
*/
|
|
43
|
+
interface TrackedQuery {
|
|
44
|
+
/** The table name extracted from .from('table'). */
|
|
45
|
+
table: string;
|
|
46
|
+
/** The primary operation type (select, insert, update, upsert, delete, rpc). */
|
|
47
|
+
operation: string;
|
|
48
|
+
/** All method calls in the chain, in order. */
|
|
49
|
+
chain: QueryChainStep[];
|
|
50
|
+
/** Human-readable string representation of the full query chain. */
|
|
51
|
+
humanReadable: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Structured parse result from a Supabase error.
|
|
55
|
+
*/
|
|
56
|
+
interface ParsedSupabaseError {
|
|
57
|
+
/** High-level category: 'postgrest' | 'auth' | 'functions' | 'storage' | 'unknown'. */
|
|
58
|
+
errorType: string;
|
|
59
|
+
/** The specific error code (e.g. '42501', 'PGRST116', 'AuthApiError'). */
|
|
60
|
+
errorCode: string;
|
|
61
|
+
/** The raw error message. */
|
|
62
|
+
message: string;
|
|
63
|
+
/** Human-readable explanation with actionable guidance. */
|
|
64
|
+
humanExplanation: string;
|
|
65
|
+
/** Suggested UncaughtEvent category for grouping. */
|
|
66
|
+
suggestedCategory: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Wrap a Supabase client with transparent error interception.
|
|
71
|
+
*
|
|
72
|
+
* The returned client has the exact same type and behavior as the original.
|
|
73
|
+
* All Supabase operations work identically — the wrapper only observes
|
|
74
|
+
* results and captures errors through the @uncaughtdev/core client.
|
|
75
|
+
*
|
|
76
|
+
* @param client - A SupabaseClient instance from `createClient()`.
|
|
77
|
+
* @param options - Optional configuration for which subsystems to track.
|
|
78
|
+
* By default, queries, auth, and functions are tracked.
|
|
79
|
+
* Storage and realtime are opt-in.
|
|
80
|
+
* @returns The same client, wrapped with transparent error interception.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { createClient } from '@supabase/supabase-js';
|
|
85
|
+
* import { initUncaught } from '@uncaughtdev/core';
|
|
86
|
+
* import { wrapSupabase } from '@uncaughtdev/supabase';
|
|
87
|
+
*
|
|
88
|
+
* initUncaught({ projectKey: 'my-project' });
|
|
89
|
+
*
|
|
90
|
+
* const supabase = wrapSupabase(
|
|
91
|
+
* createClient(SUPABASE_URL, SUPABASE_ANON_KEY),
|
|
92
|
+
* { trackQueries: true, trackAuth: true, trackFunctions: true }
|
|
93
|
+
* );
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function wrapSupabase<T>(client: T, options?: WrapSupabaseOptions): T;
|
|
97
|
+
|
|
98
|
+
export { type ParsedSupabaseError, type QueryChainStep, type TrackedQuery, type WrapSupabaseOptions, wrapSupabase };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var core=require('@uncaughtdev/core');var E=3,F=new Set(["select","insert","update","upsert","delete"]);function I(e){try{return Array.isArray(e)&&e.length>E?`[${e.slice(0,E).map(r=>r!==null&&typeof r=="object"?core.sanitize(r):r).map(r=>JSON.stringify(r)).join(", ")} ... and ${e.length-E} more]`:e!==null&&typeof e=="object"&&!Array.isArray(e)?core.sanitize(e):e}catch{return "[unserializable]"}}function q(e){return e.map(I)}function W(e){if(typeof e=="string")return `'${e}'`;if(e==null)return String(e);if(typeof e=="object")try{let t=JSON.stringify(e);return t.length>120?t.slice(0,117)+"...":t}catch{return "[object]"}return String(e)}var g=class{constructor(){this.steps=[];this.tableName="";this.operationType="unknown";}track(t,r){let n=q(r);this.steps.push({method:t,args:n}),t==="from"&&r.length>0&&typeof r[0]=="string"&&(this.tableName=r[0]),F.has(t)&&(this.operationType=t),t==="rpc"&&(this.operationType="rpc");}getTable(){return this.tableName}getOperation(){return this.operationType}getSteps(){return [...this.steps]}toHumanReadable(){return this.steps.length===0?"(empty chain)":this.steps.map(t=>{let r=t.args.map(W).join(", ");return `.${t.method}(${r})`}).join("")}toTrackedQuery(){return {table:this.tableName,operation:this.operationType,chain:[...this.steps],humanReadable:this.toHumanReadable()}}toOperationInfo(){return {provider:"supabase",type:"query",method:this.operationType,params:{table:this.tableName,chain:this.toHumanReadable()}}}isEmpty(){return this.steps.length===0}reset(){this.steps.length=0,this.tableName="",this.operationType="unknown";}};var T={42501:{template:"The RLS policy on the '{table}' table does not allow {operation} operations for the current user role. Check your RLS policies in the Supabase dashboard under Authentication > Policies for the '{table}' table. Common causes: missing policy for the operation type, policy condition not matching the current user, or the user's JWT role not having the expected grants.",category:"rls_violation"},23505:{template:"A record with this value already exists. The unique constraint on table '{table}' was violated. This typically means you are trying to insert or update a row with a value that must be unique (e.g. email, username, slug) but another row already has that value. Consider using .upsert() instead of .insert() if you want to update on conflict, or check for existing records before inserting.",category:"unique_violation"},23503:{template:"The referenced record does not exist. The foreign key constraint on table '{table}' failed. This means you are trying to insert or update a row that references another row (via a foreign key) that does not exist in the referenced table. Ensure the referenced record exists before creating this relationship, or check that the foreign key value is correct.",category:"foreign_key_violation"},23502:{template:"A required field was not provided. The not-null constraint on table '{table}' was violated. One or more columns that are defined as NOT NULL did not receive a value in the insert or update. Check your insert/update payload to ensure all required fields are present, or set a default value for the column in your database schema.",category:"not_null_violation"},"42P01":{template:"The table '{table}' does not exist in the database. This could mean the table name is misspelled, the table has not been created yet, or you are connecting to the wrong database/schema. Check the table name in your .from() call and verify it exists in the Supabase dashboard's Table Editor.",category:"undefined_table"},42703:{template:"The column '{column}' does not exist in table '{table}'. Check that the column name is spelled correctly and that any recent migrations have been applied.",category:"undefined_column"},42883:{template:"The function or operator does not exist. If you are using .rpc('{name}'), check that the function exists in your database and that the argument types match.",category:"undefined_function"},PGRST116:{template:"Expected a single row but got none. The .single() call on the query returned 0 rows. This means no record matched your filter conditions in table '{table}'. If the record might not exist, use .maybeSingle() instead of .single() to return null instead of an error when no rows match.",category:"no_rows"},PGRST301:{template:"The authentication token (JWT) has expired. The user needs to re-authenticate. This typically happens when the session has been idle for longer than the JWT expiry time. Call supabase.auth.refreshSession() to attempt a token refresh, or redirect the user to the sign-in page. Consider setting up an onAuthStateChange listener to handle token refreshes automatically.",category:"jwt_expired"},PGRST204:{template:"The column '{column}' specified in the query does not exist in the database schema. PostgREST could not find this column when processing the query.",category:"column_not_found"},PGRST200:{template:"An ambiguous embedding was detected. The relationship between '{table}' and the referenced table could not be resolved because multiple foreign keys exist. Specify the foreign key explicitly using the !inner or !left join syntax.",category:"ambiguous_embedding"},auth_invalid_credentials:{template:"The email or password is incorrect. Note: if the user recently signed up, their email may not be confirmed yet. Check the Supabase dashboard under Authentication > Users to see the user's confirmation status. Also verify that the email provider is enabled in Authentication > Providers.",category:"auth_invalid_credentials"},auth_email_not_confirmed:{template:'The user has signed up but has not confirmed their email address. Check your email confirmation settings in Authentication > Settings. You can disable email confirmation for development, or resend the confirmation email using supabase.auth.resend({ type: "signup", email }).',category:"auth_email_not_confirmed"},auth_rate_limited:{template:"Too many authentication attempts. Supabase rate limits auth endpoints to prevent abuse. The default rate limit is approximately 30 requests per hour for auth endpoints. Wait a few minutes before trying again. If you are hitting this in production, consider implementing client-side rate limiting or CAPTCHA.",category:"auth_rate_limited"},auth_user_not_found:{template:"No user was found with the provided credentials. The user may not have signed up yet, or the account may have been deleted.",category:"auth_user_not_found"},auth_session_not_found:{template:"No active session was found. The user is not currently signed in or their session has expired. Redirect the user to the sign-in page.",category:"auth_session_not_found"},auth_signup_disabled:{template:"New user signups have been disabled for this project. Enable signups in the Supabase dashboard under Authentication > Settings.",category:"auth_signup_disabled"},functions_timeout:{template:"The edge function '{name}' timed out. Edge functions have a default execution time limit (typically 60 seconds on the free plan). Consider optimizing the function, breaking it into smaller operations, or upgrading your Supabase plan for longer execution times.",category:"functions_timeout"},functions_crashed:{template:"The edge function '{name}' crashed during execution. Check the function logs in the Supabase dashboard under Edge Functions > Logs for the specific error. Common causes: unhandled exceptions, out-of-memory errors, or missing environment variables.",category:"functions_crashed"},functions_cors:{template:"The edge function '{name}' was blocked by CORS. Ensure the function sets the appropriate CORS headers in its response. Add 'Access-Control-Allow-Origin' and other necessary CORS headers, and handle OPTIONS preflight requests.",category:"functions_cors"},functions_not_found:{template:"The edge function '{name}' was not found. Verify that the function has been deployed and that the function name matches exactly (case-sensitive).",category:"functions_not_found"},functions_relay_error:{template:"The edge function '{name}' encountered a relay error. This is typically a transient infrastructure issue. Retry the request after a brief delay.",category:"functions_relay_error"},functions_fetch_error:{template:"Failed to invoke the edge function '{name}'. This could be a network connectivity issue, DNS resolution failure, or the Supabase project may be paused. Check your internet connection and verify the project is active in the Supabase dashboard.",category:"functions_fetch_error"},storage_bucket_not_found:{template:"The storage bucket was not found. Verify the bucket name is correct and that it has been created in the Supabase dashboard under Storage. Bucket names are case-sensitive.",category:"storage_bucket_not_found"},storage_object_too_large:{template:"The uploaded file exceeds the maximum allowed size. Check the file size limit configured for this bucket in the Supabase dashboard under Storage > Policies. The default maximum file size is 50MB on the free plan.",category:"storage_object_too_large"},storage_permission_denied:{template:"Permission denied for this storage operation. Check the storage policies (RLS) configured for this bucket. Storage uses its own set of policies separate from table-level RLS. Configure policies in the Supabase dashboard under Storage > Policies.",category:"storage_permission_denied"},storage_object_not_found:{template:"The requested file does not exist in storage. Verify the file path is correct and that the file has been uploaded. File paths in storage are case-sensitive.",category:"storage_object_not_found"}};function $(e,t){return e.replace(/\{(\w+)\}/g,(r,n)=>{let o=t[n];return o!==void 0?o:r})}function m(e,t){let r=T[e];return r?$(r.template,t??{}):`Supabase error (code: ${e}). Refer to the Supabase documentation or PostgreSQL error code reference for more details.`}function b(e){return T[e]?.category??"unknown"}function Q(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.message=="string"&&"code"in t&&typeof t.code=="string"&&"details"in t&&"hint"in t}function D(e){if(e===null||typeof e!="object")return false;let t=e;return t.__isAuthError===true||typeof t.name=="string"&&(t.name==="AuthApiError"||t.name==="AuthRetryableFetchError"||t.name==="AuthUnknownError"||t.name==="AuthWeakPasswordError"||t.name==="AuthSessionMissingError")}function z(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.name=="string"&&(t.name==="FunctionsHttpError"||t.name==="FunctionsRelayError"||t.name==="FunctionsFetchError")}function L(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.name=="string"&&t.name==="StorageApiError"?true:typeof t.statusCode=="string"||typeof t.statusCode=="number"?typeof t.message=="string":false}function U(e){let t=e.message.toLowerCase();return t.includes("invalid login credentials")||t.includes("invalid credentials")?"auth_invalid_credentials":t.includes("email not confirmed")||t.includes("not confirmed")?"auth_email_not_confirmed":t.includes("rate limit")||t.includes("too many requests")||e.status===429?"auth_rate_limited":t.includes("user not found")||t.includes("no user found")?"auth_user_not_found":t.includes("session not found")||t.includes("not authenticated")||t.includes("session_not_found")?"auth_session_not_found":t.includes("signups not allowed")||t.includes("signup is disabled")||t.includes("signups are disabled")?"auth_signup_disabled":"auth_unknown"}function H(e){let t=e.message.toLowerCase(),r=e.name??"";return r==="FunctionsRelayError"?"functions_relay_error":r==="FunctionsFetchError"?"functions_fetch_error":t.includes("timeout")||t.includes("timed out")||t.includes("deadline exceeded")?"functions_timeout":t.includes("cors")||t.includes("cross-origin")?"functions_cors":t.includes("not found")||t.includes("404")?"functions_not_found":(t.includes("crashed")||t.includes("internal server error")||t.includes("500"),"functions_crashed")}function B(e){let t=e.message.toLowerCase(),r=String(e.statusCode??"");return t.includes("bucket")&&(t.includes("not found")||t.includes("does not exist"))?"storage_bucket_not_found":t.includes("too large")||t.includes("payload too large")||t.includes("file size")||r==="413"?"storage_object_too_large":t.includes("permission")||t.includes("not authorized")||t.includes("policy")||r==="403"?"storage_permission_denied":t.includes("not found")||t.includes("object not found")||r==="404"?"storage_object_not_found":"storage_permission_denied"}function p(e,t){try{let r={table:t?.table,operation:t?.operation,name:t?.functionName,column:void 0,constraint:void 0};if(Q(e)){let n=e.code,o=m(n,r),a=b(n);return {errorType:"postgrest",errorCode:n,message:K(e),humanExplanation:o,suggestedCategory:a}}if(D(e)){let n=U(e),o=m(n,r),a=b(n);return {errorType:"auth",errorCode:e.name??n,message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}if(z(e)){let n=H(e),o=m(n,r),a=b(n);return {errorType:"functions",errorCode:e.name??n,message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}if(L(e)){let n=B(e),o=m(n,r),a=b(n);return {errorType:"storage",errorCode:String(e.statusCode??n),message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}return M(e)}catch{return {errorType:"unknown",errorCode:"PARSE_ERROR",message:"Failed to parse error object",humanExplanation:"An error occurred but could not be parsed. Check the raw error for details.",suggestedCategory:"unknown"}}}function K(e){let t=e.message;return e.details&&(t+=` | Details: ${e.details}`),e.hint&&(t+=` | Hint: ${e.hint}`),t}function M(e){let t="Unknown error",r="UNKNOWN";if(e instanceof Error)t=e.message,r=e.name??"Error";else if(e!==null&&typeof e=="object"){let n=e;typeof n.message=="string"&&(t=n.message),typeof n.code=="string"?r=n.code:typeof n.name=="string"&&(r=n.name);}else typeof e=="string"&&(t=e);return {errorType:"unknown",errorCode:r,message:t,humanExplanation:`Supabase error: ${t}. This error type was not recognized by the parser. Refer to the Supabase documentation for more details.`,suggestedCategory:"unknown"}}var G=new Set(["password","access_token","refresh_token","token","session","cookie","authorization","apikey","api_key","secret","credential","credentials","nonce","code_verifier","code_challenge"]);function _(e){if(e==null||typeof e!="object")return e;if(Array.isArray(e))return e.map(_);let t={};for(let[r,n]of Object.entries(e))G.has(r.toLowerCase())?t[r]="[REDACTED]":typeof n=="object"&&n!==null?t[r]=_(n):t[r]=n;return t}function S(e){if(e==null)return String(e);if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);try{let t=JSON.stringify(e);return t.length>100?t.slice(0,97)+"...":t}catch{return "[object]"}}function d(e){try{let t=core.getClient();t&&t.addBreadcrumb(e);}catch{}}function f(e,t){try{let r=core.getClient();r&&r.captureError(e,t);}catch{}}function x(e){return e===null||typeof e!="object"?false:"data"in e&&"error"in e}function w(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"}function y(e,t,r){return e==null||typeof e!="object"&&typeof e!="function"?e:new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}if(o==="then"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c,s){return u.call(n,h=>(J(h,t),c?c(h):h),h=>(k(h,t),s?s(h):Promise.reject(h)))}}if(o==="catch"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c){return u.call(n,s=>(k(s,t),c?c(s):Promise.reject(s)))}}if(o==="finally"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c){return u.call(n,c)}}let i;try{i=Reflect.get(n,o,a);}catch{return}return typeof i=="function"?function(...u){t.track(o,u);let l;try{l=i.apply(n,u);}catch(c){throw k(c,t),c}return w(l)||l!==null&&typeof l=="object"?y(l,t):l}:i!==null&&typeof i=="object"?y(i,t):i}})}function J(e,t,r){try{let n=t.toTrackedQuery(),o={table:n.table,operation:n.operation,chain:n.humanReadable};if(x(e)&&e.error){let a={table:n.table,operation:n.operation,queryChain:n.humanReadable},i=p(e.error,a);d({type:"db_query",category:"supabase.query",message:`Failed: ${n.humanReadable}`,data:{...o,errorCode:i.errorCode,errorType:i.errorType},level:"error"});let u=t.toOperationInfo();u.errorCode=i.errorCode,u.errorDetails=i.humanExplanation,f(e.error,{operation:u,extra:{supabase:{query:n.humanReadable,table:n.table,operation:n.operation,parsedError:i}}});}else d({type:"db_query",category:"supabase.query",message:`OK: ${n.humanReadable}`,data:o,level:"info"});}catch{}}function k(e,t,r){try{let n=t.toTrackedQuery(),o={table:n.table,operation:n.operation,queryChain:n.humanReadable},a=p(e,o);d({type:"db_query",category:"supabase.query",message:`Rejected: ${n.humanReadable}`,data:{table:n.table,operation:n.operation,errorCode:a.errorCode},level:"error"});let i=t.toOperationInfo();i.errorCode=a.errorCode,i.errorDetails=a.humanExplanation,f(e,{operation:i,extra:{supabase:{query:n.humanReadable,table:n.table,operation:n.operation,parsedError:a}}});}catch{}}var V=new Set(["signUp","signInWithPassword","signInWithOtp","signInWithOAuth","signInWithIdToken","signInWithSSO","signOut","getSession","getUser","refreshSession","resetPasswordForEmail","updateUser","setSession","exchangeCodeForSession","reauthenticate","resend","verifyOtp"]);function N(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}if(typeof a!="function"||!V.has(n))return a;let i=n;return function(...u){let l=u.map(s=>s!==null&&typeof s=="object"?_(s):s),c;try{c=a.apply(r,u);}catch(s){throw R(s,i,l),s}return w(c)?c.then(s=>(X(s,i,l),s),s=>(R(s,i,l),Promise.reject(s))):c}}})}function X(e,t,r){try{if(x(e)&&e.error){let n=p(e.error,{operation:t});d({type:"auth",category:"supabase.auth",message:`Auth failed: ${t}`,data:{method:t,errorCode:n.errorCode,errorType:n.errorType},level:"error"});let o={provider:"supabase",type:"auth",method:t,params:core.sanitize(Object.fromEntries(r.map((a,i)=>[`arg${i}`,S(a)]))),errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e.error,{operation:o,extra:{supabase:{subsystem:"auth",method:t,parsedError:n}}});}else d({type:"auth",category:"supabase.auth",message:`Auth OK: ${t}`,data:{method:t},level:"info"});}catch{}}function R(e,t,r){try{let n=p(e,{operation:t});d({type:"auth",category:"supabase.auth",message:`Auth rejected: ${t}`,data:{method:t,errorCode:n.errorCode},level:"error"});let o={provider:"supabase",type:"auth",method:t,params:core.sanitize(Object.fromEntries(r.map((a,i)=>[`arg${i}`,S(a)]))),errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e,{operation:o,extra:{supabase:{subsystem:"auth",method:t,parsedError:n}}});}catch{}}function Y(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}return typeof a!="function"||n!=="invoke"?a:function(i,u){let l=u?_(u):void 0,c;try{c=a.apply(r,[i,u]);}catch(s){throw v(s,i,l),s}return w(c)?c.then(s=>(Z(s,i,l),s),s=>(v(s,i,l),Promise.reject(s))):c}}})}function Z(e,t,r){try{if(x(e)&&e.error){let n=p(e.error,{functionName:t,operation:"invoke"});d({type:"api_call",category:"supabase.functions",message:`Function failed: ${t}`,data:{functionName:t,errorCode:n.errorCode,errorType:n.errorType},level:"error"});let o={provider:"supabase",type:"functions",method:"invoke",params:{functionName:t,options:S(r)},errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e.error,{operation:o,extra:{supabase:{subsystem:"functions",functionName:t,parsedError:n}}});}else d({type:"api_call",category:"supabase.functions",message:`Function OK: ${t}`,data:{functionName:t},level:"info"});}catch{}}function v(e,t,r){try{let n=p(e,{functionName:t,operation:"invoke"});d({type:"api_call",category:"supabase.functions",message:`Function rejected: ${t}`,data:{functionName:t,errorCode:n.errorCode},level:"error"});let o={provider:"supabase",type:"functions",method:"invoke",params:{functionName:t,options:S(r)},errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e,{operation:o,extra:{supabase:{subsystem:"functions",functionName:t,parsedError:n}}});}catch{}}var ee=new Set(["upload","download","remove","list","move","copy","createSignedUrl","createSignedUrls","getPublicUrl"]);function te(e,t,r){return new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}let i;try{i=Reflect.get(n,o,a);}catch{return}if(typeof i!="function"||!ee.has(o))return i;let u=o;return function(...l){let c;try{c=i.apply(n,l);}catch(s){throw P(s,t,u,l),s}return w(c)?c.then(s=>(ne(s,t,u,l),s),s=>(P(s,t,u,l),Promise.reject(s))):c}}})}function ne(e,t,r,n){try{if(x(e)&&e.error){let o=p(e.error,{bucketName:t,operation:r});d({type:"api_call",category:"supabase.storage",message:`Storage failed: ${r} on ${t}`,data:{bucket:t,method:r,errorCode:o.errorCode},level:"error"});let a={provider:"supabase",type:"storage",method:r,params:{bucket:t,path:typeof n[0]=="string"?n[0]:void 0},errorCode:o.errorCode,errorDetails:o.humanExplanation};f(e.error,{operation:a,extra:{supabase:{subsystem:"storage",bucket:t,method:r,parsedError:o}}});}else d({type:"api_call",category:"supabase.storage",message:`Storage OK: ${r} on ${t}`,data:{bucket:t,method:r},level:"info"});}catch{}}function P(e,t,r,n){try{let o=p(e,{bucketName:t,operation:r});d({type:"api_call",category:"supabase.storage",message:`Storage rejected: ${r} on ${t}`,data:{bucket:t,method:r,errorCode:o.errorCode},level:"error"});let a={provider:"supabase",type:"storage",method:r,params:{bucket:t,path:typeof n[0]=="string"?n[0]:void 0},errorCode:o.errorCode,errorDetails:o.humanExplanation};f(e,{operation:a,extra:{supabase:{subsystem:"storage",bucket:t,method:r,parsedError:o}}});}catch{}}function re(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}return typeof a=="function"&&n==="from"?function(i){let u=a.apply(r,[i]);return u!==null&&typeof u=="object"?te(u,i):u}:a}})}function oe(e){return {trackQueries:e.trackQueries??true,trackAuth:e.trackAuth??true,trackFunctions:e.trackFunctions??true,trackStorage:e.trackStorage??false,trackRealtime:e.trackRealtime??false}}function j(e,t){if(e==null||typeof e!="object"&&typeof e!="function")return e;let r=oe(t);return new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}let i;try{i=Reflect.get(n,o,a);}catch{return}return o==="from"&&typeof i=="function"&&r.trackQueries?function(...u){let l=new g;l.track("from",u);let c;try{c=i.apply(n,u);}catch(s){throw k(s,l),s}return c!==null&&typeof c=="object"?y(c,l):c}:o==="rpc"&&typeof i=="function"&&r.trackQueries?function(...u){let l=new g;l.track("rpc",u);let c;try{c=i.apply(n,u);}catch(s){throw k(s,l),s}return w(c)||c!==null&&typeof c=="object"?y(c,l):c}:o==="auth"&&r.trackAuth&&i!==null&&typeof i=="object"?N(i):o==="functions"&&r.trackFunctions&&i!==null&&typeof i=="object"?Y(i):o==="storage"&&r.trackStorage&&i!==null&&typeof i=="object"?re(i):i},set(n,o,a,i){return Reflect.set(n,o,a,i)},has(n,o){return Reflect.has(n,o)},deleteProperty(n,o){return Reflect.deleteProperty(n,o)},ownKeys(n){return Reflect.ownKeys(n)},getOwnPropertyDescriptor(n,o){return Reflect.getOwnPropertyDescriptor(n,o)},getPrototypeOf(n){return Reflect.getPrototypeOf(n)},isExtensible(n){return Reflect.isExtensible(n)},preventExtensions(n){return Reflect.preventExtensions(n)},defineProperty(n,o,a){return Reflect.defineProperty(n,o,a)},setPrototypeOf(n,o){return Reflect.setPrototypeOf(n,o)}})}function ye(e,t){return j(e,t??{})}exports.wrapSupabase=ye;//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/query-tracker.ts","../src/rls-explainer.ts","../src/error-parser.ts","../src/proxy.ts","../src/index.ts"],"names":["MAX_BULK_PREVIEW","CRUD_METHODS","sanitizeArg","value","item","sanitize","v","sanitizeArgs","args","formatValue","str","QueryTracker","method","sanitizedArgs","step","formattedArgs","EXPLANATIONS","interpolate","template","context","match","key","explainSupabaseError","errorCode","entry","getCategoryForCode","isPostgrestError","error","e","isAuthError","isFunctionsError","isStorageError","classifyAuthError","msg","classifyFunctionsError","name","classifyStorageError","code","parseSupabaseError","explainerCtx","explanation","category","buildPostgrestMessage","internalCode","parseGenericError","message","AUTH_SENSITIVE_KEYS","sanitizeAuthData","data","result","safeArgString","arg","addBreadcrumb","crumb","client","getClient","captureError","isSupabaseResult","isThenable","createQueryBuilderProxy","target","tracker","options","obj","prop","receiver","thenFn","onFulfilled","onRejected","handleQueryResult","reason","handleQueryError","catchFn","finallyFn","onFinally","err","_options","trackedQuery","breadcrumbData","parserContext","parsed","operationInfo","AUTH_METHODS","createAuthProxy","authTarget","methodName","handleAuthError","resolved","handleAuthResult","rejected","createFunctionsProxy","functionsTarget","functionName","invokeOptions","sanitizedOptions","handleFunctionsError","handleFunctionsResult","STORAGE_METHODS","createStorageBucketProxy","bucketTarget","bucketName","handleStorageError","handleStorageResult","createStorageProxy","storageTarget","bucketClient","resolveOptions","createSupabaseProxy","descriptor","proto","wrapSupabase"],"mappings":"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","file":"index.js","sourcesContent":["// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — query chain tracker\n// ---------------------------------------------------------------------------\n//\n// Records each method call in a Supabase query builder chain so that errors\n// can be reported with full context about what the developer was trying to do.\n// ---------------------------------------------------------------------------\n\nimport { sanitize } from '@uncaughtdev/core';\nimport type { OperationInfo } from '@uncaughtdev/core';\nimport type { QueryChainStep, TrackedQuery } from './types';\n\n/** Maximum number of items to keep from bulk insert/upsert arrays. */\nconst MAX_BULK_PREVIEW = 3;\n\n/** Primary CRUD operations that determine the query type. */\nconst CRUD_METHODS = new Set([\n 'select',\n 'insert',\n 'update',\n 'upsert',\n 'delete',\n]);\n\n/**\n * Sanitize a single argument value.\n * - Arrays of objects (bulk inserts) are truncated to the first N items.\n * - Everything is run through the core sanitizer to redact sensitive keys.\n */\nfunction sanitizeArg(value: unknown): unknown {\n try {\n if (Array.isArray(value) && value.length > MAX_BULK_PREVIEW) {\n const truncated = value.slice(0, MAX_BULK_PREVIEW).map((item) => {\n if (item !== null && typeof item === 'object') {\n return sanitize(item as Record<string, unknown>);\n }\n return item;\n });\n return `[${truncated.map((v) => JSON.stringify(v)).join(', ')} ... and ${value.length - MAX_BULK_PREVIEW} more]`;\n }\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return sanitize(value as Record<string, unknown>);\n }\n\n return value;\n } catch {\n return '[unserializable]';\n }\n}\n\n/**\n * Sanitize an array of arguments for safe storage and display.\n */\nfunction sanitizeArgs(args: unknown[]): unknown[] {\n return args.map(sanitizeArg);\n}\n\n/**\n * Format a single value for the human-readable query string.\n */\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') {\n return `'${value}'`;\n }\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === 'object') {\n try {\n const str = JSON.stringify(value);\n if (str.length > 120) {\n return str.slice(0, 117) + '...';\n }\n return str;\n } catch {\n return '[object]';\n }\n }\n return String(value);\n}\n\n/**\n * Tracks method calls in a Supabase query builder chain.\n *\n * Usage:\n * ```ts\n * const tracker = new QueryTracker();\n * tracker.track('from', ['orders']);\n * tracker.track('select', ['*']);\n * tracker.track('eq', ['user_id', '123']);\n *\n * tracker.getTable(); // 'orders'\n * tracker.getOperation(); // 'select'\n * tracker.toHumanReadable(); // \".from('orders').select('*').eq('user_id', '123')\"\n * ```\n */\nexport class QueryTracker {\n private readonly steps: QueryChainStep[] = [];\n private tableName = '';\n private operationType = 'unknown';\n\n /**\n * Record a method call in the chain.\n *\n * @param method - The method name (e.g. 'from', 'select', 'eq').\n * @param args - The arguments passed to the method.\n */\n track(method: string, args: unknown[]): void {\n const sanitizedArgs = sanitizeArgs(args);\n this.steps.push({ method, args: sanitizedArgs });\n\n // Extract table name from .from('tableName')\n if (method === 'from' && args.length > 0 && typeof args[0] === 'string') {\n this.tableName = args[0];\n }\n\n // Extract operation type from CRUD methods\n if (CRUD_METHODS.has(method)) {\n this.operationType = method;\n }\n\n // Also detect .rpc() calls\n if (method === 'rpc') {\n this.operationType = 'rpc';\n }\n }\n\n /**\n * Get the table name extracted from .from() calls.\n */\n getTable(): string {\n return this.tableName;\n }\n\n /**\n * Get the primary CRUD operation type.\n */\n getOperation(): string {\n return this.operationType;\n }\n\n /**\n * Get all tracked steps.\n */\n getSteps(): QueryChainStep[] {\n return [...this.steps];\n }\n\n /**\n * Build a human-readable representation of the full query chain.\n *\n * @example\n * \".from('orders').select('*').eq('user_id', '123').limit(10)\"\n */\n toHumanReadable(): string {\n if (this.steps.length === 0) {\n return '(empty chain)';\n }\n\n return this.steps\n .map((step) => {\n const formattedArgs = step.args.map(formatValue).join(', ');\n return `.${step.method}(${formattedArgs})`;\n })\n .join('');\n }\n\n /**\n * Convert the tracked query into a full TrackedQuery object.\n */\n toTrackedQuery(): TrackedQuery {\n return {\n table: this.tableName,\n operation: this.operationType,\n chain: [...this.steps],\n humanReadable: this.toHumanReadable(),\n };\n }\n\n /**\n * Convert the tracked query into an OperationInfo compatible with UncaughtEvent.\n */\n toOperationInfo(): OperationInfo {\n return {\n provider: 'supabase',\n type: 'query',\n method: this.operationType,\n params: {\n table: this.tableName,\n chain: this.toHumanReadable(),\n },\n };\n }\n\n /**\n * Check if any steps have been tracked.\n */\n isEmpty(): boolean {\n return this.steps.length === 0;\n }\n\n /**\n * Reset the tracker for reuse.\n */\n reset(): void {\n this.steps.length = 0;\n this.tableName = '';\n this.operationType = 'unknown';\n }\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — human-readable error explanations\n// ---------------------------------------------------------------------------\n//\n// Maps Supabase / PostgreSQL error codes to developer-friendly explanations\n// with contextual variable interpolation.\n// ---------------------------------------------------------------------------\n\n/**\n * Context variables that can be interpolated into explanation templates.\n */\nexport interface ExplainerContext {\n table?: string;\n operation?: string;\n name?: string;\n column?: string;\n constraint?: string;\n [key: string]: string | undefined;\n}\n\n/**\n * An explanation template with {variable} placeholders.\n */\ninterface ExplanationTemplate {\n template: string;\n category: string;\n}\n\n/**\n * Registry of error code to explanation template mappings.\n *\n * Templates support {variable} interpolation from the ExplainerContext.\n * Unknown variables are left as-is in the output (e.g. \"{table}\" if no\n * table context is provided).\n */\nconst EXPLANATIONS: Record<string, ExplanationTemplate> = {\n // -------------------------------------------------------------------------\n // PostgreSQL error codes\n // -------------------------------------------------------------------------\n\n '42501': {\n template:\n \"The RLS policy on the '{table}' table does not allow {operation} operations for the current user role. \" +\n \"Check your RLS policies in the Supabase dashboard under Authentication > Policies for the '{table}' table. \" +\n 'Common causes: missing policy for the operation type, policy condition not matching the current user, ' +\n \"or the user's JWT role not having the expected grants.\",\n category: 'rls_violation',\n },\n\n '23505': {\n template:\n \"A record with this value already exists. The unique constraint on table '{table}' was violated. \" +\n 'This typically means you are trying to insert or update a row with a value that must be unique ' +\n '(e.g. email, username, slug) but another row already has that value. ' +\n 'Consider using .upsert() instead of .insert() if you want to update on conflict, ' +\n 'or check for existing records before inserting.',\n category: 'unique_violation',\n },\n\n '23503': {\n template:\n \"The referenced record does not exist. The foreign key constraint on table '{table}' failed. \" +\n 'This means you are trying to insert or update a row that references another row (via a foreign key) ' +\n 'that does not exist in the referenced table. Ensure the referenced record exists before ' +\n 'creating this relationship, or check that the foreign key value is correct.',\n category: 'foreign_key_violation',\n },\n\n '23502': {\n template:\n \"A required field was not provided. The not-null constraint on table '{table}' was violated. \" +\n 'One or more columns that are defined as NOT NULL did not receive a value in the insert or update. ' +\n 'Check your insert/update payload to ensure all required fields are present, ' +\n 'or set a default value for the column in your database schema.',\n category: 'not_null_violation',\n },\n\n '42P01': {\n template:\n \"The table '{table}' does not exist in the database. This could mean the table name is misspelled, \" +\n 'the table has not been created yet, or you are connecting to the wrong database/schema. ' +\n \"Check the table name in your .from() call and verify it exists in the Supabase dashboard's \" +\n 'Table Editor.',\n category: 'undefined_table',\n },\n\n '42703': {\n template:\n \"The column '{column}' does not exist in table '{table}'. Check that the column name is spelled \" +\n 'correctly and that any recent migrations have been applied.',\n category: 'undefined_column',\n },\n\n '42883': {\n template:\n \"The function or operator does not exist. If you are using .rpc('{name}'), check that the function \" +\n 'exists in your database and that the argument types match.',\n category: 'undefined_function',\n },\n\n // -------------------------------------------------------------------------\n // PostgREST error codes\n // -------------------------------------------------------------------------\n\n PGRST116: {\n template:\n 'Expected a single row but got none. The .single() call on the query returned 0 rows. ' +\n \"This means no record matched your filter conditions in table '{table}'. \" +\n 'If the record might not exist, use .maybeSingle() instead of .single() ' +\n 'to return null instead of an error when no rows match.',\n category: 'no_rows',\n },\n\n PGRST301: {\n template:\n 'The authentication token (JWT) has expired. The user needs to re-authenticate. ' +\n 'This typically happens when the session has been idle for longer than the JWT expiry time. ' +\n 'Call supabase.auth.refreshSession() to attempt a token refresh, or redirect the user ' +\n 'to the sign-in page. Consider setting up an onAuthStateChange listener to handle ' +\n 'token refreshes automatically.',\n category: 'jwt_expired',\n },\n\n PGRST204: {\n template:\n \"The column '{column}' specified in the query does not exist in the database schema. \" +\n 'PostgREST could not find this column when processing the query.',\n category: 'column_not_found',\n },\n\n PGRST200: {\n template:\n \"An ambiguous embedding was detected. The relationship between '{table}' and the referenced \" +\n 'table could not be resolved because multiple foreign keys exist. ' +\n 'Specify the foreign key explicitly using the !inner or !left join syntax.',\n category: 'ambiguous_embedding',\n },\n\n // -------------------------------------------------------------------------\n // Auth error patterns (matched by message content, not code)\n // -------------------------------------------------------------------------\n\n auth_invalid_credentials: {\n template:\n 'The email or password is incorrect. Note: if the user recently signed up, their email ' +\n 'may not be confirmed yet. Check the Supabase dashboard under Authentication > Users to see ' +\n \"the user's confirmation status. Also verify that the email provider is enabled in \" +\n 'Authentication > Providers.',\n category: 'auth_invalid_credentials',\n },\n\n auth_email_not_confirmed: {\n template:\n 'The user has signed up but has not confirmed their email address. ' +\n 'Check your email confirmation settings in Authentication > Settings. ' +\n 'You can disable email confirmation for development, or resend the confirmation email ' +\n 'using supabase.auth.resend({ type: \"signup\", email }).',\n category: 'auth_email_not_confirmed',\n },\n\n auth_rate_limited: {\n template:\n 'Too many authentication attempts. Supabase rate limits auth endpoints to prevent abuse. ' +\n 'The default rate limit is approximately 30 requests per hour for auth endpoints. ' +\n 'Wait a few minutes before trying again. If you are hitting this in production, ' +\n 'consider implementing client-side rate limiting or CAPTCHA.',\n category: 'auth_rate_limited',\n },\n\n auth_user_not_found: {\n template:\n 'No user was found with the provided credentials. The user may not have signed up yet, ' +\n 'or the account may have been deleted.',\n category: 'auth_user_not_found',\n },\n\n auth_session_not_found: {\n template:\n 'No active session was found. The user is not currently signed in or their session has expired. ' +\n 'Redirect the user to the sign-in page.',\n category: 'auth_session_not_found',\n },\n\n auth_signup_disabled: {\n template:\n 'New user signups have been disabled for this project. Enable signups in the Supabase dashboard ' +\n 'under Authentication > Settings.',\n category: 'auth_signup_disabled',\n },\n\n // -------------------------------------------------------------------------\n // Edge Functions error patterns\n // -------------------------------------------------------------------------\n\n functions_timeout: {\n template:\n \"The edge function '{name}' timed out. Edge functions have a default execution time limit \" +\n '(typically 60 seconds on the free plan). Consider optimizing the function, ' +\n 'breaking it into smaller operations, or upgrading your Supabase plan for longer execution times.',\n category: 'functions_timeout',\n },\n\n functions_crashed: {\n template:\n \"The edge function '{name}' crashed during execution. Check the function logs in the \" +\n 'Supabase dashboard under Edge Functions > Logs for the specific error. ' +\n 'Common causes: unhandled exceptions, out-of-memory errors, or missing environment variables.',\n category: 'functions_crashed',\n },\n\n functions_cors: {\n template:\n \"The edge function '{name}' was blocked by CORS. Ensure the function sets the appropriate \" +\n \"CORS headers in its response. Add 'Access-Control-Allow-Origin' and other necessary CORS \" +\n 'headers, and handle OPTIONS preflight requests.',\n category: 'functions_cors',\n },\n\n functions_not_found: {\n template:\n \"The edge function '{name}' was not found. Verify that the function has been deployed \" +\n 'and that the function name matches exactly (case-sensitive).',\n category: 'functions_not_found',\n },\n\n functions_relay_error: {\n template:\n \"The edge function '{name}' encountered a relay error. This is typically a transient \" +\n 'infrastructure issue. Retry the request after a brief delay.',\n category: 'functions_relay_error',\n },\n\n functions_fetch_error: {\n template:\n \"Failed to invoke the edge function '{name}'. This could be a network connectivity issue, \" +\n 'DNS resolution failure, or the Supabase project may be paused. Check your internet connection ' +\n 'and verify the project is active in the Supabase dashboard.',\n category: 'functions_fetch_error',\n },\n\n // -------------------------------------------------------------------------\n // Storage error patterns\n // -------------------------------------------------------------------------\n\n storage_bucket_not_found: {\n template:\n 'The storage bucket was not found. Verify the bucket name is correct and that it has been ' +\n \"created in the Supabase dashboard under Storage. Bucket names are case-sensitive.\",\n category: 'storage_bucket_not_found',\n },\n\n storage_object_too_large: {\n template:\n 'The uploaded file exceeds the maximum allowed size. Check the file size limit configured ' +\n 'for this bucket in the Supabase dashboard under Storage > Policies. ' +\n 'The default maximum file size is 50MB on the free plan.',\n category: 'storage_object_too_large',\n },\n\n storage_permission_denied: {\n template:\n 'Permission denied for this storage operation. Check the storage policies (RLS) configured ' +\n 'for this bucket. Storage uses its own set of policies separate from table-level RLS. ' +\n 'Configure policies in the Supabase dashboard under Storage > Policies.',\n category: 'storage_permission_denied',\n },\n\n storage_object_not_found: {\n template:\n 'The requested file does not exist in storage. Verify the file path is correct and that ' +\n 'the file has been uploaded. File paths in storage are case-sensitive.',\n category: 'storage_object_not_found',\n },\n};\n\n/**\n * Interpolate {variable} placeholders in a template string.\n *\n * Any variable in the template that is not found in the context is left\n * as-is (e.g. `{table}` remains if context.table is undefined).\n */\nfunction interpolate(template: string, context: ExplainerContext): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const value = context[key];\n return value !== undefined ? value : match;\n });\n}\n\n/**\n * Get a human-readable explanation for a Supabase error code.\n *\n * @param errorCode - The error code (PostgreSQL code, PostgREST code, or\n * internal category key like 'auth_invalid_credentials').\n * @param context - Optional context variables for template interpolation.\n * @returns A human-readable explanation string. Falls back to a generic\n * message if the error code is not recognized.\n */\nexport function explainSupabaseError(\n errorCode: string,\n context?: ExplainerContext,\n): string {\n const entry = EXPLANATIONS[errorCode];\n\n if (!entry) {\n return `Supabase error (code: ${errorCode}). Refer to the Supabase documentation or PostgreSQL error code reference for more details.`;\n }\n\n return interpolate(entry.template, context ?? {});\n}\n\n/**\n * Get the suggested category for a known error code.\n *\n * @param errorCode - The error code to look up.\n * @returns The category string, or 'unknown' if the code is not recognized.\n */\nexport function getCategoryForCode(errorCode: string): string {\n const entry = EXPLANATIONS[errorCode];\n return entry?.category ?? 'unknown';\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — error parser\n// ---------------------------------------------------------------------------\n//\n// Detects the type of Supabase error by inspecting its shape/properties, then\n// maps it to a structured ParsedSupabaseError with human-readable explanation.\n// ---------------------------------------------------------------------------\n\nimport type { ParsedSupabaseError } from './types';\nimport {\n explainSupabaseError,\n getCategoryForCode,\n type ExplainerContext,\n} from './rls-explainer';\n\n// ---------------------------------------------------------------------------\n// Error shape interfaces (matching Supabase SDK error types)\n// ---------------------------------------------------------------------------\n\ninterface PostgrestErrorShape {\n message: string;\n details: string | null;\n hint: string | null;\n code: string;\n}\n\ninterface AuthErrorShape {\n message: string;\n status?: number;\n name?: string;\n __isAuthError?: boolean;\n}\n\ninterface FunctionsErrorShape {\n message: string;\n name?: string;\n context?: unknown;\n}\n\ninterface StorageErrorShape {\n message: string;\n statusCode?: string | number;\n error?: string;\n name?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\nfunction isPostgrestError(error: unknown): error is PostgrestErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n return (\n typeof e.message === 'string' &&\n 'code' in e &&\n typeof e.code === 'string' &&\n 'details' in e &&\n 'hint' in e\n );\n}\n\nfunction isAuthError(error: unknown): error is AuthErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n\n // Supabase auth errors have __isAuthError or specific name patterns\n if (e.__isAuthError === true) return true;\n if (\n typeof e.name === 'string' &&\n (e.name === 'AuthApiError' ||\n e.name === 'AuthRetryableFetchError' ||\n e.name === 'AuthUnknownError' ||\n e.name === 'AuthWeakPasswordError' ||\n e.name === 'AuthSessionMissingError')\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction isFunctionsError(error: unknown): error is FunctionsErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n return (\n typeof e.name === 'string' &&\n (e.name === 'FunctionsHttpError' ||\n e.name === 'FunctionsRelayError' ||\n e.name === 'FunctionsFetchError')\n );\n}\n\nfunction isStorageError(error: unknown): error is StorageErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n\n // Storage errors from Supabase have statusCode and/or a name containing 'Storage'\n if (typeof e.name === 'string' && e.name === 'StorageApiError') return true;\n if (typeof e.statusCode === 'string' || typeof e.statusCode === 'number') {\n // Must also have a message to qualify\n return typeof e.message === 'string';\n }\n\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Auth error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for auth errors based on message content.\n */\nfunction classifyAuthError(error: AuthErrorShape): string {\n const msg = error.message.toLowerCase();\n\n if (msg.includes('invalid login credentials') || msg.includes('invalid credentials')) {\n return 'auth_invalid_credentials';\n }\n if (msg.includes('email not confirmed') || msg.includes('not confirmed')) {\n return 'auth_email_not_confirmed';\n }\n if (msg.includes('rate limit') || msg.includes('too many requests') || error.status === 429) {\n return 'auth_rate_limited';\n }\n if (msg.includes('user not found') || msg.includes('no user found')) {\n return 'auth_user_not_found';\n }\n if (msg.includes('session not found') || msg.includes('not authenticated') || msg.includes('session_not_found')) {\n return 'auth_session_not_found';\n }\n if (msg.includes('signups not allowed') || msg.includes('signup is disabled') || msg.includes('signups are disabled')) {\n return 'auth_signup_disabled';\n }\n\n return 'auth_unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Functions error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for edge function errors.\n */\nfunction classifyFunctionsError(error: FunctionsErrorShape): string {\n const msg = error.message.toLowerCase();\n const name = error.name ?? '';\n\n if (name === 'FunctionsRelayError') {\n return 'functions_relay_error';\n }\n if (name === 'FunctionsFetchError') {\n return 'functions_fetch_error';\n }\n\n // FunctionsHttpError — inspect message for specifics\n if (msg.includes('timeout') || msg.includes('timed out') || msg.includes('deadline exceeded')) {\n return 'functions_timeout';\n }\n if (msg.includes('cors') || msg.includes('cross-origin')) {\n return 'functions_cors';\n }\n if (msg.includes('not found') || msg.includes('404')) {\n return 'functions_not_found';\n }\n if (msg.includes('crashed') || msg.includes('internal server error') || msg.includes('500')) {\n return 'functions_crashed';\n }\n\n return 'functions_crashed'; // default for unknown HTTP errors\n}\n\n// ---------------------------------------------------------------------------\n// Storage error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for storage errors.\n */\nfunction classifyStorageError(error: StorageErrorShape): string {\n const msg = error.message.toLowerCase();\n const code = String(error.statusCode ?? '');\n\n if (msg.includes('bucket') && (msg.includes('not found') || msg.includes('does not exist'))) {\n return 'storage_bucket_not_found';\n }\n if (msg.includes('too large') || msg.includes('payload too large') || msg.includes('file size') || code === '413') {\n return 'storage_object_too_large';\n }\n if (msg.includes('permission') || msg.includes('not authorized') || msg.includes('policy') || code === '403') {\n return 'storage_permission_denied';\n }\n if (msg.includes('not found') || msg.includes('object not found') || code === '404') {\n return 'storage_object_not_found';\n }\n\n return 'storage_permission_denied'; // default to permission for unknown storage errors\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Additional context to aid error parsing and explanation generation.\n */\nexport interface ErrorParserContext {\n /** The table name from the query tracker. */\n table?: string;\n /** The operation type (select, insert, update, etc.). */\n operation?: string;\n /** The edge function name for function invocation errors. */\n functionName?: string;\n /** The storage bucket name. */\n bucketName?: string;\n /** The human-readable query chain. */\n queryChain?: string;\n}\n\n/**\n * Parse any Supabase error into a structured ParsedSupabaseError.\n *\n * Detects the error type by inspecting the object's shape and properties,\n * then provides a categorized result with human-readable explanation.\n *\n * @param error - The error object from Supabase ({ data, error } result).\n * @param context - Optional context for richer explanations.\n * @returns A fully structured ParsedSupabaseError.\n */\nexport function parseSupabaseError(\n error: unknown,\n context?: ErrorParserContext,\n): ParsedSupabaseError {\n try {\n // Build explainer context from the parser context\n const explainerCtx: ExplainerContext = {\n table: context?.table,\n operation: context?.operation,\n name: context?.functionName,\n column: undefined,\n constraint: undefined,\n };\n\n // ----- PostgrestError -----\n if (isPostgrestError(error)) {\n const errorCode = error.code;\n const explanation = explainSupabaseError(errorCode, explainerCtx);\n const category = getCategoryForCode(errorCode);\n\n return {\n errorType: 'postgrest',\n errorCode,\n message: buildPostgrestMessage(error),\n humanExplanation: explanation,\n suggestedCategory: category,\n };\n }\n\n // ----- AuthError -----\n if (isAuthError(error)) {\n const internalCode = classifyAuthError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'auth',\n errorCode: error.name ?? internalCode,\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- FunctionsError -----\n if (isFunctionsError(error)) {\n const internalCode = classifyFunctionsError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'functions',\n errorCode: error.name ?? internalCode,\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- StorageError -----\n if (isStorageError(error)) {\n const internalCode = classifyStorageError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'storage',\n errorCode: String(error.statusCode ?? internalCode),\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- Generic / unknown error -----\n return parseGenericError(error);\n } catch {\n // Never let the parser itself crash the host app\n return {\n errorType: 'unknown',\n errorCode: 'PARSE_ERROR',\n message: 'Failed to parse error object',\n humanExplanation:\n 'An error occurred but could not be parsed. Check the raw error for details.',\n suggestedCategory: 'unknown',\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build a comprehensive message string from a PostgREST error, including\n * details and hint when available.\n */\nfunction buildPostgrestMessage(error: PostgrestErrorShape): string {\n let msg = error.message;\n if (error.details) {\n msg += ` | Details: ${error.details}`;\n }\n if (error.hint) {\n msg += ` | Hint: ${error.hint}`;\n }\n return msg;\n}\n\n/**\n * Handle generic/unknown error shapes that don't match any known Supabase type.\n */\nfunction parseGenericError(error: unknown): ParsedSupabaseError {\n let message = 'Unknown error';\n let errorCode = 'UNKNOWN';\n\n if (error instanceof Error) {\n message = error.message;\n errorCode = error.name ?? 'Error';\n } else if (error !== null && typeof error === 'object') {\n const e = error as Record<string, unknown>;\n if (typeof e.message === 'string') {\n message = e.message;\n }\n if (typeof e.code === 'string') {\n errorCode = e.code;\n } else if (typeof e.name === 'string') {\n errorCode = e.name;\n }\n } else if (typeof error === 'string') {\n message = error;\n }\n\n return {\n errorType: 'unknown',\n errorCode,\n message,\n humanExplanation: `Supabase error: ${message}. This error type was not recognized by the parser. Refer to the Supabase documentation for more details.`,\n suggestedCategory: 'unknown',\n };\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — deep Proxy wrapper\n// ---------------------------------------------------------------------------\n//\n// Creates a transparent Proxy around a SupabaseClient that intercepts all\n// operations to capture errors and record breadcrumbs, without changing any\n// observable behavior. The wrapped client has identical types and behavior\n// to the original — the Proxy is fully transparent.\n//\n// Strategy:\n// 1. Wrap the top-level SupabaseClient with a Proxy.\n// 2. When .from(), .auth, .functions, .storage is accessed, return a proxied\n// version that tracks operations via QueryTracker.\n// 3. QueryTracker records each method in the chain (.select(), .eq(), etc.).\n// 4. When a terminal operation executes (returns a Promise/thenable), we\n// intercept the resolved value.\n// 5. If the result has an `error` field (Supabase's { data, error } pattern),\n// we capture it with full context via getClient().captureError().\n// 6. We ALWAYS return the original result — completely transparent.\n// ---------------------------------------------------------------------------\n\nimport { getClient, sanitize } from '@uncaughtdev/core';\nimport type { Breadcrumb, OperationInfo } from '@uncaughtdev/core';\nimport { QueryTracker } from './query-tracker';\nimport { parseSupabaseError, type ErrorParserContext } from './error-parser';\nimport type { WrapSupabaseOptions } from './types';\n\n// ---------------------------------------------------------------------------\n// Sensitive key patterns that must never be captured\n// ---------------------------------------------------------------------------\n\nconst AUTH_SENSITIVE_KEYS = new Set([\n 'password',\n 'access_token',\n 'refresh_token',\n 'token',\n 'session',\n 'cookie',\n 'authorization',\n 'apikey',\n 'api_key',\n 'secret',\n 'credential',\n 'credentials',\n 'nonce',\n 'code_verifier',\n 'code_challenge',\n]);\n\n/**\n * Deep-sanitize an object, redacting any keys that match sensitive patterns.\n * This is used specifically for auth-related data where we want to be extra\n * cautious about not capturing passwords, tokens, or session data.\n */\nfunction sanitizeAuthData(data: unknown): unknown {\n if (data === null || data === undefined) return data;\n if (typeof data !== 'object') return data;\n if (Array.isArray(data)) return data.map(sanitizeAuthData);\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n if (AUTH_SENSITIVE_KEYS.has(key.toLowerCase())) {\n result[key] = '[REDACTED]';\n } else if (typeof value === 'object' && value !== null) {\n result[key] = sanitizeAuthData(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Safely extract a string representation from an argument for breadcrumbs.\n */\nfunction safeArgString(arg: unknown): string {\n if (arg === null || arg === undefined) return String(arg);\n if (typeof arg === 'string') return arg;\n if (typeof arg === 'number' || typeof arg === 'boolean') return String(arg);\n try {\n const str = JSON.stringify(arg);\n return str.length > 100 ? str.slice(0, 97) + '...' : str;\n } catch {\n return '[object]';\n }\n}\n\n/**\n * Add a breadcrumb to the Uncaught client. Silently no-ops if the client\n * is not initialized.\n */\nfunction addBreadcrumb(crumb: Omit<Breadcrumb, 'timestamp'>): void {\n try {\n const client = getClient();\n if (client) {\n client.addBreadcrumb(crumb);\n }\n } catch {\n // Client not initialized — silently ignore\n }\n}\n\n/**\n * Capture an error through the Uncaught client. Silently no-ops if the\n * client is not initialized.\n */\nfunction captureError(\n error: unknown,\n context: {\n operation?: OperationInfo;\n extra?: Record<string, unknown>;\n },\n): void {\n try {\n const client = getClient();\n if (client) {\n client.captureError(error, context);\n }\n } catch {\n // Client not initialized — silently ignore\n }\n}\n\n// ---------------------------------------------------------------------------\n// Result inspection\n// ---------------------------------------------------------------------------\n\n/**\n * Check if a value looks like Supabase's { data, error } response pattern.\n */\nfunction isSupabaseResult(value: unknown): value is { data: unknown; error: unknown } {\n if (value === null || typeof value !== 'object') return false;\n return 'data' in value && 'error' in value;\n}\n\n/**\n * Check if a value is a thenable (Promise-like).\n */\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as Record<string, unknown>).then === 'function'\n );\n}\n\n// ---------------------------------------------------------------------------\n// Query builder proxy (for .from() chains)\n// ---------------------------------------------------------------------------\n\n/**\n * Create a proxy around a Supabase query builder that tracks each method\n * call and intercepts the terminal operation to check for errors.\n */\nfunction createQueryBuilderProxy(\n target: unknown,\n tracker: QueryTracker,\n options: WrapSupabaseOptions,\n): unknown {\n if (target === null || target === undefined) return target;\n if (typeof target !== 'object' && typeof target !== 'function') return target;\n\n return new Proxy(target as object, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n // Pass through symbols and non-string props transparently\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n // Special: handle `then` to intercept Promise resolution\n if (prop === 'then') {\n const thenFn = Reflect.get(obj, prop, receiver);\n if (typeof thenFn !== 'function') return thenFn;\n\n // This is a terminal operation — the chain is being awaited\n return function proxiedThen(\n onFulfilled?: ((value: unknown) => unknown) | null,\n onRejected?: ((reason: unknown) => unknown) | null,\n ): unknown {\n return thenFn.call(\n obj,\n (result: unknown) => {\n handleQueryResult(result, tracker, options);\n return onFulfilled ? onFulfilled(result) : result;\n },\n (reason: unknown) => {\n handleQueryError(reason, tracker, options);\n return onRejected ? onRejected(reason) : Promise.reject(reason);\n },\n );\n };\n }\n\n // Handle `catch` for Promise rejection\n if (prop === 'catch') {\n const catchFn = Reflect.get(obj, prop, receiver);\n if (typeof catchFn !== 'function') return catchFn;\n\n return function proxiedCatch(\n onRejected?: ((reason: unknown) => unknown) | null,\n ): unknown {\n return catchFn.call(obj, (reason: unknown) => {\n handleQueryError(reason, tracker, options);\n return onRejected ? onRejected(reason) : Promise.reject(reason);\n });\n };\n }\n\n // Handle `finally` passthrough\n if (prop === 'finally') {\n const finallyFn = Reflect.get(obj, prop, receiver);\n if (typeof finallyFn !== 'function') return finallyFn;\n\n return function proxiedFinally(onFinally?: (() => void) | null): unknown {\n return finallyFn.call(obj, onFinally);\n };\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // If the property is a function, wrap it to track the call\n if (typeof value === 'function') {\n return function (this: unknown, ...args: unknown[]): unknown {\n // Track the method call\n tracker.track(prop, args);\n\n let result: unknown;\n try {\n result = value.apply(obj, args);\n } catch (err) {\n // Synchronous error during method call\n handleQueryError(err, tracker, options);\n throw err;\n }\n\n // If the result is thenable, wrap it for error interception\n if (isThenable(result)) {\n return createQueryBuilderProxy(result, tracker, options);\n }\n\n // If the result is an object (next builder in chain), proxy it too\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, options);\n }\n\n return result;\n };\n }\n\n // If the value is an object, recursively proxy for continued chaining\n if (value !== null && typeof value === 'object') {\n return createQueryBuilderProxy(value, tracker, options);\n }\n\n return value;\n },\n });\n}\n\n/**\n * Handle the resolved result of a query chain, checking for Supabase errors.\n */\nfunction handleQueryResult(\n result: unknown,\n tracker: QueryTracker,\n _options: WrapSupabaseOptions,\n): void {\n try {\n const trackedQuery = tracker.toTrackedQuery();\n const breadcrumbData: Record<string, unknown> = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n chain: trackedQuery.humanReadable,\n };\n\n if (isSupabaseResult(result) && result.error) {\n // Error in the { data, error } response\n const parserContext: ErrorParserContext = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n queryChain: trackedQuery.humanReadable,\n };\n\n const parsed = parseSupabaseError(result.error, parserContext);\n\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `Failed: ${trackedQuery.humanReadable}`,\n data: {\n ...breadcrumbData,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo = tracker.toOperationInfo();\n operationInfo.errorCode = parsed.errorCode;\n operationInfo.errorDetails = parsed.humanExplanation;\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n query: trackedQuery.humanReadable,\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n parsedError: parsed,\n },\n },\n });\n } else {\n // Successful query — add success breadcrumb\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `OK: ${trackedQuery.humanReadable}`,\n data: breadcrumbData,\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app — silently swallow tracking errors\n }\n}\n\n/**\n * Handle a rejected Promise or synchronous throw from a query chain.\n */\nfunction handleQueryError(\n reason: unknown,\n tracker: QueryTracker,\n _options: WrapSupabaseOptions,\n): void {\n try {\n const trackedQuery = tracker.toTrackedQuery();\n\n const parserContext: ErrorParserContext = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n queryChain: trackedQuery.humanReadable,\n };\n\n const parsed = parseSupabaseError(reason, parserContext);\n\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `Rejected: ${trackedQuery.humanReadable}`,\n data: {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo = tracker.toOperationInfo();\n operationInfo.errorCode = parsed.errorCode;\n operationInfo.errorDetails = parsed.humanExplanation;\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n query: trackedQuery.humanReadable,\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auth proxy\n// ---------------------------------------------------------------------------\n\n/** Auth methods that should be intercepted. */\nconst AUTH_METHODS = new Set([\n 'signUp',\n 'signInWithPassword',\n 'signInWithOtp',\n 'signInWithOAuth',\n 'signInWithIdToken',\n 'signInWithSSO',\n 'signOut',\n 'getSession',\n 'getUser',\n 'refreshSession',\n 'resetPasswordForEmail',\n 'updateUser',\n 'setSession',\n 'exchangeCodeForSession',\n 'reauthenticate',\n 'resend',\n 'verifyOtp',\n]);\n\n/**\n * Create a proxy around the Supabase auth object that tracks auth operations.\n */\nfunction createAuthProxy(authTarget: object, options: WrapSupabaseOptions): object {\n return new Proxy(authTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Only intercept known auth methods\n if (typeof value !== 'function' || !AUTH_METHODS.has(prop)) {\n return value;\n }\n\n const methodName = prop;\n\n return function (this: unknown, ...args: unknown[]): unknown {\n // Sanitize auth arguments before recording\n const sanitizedArgs = args.map((arg) => {\n if (arg !== null && typeof arg === 'object') {\n return sanitizeAuthData(arg);\n }\n return arg;\n });\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleAuthError(err, methodName, sanitizedArgs);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleAuthResult(resolved, methodName, sanitizedArgs);\n return resolved;\n },\n (rejected) => {\n handleAuthError(rejected, methodName, sanitizedArgs);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved auth result, checking for errors.\n */\nfunction handleAuthResult(\n result: unknown,\n method: string,\n sanitizedArgs: unknown[],\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, { operation: method });\n\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth failed: ${method}`,\n data: {\n method,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'auth',\n method,\n params: sanitize(\n Object.fromEntries(\n sanitizedArgs.map((a, i) => [`arg${i}`, safeArgString(a)]),\n ),\n ),\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'auth',\n method,\n parsedError: parsed,\n },\n },\n });\n } else {\n // Successful auth operation\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth OK: ${method}`,\n data: { method },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected auth Promise or synchronous throw.\n */\nfunction handleAuthError(\n reason: unknown,\n method: string,\n sanitizedArgs: unknown[],\n): void {\n try {\n const parsed = parseSupabaseError(reason, { operation: method });\n\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth rejected: ${method}`,\n data: {\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'auth',\n method,\n params: sanitize(\n Object.fromEntries(\n sanitizedArgs.map((a, i) => [`arg${i}`, safeArgString(a)]),\n ),\n ),\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'auth',\n method,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Functions proxy\n// ---------------------------------------------------------------------------\n\n/**\n * Create a proxy around the Supabase functions object that intercepts .invoke().\n */\nfunction createFunctionsProxy(\n functionsTarget: object,\n _options: WrapSupabaseOptions,\n): object {\n return new Proxy(functionsTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Only intercept the .invoke() method\n if (typeof value !== 'function' || prop !== 'invoke') {\n return value;\n }\n\n return function (this: unknown, functionName: string, invokeOptions?: unknown): unknown {\n const sanitizedOptions = invokeOptions\n ? sanitizeAuthData(invokeOptions)\n : undefined;\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, [functionName, invokeOptions]);\n } catch (err) {\n handleFunctionsError(err, functionName, sanitizedOptions);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleFunctionsResult(resolved, functionName, sanitizedOptions);\n return resolved;\n },\n (rejected) => {\n handleFunctionsError(rejected, functionName, sanitizedOptions);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved edge function invocation result.\n */\nfunction handleFunctionsResult(\n result: unknown,\n functionName: string,\n sanitizedOptions: unknown,\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, {\n functionName,\n operation: 'invoke',\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function failed: ${functionName}`,\n data: {\n functionName,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'functions',\n method: 'invoke',\n params: {\n functionName,\n options: safeArgString(sanitizedOptions),\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'functions',\n functionName,\n parsedError: parsed,\n },\n },\n });\n } else {\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function OK: ${functionName}`,\n data: { functionName },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected edge function invocation.\n */\nfunction handleFunctionsError(\n reason: unknown,\n functionName: string,\n sanitizedOptions: unknown,\n): void {\n try {\n const parsed = parseSupabaseError(reason, {\n functionName,\n operation: 'invoke',\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function rejected: ${functionName}`,\n data: {\n functionName,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'functions',\n method: 'invoke',\n params: {\n functionName,\n options: safeArgString(sanitizedOptions),\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'functions',\n functionName,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Storage proxy\n// ---------------------------------------------------------------------------\n\n/** Storage methods that should be intercepted. */\nconst STORAGE_METHODS = new Set([\n 'upload',\n 'download',\n 'remove',\n 'list',\n 'move',\n 'copy',\n 'createSignedUrl',\n 'createSignedUrls',\n 'getPublicUrl',\n]);\n\n/**\n * Create a proxy around a Supabase storage bucket (from .storage.from('bucket')).\n */\nfunction createStorageBucketProxy(\n bucketTarget: object,\n bucketName: string,\n _options: WrapSupabaseOptions,\n): object {\n return new Proxy(bucketTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n if (typeof value !== 'function' || !STORAGE_METHODS.has(prop)) {\n return value;\n }\n\n const methodName = prop;\n\n return function (this: unknown, ...args: unknown[]): unknown {\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleStorageError(err, bucketName, methodName, args);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleStorageResult(resolved, bucketName, methodName, args);\n return resolved;\n },\n (rejected) => {\n handleStorageError(rejected, bucketName, methodName, args);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved storage operation result.\n */\nfunction handleStorageResult(\n result: unknown,\n bucketName: string,\n method: string,\n args: unknown[],\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, {\n bucketName,\n operation: method,\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage failed: ${method} on ${bucketName}`,\n data: {\n bucket: bucketName,\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'storage',\n method,\n params: {\n bucket: bucketName,\n path: typeof args[0] === 'string' ? args[0] : undefined,\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'storage',\n bucket: bucketName,\n method,\n parsedError: parsed,\n },\n },\n });\n } else {\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage OK: ${method} on ${bucketName}`,\n data: { bucket: bucketName, method },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected storage operation.\n */\nfunction handleStorageError(\n reason: unknown,\n bucketName: string,\n method: string,\n args: unknown[],\n): void {\n try {\n const parsed = parseSupabaseError(reason, {\n bucketName,\n operation: method,\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage rejected: ${method} on ${bucketName}`,\n data: {\n bucket: bucketName,\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'storage',\n method,\n params: {\n bucket: bucketName,\n path: typeof args[0] === 'string' ? args[0] : undefined,\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'storage',\n bucket: bucketName,\n method,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Create a proxy around the Supabase storage object that intercepts\n * .from('bucket') to return a proxied bucket client.\n */\nfunction createStorageProxy(\n storageTarget: object,\n options: WrapSupabaseOptions,\n): object {\n return new Proxy(storageTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Intercept .from('bucketName') to return a proxied bucket client\n if (typeof value === 'function' && prop === 'from') {\n return function (this: unknown, bucketName: string): unknown {\n const bucketClient = (value as Function).apply(obj, [bucketName]);\n if (bucketClient !== null && typeof bucketClient === 'object') {\n return createStorageBucketProxy(bucketClient as object, bucketName, options);\n }\n return bucketClient;\n };\n }\n\n return value;\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Top-level SupabaseClient proxy\n// ---------------------------------------------------------------------------\n\n/**\n * Resolved options with defaults applied.\n */\nfunction resolveOptions(options: WrapSupabaseOptions): Required<WrapSupabaseOptions> {\n return {\n trackQueries: options.trackQueries ?? true,\n trackAuth: options.trackAuth ?? true,\n trackFunctions: options.trackFunctions ?? true,\n trackStorage: options.trackStorage ?? false,\n trackRealtime: options.trackRealtime ?? false,\n };\n}\n\n/**\n * Create the top-level deep Proxy around a SupabaseClient.\n *\n * This is the main entry point. The returned Proxy intercepts access to\n * `.from()`, `.auth`, `.functions`, and `.storage` to create sub-proxies\n * that track operations and capture errors.\n *\n * The Proxy is fully transparent:\n * - typeof and instanceof work as expected\n * - TypeScript types pass through unchanged\n * - No observable behavior change when there are no errors\n * - Negligible performance overhead (one Proxy get trap per property access)\n *\n * @param client - The original SupabaseClient instance.\n * @param options - Configuration for which subsystems to track.\n * @returns A proxied version of the client with identical type and behavior.\n */\nexport function createSupabaseProxy(\n client: unknown,\n options: WrapSupabaseOptions,\n): unknown {\n // Safety: if the client is null/undefined or not an object, return as-is\n if (client === null || client === undefined) return client;\n if (typeof client !== 'object' && typeof client !== 'function') return client;\n\n const resolved = resolveOptions(options);\n\n return new Proxy(client as object, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n // Pass through symbols transparently (supports typeof, instanceof, etc.)\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // ----- .from('table') — database query builder -----\n if (prop === 'from' && typeof value === 'function' && resolved.trackQueries) {\n return function (this: unknown, ...args: unknown[]): unknown {\n const tracker = new QueryTracker();\n tracker.track('from', args);\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleQueryError(err, tracker, resolved);\n throw err;\n }\n\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n return result;\n };\n }\n\n // ----- .rpc('fn_name', params) — RPC call -----\n if (prop === 'rpc' && typeof value === 'function' && resolved.trackQueries) {\n return function (this: unknown, ...args: unknown[]): unknown {\n const tracker = new QueryTracker();\n tracker.track('rpc', args);\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleQueryError(err, tracker, resolved);\n throw err;\n }\n\n if (isThenable(result)) {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n\n return result;\n };\n }\n\n // ----- .auth — auth operations -----\n if (prop === 'auth' && resolved.trackAuth) {\n if (value !== null && typeof value === 'object') {\n return createAuthProxy(value as object, resolved);\n }\n }\n\n // ----- .functions — edge function invocations -----\n if (prop === 'functions' && resolved.trackFunctions) {\n if (value !== null && typeof value === 'object') {\n return createFunctionsProxy(value as object, resolved);\n }\n }\n\n // ----- .storage — storage operations -----\n if (prop === 'storage' && resolved.trackStorage) {\n if (value !== null && typeof value === 'object') {\n return createStorageProxy(value as object, resolved);\n }\n }\n\n // ----- Everything else passes through -----\n return value;\n },\n\n // Ensure all other traps pass through transparently\n set(obj: object, prop: string | symbol, value: unknown, receiver: unknown): boolean {\n return Reflect.set(obj, prop, value, receiver);\n },\n\n has(obj: object, prop: string | symbol): boolean {\n return Reflect.has(obj, prop);\n },\n\n deleteProperty(obj: object, prop: string | symbol): boolean {\n return Reflect.deleteProperty(obj, prop);\n },\n\n ownKeys(obj: object): ArrayLike<string | symbol> {\n return Reflect.ownKeys(obj);\n },\n\n getOwnPropertyDescriptor(\n obj: object,\n prop: string | symbol,\n ): PropertyDescriptor | undefined {\n return Reflect.getOwnPropertyDescriptor(obj, prop);\n },\n\n getPrototypeOf(obj: object): object | null {\n return Reflect.getPrototypeOf(obj);\n },\n\n isExtensible(obj: object): boolean {\n return Reflect.isExtensible(obj);\n },\n\n preventExtensions(obj: object): boolean {\n return Reflect.preventExtensions(obj);\n },\n\n defineProperty(\n obj: object,\n prop: string | symbol,\n descriptor: PropertyDescriptor,\n ): boolean {\n return Reflect.defineProperty(obj, prop, descriptor);\n },\n\n setPrototypeOf(obj: object, proto: object | null): boolean {\n return Reflect.setPrototypeOf(obj, proto);\n },\n });\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — public API\n// ---------------------------------------------------------------------------\n//\n// Minimal surface: one function, one type export. Wrap your Supabase client\n// to automatically capture failed queries, auth errors, and edge function\n// invocations via the Uncaught error monitoring SDK.\n//\n// Usage:\n// import { createClient } from '@supabase/supabase-js';\n// import { wrapSupabase } from '@uncaughtdev/supabase';\n//\n// const supabase = wrapSupabase(\n// createClient(SUPABASE_URL, SUPABASE_ANON_KEY),\n// { trackStorage: true }\n// );\n//\n// // Use supabase exactly as before — errors are captured automatically.\n// const { data, error } = await supabase.from('todos').select('*');\n// ---------------------------------------------------------------------------\n\nimport { createSupabaseProxy } from './proxy';\nimport type { WrapSupabaseOptions } from './types';\n\nexport type { WrapSupabaseOptions } from './types';\nexport type { TrackedQuery, QueryChainStep, ParsedSupabaseError } from './types';\n\n/**\n * Wrap a Supabase client with transparent error interception.\n *\n * The returned client has the exact same type and behavior as the original.\n * All Supabase operations work identically — the wrapper only observes\n * results and captures errors through the @uncaughtdev/core client.\n *\n * @param client - A SupabaseClient instance from `createClient()`.\n * @param options - Optional configuration for which subsystems to track.\n * By default, queries, auth, and functions are tracked.\n * Storage and realtime are opt-in.\n * @returns The same client, wrapped with transparent error interception.\n *\n * @example\n * ```ts\n * import { createClient } from '@supabase/supabase-js';\n * import { initUncaught } from '@uncaughtdev/core';\n * import { wrapSupabase } from '@uncaughtdev/supabase';\n *\n * initUncaught({ projectKey: 'my-project' });\n *\n * const supabase = wrapSupabase(\n * createClient(SUPABASE_URL, SUPABASE_ANON_KEY),\n * { trackQueries: true, trackAuth: true, trackFunctions: true }\n * );\n * ```\n */\nexport function wrapSupabase<T>(client: T, options?: WrapSupabaseOptions): T {\n return createSupabaseProxy(client, options ?? {}) as T;\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {getClient,sanitize}from'@uncaughtdev/core';var E=3,F=new Set(["select","insert","update","upsert","delete"]);function I(e){try{return Array.isArray(e)&&e.length>E?`[${e.slice(0,E).map(r=>r!==null&&typeof r=="object"?sanitize(r):r).map(r=>JSON.stringify(r)).join(", ")} ... and ${e.length-E} more]`:e!==null&&typeof e=="object"&&!Array.isArray(e)?sanitize(e):e}catch{return "[unserializable]"}}function q(e){return e.map(I)}function W(e){if(typeof e=="string")return `'${e}'`;if(e==null)return String(e);if(typeof e=="object")try{let t=JSON.stringify(e);return t.length>120?t.slice(0,117)+"...":t}catch{return "[object]"}return String(e)}var g=class{constructor(){this.steps=[];this.tableName="";this.operationType="unknown";}track(t,r){let n=q(r);this.steps.push({method:t,args:n}),t==="from"&&r.length>0&&typeof r[0]=="string"&&(this.tableName=r[0]),F.has(t)&&(this.operationType=t),t==="rpc"&&(this.operationType="rpc");}getTable(){return this.tableName}getOperation(){return this.operationType}getSteps(){return [...this.steps]}toHumanReadable(){return this.steps.length===0?"(empty chain)":this.steps.map(t=>{let r=t.args.map(W).join(", ");return `.${t.method}(${r})`}).join("")}toTrackedQuery(){return {table:this.tableName,operation:this.operationType,chain:[...this.steps],humanReadable:this.toHumanReadable()}}toOperationInfo(){return {provider:"supabase",type:"query",method:this.operationType,params:{table:this.tableName,chain:this.toHumanReadable()}}}isEmpty(){return this.steps.length===0}reset(){this.steps.length=0,this.tableName="",this.operationType="unknown";}};var T={42501:{template:"The RLS policy on the '{table}' table does not allow {operation} operations for the current user role. Check your RLS policies in the Supabase dashboard under Authentication > Policies for the '{table}' table. Common causes: missing policy for the operation type, policy condition not matching the current user, or the user's JWT role not having the expected grants.",category:"rls_violation"},23505:{template:"A record with this value already exists. The unique constraint on table '{table}' was violated. This typically means you are trying to insert or update a row with a value that must be unique (e.g. email, username, slug) but another row already has that value. Consider using .upsert() instead of .insert() if you want to update on conflict, or check for existing records before inserting.",category:"unique_violation"},23503:{template:"The referenced record does not exist. The foreign key constraint on table '{table}' failed. This means you are trying to insert or update a row that references another row (via a foreign key) that does not exist in the referenced table. Ensure the referenced record exists before creating this relationship, or check that the foreign key value is correct.",category:"foreign_key_violation"},23502:{template:"A required field was not provided. The not-null constraint on table '{table}' was violated. One or more columns that are defined as NOT NULL did not receive a value in the insert or update. Check your insert/update payload to ensure all required fields are present, or set a default value for the column in your database schema.",category:"not_null_violation"},"42P01":{template:"The table '{table}' does not exist in the database. This could mean the table name is misspelled, the table has not been created yet, or you are connecting to the wrong database/schema. Check the table name in your .from() call and verify it exists in the Supabase dashboard's Table Editor.",category:"undefined_table"},42703:{template:"The column '{column}' does not exist in table '{table}'. Check that the column name is spelled correctly and that any recent migrations have been applied.",category:"undefined_column"},42883:{template:"The function or operator does not exist. If you are using .rpc('{name}'), check that the function exists in your database and that the argument types match.",category:"undefined_function"},PGRST116:{template:"Expected a single row but got none. The .single() call on the query returned 0 rows. This means no record matched your filter conditions in table '{table}'. If the record might not exist, use .maybeSingle() instead of .single() to return null instead of an error when no rows match.",category:"no_rows"},PGRST301:{template:"The authentication token (JWT) has expired. The user needs to re-authenticate. This typically happens when the session has been idle for longer than the JWT expiry time. Call supabase.auth.refreshSession() to attempt a token refresh, or redirect the user to the sign-in page. Consider setting up an onAuthStateChange listener to handle token refreshes automatically.",category:"jwt_expired"},PGRST204:{template:"The column '{column}' specified in the query does not exist in the database schema. PostgREST could not find this column when processing the query.",category:"column_not_found"},PGRST200:{template:"An ambiguous embedding was detected. The relationship between '{table}' and the referenced table could not be resolved because multiple foreign keys exist. Specify the foreign key explicitly using the !inner or !left join syntax.",category:"ambiguous_embedding"},auth_invalid_credentials:{template:"The email or password is incorrect. Note: if the user recently signed up, their email may not be confirmed yet. Check the Supabase dashboard under Authentication > Users to see the user's confirmation status. Also verify that the email provider is enabled in Authentication > Providers.",category:"auth_invalid_credentials"},auth_email_not_confirmed:{template:'The user has signed up but has not confirmed their email address. Check your email confirmation settings in Authentication > Settings. You can disable email confirmation for development, or resend the confirmation email using supabase.auth.resend({ type: "signup", email }).',category:"auth_email_not_confirmed"},auth_rate_limited:{template:"Too many authentication attempts. Supabase rate limits auth endpoints to prevent abuse. The default rate limit is approximately 30 requests per hour for auth endpoints. Wait a few minutes before trying again. If you are hitting this in production, consider implementing client-side rate limiting or CAPTCHA.",category:"auth_rate_limited"},auth_user_not_found:{template:"No user was found with the provided credentials. The user may not have signed up yet, or the account may have been deleted.",category:"auth_user_not_found"},auth_session_not_found:{template:"No active session was found. The user is not currently signed in or their session has expired. Redirect the user to the sign-in page.",category:"auth_session_not_found"},auth_signup_disabled:{template:"New user signups have been disabled for this project. Enable signups in the Supabase dashboard under Authentication > Settings.",category:"auth_signup_disabled"},functions_timeout:{template:"The edge function '{name}' timed out. Edge functions have a default execution time limit (typically 60 seconds on the free plan). Consider optimizing the function, breaking it into smaller operations, or upgrading your Supabase plan for longer execution times.",category:"functions_timeout"},functions_crashed:{template:"The edge function '{name}' crashed during execution. Check the function logs in the Supabase dashboard under Edge Functions > Logs for the specific error. Common causes: unhandled exceptions, out-of-memory errors, or missing environment variables.",category:"functions_crashed"},functions_cors:{template:"The edge function '{name}' was blocked by CORS. Ensure the function sets the appropriate CORS headers in its response. Add 'Access-Control-Allow-Origin' and other necessary CORS headers, and handle OPTIONS preflight requests.",category:"functions_cors"},functions_not_found:{template:"The edge function '{name}' was not found. Verify that the function has been deployed and that the function name matches exactly (case-sensitive).",category:"functions_not_found"},functions_relay_error:{template:"The edge function '{name}' encountered a relay error. This is typically a transient infrastructure issue. Retry the request after a brief delay.",category:"functions_relay_error"},functions_fetch_error:{template:"Failed to invoke the edge function '{name}'. This could be a network connectivity issue, DNS resolution failure, or the Supabase project may be paused. Check your internet connection and verify the project is active in the Supabase dashboard.",category:"functions_fetch_error"},storage_bucket_not_found:{template:"The storage bucket was not found. Verify the bucket name is correct and that it has been created in the Supabase dashboard under Storage. Bucket names are case-sensitive.",category:"storage_bucket_not_found"},storage_object_too_large:{template:"The uploaded file exceeds the maximum allowed size. Check the file size limit configured for this bucket in the Supabase dashboard under Storage > Policies. The default maximum file size is 50MB on the free plan.",category:"storage_object_too_large"},storage_permission_denied:{template:"Permission denied for this storage operation. Check the storage policies (RLS) configured for this bucket. Storage uses its own set of policies separate from table-level RLS. Configure policies in the Supabase dashboard under Storage > Policies.",category:"storage_permission_denied"},storage_object_not_found:{template:"The requested file does not exist in storage. Verify the file path is correct and that the file has been uploaded. File paths in storage are case-sensitive.",category:"storage_object_not_found"}};function $(e,t){return e.replace(/\{(\w+)\}/g,(r,n)=>{let o=t[n];return o!==void 0?o:r})}function m(e,t){let r=T[e];return r?$(r.template,t??{}):`Supabase error (code: ${e}). Refer to the Supabase documentation or PostgreSQL error code reference for more details.`}function b(e){return T[e]?.category??"unknown"}function Q(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.message=="string"&&"code"in t&&typeof t.code=="string"&&"details"in t&&"hint"in t}function D(e){if(e===null||typeof e!="object")return false;let t=e;return t.__isAuthError===true||typeof t.name=="string"&&(t.name==="AuthApiError"||t.name==="AuthRetryableFetchError"||t.name==="AuthUnknownError"||t.name==="AuthWeakPasswordError"||t.name==="AuthSessionMissingError")}function z(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.name=="string"&&(t.name==="FunctionsHttpError"||t.name==="FunctionsRelayError"||t.name==="FunctionsFetchError")}function L(e){if(e===null||typeof e!="object")return false;let t=e;return typeof t.name=="string"&&t.name==="StorageApiError"?true:typeof t.statusCode=="string"||typeof t.statusCode=="number"?typeof t.message=="string":false}function U(e){let t=e.message.toLowerCase();return t.includes("invalid login credentials")||t.includes("invalid credentials")?"auth_invalid_credentials":t.includes("email not confirmed")||t.includes("not confirmed")?"auth_email_not_confirmed":t.includes("rate limit")||t.includes("too many requests")||e.status===429?"auth_rate_limited":t.includes("user not found")||t.includes("no user found")?"auth_user_not_found":t.includes("session not found")||t.includes("not authenticated")||t.includes("session_not_found")?"auth_session_not_found":t.includes("signups not allowed")||t.includes("signup is disabled")||t.includes("signups are disabled")?"auth_signup_disabled":"auth_unknown"}function H(e){let t=e.message.toLowerCase(),r=e.name??"";return r==="FunctionsRelayError"?"functions_relay_error":r==="FunctionsFetchError"?"functions_fetch_error":t.includes("timeout")||t.includes("timed out")||t.includes("deadline exceeded")?"functions_timeout":t.includes("cors")||t.includes("cross-origin")?"functions_cors":t.includes("not found")||t.includes("404")?"functions_not_found":(t.includes("crashed")||t.includes("internal server error")||t.includes("500"),"functions_crashed")}function B(e){let t=e.message.toLowerCase(),r=String(e.statusCode??"");return t.includes("bucket")&&(t.includes("not found")||t.includes("does not exist"))?"storage_bucket_not_found":t.includes("too large")||t.includes("payload too large")||t.includes("file size")||r==="413"?"storage_object_too_large":t.includes("permission")||t.includes("not authorized")||t.includes("policy")||r==="403"?"storage_permission_denied":t.includes("not found")||t.includes("object not found")||r==="404"?"storage_object_not_found":"storage_permission_denied"}function p(e,t){try{let r={table:t?.table,operation:t?.operation,name:t?.functionName,column:void 0,constraint:void 0};if(Q(e)){let n=e.code,o=m(n,r),a=b(n);return {errorType:"postgrest",errorCode:n,message:K(e),humanExplanation:o,suggestedCategory:a}}if(D(e)){let n=U(e),o=m(n,r),a=b(n);return {errorType:"auth",errorCode:e.name??n,message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}if(z(e)){let n=H(e),o=m(n,r),a=b(n);return {errorType:"functions",errorCode:e.name??n,message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}if(L(e)){let n=B(e),o=m(n,r),a=b(n);return {errorType:"storage",errorCode:String(e.statusCode??n),message:e.message,humanExplanation:o,suggestedCategory:a!=="unknown"?a:n}}return M(e)}catch{return {errorType:"unknown",errorCode:"PARSE_ERROR",message:"Failed to parse error object",humanExplanation:"An error occurred but could not be parsed. Check the raw error for details.",suggestedCategory:"unknown"}}}function K(e){let t=e.message;return e.details&&(t+=` | Details: ${e.details}`),e.hint&&(t+=` | Hint: ${e.hint}`),t}function M(e){let t="Unknown error",r="UNKNOWN";if(e instanceof Error)t=e.message,r=e.name??"Error";else if(e!==null&&typeof e=="object"){let n=e;typeof n.message=="string"&&(t=n.message),typeof n.code=="string"?r=n.code:typeof n.name=="string"&&(r=n.name);}else typeof e=="string"&&(t=e);return {errorType:"unknown",errorCode:r,message:t,humanExplanation:`Supabase error: ${t}. This error type was not recognized by the parser. Refer to the Supabase documentation for more details.`,suggestedCategory:"unknown"}}var G=new Set(["password","access_token","refresh_token","token","session","cookie","authorization","apikey","api_key","secret","credential","credentials","nonce","code_verifier","code_challenge"]);function _(e){if(e==null||typeof e!="object")return e;if(Array.isArray(e))return e.map(_);let t={};for(let[r,n]of Object.entries(e))G.has(r.toLowerCase())?t[r]="[REDACTED]":typeof n=="object"&&n!==null?t[r]=_(n):t[r]=n;return t}function S(e){if(e==null)return String(e);if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);try{let t=JSON.stringify(e);return t.length>100?t.slice(0,97)+"...":t}catch{return "[object]"}}function d(e){try{let t=getClient();t&&t.addBreadcrumb(e);}catch{}}function f(e,t){try{let r=getClient();r&&r.captureError(e,t);}catch{}}function x(e){return e===null||typeof e!="object"?false:"data"in e&&"error"in e}function w(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"}function y(e,t,r){return e==null||typeof e!="object"&&typeof e!="function"?e:new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}if(o==="then"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c,s){return u.call(n,h=>(J(h,t),c?c(h):h),h=>(k(h,t),s?s(h):Promise.reject(h)))}}if(o==="catch"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c){return u.call(n,s=>(k(s,t),c?c(s):Promise.reject(s)))}}if(o==="finally"){let u=Reflect.get(n,o,a);return typeof u!="function"?u:function(c){return u.call(n,c)}}let i;try{i=Reflect.get(n,o,a);}catch{return}return typeof i=="function"?function(...u){t.track(o,u);let l;try{l=i.apply(n,u);}catch(c){throw k(c,t),c}return w(l)||l!==null&&typeof l=="object"?y(l,t):l}:i!==null&&typeof i=="object"?y(i,t):i}})}function J(e,t,r){try{let n=t.toTrackedQuery(),o={table:n.table,operation:n.operation,chain:n.humanReadable};if(x(e)&&e.error){let a={table:n.table,operation:n.operation,queryChain:n.humanReadable},i=p(e.error,a);d({type:"db_query",category:"supabase.query",message:`Failed: ${n.humanReadable}`,data:{...o,errorCode:i.errorCode,errorType:i.errorType},level:"error"});let u=t.toOperationInfo();u.errorCode=i.errorCode,u.errorDetails=i.humanExplanation,f(e.error,{operation:u,extra:{supabase:{query:n.humanReadable,table:n.table,operation:n.operation,parsedError:i}}});}else d({type:"db_query",category:"supabase.query",message:`OK: ${n.humanReadable}`,data:o,level:"info"});}catch{}}function k(e,t,r){try{let n=t.toTrackedQuery(),o={table:n.table,operation:n.operation,queryChain:n.humanReadable},a=p(e,o);d({type:"db_query",category:"supabase.query",message:`Rejected: ${n.humanReadable}`,data:{table:n.table,operation:n.operation,errorCode:a.errorCode},level:"error"});let i=t.toOperationInfo();i.errorCode=a.errorCode,i.errorDetails=a.humanExplanation,f(e,{operation:i,extra:{supabase:{query:n.humanReadable,table:n.table,operation:n.operation,parsedError:a}}});}catch{}}var V=new Set(["signUp","signInWithPassword","signInWithOtp","signInWithOAuth","signInWithIdToken","signInWithSSO","signOut","getSession","getUser","refreshSession","resetPasswordForEmail","updateUser","setSession","exchangeCodeForSession","reauthenticate","resend","verifyOtp"]);function N(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}if(typeof a!="function"||!V.has(n))return a;let i=n;return function(...u){let l=u.map(s=>s!==null&&typeof s=="object"?_(s):s),c;try{c=a.apply(r,u);}catch(s){throw R(s,i,l),s}return w(c)?c.then(s=>(X(s,i,l),s),s=>(R(s,i,l),Promise.reject(s))):c}}})}function X(e,t,r){try{if(x(e)&&e.error){let n=p(e.error,{operation:t});d({type:"auth",category:"supabase.auth",message:`Auth failed: ${t}`,data:{method:t,errorCode:n.errorCode,errorType:n.errorType},level:"error"});let o={provider:"supabase",type:"auth",method:t,params:sanitize(Object.fromEntries(r.map((a,i)=>[`arg${i}`,S(a)]))),errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e.error,{operation:o,extra:{supabase:{subsystem:"auth",method:t,parsedError:n}}});}else d({type:"auth",category:"supabase.auth",message:`Auth OK: ${t}`,data:{method:t},level:"info"});}catch{}}function R(e,t,r){try{let n=p(e,{operation:t});d({type:"auth",category:"supabase.auth",message:`Auth rejected: ${t}`,data:{method:t,errorCode:n.errorCode},level:"error"});let o={provider:"supabase",type:"auth",method:t,params:sanitize(Object.fromEntries(r.map((a,i)=>[`arg${i}`,S(a)]))),errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e,{operation:o,extra:{supabase:{subsystem:"auth",method:t,parsedError:n}}});}catch{}}function Y(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}return typeof a!="function"||n!=="invoke"?a:function(i,u){let l=u?_(u):void 0,c;try{c=a.apply(r,[i,u]);}catch(s){throw v(s,i,l),s}return w(c)?c.then(s=>(Z(s,i,l),s),s=>(v(s,i,l),Promise.reject(s))):c}}})}function Z(e,t,r){try{if(x(e)&&e.error){let n=p(e.error,{functionName:t,operation:"invoke"});d({type:"api_call",category:"supabase.functions",message:`Function failed: ${t}`,data:{functionName:t,errorCode:n.errorCode,errorType:n.errorType},level:"error"});let o={provider:"supabase",type:"functions",method:"invoke",params:{functionName:t,options:S(r)},errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e.error,{operation:o,extra:{supabase:{subsystem:"functions",functionName:t,parsedError:n}}});}else d({type:"api_call",category:"supabase.functions",message:`Function OK: ${t}`,data:{functionName:t},level:"info"});}catch{}}function v(e,t,r){try{let n=p(e,{functionName:t,operation:"invoke"});d({type:"api_call",category:"supabase.functions",message:`Function rejected: ${t}`,data:{functionName:t,errorCode:n.errorCode},level:"error"});let o={provider:"supabase",type:"functions",method:"invoke",params:{functionName:t,options:S(r)},errorCode:n.errorCode,errorDetails:n.humanExplanation};f(e,{operation:o,extra:{supabase:{subsystem:"functions",functionName:t,parsedError:n}}});}catch{}}var ee=new Set(["upload","download","remove","list","move","copy","createSignedUrl","createSignedUrls","getPublicUrl"]);function te(e,t,r){return new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}let i;try{i=Reflect.get(n,o,a);}catch{return}if(typeof i!="function"||!ee.has(o))return i;let u=o;return function(...l){let c;try{c=i.apply(n,l);}catch(s){throw P(s,t,u,l),s}return w(c)?c.then(s=>(ne(s,t,u,l),s),s=>(P(s,t,u,l),Promise.reject(s))):c}}})}function ne(e,t,r,n){try{if(x(e)&&e.error){let o=p(e.error,{bucketName:t,operation:r});d({type:"api_call",category:"supabase.storage",message:`Storage failed: ${r} on ${t}`,data:{bucket:t,method:r,errorCode:o.errorCode},level:"error"});let a={provider:"supabase",type:"storage",method:r,params:{bucket:t,path:typeof n[0]=="string"?n[0]:void 0},errorCode:o.errorCode,errorDetails:o.humanExplanation};f(e.error,{operation:a,extra:{supabase:{subsystem:"storage",bucket:t,method:r,parsedError:o}}});}else d({type:"api_call",category:"supabase.storage",message:`Storage OK: ${r} on ${t}`,data:{bucket:t,method:r},level:"info"});}catch{}}function P(e,t,r,n){try{let o=p(e,{bucketName:t,operation:r});d({type:"api_call",category:"supabase.storage",message:`Storage rejected: ${r} on ${t}`,data:{bucket:t,method:r,errorCode:o.errorCode},level:"error"});let a={provider:"supabase",type:"storage",method:r,params:{bucket:t,path:typeof n[0]=="string"?n[0]:void 0},errorCode:o.errorCode,errorDetails:o.humanExplanation};f(e,{operation:a,extra:{supabase:{subsystem:"storage",bucket:t,method:r,parsedError:o}}});}catch{}}function re(e,t){return new Proxy(e,{get(r,n,o){if(typeof n=="symbol")try{return Reflect.get(r,n,o)}catch{return}let a;try{a=Reflect.get(r,n,o);}catch{return}return typeof a=="function"&&n==="from"?function(i){let u=a.apply(r,[i]);return u!==null&&typeof u=="object"?te(u,i):u}:a}})}function oe(e){return {trackQueries:e.trackQueries??true,trackAuth:e.trackAuth??true,trackFunctions:e.trackFunctions??true,trackStorage:e.trackStorage??false,trackRealtime:e.trackRealtime??false}}function j(e,t){if(e==null||typeof e!="object"&&typeof e!="function")return e;let r=oe(t);return new Proxy(e,{get(n,o,a){if(typeof o=="symbol")try{return Reflect.get(n,o,a)}catch{return}let i;try{i=Reflect.get(n,o,a);}catch{return}return o==="from"&&typeof i=="function"&&r.trackQueries?function(...u){let l=new g;l.track("from",u);let c;try{c=i.apply(n,u);}catch(s){throw k(s,l),s}return c!==null&&typeof c=="object"?y(c,l):c}:o==="rpc"&&typeof i=="function"&&r.trackQueries?function(...u){let l=new g;l.track("rpc",u);let c;try{c=i.apply(n,u);}catch(s){throw k(s,l),s}return w(c)||c!==null&&typeof c=="object"?y(c,l):c}:o==="auth"&&r.trackAuth&&i!==null&&typeof i=="object"?N(i):o==="functions"&&r.trackFunctions&&i!==null&&typeof i=="object"?Y(i):o==="storage"&&r.trackStorage&&i!==null&&typeof i=="object"?re(i):i},set(n,o,a,i){return Reflect.set(n,o,a,i)},has(n,o){return Reflect.has(n,o)},deleteProperty(n,o){return Reflect.deleteProperty(n,o)},ownKeys(n){return Reflect.ownKeys(n)},getOwnPropertyDescriptor(n,o){return Reflect.getOwnPropertyDescriptor(n,o)},getPrototypeOf(n){return Reflect.getPrototypeOf(n)},isExtensible(n){return Reflect.isExtensible(n)},preventExtensions(n){return Reflect.preventExtensions(n)},defineProperty(n,o,a){return Reflect.defineProperty(n,o,a)},setPrototypeOf(n,o){return Reflect.setPrototypeOf(n,o)}})}function ye(e,t){return j(e,t??{})}export{ye as wrapSupabase};//# sourceMappingURL=index.mjs.map
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/query-tracker.ts","../src/rls-explainer.ts","../src/error-parser.ts","../src/proxy.ts","../src/index.ts"],"names":["MAX_BULK_PREVIEW","CRUD_METHODS","sanitizeArg","value","item","sanitize","v","sanitizeArgs","args","formatValue","str","QueryTracker","method","sanitizedArgs","step","formattedArgs","EXPLANATIONS","interpolate","template","context","match","key","explainSupabaseError","errorCode","entry","getCategoryForCode","isPostgrestError","error","e","isAuthError","isFunctionsError","isStorageError","classifyAuthError","msg","classifyFunctionsError","name","classifyStorageError","code","parseSupabaseError","explainerCtx","explanation","category","buildPostgrestMessage","internalCode","parseGenericError","message","AUTH_SENSITIVE_KEYS","sanitizeAuthData","data","result","safeArgString","arg","addBreadcrumb","crumb","client","getClient","captureError","isSupabaseResult","isThenable","createQueryBuilderProxy","target","tracker","options","obj","prop","receiver","thenFn","onFulfilled","onRejected","handleQueryResult","reason","handleQueryError","catchFn","finallyFn","onFinally","err","_options","trackedQuery","breadcrumbData","parserContext","parsed","operationInfo","AUTH_METHODS","createAuthProxy","authTarget","methodName","handleAuthError","resolved","handleAuthResult","rejected","createFunctionsProxy","functionsTarget","functionName","invokeOptions","sanitizedOptions","handleFunctionsError","handleFunctionsResult","STORAGE_METHODS","createStorageBucketProxy","bucketTarget","bucketName","handleStorageError","handleStorageResult","createStorageProxy","storageTarget","bucketClient","resolveOptions","createSupabaseProxy","descriptor","proto","wrapSupabase"],"mappings":"mDAaA,IAAMA,CAAAA,CAAmB,EAGnBC,CAAAA,CAAe,IAAI,GAAA,CAAI,CAC3B,QAAA,CACA,QAAA,CACA,SACA,QAAA,CACA,QACF,CAAC,CAAA,CAOD,SAASC,CAAAA,CAAYC,EAAyB,CAC5C,GAAI,CACF,OAAI,KAAA,CAAM,QAAQA,CAAK,CAAA,EAAKA,CAAAA,CAAM,MAAA,CAASH,CAAAA,CAOlC,CAAA,CAAA,EANWG,EAAM,KAAA,CAAM,CAAA,CAAGH,CAAgB,CAAA,CAAE,GAAA,CAAKI,CAAAA,EAClDA,IAAS,IAAA,EAAQ,OAAOA,CAAAA,EAAS,QAAA,CAC5BC,QAAAA,CAASD,CAA+B,EAE1CA,CACR,CAAA,CACoB,IAAKE,CAAAA,EAAM,IAAA,CAAK,UAAUA,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,YAAYH,CAAAA,CAAM,MAAA,CAASH,CAAgB,CAAA,MAAA,CAAA,CAGtGG,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,EAAY,CAAC,KAAA,CAAM,OAAA,CAAQA,CAAK,EAC9DE,QAAAA,CAASF,CAAgC,EAG3CA,CACT,CAAA,KAAQ,CACN,OAAO,kBACT,CACF,CAKA,SAASI,CAAAA,CAAaC,EAA4B,CAChD,OAAOA,CAAAA,CAAK,GAAA,CAAIN,CAAW,CAC7B,CAKA,SAASO,CAAAA,CAAYN,CAAAA,CAAwB,CAC3C,GAAI,OAAOA,GAAU,QAAA,CACnB,OAAO,IAAIA,CAAK,CAAA,CAAA,CAAA,CAElB,GAAIA,CAAAA,EAAU,IAAA,CACZ,OAAO,MAAA,CAAOA,CAAK,CAAA,CAErB,GAAI,OAAOA,CAAAA,EAAU,QAAA,CACnB,GAAI,CACF,IAAMO,EAAM,IAAA,CAAK,SAAA,CAAUP,CAAK,CAAA,CAChC,OAAIO,CAAAA,CAAI,OAAS,GAAA,CACRA,CAAAA,CAAI,MAAM,CAAA,CAAG,GAAG,EAAI,KAAA,CAEtBA,CACT,CAAA,KAAQ,CACN,OAAO,UACT,CAEF,OAAO,MAAA,CAAOP,CAAK,CACrB,CAiBO,IAAMQ,EAAN,KAAmB,CAAnB,WAAA,EAAA,CACL,IAAA,CAAiB,KAAA,CAA0B,GAC3C,IAAA,CAAQ,SAAA,CAAY,GACpB,IAAA,CAAQ,aAAA,CAAgB,WAQxB,KAAA,CAAMC,CAAAA,CAAgBJ,CAAAA,CAAuB,CAC3C,IAAMK,CAAAA,CAAgBN,EAAaC,CAAI,CAAA,CACvC,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,CAAE,OAAAI,CAAAA,CAAQ,IAAA,CAAMC,CAAc,CAAC,CAAA,CAG3CD,CAAAA,GAAW,QAAUJ,CAAAA,CAAK,MAAA,CAAS,GAAK,OAAOA,CAAAA,CAAK,CAAC,CAAA,EAAM,QAAA,GAC7D,IAAA,CAAK,SAAA,CAAYA,CAAAA,CAAK,CAAC,GAIrBP,CAAAA,CAAa,GAAA,CAAIW,CAAM,CAAA,GACzB,IAAA,CAAK,aAAA,CAAgBA,GAInBA,CAAAA,GAAW,KAAA,GACb,IAAA,CAAK,aAAA,CAAgB,KAAA,EAEzB,CAKA,UAAmB,CACjB,OAAO,KAAK,SACd,CAKA,cAAuB,CACrB,OAAO,IAAA,CAAK,aACd,CAKA,QAAA,EAA6B,CAC3B,OAAO,CAAC,GAAG,IAAA,CAAK,KAAK,CACvB,CAQA,eAAA,EAA0B,CACxB,OAAI,IAAA,CAAK,KAAA,CAAM,MAAA,GAAW,EACjB,eAAA,CAGF,IAAA,CAAK,MACT,GAAA,CAAKE,CAAAA,EAAS,CACb,IAAMC,CAAAA,CAAgBD,CAAAA,CAAK,IAAA,CAAK,GAAA,CAAIL,CAAW,EAAE,IAAA,CAAK,IAAI,CAAA,CAC1D,OAAO,CAAA,CAAA,EAAIK,CAAAA,CAAK,MAAM,CAAA,CAAA,EAAIC,CAAa,CAAA,CAAA,CACzC,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CACZ,CAKA,gBAA+B,CAC7B,OAAO,CACL,KAAA,CAAO,IAAA,CAAK,SAAA,CACZ,SAAA,CAAW,IAAA,CAAK,aAAA,CAChB,MAAO,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA,CACrB,aAAA,CAAe,KAAK,eAAA,EACtB,CACF,CAKA,eAAA,EAAiC,CAC/B,OAAO,CACL,QAAA,CAAU,WACV,IAAA,CAAM,OAAA,CACN,OAAQ,IAAA,CAAK,aAAA,CACb,MAAA,CAAQ,CACN,KAAA,CAAO,IAAA,CAAK,UACZ,KAAA,CAAO,IAAA,CAAK,eAAA,EACd,CACF,CACF,CAKA,OAAA,EAAmB,CACjB,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,GAAW,CAC/B,CAKA,KAAA,EAAc,CACZ,IAAA,CAAK,KAAA,CAAM,OAAS,CAAA,CACpB,IAAA,CAAK,SAAA,CAAY,EAAA,CACjB,IAAA,CAAK,aAAA,CAAgB,UACvB,CACF,CAAA,CC/KA,IAAMC,CAAAA,CAAoD,CAKxD,KAAA,CAAS,CACP,QAAA,CACE,gXAAA,CAIF,QAAA,CAAU,eACZ,CAAA,CAEA,KAAA,CAAS,CACP,QAAA,CACE,sYAAA,CAKF,SAAU,kBACZ,CAAA,CAEA,MAAS,CACP,QAAA,CACE,qWAAA,CAIF,QAAA,CAAU,uBACZ,CAAA,CAEA,MAAS,CACP,QAAA,CACE,0UAAA,CAIF,QAAA,CAAU,oBACZ,CAAA,CAEA,QAAS,CACP,QAAA,CACE,oSAAA,CAIF,QAAA,CAAU,iBACZ,CAAA,CAEA,MAAS,CACP,QAAA,CACE,6JAEF,QAAA,CAAU,kBACZ,EAEA,KAAA,CAAS,CACP,QAAA,CACE,8JAAA,CAEF,QAAA,CAAU,oBACZ,EAMA,QAAA,CAAU,CACR,QAAA,CACE,4RAAA,CAIF,QAAA,CAAU,SACZ,EAEA,QAAA,CAAU,CACR,QAAA,CACE,gXAAA,CAKF,QAAA,CAAU,aACZ,EAEA,QAAA,CAAU,CACR,SACE,qJAAA,CAEF,QAAA,CAAU,kBACZ,CAAA,CAEA,QAAA,CAAU,CACR,QAAA,CACE,uOAAA,CAGF,QAAA,CAAU,qBACZ,CAAA,CAMA,wBAAA,CAA0B,CACxB,QAAA,CACE,gSAAA,CAIF,QAAA,CAAU,0BACZ,CAAA,CAEA,wBAAA,CAA0B,CACxB,QAAA,CACE,oRAAA,CAIF,QAAA,CAAU,0BACZ,CAAA,CAEA,iBAAA,CAAmB,CACjB,QAAA,CACE,qTAAA,CAIF,SAAU,mBACZ,CAAA,CAEA,mBAAA,CAAqB,CACnB,QAAA,CACE,6HAAA,CAEF,SAAU,qBACZ,CAAA,CAEA,sBAAA,CAAwB,CACtB,QAAA,CACE,uIAAA,CAEF,SAAU,wBACZ,CAAA,CAEA,oBAAA,CAAsB,CACpB,QAAA,CACE,iIAAA,CAEF,SAAU,sBACZ,CAAA,CAMA,kBAAmB,CACjB,QAAA,CACE,uQAGF,QAAA,CAAU,mBACZ,CAAA,CAEA,iBAAA,CAAmB,CACjB,QAAA,CACE,0PAGF,QAAA,CAAU,mBACZ,CAAA,CAEA,cAAA,CAAgB,CACd,QAAA,CACE,oOAGF,QAAA,CAAU,gBACZ,CAAA,CAEA,mBAAA,CAAqB,CACnB,QAAA,CACE,oJAEF,QAAA,CAAU,qBACZ,EAEA,qBAAA,CAAuB,CACrB,SACE,kJAAA,CAEF,QAAA,CAAU,uBACZ,CAAA,CAEA,qBAAA,CAAuB,CACrB,SACE,oPAAA,CAGF,QAAA,CAAU,uBACZ,CAAA,CAMA,wBAAA,CAA0B,CACxB,SACE,4KAAA,CAEF,QAAA,CAAU,0BACZ,CAAA,CAEA,wBAAA,CAA0B,CACxB,SACE,sNAAA,CAGF,QAAA,CAAU,0BACZ,CAAA,CAEA,yBAAA,CAA2B,CACzB,QAAA,CACE,uPAAA,CAGF,QAAA,CAAU,2BACZ,CAAA,CAEA,wBAAA,CAA0B,CACxB,QAAA,CACE,8JAAA,CAEF,QAAA,CAAU,0BACZ,CACF,CAAA,CAQA,SAASC,CAAAA,CAAYC,CAAAA,CAAkBC,CAAAA,CAAmC,CACxE,OAAOD,CAAAA,CAAS,QAAQ,YAAA,CAAc,CAACE,EAAOC,CAAAA,GAAgB,CAC5D,IAAMlB,CAAAA,CAAQgB,CAAAA,CAAQE,CAAG,CAAA,CACzB,OAAOlB,CAAAA,GAAU,OAAYA,CAAAA,CAAQiB,CACvC,CAAC,CACH,CAWO,SAASE,EACdC,CAAAA,CACAJ,CAAAA,CACQ,CACR,IAAMK,CAAAA,CAAQR,CAAAA,CAAaO,CAAS,CAAA,CAEpC,OAAKC,EAIEP,CAAAA,CAAYO,CAAAA,CAAM,SAAUL,CAAAA,EAAW,EAAE,CAAA,CAHvC,CAAA,sBAAA,EAAyBI,CAAS,6FAI7C,CAQO,SAASE,CAAAA,CAAmBF,CAAAA,CAA2B,CAE5D,OADcP,EAAaO,CAAS,CAAA,EACtB,QAAA,EAAY,SAC5B,CC7QA,SAASG,EAAiBC,CAAAA,CAA8C,CACtE,GAAIA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAAU,OAAO,MAAA,CACxD,IAAMC,CAAAA,CAAID,EACV,OACE,OAAOC,CAAAA,CAAE,OAAA,EAAY,QAAA,EACrB,MAAA,GAAUA,GACV,OAAOA,CAAAA,CAAE,IAAA,EAAS,QAAA,EAClB,SAAA,GAAaA,CAAAA,EACb,SAAUA,CAEd,CAEA,SAASC,CAAAA,CAAYF,CAAAA,CAAyC,CAC5D,GAAIA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAAU,OAAO,MAAA,CACxD,IAAMC,CAAAA,CAAID,CAAAA,CAIV,OADIC,CAAAA,CAAE,gBAAkB,IAAA,EAEtB,OAAOA,CAAAA,CAAE,IAAA,EAAS,QAAA,GACjBA,CAAAA,CAAE,OAAS,cAAA,EACVA,CAAAA,CAAE,OAAS,yBAAA,EACXA,CAAAA,CAAE,OAAS,kBAAA,EACXA,CAAAA,CAAE,IAAA,GAAS,uBAAA,EACXA,CAAAA,CAAE,IAAA,GAAS,0BAMjB,CAEA,SAASE,CAAAA,CAAiBH,CAAAA,CAA8C,CACtE,GAAIA,IAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAAU,OAAO,MAAA,CACxD,IAAMC,CAAAA,CAAID,CAAAA,CACV,OACE,OAAOC,CAAAA,CAAE,MAAS,QAAA,GACjBA,CAAAA,CAAE,IAAA,GAAS,oBAAA,EACVA,CAAAA,CAAE,IAAA,GAAS,uBACXA,CAAAA,CAAE,IAAA,GAAS,qBAAA,CAEjB,CAEA,SAASG,CAAAA,CAAeJ,EAA4C,CAClE,GAAIA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,SAAU,OAAO,MAAA,CACxD,IAAMC,CAAAA,CAAID,CAAAA,CAGV,OAAI,OAAOC,CAAAA,CAAE,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAE,IAAA,GAAS,kBAA0B,IAAA,CACnE,OAAOA,CAAAA,CAAE,UAAA,EAAe,QAAA,EAAY,OAAOA,EAAE,UAAA,EAAe,QAAA,CAEvD,OAAOA,CAAAA,CAAE,OAAA,EAAY,QAAA,CAGvB,KACT,CASA,SAASI,EAAkBL,CAAAA,CAA+B,CACxD,IAAMM,CAAAA,CAAMN,CAAAA,CAAM,OAAA,CAAQ,WAAA,EAAY,CAEtC,OAAIM,EAAI,QAAA,CAAS,2BAA2B,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,qBAAqB,EAC1E,0BAAA,CAELA,CAAAA,CAAI,QAAA,CAAS,qBAAqB,CAAA,EAAKA,CAAAA,CAAI,SAAS,eAAe,CAAA,CAC9D,2BAELA,CAAAA,CAAI,QAAA,CAAS,YAAY,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,mBAAmB,CAAA,EAAKN,CAAAA,CAAM,SAAW,GAAA,CAC/E,mBAAA,CAELM,CAAAA,CAAI,QAAA,CAAS,gBAAgB,CAAA,EAAKA,EAAI,QAAA,CAAS,eAAe,CAAA,CACzD,qBAAA,CAELA,CAAAA,CAAI,QAAA,CAAS,mBAAmB,CAAA,EAAKA,CAAAA,CAAI,SAAS,mBAAmB,CAAA,EAAKA,EAAI,QAAA,CAAS,mBAAmB,CAAA,CACrG,wBAAA,CAELA,CAAAA,CAAI,QAAA,CAAS,qBAAqB,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,oBAAoB,CAAA,EAAKA,CAAAA,CAAI,SAAS,sBAAsB,CAAA,CAC3G,sBAAA,CAGF,cACT,CASA,SAASC,EAAuBP,CAAAA,CAAoC,CAClE,IAAMM,CAAAA,CAAMN,CAAAA,CAAM,QAAQ,WAAA,EAAY,CAChCQ,CAAAA,CAAOR,CAAAA,CAAM,IAAA,EAAQ,EAAA,CAE3B,OAAIQ,CAAAA,GAAS,qBAAA,CACJ,uBAAA,CAELA,CAAAA,GAAS,qBAAA,CACJ,uBAAA,CAILF,EAAI,QAAA,CAAS,SAAS,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,WAAW,GAAKA,CAAAA,CAAI,QAAA,CAAS,mBAAmB,CAAA,CACnF,mBAAA,CAELA,CAAAA,CAAI,SAAS,MAAM,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,cAAc,CAAA,CAC9C,iBAELA,CAAAA,CAAI,QAAA,CAAS,WAAW,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,KAAK,CAAA,CAC1C,qBAAA,EAELA,CAAAA,CAAI,QAAA,CAAS,SAAS,CAAA,EAAKA,EAAI,QAAA,CAAS,uBAAuB,GAAKA,CAAAA,CAAI,QAAA,CAAS,KAAK,CAAA,CACjF,mBAAA,CAIX,CASA,SAASG,CAAAA,CAAqBT,CAAAA,CAAkC,CAC9D,IAAMM,CAAAA,CAAMN,CAAAA,CAAM,OAAA,CAAQ,WAAA,EAAY,CAChCU,EAAO,MAAA,CAAOV,CAAAA,CAAM,UAAA,EAAc,EAAE,CAAA,CAE1C,OAAIM,EAAI,QAAA,CAAS,QAAQ,IAAMA,CAAAA,CAAI,QAAA,CAAS,WAAW,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,gBAAgB,CAAA,CAAA,CAChF,0BAAA,CAELA,EAAI,QAAA,CAAS,WAAW,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,mBAAmB,GAAKA,CAAAA,CAAI,QAAA,CAAS,WAAW,CAAA,EAAKI,CAAAA,GAAS,KAAA,CACnG,2BAELJ,CAAAA,CAAI,QAAA,CAAS,YAAY,CAAA,EAAKA,CAAAA,CAAI,SAAS,gBAAgB,CAAA,EAAKA,CAAAA,CAAI,QAAA,CAAS,QAAQ,CAAA,EAAKI,IAAS,KAAA,CAC9F,2BAAA,CAELJ,CAAAA,CAAI,QAAA,CAAS,WAAW,CAAA,EAAKA,EAAI,QAAA,CAAS,kBAAkB,CAAA,EAAKI,CAAAA,GAAS,KAAA,CACrE,0BAAA,CAGF,2BACT,CAgCO,SAASC,EACdX,CAAAA,CACAR,CAAAA,CACqB,CACrB,GAAI,CAEF,IAAMoB,CAAAA,CAAiC,CACrC,KAAA,CAAOpB,GAAS,KAAA,CAChB,SAAA,CAAWA,CAAAA,EAAS,SAAA,CACpB,IAAA,CAAMA,CAAAA,EAAS,aACf,MAAA,CAAQ,KAAA,CAAA,CACR,UAAA,CAAY,KAAA,CACd,CAAA,CAGA,GAAIO,EAAiBC,CAAK,CAAA,CAAG,CAC3B,IAAMJ,CAAAA,CAAYI,EAAM,IAAA,CAClBa,CAAAA,CAAclB,CAAAA,CAAqBC,CAAAA,CAAWgB,CAAY,CAAA,CAC1DE,EAAWhB,CAAAA,CAAmBF,CAAS,CAAA,CAE7C,OAAO,CACL,SAAA,CAAW,YACX,SAAA,CAAAA,CAAAA,CACA,OAAA,CAASmB,CAAAA,CAAsBf,CAAK,CAAA,CACpC,iBAAkBa,CAAAA,CAClB,iBAAA,CAAmBC,CACrB,CACF,CAGA,GAAIZ,CAAAA,CAAYF,CAAK,CAAA,CAAG,CACtB,IAAMgB,CAAAA,CAAeX,EAAkBL,CAAK,CAAA,CACtCa,CAAAA,CAAclB,CAAAA,CAAqBqB,CAAAA,CAAcJ,CAAY,EAC7DE,CAAAA,CAAWhB,CAAAA,CAAmBkB,CAAY,CAAA,CAEhD,OAAO,CACL,UAAW,MAAA,CACX,SAAA,CAAWhB,EAAM,IAAA,EAAQgB,CAAAA,CACzB,QAAShB,CAAAA,CAAM,OAAA,CACf,gBAAA,CAAkBa,CAAAA,CAClB,iBAAA,CAAmBC,CAAAA,GAAa,UAAYA,CAAAA,CAAWE,CACzD,CACF,CAGA,GAAIb,CAAAA,CAAiBH,CAAK,CAAA,CAAG,CAC3B,IAAMgB,CAAAA,CAAeT,CAAAA,CAAuBP,CAAK,EAC3Ca,CAAAA,CAAclB,CAAAA,CAAqBqB,EAAcJ,CAAY,CAAA,CAC7DE,EAAWhB,CAAAA,CAAmBkB,CAAY,CAAA,CAEhD,OAAO,CACL,SAAA,CAAW,YACX,SAAA,CAAWhB,CAAAA,CAAM,IAAA,EAAQgB,CAAAA,CACzB,OAAA,CAAShB,CAAAA,CAAM,QACf,gBAAA,CAAkBa,CAAAA,CAClB,iBAAA,CAAmBC,CAAAA,GAAa,SAAA,CAAYA,CAAAA,CAAWE,CACzD,CACF,CAGA,GAAIZ,CAAAA,CAAeJ,CAAK,EAAG,CACzB,IAAMgB,CAAAA,CAAeP,CAAAA,CAAqBT,CAAK,CAAA,CACzCa,EAAclB,CAAAA,CAAqBqB,CAAAA,CAAcJ,CAAY,CAAA,CAC7DE,CAAAA,CAAWhB,CAAAA,CAAmBkB,CAAY,CAAA,CAEhD,OAAO,CACL,SAAA,CAAW,SAAA,CACX,SAAA,CAAW,OAAOhB,CAAAA,CAAM,UAAA,EAAcgB,CAAY,CAAA,CAClD,OAAA,CAAShB,EAAM,OAAA,CACf,gBAAA,CAAkBa,CAAAA,CAClB,iBAAA,CAAmBC,CAAAA,GAAa,SAAA,CAAYA,EAAWE,CACzD,CACF,CAGA,OAAOC,CAAAA,CAAkBjB,CAAK,CAChC,CAAA,KAAQ,CAEN,OAAO,CACL,SAAA,CAAW,SAAA,CACX,UAAW,aAAA,CACX,OAAA,CAAS,+BACT,gBAAA,CACE,6EAAA,CACF,kBAAmB,SACrB,CACF,CACF,CAUA,SAASe,CAAAA,CAAsBf,EAAoC,CACjE,IAAIM,CAAAA,CAAMN,CAAAA,CAAM,OAAA,CAChB,OAAIA,EAAM,OAAA,GACRM,CAAAA,EAAO,CAAA,YAAA,EAAeN,CAAAA,CAAM,OAAO,CAAA,CAAA,CAAA,CAEjCA,EAAM,IAAA,GACRM,CAAAA,EAAO,YAAYN,CAAAA,CAAM,IAAI,IAExBM,CACT,CAKA,SAASW,CAAAA,CAAkBjB,CAAAA,CAAqC,CAC9D,IAAIkB,CAAAA,CAAU,eAAA,CACVtB,CAAAA,CAAY,SAAA,CAEhB,GAAII,CAAAA,YAAiB,MACnBkB,CAAAA,CAAUlB,CAAAA,CAAM,OAAA,CAChBJ,CAAAA,CAAYI,CAAAA,CAAM,IAAA,EAAQ,gBACjBA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAAU,CACtD,IAAMC,CAAAA,CAAID,CAAAA,CACN,OAAOC,CAAAA,CAAE,OAAA,EAAY,WACvBiB,CAAAA,CAAUjB,CAAAA,CAAE,OAAA,CAAA,CAEV,OAAOA,CAAAA,CAAE,IAAA,EAAS,SACpBL,CAAAA,CAAYK,CAAAA,CAAE,IAAA,CACL,OAAOA,CAAAA,CAAE,IAAA,EAAS,WAC3BL,CAAAA,CAAYK,CAAAA,CAAE,MAElB,CAAA,KAAW,OAAOD,GAAU,QAAA,GAC1BkB,CAAAA,CAAUlB,CAAAA,CAAAA,CAGZ,OAAO,CACL,SAAA,CAAW,UACX,SAAA,CAAAJ,CAAAA,CACA,OAAA,CAAAsB,CAAAA,CACA,gBAAA,CAAkB,CAAA,gBAAA,EAAmBA,CAAO,CAAA,yGAAA,CAAA,CAC5C,iBAAA,CAAmB,SACrB,CACF,CCnVA,IAAMC,EAAsB,IAAI,GAAA,CAAI,CAClC,UAAA,CACA,cAAA,CACA,gBACA,OAAA,CACA,SAAA,CACA,QAAA,CACA,eAAA,CACA,QAAA,CACA,SAAA,CACA,SACA,YAAA,CACA,aAAA,CACA,OAAA,CACA,eAAA,CACA,gBACF,CAAC,EAOD,SAASC,CAAAA,CAAiBC,CAAAA,CAAwB,CAEhD,GADIA,CAAAA,EAAS,MACT,OAAOA,CAAAA,EAAS,SAAU,OAAOA,CAAAA,CACrC,GAAI,KAAA,CAAM,OAAA,CAAQA,CAAI,CAAA,CAAG,OAAOA,CAAAA,CAAK,IAAID,CAAgB,CAAA,CAEzD,IAAME,CAAAA,CAAkC,EAAC,CACzC,OAAW,CAAC5B,CAAAA,CAAKlB,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQ6C,CAA+B,CAAA,CACnEF,CAAAA,CAAoB,IAAIzB,CAAAA,CAAI,WAAA,EAAa,CAAA,CAC3C4B,CAAAA,CAAO5B,CAAG,CAAA,CAAI,YAAA,CACL,OAAOlB,GAAU,QAAA,EAAYA,CAAAA,GAAU,IAAA,CAChD8C,CAAAA,CAAO5B,CAAG,CAAA,CAAI0B,EAAiB5C,CAAK,CAAA,CAEpC8C,CAAAA,CAAO5B,CAAG,CAAA,CAAIlB,CAAAA,CAGlB,OAAO8C,CACT,CAKA,SAASC,CAAAA,CAAcC,CAAAA,CAAsB,CAC3C,GAAIA,CAAAA,EAAQ,IAAA,CAA2B,OAAO,MAAA,CAAOA,CAAG,EACxD,GAAI,OAAOA,CAAAA,EAAQ,QAAA,CAAU,OAAOA,CAAAA,CACpC,GAAI,OAAOA,CAAAA,EAAQ,QAAA,EAAY,OAAOA,CAAAA,EAAQ,SAAA,CAAW,OAAO,MAAA,CAAOA,CAAG,EAC1E,GAAI,CACF,IAAMzC,CAAAA,CAAM,IAAA,CAAK,SAAA,CAAUyC,CAAG,CAAA,CAC9B,OAAOzC,EAAI,MAAA,CAAS,GAAA,CAAMA,CAAAA,CAAI,KAAA,CAAM,CAAA,CAAG,EAAE,EAAI,KAAA,CAAQA,CACvD,CAAA,KAAQ,CACN,OAAO,UACT,CACF,CAMA,SAAS0C,EAAcC,CAAAA,CAA4C,CACjE,GAAI,CACF,IAAMC,CAAAA,CAASC,SAAAA,EAAU,CACrBD,CAAAA,EACFA,EAAO,aAAA,CAAcD,CAAK,EAE9B,CAAA,KAAQ,CAER,CACF,CAMA,SAASG,CAAAA,CACP7B,CAAAA,CACAR,CAAAA,CAIM,CACN,GAAI,CACF,IAAMmC,CAAAA,CAASC,WAAU,CACrBD,CAAAA,EACFA,EAAO,YAAA,CAAa3B,CAAAA,CAAOR,CAAO,EAEtC,CAAA,KAAQ,CAER,CACF,CASA,SAASsC,CAAAA,CAAiBtD,CAAAA,CAA4D,CACpF,OAAIA,IAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAAiB,KAAA,CACjD,MAAA,GAAUA,GAAS,OAAA,GAAWA,CACvC,CAKA,SAASuD,CAAAA,CAAWvD,EAA+C,CACjE,OACEA,CAAAA,GAAU,IAAA,EACV,OAAOA,CAAAA,EAAU,UACjB,OAAQA,CAAAA,CAAkC,IAAA,EAAS,UAEvD,CAUA,SAASwD,EACPC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACS,CAET,OADIF,CAAAA,EAAW,MACX,OAAOA,CAAAA,EAAW,UAAY,OAAOA,CAAAA,EAAW,WAAmBA,CAAAA,CAEhE,IAAI,KAAA,CAAMA,CAAAA,CAAkB,CACjC,GAAA,CAAIG,EAAaC,CAAAA,CAAuBC,CAAAA,CAA4B,CAElE,GAAI,OAAOD,CAAAA,EAAS,SAClB,GAAI,CACF,OAAO,OAAA,CAAQ,GAAA,CAAID,CAAAA,CAAKC,EAAMC,CAAQ,CACxC,MAAQ,CACN,MACF,CAIF,GAAID,CAAAA,GAAS,MAAA,CAAQ,CACnB,IAAME,CAAAA,CAAS,QAAQ,GAAA,CAAIH,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CAAA,CAC9C,OAAI,OAAOC,CAAAA,EAAW,UAAA,CAAmBA,CAAAA,CAGlC,SACLC,CAAAA,CACAC,CAAAA,CACS,CACT,OAAOF,CAAAA,CAAO,KACZH,CAAAA,CACCd,CAAAA,GACCoB,EAAkBpB,CAAAA,CAAQY,CAAgB,CAAA,CACnCM,CAAAA,CAAcA,CAAAA,CAAYlB,CAAM,CAAA,CAAIA,CAAAA,CAAAA,CAE5CqB,CAAAA,GACCC,CAAAA,CAAiBD,CAAAA,CAAQT,CAAgB,CAAA,CAClCO,CAAAA,CAAaA,CAAAA,CAAWE,CAAM,CAAA,CAAI,OAAA,CAAQ,OAAOA,CAAM,CAAA,CAElE,CACF,CACF,CAGA,GAAIN,CAAAA,GAAS,OAAA,CAAS,CACpB,IAAMQ,CAAAA,CAAU,OAAA,CAAQ,IAAIT,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CAAA,CAC/C,OAAI,OAAOO,GAAY,UAAA,CAAmBA,CAAAA,CAEnC,SACLJ,CAAAA,CACS,CACT,OAAOI,EAAQ,IAAA,CAAKT,CAAAA,CAAMO,IACxBC,CAAAA,CAAiBD,CAAAA,CAAQT,CAAgB,CAAA,CAClCO,CAAAA,CAAaA,CAAAA,CAAWE,CAAM,CAAA,CAAI,QAAQ,MAAA,CAAOA,CAAM,CAAA,CAC/D,CACH,CACF,CAGA,GAAIN,CAAAA,GAAS,SAAA,CAAW,CACtB,IAAMS,CAAAA,CAAY,OAAA,CAAQ,IAAIV,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CAAA,CACjD,OAAI,OAAOQ,CAAAA,EAAc,UAAA,CAAmBA,CAAAA,CAErC,SAAwBC,CAAAA,CAA0C,CACvE,OAAOD,CAAAA,CAAU,IAAA,CAAKV,CAAAA,CAAKW,CAAS,CACtC,CACF,CAEA,IAAIvE,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAQ,OAAA,CAAQ,IAAI4D,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,EACzC,CAAA,KAAQ,CACN,MACF,CAGA,OAAI,OAAO9D,CAAAA,EAAU,UAAA,CACZ,YAA4BK,CAAAA,CAA0B,CAE3DqD,CAAAA,CAAQ,KAAA,CAAMG,CAAAA,CAAMxD,CAAI,EAExB,IAAIyC,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAS9C,CAAAA,CAAM,MAAM4D,CAAAA,CAAKvD,CAAI,EAChC,CAAA,MAASmE,CAAAA,CAAK,CAEZ,MAAAJ,CAAAA,CAAiBI,CAAAA,CAAKd,CAAgB,CAAA,CAChCc,CACR,CAQA,OALIjB,CAAAA,CAAWT,CAAM,CAAA,EAKjBA,CAAAA,GAAW,MAAQ,OAAOA,CAAAA,EAAW,QAAA,CAChCU,CAAAA,CAAwBV,CAAAA,CAAQY,CAAgB,CAAA,CAGlDZ,CACT,EAIE9C,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAC9BwD,CAAAA,CAAwBxD,CAAAA,CAAO0D,CAAgB,EAGjD1D,CACT,CACF,CAAC,CACH,CAKA,SAASkE,EACPpB,CAAAA,CACAY,CAAAA,CACAe,CAAAA,CACM,CACN,GAAI,CACF,IAAMC,CAAAA,CAAehB,CAAAA,CAAQ,cAAA,EAAe,CACtCiB,CAAAA,CAA0C,CAC9C,MAAOD,CAAAA,CAAa,KAAA,CACpB,SAAA,CAAWA,CAAAA,CAAa,SAAA,CACxB,KAAA,CAAOA,EAAa,aACtB,CAAA,CAEA,GAAIpB,CAAAA,CAAiBR,CAAM,CAAA,EAAKA,EAAO,KAAA,CAAO,CAE5C,IAAM8B,CAAAA,CAAoC,CACxC,KAAA,CAAOF,EAAa,KAAA,CACpB,SAAA,CAAWA,EAAa,SAAA,CACxB,UAAA,CAAYA,EAAa,aAC3B,CAAA,CAEMG,CAAAA,CAAS1C,CAAAA,CAAmBW,CAAAA,CAAO,KAAA,CAAO8B,CAAa,CAAA,CAE7D3B,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,QAAA,CAAU,iBACV,OAAA,CAAS,CAAA,QAAA,EAAWyB,CAAAA,CAAa,aAAa,CAAA,CAAA,CAC9C,IAAA,CAAM,CACJ,GAAGC,CAAAA,CACH,UAAWE,CAAAA,CAAO,SAAA,CAClB,UAAWA,CAAAA,CAAO,SACpB,CAAA,CACA,KAAA,CAAO,OACT,CAAC,EAED,IAAMC,CAAAA,CAAgBpB,CAAAA,CAAQ,eAAA,EAAgB,CAC9CoB,CAAAA,CAAc,UAAYD,CAAAA,CAAO,SAAA,CACjCC,CAAAA,CAAc,YAAA,CAAeD,CAAAA,CAAO,gBAAA,CAEpCxB,EAAaP,CAAAA,CAAO,KAAA,CAAO,CACzB,SAAA,CAAWgC,CAAAA,CACX,MAAO,CACL,QAAA,CAAU,CACR,KAAA,CAAOJ,CAAAA,CAAa,aAAA,CACpB,MAAOA,CAAAA,CAAa,KAAA,CACpB,SAAA,CAAWA,CAAAA,CAAa,SAAA,CACxB,WAAA,CAAaG,CACf,CACF,CACF,CAAC,EACH,CAAA,KAEE5B,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,SAAU,gBAAA,CACV,OAAA,CAAS,OAAOyB,CAAAA,CAAa,aAAa,CAAA,CAAA,CAC1C,IAAA,CAAMC,CAAAA,CACN,KAAA,CAAO,MACT,CAAC,EAEL,CAAA,KAAQ,CAER,CACF,CAKA,SAASP,CAAAA,CACPD,CAAAA,CACAT,CAAAA,CACAe,CAAAA,CACM,CACN,GAAI,CACF,IAAMC,CAAAA,CAAehB,EAAQ,cAAA,EAAe,CAEtCkB,EAAoC,CACxC,KAAA,CAAOF,CAAAA,CAAa,KAAA,CACpB,SAAA,CAAWA,CAAAA,CAAa,UACxB,UAAA,CAAYA,CAAAA,CAAa,aAC3B,CAAA,CAEMG,CAAAA,CAAS1C,CAAAA,CAAmBgC,EAAQS,CAAa,CAAA,CAEvD3B,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,SAAU,gBAAA,CACV,OAAA,CAAS,aAAayB,CAAAA,CAAa,aAAa,GAChD,IAAA,CAAM,CACJ,KAAA,CAAOA,CAAAA,CAAa,KAAA,CACpB,SAAA,CAAWA,EAAa,SAAA,CACxB,SAAA,CAAWG,CAAAA,CAAO,SACpB,CAAA,CACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAAgBpB,CAAAA,CAAQ,eAAA,GAC9BoB,CAAAA,CAAc,SAAA,CAAYD,EAAO,SAAA,CACjCC,CAAAA,CAAc,aAAeD,CAAAA,CAAO,gBAAA,CAEpCxB,CAAAA,CAAac,CAAAA,CAAQ,CACnB,SAAA,CAAWW,EACX,KAAA,CAAO,CACL,QAAA,CAAU,CACR,KAAA,CAAOJ,CAAAA,CAAa,cACpB,KAAA,CAAOA,CAAAA,CAAa,KAAA,CACpB,SAAA,CAAWA,CAAAA,CAAa,SAAA,CACxB,YAAaG,CACf,CACF,CACF,CAAC,EACH,MAAQ,CAER,CACF,CAOA,IAAME,CAAAA,CAAe,IAAI,IAAI,CAC3B,QAAA,CACA,oBAAA,CACA,eAAA,CACA,iBAAA,CACA,mBAAA,CACA,gBACA,SAAA,CACA,YAAA,CACA,SAAA,CACA,gBAAA,CACA,uBAAA,CACA,YAAA,CACA,aACA,wBAAA,CACA,gBAAA,CACA,SACA,WACF,CAAC,EAKD,SAASC,CAAAA,CAAgBC,CAAAA,CAAoBtB,CAAAA,CAAsC,CACjF,OAAO,IAAI,KAAA,CAAMsB,CAAAA,CAAY,CAC3B,GAAA,CAAIrB,CAAAA,CAAaC,CAAAA,CAAuBC,EAA4B,CAClE,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAClB,GAAI,CACF,OAAO,OAAA,CAAQ,IAAID,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CACxC,CAAA,KAAQ,CACN,MACF,CAGF,IAAI9D,EACJ,GAAI,CACFA,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI4D,CAAAA,CAAKC,EAAMC,CAAQ,EACzC,CAAA,KAAQ,CACN,MACF,CAGA,GAAI,OAAO9D,CAAAA,EAAU,YAAc,CAAC+E,CAAAA,CAAa,IAAIlB,CAAI,CAAA,CACvD,OAAO7D,CAAAA,CAGT,IAAMkF,CAAAA,CAAarB,EAEnB,OAAO,SAAA,GAA4BxD,CAAAA,CAA0B,CAE3D,IAAMK,CAAAA,CAAgBL,EAAK,GAAA,CAAK2C,CAAAA,EAC1BA,CAAAA,GAAQ,IAAA,EAAQ,OAAOA,CAAAA,EAAQ,SAC1BJ,CAAAA,CAAiBI,CAAG,EAEtBA,CACR,CAAA,CAEGF,EACJ,GAAI,CACFA,CAAAA,CAAU9C,CAAAA,CAAmB,KAAA,CAAM4D,CAAAA,CAAKvD,CAAI,EAC9C,CAAA,MAASmE,CAAAA,CAAK,CACZ,MAAAW,CAAAA,CAAgBX,EAAKU,CAAAA,CAAYxE,CAAa,CAAA,CACxC8D,CACR,CAEA,OAAIjB,EAAWT,CAAM,CAAA,CACXA,EAA4B,IAAA,CACjCsC,CAAAA,GACCC,EAAiBD,CAAAA,CAAUF,CAAAA,CAAYxE,CAAa,CAAA,CAC7C0E,CAAAA,CAAAA,CAERE,CAAAA,GACCH,EAAgBG,CAAAA,CAAUJ,CAAAA,CAAYxE,CAAa,CAAA,CAC5C,OAAA,CAAQ,MAAA,CAAO4E,CAAQ,CAAA,CAElC,CAAA,CAGKxC,CACT,CACF,CACF,CAAC,CACH,CAKA,SAASuC,EACPvC,CAAAA,CACArC,CAAAA,CACAC,EACM,CACN,GAAI,CACF,GAAI4C,CAAAA,CAAiBR,CAAM,GAAKA,CAAAA,CAAO,KAAA,CAAO,CAC5C,IAAM+B,CAAAA,CAAS1C,CAAAA,CAAmBW,EAAO,KAAA,CAAO,CAAE,SAAA,CAAWrC,CAAO,CAAC,CAAA,CAErEwC,EAAc,CACZ,IAAA,CAAM,OACN,QAAA,CAAU,eAAA,CACV,QAAS,CAAA,aAAA,EAAgBxC,CAAM,CAAA,CAAA,CAC/B,IAAA,CAAM,CACJ,MAAA,CAAAA,EACA,SAAA,CAAWoE,CAAAA,CAAO,SAAA,CAClB,SAAA,CAAWA,CAAAA,CAAO,SACpB,EACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,QAAA,CAAU,UAAA,CACV,KAAM,MAAA,CACN,MAAA,CAAArE,EACA,MAAA,CAAQP,QAAAA,CACN,MAAA,CAAO,WAAA,CACLQ,CAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,CAAG,CAAA,GAAM,CAAC,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAIqC,EAAc,CAAC,CAAC,CAAC,CAC3D,CACF,CAAA,CACA,UAAW8B,CAAAA,CAAO,SAAA,CAClB,aAAcA,CAAAA,CAAO,gBACvB,EAEAxB,CAAAA,CAAaP,CAAAA,CAAO,KAAA,CAAO,CACzB,SAAA,CAAWgC,CAAAA,CACX,MAAO,CACL,QAAA,CAAU,CACR,SAAA,CAAW,MAAA,CACX,MAAA,CAAArE,EACA,WAAA,CAAaoE,CACf,CACF,CACF,CAAC,EACH,MAEE5B,CAAAA,CAAc,CACZ,KAAM,MAAA,CACN,QAAA,CAAU,gBACV,OAAA,CAAS,CAAA,SAAA,EAAYxC,CAAM,CAAA,CAAA,CAC3B,IAAA,CAAM,CAAE,OAAAA,CAAO,CAAA,CACf,KAAA,CAAO,MACT,CAAC,EAEL,MAAQ,CAER,CACF,CAKA,SAAS0E,CAAAA,CACPhB,CAAAA,CACA1D,EACAC,CAAAA,CACM,CACN,GAAI,CACF,IAAMmE,EAAS1C,CAAAA,CAAmBgC,CAAAA,CAAQ,CAAE,SAAA,CAAW1D,CAAO,CAAC,EAE/DwC,CAAAA,CAAc,CACZ,IAAA,CAAM,MAAA,CACN,QAAA,CAAU,eAAA,CACV,QAAS,CAAA,eAAA,EAAkBxC,CAAM,CAAA,CAAA,CACjC,IAAA,CAAM,CACJ,MAAA,CAAAA,EACA,SAAA,CAAWoE,CAAAA,CAAO,SACpB,CAAA,CACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,QAAA,CAAU,WACV,IAAA,CAAM,MAAA,CACN,MAAA,CAAArE,CAAAA,CACA,MAAA,CAAQP,QAAAA,CACN,OAAO,WAAA,CACLQ,CAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,CAAG,CAAA,GAAM,CAAC,CAAA,GAAA,EAAM,CAAC,GAAIqC,CAAAA,CAAc,CAAC,CAAC,CAAC,CAC3D,CACF,CAAA,CACA,SAAA,CAAW8B,CAAAA,CAAO,UAClB,YAAA,CAAcA,CAAAA,CAAO,gBACvB,CAAA,CAEAxB,CAAAA,CAAac,CAAAA,CAAQ,CACnB,SAAA,CAAWW,CAAAA,CACX,KAAA,CAAO,CACL,QAAA,CAAU,CACR,UAAW,MAAA,CACX,MAAA,CAAArE,EACA,WAAA,CAAaoE,CACf,CACF,CACF,CAAC,EACH,CAAA,KAAQ,CAER,CACF,CASA,SAASU,CAAAA,CACPC,CAAAA,CACAf,CAAAA,CACQ,CACR,OAAO,IAAI,KAAA,CAAMe,CAAAA,CAAiB,CAChC,GAAA,CAAI5B,CAAAA,CAAaC,CAAAA,CAAuBC,EAA4B,CAClE,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAClB,GAAI,CACF,OAAO,OAAA,CAAQ,GAAA,CAAID,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CACxC,CAAA,KAAQ,CACN,MACF,CAGF,IAAI9D,EACJ,GAAI,CACFA,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI4D,CAAAA,CAAKC,EAAMC,CAAQ,EACzC,MAAQ,CACN,MACF,CAGA,OAAI,OAAO9D,CAAAA,EAAU,UAAA,EAAc6D,CAAAA,GAAS,QAAA,CACnC7D,EAGF,SAAyByF,CAAAA,CAAsBC,CAAAA,CAAkC,CACtF,IAAMC,CAAAA,CAAmBD,EACrB9C,CAAAA,CAAiB8C,CAAa,CAAA,CAC9B,MAAA,CAEA5C,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAU9C,CAAAA,CAAmB,MAAM4D,CAAAA,CAAK,CAAC6B,EAAcC,CAAa,CAAC,EACvE,CAAA,MAASlB,CAAAA,CAAK,CACZ,MAAAoB,CAAAA,CAAqBpB,CAAAA,CAAKiB,CAAAA,CAAcE,CAAgB,CAAA,CAClDnB,CACR,CAEA,OAAIjB,CAAAA,CAAWT,CAAM,CAAA,CACXA,CAAAA,CAA4B,IAAA,CACjCsC,IACCS,CAAAA,CAAsBT,CAAAA,CAAUK,EAAcE,CAAgB,CAAA,CACvDP,GAERE,CAAAA,GACCM,CAAAA,CAAqBN,CAAAA,CAAUG,CAAAA,CAAcE,CAAgB,CAAA,CACtD,QAAQ,MAAA,CAAOL,CAAQ,CAAA,CAElC,CAAA,CAGKxC,CACT,CACF,CACF,CAAC,CACH,CAKA,SAAS+C,CAAAA,CACP/C,CAAAA,CACA2C,EACAE,CAAAA,CACM,CACN,GAAI,CACF,GAAIrC,EAAiBR,CAAM,CAAA,EAAKA,CAAAA,CAAO,KAAA,CAAO,CAC5C,IAAM+B,EAAS1C,CAAAA,CAAmBW,CAAAA,CAAO,KAAA,CAAO,CAC9C,YAAA,CAAA2C,CAAAA,CACA,UAAW,QACb,CAAC,CAAA,CAEDxC,CAAAA,CAAc,CACZ,IAAA,CAAM,WACN,QAAA,CAAU,oBAAA,CACV,QAAS,CAAA,iBAAA,EAAoBwC,CAAY,GACzC,IAAA,CAAM,CACJ,YAAA,CAAAA,CAAAA,CACA,SAAA,CAAWZ,CAAAA,CAAO,UAClB,SAAA,CAAWA,CAAAA,CAAO,SACpB,CAAA,CACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,QAAA,CAAU,UAAA,CACV,KAAM,WAAA,CACN,MAAA,CAAQ,SACR,MAAA,CAAQ,CACN,aAAAW,CAAAA,CACA,OAAA,CAAS1C,CAAAA,CAAc4C,CAAgB,CACzC,CAAA,CACA,UAAWd,CAAAA,CAAO,SAAA,CAClB,YAAA,CAAcA,CAAAA,CAAO,gBACvB,CAAA,CAEAxB,EAAaP,CAAAA,CAAO,KAAA,CAAO,CACzB,SAAA,CAAWgC,CAAAA,CACX,KAAA,CAAO,CACL,QAAA,CAAU,CACR,UAAW,WAAA,CACX,YAAA,CAAAW,EACA,WAAA,CAAaZ,CACf,CACF,CACF,CAAC,EACH,MACE5B,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,QAAA,CAAU,oBAAA,CACV,QAAS,CAAA,aAAA,EAAgBwC,CAAY,CAAA,CAAA,CACrC,IAAA,CAAM,CAAE,YAAA,CAAAA,CAAa,CAAA,CACrB,KAAA,CAAO,MACT,CAAC,EAEL,MAAQ,CAER,CACF,CAKA,SAASG,CAAAA,CACPzB,CAAAA,CACAsB,EACAE,CAAAA,CACM,CACN,GAAI,CACF,IAAMd,CAAAA,CAAS1C,EAAmBgC,CAAAA,CAAQ,CACxC,YAAA,CAAAsB,CAAAA,CACA,SAAA,CAAW,QACb,CAAC,CAAA,CAEDxC,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,QAAA,CAAU,qBACV,OAAA,CAAS,CAAA,mBAAA,EAAsBwC,CAAY,CAAA,CAAA,CAC3C,IAAA,CAAM,CACJ,aAAAA,CAAAA,CACA,SAAA,CAAWZ,CAAAA,CAAO,SACpB,CAAA,CACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,QAAA,CAAU,WACV,IAAA,CAAM,WAAA,CACN,OAAQ,QAAA,CACR,MAAA,CAAQ,CACN,YAAA,CAAAW,CAAAA,CACA,OAAA,CAAS1C,CAAAA,CAAc4C,CAAgB,CACzC,EACA,SAAA,CAAWd,CAAAA,CAAO,SAAA,CAClB,YAAA,CAAcA,CAAAA,CAAO,gBACvB,EAEAxB,CAAAA,CAAac,CAAAA,CAAQ,CACnB,SAAA,CAAWW,CAAAA,CACX,KAAA,CAAO,CACL,QAAA,CAAU,CACR,UAAW,WAAA,CACX,YAAA,CAAAW,EACA,WAAA,CAAaZ,CACf,CACF,CACF,CAAC,EACH,MAAQ,CAER,CACF,CAOA,IAAMiB,EAAAA,CAAkB,IAAI,IAAI,CAC9B,QAAA,CACA,UAAA,CACA,QAAA,CACA,MAAA,CACA,MAAA,CACA,OACA,iBAAA,CACA,kBAAA,CACA,cACF,CAAC,CAAA,CAKD,SAASC,EAAAA,CACPC,CAAAA,CACAC,CAAAA,CACAxB,CAAAA,CACQ,CACR,OAAO,IAAI,KAAA,CAAMuB,CAAAA,CAAc,CAC7B,GAAA,CAAIpC,CAAAA,CAAaC,CAAAA,CAAuBC,EAA4B,CAClE,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAClB,GAAI,CACF,OAAO,OAAA,CAAQ,IAAID,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CACxC,CAAA,KAAQ,CACN,MACF,CAGF,IAAI9D,EACJ,GAAI,CACFA,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI4D,CAAAA,CAAKC,EAAMC,CAAQ,EACzC,CAAA,KAAQ,CACN,MACF,CAEA,GAAI,OAAO9D,CAAAA,EAAU,YAAc,CAAC8F,EAAAA,CAAgB,IAAIjC,CAAI,CAAA,CAC1D,OAAO7D,CAAAA,CAGT,IAAMkF,CAAAA,CAAarB,EAEnB,OAAO,SAAA,GAA4BxD,CAAAA,CAA0B,CAC3D,IAAIyC,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAU9C,CAAAA,CAAmB,KAAA,CAAM4D,CAAAA,CAAKvD,CAAI,EAC9C,CAAA,MAASmE,CAAAA,CAAK,CACZ,MAAA0B,CAAAA,CAAmB1B,EAAKyB,CAAAA,CAAYf,CAAAA,CAAY7E,CAAI,CAAA,CAC9CmE,CACR,CAEA,OAAIjB,CAAAA,CAAWT,CAAM,CAAA,CACXA,CAAAA,CAA4B,IAAA,CACjCsC,CAAAA,GACCe,GAAoBf,CAAAA,CAAUa,CAAAA,CAAYf,CAAAA,CAAY7E,CAAI,CAAA,CACnD+E,CAAAA,CAAAA,CAERE,IACCY,CAAAA,CAAmBZ,CAAAA,CAAUW,EAAYf,CAAAA,CAAY7E,CAAI,EAClD,OAAA,CAAQ,MAAA,CAAOiF,CAAQ,CAAA,CAElC,CAAA,CAGKxC,CACT,CACF,CACF,CAAC,CACH,CAKA,SAASqD,EAAAA,CACPrD,EACAmD,CAAAA,CACAxF,CAAAA,CACAJ,CAAAA,CACM,CACN,GAAI,CACF,GAAIiD,CAAAA,CAAiBR,CAAM,GAAKA,CAAAA,CAAO,KAAA,CAAO,CAC5C,IAAM+B,CAAAA,CAAS1C,CAAAA,CAAmBW,CAAAA,CAAO,KAAA,CAAO,CAC9C,WAAAmD,CAAAA,CACA,SAAA,CAAWxF,CACb,CAAC,CAAA,CAEDwC,CAAAA,CAAc,CACZ,IAAA,CAAM,UAAA,CACN,QAAA,CAAU,kBAAA,CACV,OAAA,CAAS,CAAA,gBAAA,EAAmBxC,CAAM,CAAA,IAAA,EAAOwF,CAAU,GACnD,IAAA,CAAM,CACJ,OAAQA,CAAAA,CACR,MAAA,CAAAxF,CAAAA,CACA,SAAA,CAAWoE,CAAAA,CAAO,SACpB,EACA,KAAA,CAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,QAAA,CAAU,UAAA,CACV,IAAA,CAAM,SAAA,CACN,MAAA,CAAArE,CAAAA,CACA,OAAQ,CACN,MAAA,CAAQwF,EACR,IAAA,CAAM,OAAO5F,EAAK,CAAC,CAAA,EAAM,QAAA,CAAWA,CAAAA,CAAK,CAAC,CAAA,CAAI,MAChD,CAAA,CACA,SAAA,CAAWwE,CAAAA,CAAO,SAAA,CAClB,YAAA,CAAcA,CAAAA,CAAO,gBACvB,CAAA,CAEAxB,CAAAA,CAAaP,CAAAA,CAAO,KAAA,CAAO,CACzB,SAAA,CAAWgC,EACX,KAAA,CAAO,CACL,SAAU,CACR,SAAA,CAAW,UACX,MAAA,CAAQmB,CAAAA,CACR,MAAA,CAAAxF,CAAAA,CACA,WAAA,CAAaoE,CACf,CACF,CACF,CAAC,EACH,CAAA,KACE5B,CAAAA,CAAc,CACZ,KAAM,UAAA,CACN,QAAA,CAAU,kBAAA,CACV,OAAA,CAAS,CAAA,YAAA,EAAexC,CAAM,OAAOwF,CAAU,CAAA,CAAA,CAC/C,KAAM,CAAE,MAAA,CAAQA,EAAY,MAAA,CAAAxF,CAAO,CAAA,CACnC,KAAA,CAAO,MACT,CAAC,EAEL,CAAA,KAAQ,CAER,CACF,CAKA,SAASyF,CAAAA,CACP/B,EACA8B,CAAAA,CACAxF,CAAAA,CACAJ,CAAAA,CACM,CACN,GAAI,CACF,IAAMwE,CAAAA,CAAS1C,CAAAA,CAAmBgC,EAAQ,CACxC,UAAA,CAAA8B,EACA,SAAA,CAAWxF,CACb,CAAC,CAAA,CAEDwC,CAAAA,CAAc,CACZ,KAAM,UAAA,CACN,QAAA,CAAU,kBAAA,CACV,OAAA,CAAS,CAAA,kBAAA,EAAqBxC,CAAM,OAAOwF,CAAU,CAAA,CAAA,CACrD,IAAA,CAAM,CACJ,MAAA,CAAQA,CAAAA,CACR,OAAAxF,CAAAA,CACA,SAAA,CAAWoE,EAAO,SACpB,CAAA,CACA,MAAO,OACT,CAAC,CAAA,CAED,IAAMC,CAAAA,CAA+B,CACnC,SAAU,UAAA,CACV,IAAA,CAAM,SAAA,CACN,MAAA,CAAArE,CAAAA,CACA,MAAA,CAAQ,CACN,MAAA,CAAQwF,CAAAA,CACR,IAAA,CAAM,OAAO5F,CAAAA,CAAK,CAAC,GAAM,QAAA,CAAWA,CAAAA,CAAK,CAAC,CAAA,CAAI,KAAA,CAChD,EACA,SAAA,CAAWwE,CAAAA,CAAO,SAAA,CAClB,YAAA,CAAcA,CAAAA,CAAO,gBACvB,EAEAxB,CAAAA,CAAac,CAAAA,CAAQ,CACnB,SAAA,CAAWW,CAAAA,CACX,KAAA,CAAO,CACL,QAAA,CAAU,CACR,SAAA,CAAW,SAAA,CACX,MAAA,CAAQmB,CAAAA,CACR,OAAAxF,CAAAA,CACA,WAAA,CAAaoE,CACf,CACF,CACF,CAAC,EACH,CAAA,KAAQ,CAER,CACF,CAMA,SAASuB,EAAAA,CACPC,EACA1C,CAAAA,CACQ,CACR,OAAO,IAAI,KAAA,CAAM0C,CAAAA,CAAe,CAC9B,GAAA,CAAIzC,CAAAA,CAAaC,CAAAA,CAAuBC,CAAAA,CAA4B,CAClE,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAClB,GAAI,CACF,OAAO,QAAQ,GAAA,CAAID,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,CACxC,CAAA,KAAQ,CACN,MACF,CAGF,IAAI9D,CAAAA,CACJ,GAAI,CACFA,EAAQ,OAAA,CAAQ,GAAA,CAAI4D,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,EACzC,MAAQ,CACN,MACF,CAGA,OAAI,OAAO9D,GAAU,UAAA,EAAc6D,CAAAA,GAAS,MAAA,CACnC,SAAyBoC,CAAAA,CAA6B,CAC3D,IAAMK,CAAAA,CAAgBtG,CAAAA,CAAmB,KAAA,CAAM4D,CAAAA,CAAK,CAACqC,CAAU,CAAC,CAAA,CAChE,OAAIK,CAAAA,GAAiB,IAAA,EAAQ,OAAOA,CAAAA,EAAiB,SAC5CP,EAAAA,CAAyBO,CAAAA,CAAwBL,CAAmB,CAAA,CAEtEK,CACT,CAAA,CAGKtG,CACT,CACF,CAAC,CACH,CASA,SAASuG,EAAAA,CAAe5C,CAAAA,CAA6D,CACnF,OAAO,CACL,YAAA,CAAcA,EAAQ,YAAA,EAAgB,IAAA,CACtC,SAAA,CAAWA,CAAAA,CAAQ,SAAA,EAAa,IAAA,CAChC,eAAgBA,CAAAA,CAAQ,cAAA,EAAkB,KAC1C,YAAA,CAAcA,CAAAA,CAAQ,cAAgB,KAAA,CACtC,aAAA,CAAeA,CAAAA,CAAQ,aAAA,EAAiB,KAC1C,CACF,CAmBO,SAAS6C,CAAAA,CACdrD,CAAAA,CACAQ,CAAAA,CACS,CAGT,GADIR,GAAW,IAAA,EACX,OAAOA,CAAAA,EAAW,QAAA,EAAY,OAAOA,CAAAA,EAAW,WAAY,OAAOA,CAAAA,CAEvE,IAAMiC,CAAAA,CAAWmB,EAAAA,CAAe5C,CAAO,CAAA,CAEvC,OAAO,IAAI,KAAA,CAAMR,CAAAA,CAAkB,CACjC,IAAIS,CAAAA,CAAaC,CAAAA,CAAuBC,CAAAA,CAA4B,CAElE,GAAI,OAAOD,GAAS,QAAA,CAClB,GAAI,CACF,OAAO,OAAA,CAAQ,GAAA,CAAID,EAAKC,CAAAA,CAAMC,CAAQ,CACxC,CAAA,KAAQ,CACN,MACF,CAGF,IAAI9D,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAQ,QAAQ,GAAA,CAAI4D,CAAAA,CAAKC,CAAAA,CAAMC,CAAQ,EACzC,CAAA,KAAQ,CACN,MACF,CAGA,OAAID,CAAAA,GAAS,MAAA,EAAU,OAAO7D,GAAU,UAAA,EAAcoF,CAAAA,CAAS,aACtD,SAAA,GAA4B/E,CAAAA,CAA0B,CAC3D,IAAMqD,CAAAA,CAAU,IAAIlD,CAAAA,CACpBkD,CAAAA,CAAQ,KAAA,CAAM,OAAQrD,CAAI,CAAA,CAE1B,IAAIyC,CAAAA,CACJ,GAAI,CACFA,EAAU9C,CAAAA,CAAmB,KAAA,CAAM4D,CAAAA,CAAKvD,CAAI,EAC9C,CAAA,MAASmE,EAAK,CACZ,MAAAJ,EAAiBI,CAAAA,CAAKd,CAAiB,CAAA,CACjCc,CACR,CAEA,OAAI1B,CAAAA,GAAW,IAAA,EAAQ,OAAOA,CAAAA,EAAW,QAAA,CAChCU,CAAAA,CAAwBV,CAAAA,CAAQY,CAAiB,EAEnDZ,CACT,CAAA,CAIEe,CAAAA,GAAS,KAAA,EAAS,OAAO7D,CAAAA,EAAU,YAAcoF,CAAAA,CAAS,YAAA,CACrD,YAA4B/E,CAAAA,CAA0B,CAC3D,IAAMqD,CAAAA,CAAU,IAAIlD,CAAAA,CACpBkD,CAAAA,CAAQ,KAAA,CAAM,KAAA,CAAOrD,CAAI,CAAA,CAEzB,IAAIyC,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAU9C,EAAmB,KAAA,CAAM4D,CAAAA,CAAKvD,CAAI,EAC9C,CAAA,MAASmE,CAAAA,CAAK,CACZ,MAAAJ,CAAAA,CAAiBI,EAAKd,CAAiB,EACjCc,CACR,CAMA,OAJIjB,CAAAA,CAAWT,CAAM,CAAA,EAIjBA,IAAW,IAAA,EAAQ,OAAOA,CAAAA,EAAW,QAAA,CAChCU,CAAAA,CAAwBV,CAAAA,CAAQY,CAAiB,CAAA,CAGnDZ,CACT,CAAA,CAIEe,CAAAA,GAAS,MAAA,EAAUuB,EAAS,SAAA,EAC1BpF,CAAAA,GAAU,MAAQ,OAAOA,CAAAA,EAAU,SAC9BgF,CAAAA,CAAgBhF,CAAyB,CAAA,CAKhD6D,CAAAA,GAAS,WAAA,EAAeuB,EAAS,cAAA,EAC/BpF,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAC9BuF,EAAqBvF,CAAyB,CAAA,CAKrD6D,CAAAA,GAAS,SAAA,EAAauB,CAAAA,CAAS,cAC7BpF,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,EAAU,QAAA,CAC9BoG,GAAmBpG,CAAyB,CAAA,CAKhDA,CACT,CAAA,CAGA,GAAA,CAAI4D,EAAaC,CAAAA,CAAuB7D,CAAAA,CAAgB8D,CAAAA,CAA4B,CAClF,OAAO,OAAA,CAAQ,IAAIF,CAAAA,CAAKC,CAAAA,CAAM7D,CAAAA,CAAO8D,CAAQ,CAC/C,CAAA,CAEA,IAAIF,CAAAA,CAAaC,CAAAA,CAAgC,CAC/C,OAAO,OAAA,CAAQ,IAAID,CAAAA,CAAKC,CAAI,CAC9B,CAAA,CAEA,cAAA,CAAeD,CAAAA,CAAaC,EAAgC,CAC1D,OAAO,OAAA,CAAQ,cAAA,CAAeD,CAAAA,CAAKC,CAAI,CACzC,CAAA,CAEA,OAAA,CAAQD,CAAAA,CAAyC,CAC/C,OAAO,OAAA,CAAQ,QAAQA,CAAG,CAC5B,EAEA,wBAAA,CACEA,CAAAA,CACAC,EACgC,CAChC,OAAO,OAAA,CAAQ,wBAAA,CAAyBD,CAAAA,CAAKC,CAAI,CACnD,CAAA,CAEA,cAAA,CAAeD,CAAAA,CAA4B,CACzC,OAAO,OAAA,CAAQ,eAAeA,CAAG,CACnC,CAAA,CAEA,YAAA,CAAaA,CAAAA,CAAsB,CACjC,OAAO,OAAA,CAAQ,YAAA,CAAaA,CAAG,CACjC,CAAA,CAEA,kBAAkBA,CAAAA,CAAsB,CACtC,OAAO,OAAA,CAAQ,iBAAA,CAAkBA,CAAG,CACtC,CAAA,CAEA,cAAA,CACEA,CAAAA,CACAC,CAAAA,CACA4C,CAAAA,CACS,CACT,OAAO,OAAA,CAAQ,cAAA,CAAe7C,CAAAA,CAAKC,CAAAA,CAAM4C,CAAU,CACrD,EAEA,cAAA,CAAe7C,CAAAA,CAAa8C,CAAAA,CAA+B,CACzD,OAAO,OAAA,CAAQ,eAAe9C,CAAAA,CAAK8C,CAAK,CAC1C,CACF,CAAC,CACH,CC7mCO,SAASC,EAAAA,CAAgBxD,CAAAA,CAAWQ,CAAAA,CAAkC,CAC3E,OAAO6C,EAAoBrD,CAAAA,CAAQQ,CAAAA,EAAW,EAAE,CAClD","file":"index.mjs","sourcesContent":["// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — query chain tracker\n// ---------------------------------------------------------------------------\n//\n// Records each method call in a Supabase query builder chain so that errors\n// can be reported with full context about what the developer was trying to do.\n// ---------------------------------------------------------------------------\n\nimport { sanitize } from '@uncaughtdev/core';\nimport type { OperationInfo } from '@uncaughtdev/core';\nimport type { QueryChainStep, TrackedQuery } from './types';\n\n/** Maximum number of items to keep from bulk insert/upsert arrays. */\nconst MAX_BULK_PREVIEW = 3;\n\n/** Primary CRUD operations that determine the query type. */\nconst CRUD_METHODS = new Set([\n 'select',\n 'insert',\n 'update',\n 'upsert',\n 'delete',\n]);\n\n/**\n * Sanitize a single argument value.\n * - Arrays of objects (bulk inserts) are truncated to the first N items.\n * - Everything is run through the core sanitizer to redact sensitive keys.\n */\nfunction sanitizeArg(value: unknown): unknown {\n try {\n if (Array.isArray(value) && value.length > MAX_BULK_PREVIEW) {\n const truncated = value.slice(0, MAX_BULK_PREVIEW).map((item) => {\n if (item !== null && typeof item === 'object') {\n return sanitize(item as Record<string, unknown>);\n }\n return item;\n });\n return `[${truncated.map((v) => JSON.stringify(v)).join(', ')} ... and ${value.length - MAX_BULK_PREVIEW} more]`;\n }\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return sanitize(value as Record<string, unknown>);\n }\n\n return value;\n } catch {\n return '[unserializable]';\n }\n}\n\n/**\n * Sanitize an array of arguments for safe storage and display.\n */\nfunction sanitizeArgs(args: unknown[]): unknown[] {\n return args.map(sanitizeArg);\n}\n\n/**\n * Format a single value for the human-readable query string.\n */\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') {\n return `'${value}'`;\n }\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === 'object') {\n try {\n const str = JSON.stringify(value);\n if (str.length > 120) {\n return str.slice(0, 117) + '...';\n }\n return str;\n } catch {\n return '[object]';\n }\n }\n return String(value);\n}\n\n/**\n * Tracks method calls in a Supabase query builder chain.\n *\n * Usage:\n * ```ts\n * const tracker = new QueryTracker();\n * tracker.track('from', ['orders']);\n * tracker.track('select', ['*']);\n * tracker.track('eq', ['user_id', '123']);\n *\n * tracker.getTable(); // 'orders'\n * tracker.getOperation(); // 'select'\n * tracker.toHumanReadable(); // \".from('orders').select('*').eq('user_id', '123')\"\n * ```\n */\nexport class QueryTracker {\n private readonly steps: QueryChainStep[] = [];\n private tableName = '';\n private operationType = 'unknown';\n\n /**\n * Record a method call in the chain.\n *\n * @param method - The method name (e.g. 'from', 'select', 'eq').\n * @param args - The arguments passed to the method.\n */\n track(method: string, args: unknown[]): void {\n const sanitizedArgs = sanitizeArgs(args);\n this.steps.push({ method, args: sanitizedArgs });\n\n // Extract table name from .from('tableName')\n if (method === 'from' && args.length > 0 && typeof args[0] === 'string') {\n this.tableName = args[0];\n }\n\n // Extract operation type from CRUD methods\n if (CRUD_METHODS.has(method)) {\n this.operationType = method;\n }\n\n // Also detect .rpc() calls\n if (method === 'rpc') {\n this.operationType = 'rpc';\n }\n }\n\n /**\n * Get the table name extracted from .from() calls.\n */\n getTable(): string {\n return this.tableName;\n }\n\n /**\n * Get the primary CRUD operation type.\n */\n getOperation(): string {\n return this.operationType;\n }\n\n /**\n * Get all tracked steps.\n */\n getSteps(): QueryChainStep[] {\n return [...this.steps];\n }\n\n /**\n * Build a human-readable representation of the full query chain.\n *\n * @example\n * \".from('orders').select('*').eq('user_id', '123').limit(10)\"\n */\n toHumanReadable(): string {\n if (this.steps.length === 0) {\n return '(empty chain)';\n }\n\n return this.steps\n .map((step) => {\n const formattedArgs = step.args.map(formatValue).join(', ');\n return `.${step.method}(${formattedArgs})`;\n })\n .join('');\n }\n\n /**\n * Convert the tracked query into a full TrackedQuery object.\n */\n toTrackedQuery(): TrackedQuery {\n return {\n table: this.tableName,\n operation: this.operationType,\n chain: [...this.steps],\n humanReadable: this.toHumanReadable(),\n };\n }\n\n /**\n * Convert the tracked query into an OperationInfo compatible with UncaughtEvent.\n */\n toOperationInfo(): OperationInfo {\n return {\n provider: 'supabase',\n type: 'query',\n method: this.operationType,\n params: {\n table: this.tableName,\n chain: this.toHumanReadable(),\n },\n };\n }\n\n /**\n * Check if any steps have been tracked.\n */\n isEmpty(): boolean {\n return this.steps.length === 0;\n }\n\n /**\n * Reset the tracker for reuse.\n */\n reset(): void {\n this.steps.length = 0;\n this.tableName = '';\n this.operationType = 'unknown';\n }\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — human-readable error explanations\n// ---------------------------------------------------------------------------\n//\n// Maps Supabase / PostgreSQL error codes to developer-friendly explanations\n// with contextual variable interpolation.\n// ---------------------------------------------------------------------------\n\n/**\n * Context variables that can be interpolated into explanation templates.\n */\nexport interface ExplainerContext {\n table?: string;\n operation?: string;\n name?: string;\n column?: string;\n constraint?: string;\n [key: string]: string | undefined;\n}\n\n/**\n * An explanation template with {variable} placeholders.\n */\ninterface ExplanationTemplate {\n template: string;\n category: string;\n}\n\n/**\n * Registry of error code to explanation template mappings.\n *\n * Templates support {variable} interpolation from the ExplainerContext.\n * Unknown variables are left as-is in the output (e.g. \"{table}\" if no\n * table context is provided).\n */\nconst EXPLANATIONS: Record<string, ExplanationTemplate> = {\n // -------------------------------------------------------------------------\n // PostgreSQL error codes\n // -------------------------------------------------------------------------\n\n '42501': {\n template:\n \"The RLS policy on the '{table}' table does not allow {operation} operations for the current user role. \" +\n \"Check your RLS policies in the Supabase dashboard under Authentication > Policies for the '{table}' table. \" +\n 'Common causes: missing policy for the operation type, policy condition not matching the current user, ' +\n \"or the user's JWT role not having the expected grants.\",\n category: 'rls_violation',\n },\n\n '23505': {\n template:\n \"A record with this value already exists. The unique constraint on table '{table}' was violated. \" +\n 'This typically means you are trying to insert or update a row with a value that must be unique ' +\n '(e.g. email, username, slug) but another row already has that value. ' +\n 'Consider using .upsert() instead of .insert() if you want to update on conflict, ' +\n 'or check for existing records before inserting.',\n category: 'unique_violation',\n },\n\n '23503': {\n template:\n \"The referenced record does not exist. The foreign key constraint on table '{table}' failed. \" +\n 'This means you are trying to insert or update a row that references another row (via a foreign key) ' +\n 'that does not exist in the referenced table. Ensure the referenced record exists before ' +\n 'creating this relationship, or check that the foreign key value is correct.',\n category: 'foreign_key_violation',\n },\n\n '23502': {\n template:\n \"A required field was not provided. The not-null constraint on table '{table}' was violated. \" +\n 'One or more columns that are defined as NOT NULL did not receive a value in the insert or update. ' +\n 'Check your insert/update payload to ensure all required fields are present, ' +\n 'or set a default value for the column in your database schema.',\n category: 'not_null_violation',\n },\n\n '42P01': {\n template:\n \"The table '{table}' does not exist in the database. This could mean the table name is misspelled, \" +\n 'the table has not been created yet, or you are connecting to the wrong database/schema. ' +\n \"Check the table name in your .from() call and verify it exists in the Supabase dashboard's \" +\n 'Table Editor.',\n category: 'undefined_table',\n },\n\n '42703': {\n template:\n \"The column '{column}' does not exist in table '{table}'. Check that the column name is spelled \" +\n 'correctly and that any recent migrations have been applied.',\n category: 'undefined_column',\n },\n\n '42883': {\n template:\n \"The function or operator does not exist. If you are using .rpc('{name}'), check that the function \" +\n 'exists in your database and that the argument types match.',\n category: 'undefined_function',\n },\n\n // -------------------------------------------------------------------------\n // PostgREST error codes\n // -------------------------------------------------------------------------\n\n PGRST116: {\n template:\n 'Expected a single row but got none. The .single() call on the query returned 0 rows. ' +\n \"This means no record matched your filter conditions in table '{table}'. \" +\n 'If the record might not exist, use .maybeSingle() instead of .single() ' +\n 'to return null instead of an error when no rows match.',\n category: 'no_rows',\n },\n\n PGRST301: {\n template:\n 'The authentication token (JWT) has expired. The user needs to re-authenticate. ' +\n 'This typically happens when the session has been idle for longer than the JWT expiry time. ' +\n 'Call supabase.auth.refreshSession() to attempt a token refresh, or redirect the user ' +\n 'to the sign-in page. Consider setting up an onAuthStateChange listener to handle ' +\n 'token refreshes automatically.',\n category: 'jwt_expired',\n },\n\n PGRST204: {\n template:\n \"The column '{column}' specified in the query does not exist in the database schema. \" +\n 'PostgREST could not find this column when processing the query.',\n category: 'column_not_found',\n },\n\n PGRST200: {\n template:\n \"An ambiguous embedding was detected. The relationship between '{table}' and the referenced \" +\n 'table could not be resolved because multiple foreign keys exist. ' +\n 'Specify the foreign key explicitly using the !inner or !left join syntax.',\n category: 'ambiguous_embedding',\n },\n\n // -------------------------------------------------------------------------\n // Auth error patterns (matched by message content, not code)\n // -------------------------------------------------------------------------\n\n auth_invalid_credentials: {\n template:\n 'The email or password is incorrect. Note: if the user recently signed up, their email ' +\n 'may not be confirmed yet. Check the Supabase dashboard under Authentication > Users to see ' +\n \"the user's confirmation status. Also verify that the email provider is enabled in \" +\n 'Authentication > Providers.',\n category: 'auth_invalid_credentials',\n },\n\n auth_email_not_confirmed: {\n template:\n 'The user has signed up but has not confirmed their email address. ' +\n 'Check your email confirmation settings in Authentication > Settings. ' +\n 'You can disable email confirmation for development, or resend the confirmation email ' +\n 'using supabase.auth.resend({ type: \"signup\", email }).',\n category: 'auth_email_not_confirmed',\n },\n\n auth_rate_limited: {\n template:\n 'Too many authentication attempts. Supabase rate limits auth endpoints to prevent abuse. ' +\n 'The default rate limit is approximately 30 requests per hour for auth endpoints. ' +\n 'Wait a few minutes before trying again. If you are hitting this in production, ' +\n 'consider implementing client-side rate limiting or CAPTCHA.',\n category: 'auth_rate_limited',\n },\n\n auth_user_not_found: {\n template:\n 'No user was found with the provided credentials. The user may not have signed up yet, ' +\n 'or the account may have been deleted.',\n category: 'auth_user_not_found',\n },\n\n auth_session_not_found: {\n template:\n 'No active session was found. The user is not currently signed in or their session has expired. ' +\n 'Redirect the user to the sign-in page.',\n category: 'auth_session_not_found',\n },\n\n auth_signup_disabled: {\n template:\n 'New user signups have been disabled for this project. Enable signups in the Supabase dashboard ' +\n 'under Authentication > Settings.',\n category: 'auth_signup_disabled',\n },\n\n // -------------------------------------------------------------------------\n // Edge Functions error patterns\n // -------------------------------------------------------------------------\n\n functions_timeout: {\n template:\n \"The edge function '{name}' timed out. Edge functions have a default execution time limit \" +\n '(typically 60 seconds on the free plan). Consider optimizing the function, ' +\n 'breaking it into smaller operations, or upgrading your Supabase plan for longer execution times.',\n category: 'functions_timeout',\n },\n\n functions_crashed: {\n template:\n \"The edge function '{name}' crashed during execution. Check the function logs in the \" +\n 'Supabase dashboard under Edge Functions > Logs for the specific error. ' +\n 'Common causes: unhandled exceptions, out-of-memory errors, or missing environment variables.',\n category: 'functions_crashed',\n },\n\n functions_cors: {\n template:\n \"The edge function '{name}' was blocked by CORS. Ensure the function sets the appropriate \" +\n \"CORS headers in its response. Add 'Access-Control-Allow-Origin' and other necessary CORS \" +\n 'headers, and handle OPTIONS preflight requests.',\n category: 'functions_cors',\n },\n\n functions_not_found: {\n template:\n \"The edge function '{name}' was not found. Verify that the function has been deployed \" +\n 'and that the function name matches exactly (case-sensitive).',\n category: 'functions_not_found',\n },\n\n functions_relay_error: {\n template:\n \"The edge function '{name}' encountered a relay error. This is typically a transient \" +\n 'infrastructure issue. Retry the request after a brief delay.',\n category: 'functions_relay_error',\n },\n\n functions_fetch_error: {\n template:\n \"Failed to invoke the edge function '{name}'. This could be a network connectivity issue, \" +\n 'DNS resolution failure, or the Supabase project may be paused. Check your internet connection ' +\n 'and verify the project is active in the Supabase dashboard.',\n category: 'functions_fetch_error',\n },\n\n // -------------------------------------------------------------------------\n // Storage error patterns\n // -------------------------------------------------------------------------\n\n storage_bucket_not_found: {\n template:\n 'The storage bucket was not found. Verify the bucket name is correct and that it has been ' +\n \"created in the Supabase dashboard under Storage. Bucket names are case-sensitive.\",\n category: 'storage_bucket_not_found',\n },\n\n storage_object_too_large: {\n template:\n 'The uploaded file exceeds the maximum allowed size. Check the file size limit configured ' +\n 'for this bucket in the Supabase dashboard under Storage > Policies. ' +\n 'The default maximum file size is 50MB on the free plan.',\n category: 'storage_object_too_large',\n },\n\n storage_permission_denied: {\n template:\n 'Permission denied for this storage operation. Check the storage policies (RLS) configured ' +\n 'for this bucket. Storage uses its own set of policies separate from table-level RLS. ' +\n 'Configure policies in the Supabase dashboard under Storage > Policies.',\n category: 'storage_permission_denied',\n },\n\n storage_object_not_found: {\n template:\n 'The requested file does not exist in storage. Verify the file path is correct and that ' +\n 'the file has been uploaded. File paths in storage are case-sensitive.',\n category: 'storage_object_not_found',\n },\n};\n\n/**\n * Interpolate {variable} placeholders in a template string.\n *\n * Any variable in the template that is not found in the context is left\n * as-is (e.g. `{table}` remains if context.table is undefined).\n */\nfunction interpolate(template: string, context: ExplainerContext): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const value = context[key];\n return value !== undefined ? value : match;\n });\n}\n\n/**\n * Get a human-readable explanation for a Supabase error code.\n *\n * @param errorCode - The error code (PostgreSQL code, PostgREST code, or\n * internal category key like 'auth_invalid_credentials').\n * @param context - Optional context variables for template interpolation.\n * @returns A human-readable explanation string. Falls back to a generic\n * message if the error code is not recognized.\n */\nexport function explainSupabaseError(\n errorCode: string,\n context?: ExplainerContext,\n): string {\n const entry = EXPLANATIONS[errorCode];\n\n if (!entry) {\n return `Supabase error (code: ${errorCode}). Refer to the Supabase documentation or PostgreSQL error code reference for more details.`;\n }\n\n return interpolate(entry.template, context ?? {});\n}\n\n/**\n * Get the suggested category for a known error code.\n *\n * @param errorCode - The error code to look up.\n * @returns The category string, or 'unknown' if the code is not recognized.\n */\nexport function getCategoryForCode(errorCode: string): string {\n const entry = EXPLANATIONS[errorCode];\n return entry?.category ?? 'unknown';\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — error parser\n// ---------------------------------------------------------------------------\n//\n// Detects the type of Supabase error by inspecting its shape/properties, then\n// maps it to a structured ParsedSupabaseError with human-readable explanation.\n// ---------------------------------------------------------------------------\n\nimport type { ParsedSupabaseError } from './types';\nimport {\n explainSupabaseError,\n getCategoryForCode,\n type ExplainerContext,\n} from './rls-explainer';\n\n// ---------------------------------------------------------------------------\n// Error shape interfaces (matching Supabase SDK error types)\n// ---------------------------------------------------------------------------\n\ninterface PostgrestErrorShape {\n message: string;\n details: string | null;\n hint: string | null;\n code: string;\n}\n\ninterface AuthErrorShape {\n message: string;\n status?: number;\n name?: string;\n __isAuthError?: boolean;\n}\n\ninterface FunctionsErrorShape {\n message: string;\n name?: string;\n context?: unknown;\n}\n\ninterface StorageErrorShape {\n message: string;\n statusCode?: string | number;\n error?: string;\n name?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\nfunction isPostgrestError(error: unknown): error is PostgrestErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n return (\n typeof e.message === 'string' &&\n 'code' in e &&\n typeof e.code === 'string' &&\n 'details' in e &&\n 'hint' in e\n );\n}\n\nfunction isAuthError(error: unknown): error is AuthErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n\n // Supabase auth errors have __isAuthError or specific name patterns\n if (e.__isAuthError === true) return true;\n if (\n typeof e.name === 'string' &&\n (e.name === 'AuthApiError' ||\n e.name === 'AuthRetryableFetchError' ||\n e.name === 'AuthUnknownError' ||\n e.name === 'AuthWeakPasswordError' ||\n e.name === 'AuthSessionMissingError')\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction isFunctionsError(error: unknown): error is FunctionsErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n return (\n typeof e.name === 'string' &&\n (e.name === 'FunctionsHttpError' ||\n e.name === 'FunctionsRelayError' ||\n e.name === 'FunctionsFetchError')\n );\n}\n\nfunction isStorageError(error: unknown): error is StorageErrorShape {\n if (error === null || typeof error !== 'object') return false;\n const e = error as Record<string, unknown>;\n\n // Storage errors from Supabase have statusCode and/or a name containing 'Storage'\n if (typeof e.name === 'string' && e.name === 'StorageApiError') return true;\n if (typeof e.statusCode === 'string' || typeof e.statusCode === 'number') {\n // Must also have a message to qualify\n return typeof e.message === 'string';\n }\n\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Auth error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for auth errors based on message content.\n */\nfunction classifyAuthError(error: AuthErrorShape): string {\n const msg = error.message.toLowerCase();\n\n if (msg.includes('invalid login credentials') || msg.includes('invalid credentials')) {\n return 'auth_invalid_credentials';\n }\n if (msg.includes('email not confirmed') || msg.includes('not confirmed')) {\n return 'auth_email_not_confirmed';\n }\n if (msg.includes('rate limit') || msg.includes('too many requests') || error.status === 429) {\n return 'auth_rate_limited';\n }\n if (msg.includes('user not found') || msg.includes('no user found')) {\n return 'auth_user_not_found';\n }\n if (msg.includes('session not found') || msg.includes('not authenticated') || msg.includes('session_not_found')) {\n return 'auth_session_not_found';\n }\n if (msg.includes('signups not allowed') || msg.includes('signup is disabled') || msg.includes('signups are disabled')) {\n return 'auth_signup_disabled';\n }\n\n return 'auth_unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Functions error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for edge function errors.\n */\nfunction classifyFunctionsError(error: FunctionsErrorShape): string {\n const msg = error.message.toLowerCase();\n const name = error.name ?? '';\n\n if (name === 'FunctionsRelayError') {\n return 'functions_relay_error';\n }\n if (name === 'FunctionsFetchError') {\n return 'functions_fetch_error';\n }\n\n // FunctionsHttpError — inspect message for specifics\n if (msg.includes('timeout') || msg.includes('timed out') || msg.includes('deadline exceeded')) {\n return 'functions_timeout';\n }\n if (msg.includes('cors') || msg.includes('cross-origin')) {\n return 'functions_cors';\n }\n if (msg.includes('not found') || msg.includes('404')) {\n return 'functions_not_found';\n }\n if (msg.includes('crashed') || msg.includes('internal server error') || msg.includes('500')) {\n return 'functions_crashed';\n }\n\n return 'functions_crashed'; // default for unknown HTTP errors\n}\n\n// ---------------------------------------------------------------------------\n// Storage error classification\n// ---------------------------------------------------------------------------\n\n/**\n * Derive an internal error code key for storage errors.\n */\nfunction classifyStorageError(error: StorageErrorShape): string {\n const msg = error.message.toLowerCase();\n const code = String(error.statusCode ?? '');\n\n if (msg.includes('bucket') && (msg.includes('not found') || msg.includes('does not exist'))) {\n return 'storage_bucket_not_found';\n }\n if (msg.includes('too large') || msg.includes('payload too large') || msg.includes('file size') || code === '413') {\n return 'storage_object_too_large';\n }\n if (msg.includes('permission') || msg.includes('not authorized') || msg.includes('policy') || code === '403') {\n return 'storage_permission_denied';\n }\n if (msg.includes('not found') || msg.includes('object not found') || code === '404') {\n return 'storage_object_not_found';\n }\n\n return 'storage_permission_denied'; // default to permission for unknown storage errors\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Additional context to aid error parsing and explanation generation.\n */\nexport interface ErrorParserContext {\n /** The table name from the query tracker. */\n table?: string;\n /** The operation type (select, insert, update, etc.). */\n operation?: string;\n /** The edge function name for function invocation errors. */\n functionName?: string;\n /** The storage bucket name. */\n bucketName?: string;\n /** The human-readable query chain. */\n queryChain?: string;\n}\n\n/**\n * Parse any Supabase error into a structured ParsedSupabaseError.\n *\n * Detects the error type by inspecting the object's shape and properties,\n * then provides a categorized result with human-readable explanation.\n *\n * @param error - The error object from Supabase ({ data, error } result).\n * @param context - Optional context for richer explanations.\n * @returns A fully structured ParsedSupabaseError.\n */\nexport function parseSupabaseError(\n error: unknown,\n context?: ErrorParserContext,\n): ParsedSupabaseError {\n try {\n // Build explainer context from the parser context\n const explainerCtx: ExplainerContext = {\n table: context?.table,\n operation: context?.operation,\n name: context?.functionName,\n column: undefined,\n constraint: undefined,\n };\n\n // ----- PostgrestError -----\n if (isPostgrestError(error)) {\n const errorCode = error.code;\n const explanation = explainSupabaseError(errorCode, explainerCtx);\n const category = getCategoryForCode(errorCode);\n\n return {\n errorType: 'postgrest',\n errorCode,\n message: buildPostgrestMessage(error),\n humanExplanation: explanation,\n suggestedCategory: category,\n };\n }\n\n // ----- AuthError -----\n if (isAuthError(error)) {\n const internalCode = classifyAuthError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'auth',\n errorCode: error.name ?? internalCode,\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- FunctionsError -----\n if (isFunctionsError(error)) {\n const internalCode = classifyFunctionsError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'functions',\n errorCode: error.name ?? internalCode,\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- StorageError -----\n if (isStorageError(error)) {\n const internalCode = classifyStorageError(error);\n const explanation = explainSupabaseError(internalCode, explainerCtx);\n const category = getCategoryForCode(internalCode);\n\n return {\n errorType: 'storage',\n errorCode: String(error.statusCode ?? internalCode),\n message: error.message,\n humanExplanation: explanation,\n suggestedCategory: category !== 'unknown' ? category : internalCode,\n };\n }\n\n // ----- Generic / unknown error -----\n return parseGenericError(error);\n } catch {\n // Never let the parser itself crash the host app\n return {\n errorType: 'unknown',\n errorCode: 'PARSE_ERROR',\n message: 'Failed to parse error object',\n humanExplanation:\n 'An error occurred but could not be parsed. Check the raw error for details.',\n suggestedCategory: 'unknown',\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build a comprehensive message string from a PostgREST error, including\n * details and hint when available.\n */\nfunction buildPostgrestMessage(error: PostgrestErrorShape): string {\n let msg = error.message;\n if (error.details) {\n msg += ` | Details: ${error.details}`;\n }\n if (error.hint) {\n msg += ` | Hint: ${error.hint}`;\n }\n return msg;\n}\n\n/**\n * Handle generic/unknown error shapes that don't match any known Supabase type.\n */\nfunction parseGenericError(error: unknown): ParsedSupabaseError {\n let message = 'Unknown error';\n let errorCode = 'UNKNOWN';\n\n if (error instanceof Error) {\n message = error.message;\n errorCode = error.name ?? 'Error';\n } else if (error !== null && typeof error === 'object') {\n const e = error as Record<string, unknown>;\n if (typeof e.message === 'string') {\n message = e.message;\n }\n if (typeof e.code === 'string') {\n errorCode = e.code;\n } else if (typeof e.name === 'string') {\n errorCode = e.name;\n }\n } else if (typeof error === 'string') {\n message = error;\n }\n\n return {\n errorType: 'unknown',\n errorCode,\n message,\n humanExplanation: `Supabase error: ${message}. This error type was not recognized by the parser. Refer to the Supabase documentation for more details.`,\n suggestedCategory: 'unknown',\n };\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — deep Proxy wrapper\n// ---------------------------------------------------------------------------\n//\n// Creates a transparent Proxy around a SupabaseClient that intercepts all\n// operations to capture errors and record breadcrumbs, without changing any\n// observable behavior. The wrapped client has identical types and behavior\n// to the original — the Proxy is fully transparent.\n//\n// Strategy:\n// 1. Wrap the top-level SupabaseClient with a Proxy.\n// 2. When .from(), .auth, .functions, .storage is accessed, return a proxied\n// version that tracks operations via QueryTracker.\n// 3. QueryTracker records each method in the chain (.select(), .eq(), etc.).\n// 4. When a terminal operation executes (returns a Promise/thenable), we\n// intercept the resolved value.\n// 5. If the result has an `error` field (Supabase's { data, error } pattern),\n// we capture it with full context via getClient().captureError().\n// 6. We ALWAYS return the original result — completely transparent.\n// ---------------------------------------------------------------------------\n\nimport { getClient, sanitize } from '@uncaughtdev/core';\nimport type { Breadcrumb, OperationInfo } from '@uncaughtdev/core';\nimport { QueryTracker } from './query-tracker';\nimport { parseSupabaseError, type ErrorParserContext } from './error-parser';\nimport type { WrapSupabaseOptions } from './types';\n\n// ---------------------------------------------------------------------------\n// Sensitive key patterns that must never be captured\n// ---------------------------------------------------------------------------\n\nconst AUTH_SENSITIVE_KEYS = new Set([\n 'password',\n 'access_token',\n 'refresh_token',\n 'token',\n 'session',\n 'cookie',\n 'authorization',\n 'apikey',\n 'api_key',\n 'secret',\n 'credential',\n 'credentials',\n 'nonce',\n 'code_verifier',\n 'code_challenge',\n]);\n\n/**\n * Deep-sanitize an object, redacting any keys that match sensitive patterns.\n * This is used specifically for auth-related data where we want to be extra\n * cautious about not capturing passwords, tokens, or session data.\n */\nfunction sanitizeAuthData(data: unknown): unknown {\n if (data === null || data === undefined) return data;\n if (typeof data !== 'object') return data;\n if (Array.isArray(data)) return data.map(sanitizeAuthData);\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n if (AUTH_SENSITIVE_KEYS.has(key.toLowerCase())) {\n result[key] = '[REDACTED]';\n } else if (typeof value === 'object' && value !== null) {\n result[key] = sanitizeAuthData(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Safely extract a string representation from an argument for breadcrumbs.\n */\nfunction safeArgString(arg: unknown): string {\n if (arg === null || arg === undefined) return String(arg);\n if (typeof arg === 'string') return arg;\n if (typeof arg === 'number' || typeof arg === 'boolean') return String(arg);\n try {\n const str = JSON.stringify(arg);\n return str.length > 100 ? str.slice(0, 97) + '...' : str;\n } catch {\n return '[object]';\n }\n}\n\n/**\n * Add a breadcrumb to the Uncaught client. Silently no-ops if the client\n * is not initialized.\n */\nfunction addBreadcrumb(crumb: Omit<Breadcrumb, 'timestamp'>): void {\n try {\n const client = getClient();\n if (client) {\n client.addBreadcrumb(crumb);\n }\n } catch {\n // Client not initialized — silently ignore\n }\n}\n\n/**\n * Capture an error through the Uncaught client. Silently no-ops if the\n * client is not initialized.\n */\nfunction captureError(\n error: unknown,\n context: {\n operation?: OperationInfo;\n extra?: Record<string, unknown>;\n },\n): void {\n try {\n const client = getClient();\n if (client) {\n client.captureError(error, context);\n }\n } catch {\n // Client not initialized — silently ignore\n }\n}\n\n// ---------------------------------------------------------------------------\n// Result inspection\n// ---------------------------------------------------------------------------\n\n/**\n * Check if a value looks like Supabase's { data, error } response pattern.\n */\nfunction isSupabaseResult(value: unknown): value is { data: unknown; error: unknown } {\n if (value === null || typeof value !== 'object') return false;\n return 'data' in value && 'error' in value;\n}\n\n/**\n * Check if a value is a thenable (Promise-like).\n */\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as Record<string, unknown>).then === 'function'\n );\n}\n\n// ---------------------------------------------------------------------------\n// Query builder proxy (for .from() chains)\n// ---------------------------------------------------------------------------\n\n/**\n * Create a proxy around a Supabase query builder that tracks each method\n * call and intercepts the terminal operation to check for errors.\n */\nfunction createQueryBuilderProxy(\n target: unknown,\n tracker: QueryTracker,\n options: WrapSupabaseOptions,\n): unknown {\n if (target === null || target === undefined) return target;\n if (typeof target !== 'object' && typeof target !== 'function') return target;\n\n return new Proxy(target as object, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n // Pass through symbols and non-string props transparently\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n // Special: handle `then` to intercept Promise resolution\n if (prop === 'then') {\n const thenFn = Reflect.get(obj, prop, receiver);\n if (typeof thenFn !== 'function') return thenFn;\n\n // This is a terminal operation — the chain is being awaited\n return function proxiedThen(\n onFulfilled?: ((value: unknown) => unknown) | null,\n onRejected?: ((reason: unknown) => unknown) | null,\n ): unknown {\n return thenFn.call(\n obj,\n (result: unknown) => {\n handleQueryResult(result, tracker, options);\n return onFulfilled ? onFulfilled(result) : result;\n },\n (reason: unknown) => {\n handleQueryError(reason, tracker, options);\n return onRejected ? onRejected(reason) : Promise.reject(reason);\n },\n );\n };\n }\n\n // Handle `catch` for Promise rejection\n if (prop === 'catch') {\n const catchFn = Reflect.get(obj, prop, receiver);\n if (typeof catchFn !== 'function') return catchFn;\n\n return function proxiedCatch(\n onRejected?: ((reason: unknown) => unknown) | null,\n ): unknown {\n return catchFn.call(obj, (reason: unknown) => {\n handleQueryError(reason, tracker, options);\n return onRejected ? onRejected(reason) : Promise.reject(reason);\n });\n };\n }\n\n // Handle `finally` passthrough\n if (prop === 'finally') {\n const finallyFn = Reflect.get(obj, prop, receiver);\n if (typeof finallyFn !== 'function') return finallyFn;\n\n return function proxiedFinally(onFinally?: (() => void) | null): unknown {\n return finallyFn.call(obj, onFinally);\n };\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // If the property is a function, wrap it to track the call\n if (typeof value === 'function') {\n return function (this: unknown, ...args: unknown[]): unknown {\n // Track the method call\n tracker.track(prop, args);\n\n let result: unknown;\n try {\n result = value.apply(obj, args);\n } catch (err) {\n // Synchronous error during method call\n handleQueryError(err, tracker, options);\n throw err;\n }\n\n // If the result is thenable, wrap it for error interception\n if (isThenable(result)) {\n return createQueryBuilderProxy(result, tracker, options);\n }\n\n // If the result is an object (next builder in chain), proxy it too\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, options);\n }\n\n return result;\n };\n }\n\n // If the value is an object, recursively proxy for continued chaining\n if (value !== null && typeof value === 'object') {\n return createQueryBuilderProxy(value, tracker, options);\n }\n\n return value;\n },\n });\n}\n\n/**\n * Handle the resolved result of a query chain, checking for Supabase errors.\n */\nfunction handleQueryResult(\n result: unknown,\n tracker: QueryTracker,\n _options: WrapSupabaseOptions,\n): void {\n try {\n const trackedQuery = tracker.toTrackedQuery();\n const breadcrumbData: Record<string, unknown> = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n chain: trackedQuery.humanReadable,\n };\n\n if (isSupabaseResult(result) && result.error) {\n // Error in the { data, error } response\n const parserContext: ErrorParserContext = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n queryChain: trackedQuery.humanReadable,\n };\n\n const parsed = parseSupabaseError(result.error, parserContext);\n\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `Failed: ${trackedQuery.humanReadable}`,\n data: {\n ...breadcrumbData,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo = tracker.toOperationInfo();\n operationInfo.errorCode = parsed.errorCode;\n operationInfo.errorDetails = parsed.humanExplanation;\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n query: trackedQuery.humanReadable,\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n parsedError: parsed,\n },\n },\n });\n } else {\n // Successful query — add success breadcrumb\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `OK: ${trackedQuery.humanReadable}`,\n data: breadcrumbData,\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app — silently swallow tracking errors\n }\n}\n\n/**\n * Handle a rejected Promise or synchronous throw from a query chain.\n */\nfunction handleQueryError(\n reason: unknown,\n tracker: QueryTracker,\n _options: WrapSupabaseOptions,\n): void {\n try {\n const trackedQuery = tracker.toTrackedQuery();\n\n const parserContext: ErrorParserContext = {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n queryChain: trackedQuery.humanReadable,\n };\n\n const parsed = parseSupabaseError(reason, parserContext);\n\n addBreadcrumb({\n type: 'db_query',\n category: 'supabase.query',\n message: `Rejected: ${trackedQuery.humanReadable}`,\n data: {\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo = tracker.toOperationInfo();\n operationInfo.errorCode = parsed.errorCode;\n operationInfo.errorDetails = parsed.humanExplanation;\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n query: trackedQuery.humanReadable,\n table: trackedQuery.table,\n operation: trackedQuery.operation,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auth proxy\n// ---------------------------------------------------------------------------\n\n/** Auth methods that should be intercepted. */\nconst AUTH_METHODS = new Set([\n 'signUp',\n 'signInWithPassword',\n 'signInWithOtp',\n 'signInWithOAuth',\n 'signInWithIdToken',\n 'signInWithSSO',\n 'signOut',\n 'getSession',\n 'getUser',\n 'refreshSession',\n 'resetPasswordForEmail',\n 'updateUser',\n 'setSession',\n 'exchangeCodeForSession',\n 'reauthenticate',\n 'resend',\n 'verifyOtp',\n]);\n\n/**\n * Create a proxy around the Supabase auth object that tracks auth operations.\n */\nfunction createAuthProxy(authTarget: object, options: WrapSupabaseOptions): object {\n return new Proxy(authTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Only intercept known auth methods\n if (typeof value !== 'function' || !AUTH_METHODS.has(prop)) {\n return value;\n }\n\n const methodName = prop;\n\n return function (this: unknown, ...args: unknown[]): unknown {\n // Sanitize auth arguments before recording\n const sanitizedArgs = args.map((arg) => {\n if (arg !== null && typeof arg === 'object') {\n return sanitizeAuthData(arg);\n }\n return arg;\n });\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleAuthError(err, methodName, sanitizedArgs);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleAuthResult(resolved, methodName, sanitizedArgs);\n return resolved;\n },\n (rejected) => {\n handleAuthError(rejected, methodName, sanitizedArgs);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved auth result, checking for errors.\n */\nfunction handleAuthResult(\n result: unknown,\n method: string,\n sanitizedArgs: unknown[],\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, { operation: method });\n\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth failed: ${method}`,\n data: {\n method,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'auth',\n method,\n params: sanitize(\n Object.fromEntries(\n sanitizedArgs.map((a, i) => [`arg${i}`, safeArgString(a)]),\n ),\n ),\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'auth',\n method,\n parsedError: parsed,\n },\n },\n });\n } else {\n // Successful auth operation\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth OK: ${method}`,\n data: { method },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected auth Promise or synchronous throw.\n */\nfunction handleAuthError(\n reason: unknown,\n method: string,\n sanitizedArgs: unknown[],\n): void {\n try {\n const parsed = parseSupabaseError(reason, { operation: method });\n\n addBreadcrumb({\n type: 'auth',\n category: 'supabase.auth',\n message: `Auth rejected: ${method}`,\n data: {\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'auth',\n method,\n params: sanitize(\n Object.fromEntries(\n sanitizedArgs.map((a, i) => [`arg${i}`, safeArgString(a)]),\n ),\n ),\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'auth',\n method,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Functions proxy\n// ---------------------------------------------------------------------------\n\n/**\n * Create a proxy around the Supabase functions object that intercepts .invoke().\n */\nfunction createFunctionsProxy(\n functionsTarget: object,\n _options: WrapSupabaseOptions,\n): object {\n return new Proxy(functionsTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Only intercept the .invoke() method\n if (typeof value !== 'function' || prop !== 'invoke') {\n return value;\n }\n\n return function (this: unknown, functionName: string, invokeOptions?: unknown): unknown {\n const sanitizedOptions = invokeOptions\n ? sanitizeAuthData(invokeOptions)\n : undefined;\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, [functionName, invokeOptions]);\n } catch (err) {\n handleFunctionsError(err, functionName, sanitizedOptions);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleFunctionsResult(resolved, functionName, sanitizedOptions);\n return resolved;\n },\n (rejected) => {\n handleFunctionsError(rejected, functionName, sanitizedOptions);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved edge function invocation result.\n */\nfunction handleFunctionsResult(\n result: unknown,\n functionName: string,\n sanitizedOptions: unknown,\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, {\n functionName,\n operation: 'invoke',\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function failed: ${functionName}`,\n data: {\n functionName,\n errorCode: parsed.errorCode,\n errorType: parsed.errorType,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'functions',\n method: 'invoke',\n params: {\n functionName,\n options: safeArgString(sanitizedOptions),\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'functions',\n functionName,\n parsedError: parsed,\n },\n },\n });\n } else {\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function OK: ${functionName}`,\n data: { functionName },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected edge function invocation.\n */\nfunction handleFunctionsError(\n reason: unknown,\n functionName: string,\n sanitizedOptions: unknown,\n): void {\n try {\n const parsed = parseSupabaseError(reason, {\n functionName,\n operation: 'invoke',\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.functions',\n message: `Function rejected: ${functionName}`,\n data: {\n functionName,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'functions',\n method: 'invoke',\n params: {\n functionName,\n options: safeArgString(sanitizedOptions),\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'functions',\n functionName,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n// ---------------------------------------------------------------------------\n// Storage proxy\n// ---------------------------------------------------------------------------\n\n/** Storage methods that should be intercepted. */\nconst STORAGE_METHODS = new Set([\n 'upload',\n 'download',\n 'remove',\n 'list',\n 'move',\n 'copy',\n 'createSignedUrl',\n 'createSignedUrls',\n 'getPublicUrl',\n]);\n\n/**\n * Create a proxy around a Supabase storage bucket (from .storage.from('bucket')).\n */\nfunction createStorageBucketProxy(\n bucketTarget: object,\n bucketName: string,\n _options: WrapSupabaseOptions,\n): object {\n return new Proxy(bucketTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n if (typeof value !== 'function' || !STORAGE_METHODS.has(prop)) {\n return value;\n }\n\n const methodName = prop;\n\n return function (this: unknown, ...args: unknown[]): unknown {\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleStorageError(err, bucketName, methodName, args);\n throw err;\n }\n\n if (isThenable(result)) {\n return (result as Promise<unknown>).then(\n (resolved) => {\n handleStorageResult(resolved, bucketName, methodName, args);\n return resolved;\n },\n (rejected) => {\n handleStorageError(rejected, bucketName, methodName, args);\n return Promise.reject(rejected);\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n\n/**\n * Handle a resolved storage operation result.\n */\nfunction handleStorageResult(\n result: unknown,\n bucketName: string,\n method: string,\n args: unknown[],\n): void {\n try {\n if (isSupabaseResult(result) && result.error) {\n const parsed = parseSupabaseError(result.error, {\n bucketName,\n operation: method,\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage failed: ${method} on ${bucketName}`,\n data: {\n bucket: bucketName,\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'storage',\n method,\n params: {\n bucket: bucketName,\n path: typeof args[0] === 'string' ? args[0] : undefined,\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(result.error, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'storage',\n bucket: bucketName,\n method,\n parsedError: parsed,\n },\n },\n });\n } else {\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage OK: ${method} on ${bucketName}`,\n data: { bucket: bucketName, method },\n level: 'info',\n });\n }\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Handle a rejected storage operation.\n */\nfunction handleStorageError(\n reason: unknown,\n bucketName: string,\n method: string,\n args: unknown[],\n): void {\n try {\n const parsed = parseSupabaseError(reason, {\n bucketName,\n operation: method,\n });\n\n addBreadcrumb({\n type: 'api_call',\n category: 'supabase.storage',\n message: `Storage rejected: ${method} on ${bucketName}`,\n data: {\n bucket: bucketName,\n method,\n errorCode: parsed.errorCode,\n },\n level: 'error',\n });\n\n const operationInfo: OperationInfo = {\n provider: 'supabase',\n type: 'storage',\n method,\n params: {\n bucket: bucketName,\n path: typeof args[0] === 'string' ? args[0] : undefined,\n },\n errorCode: parsed.errorCode,\n errorDetails: parsed.humanExplanation,\n };\n\n captureError(reason, {\n operation: operationInfo,\n extra: {\n supabase: {\n subsystem: 'storage',\n bucket: bucketName,\n method,\n parsedError: parsed,\n },\n },\n });\n } catch {\n // Never crash the host app\n }\n}\n\n/**\n * Create a proxy around the Supabase storage object that intercepts\n * .from('bucket') to return a proxied bucket client.\n */\nfunction createStorageProxy(\n storageTarget: object,\n options: WrapSupabaseOptions,\n): object {\n return new Proxy(storageTarget, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // Intercept .from('bucketName') to return a proxied bucket client\n if (typeof value === 'function' && prop === 'from') {\n return function (this: unknown, bucketName: string): unknown {\n const bucketClient = (value as Function).apply(obj, [bucketName]);\n if (bucketClient !== null && typeof bucketClient === 'object') {\n return createStorageBucketProxy(bucketClient as object, bucketName, options);\n }\n return bucketClient;\n };\n }\n\n return value;\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Top-level SupabaseClient proxy\n// ---------------------------------------------------------------------------\n\n/**\n * Resolved options with defaults applied.\n */\nfunction resolveOptions(options: WrapSupabaseOptions): Required<WrapSupabaseOptions> {\n return {\n trackQueries: options.trackQueries ?? true,\n trackAuth: options.trackAuth ?? true,\n trackFunctions: options.trackFunctions ?? true,\n trackStorage: options.trackStorage ?? false,\n trackRealtime: options.trackRealtime ?? false,\n };\n}\n\n/**\n * Create the top-level deep Proxy around a SupabaseClient.\n *\n * This is the main entry point. The returned Proxy intercepts access to\n * `.from()`, `.auth`, `.functions`, and `.storage` to create sub-proxies\n * that track operations and capture errors.\n *\n * The Proxy is fully transparent:\n * - typeof and instanceof work as expected\n * - TypeScript types pass through unchanged\n * - No observable behavior change when there are no errors\n * - Negligible performance overhead (one Proxy get trap per property access)\n *\n * @param client - The original SupabaseClient instance.\n * @param options - Configuration for which subsystems to track.\n * @returns A proxied version of the client with identical type and behavior.\n */\nexport function createSupabaseProxy(\n client: unknown,\n options: WrapSupabaseOptions,\n): unknown {\n // Safety: if the client is null/undefined or not an object, return as-is\n if (client === null || client === undefined) return client;\n if (typeof client !== 'object' && typeof client !== 'function') return client;\n\n const resolved = resolveOptions(options);\n\n return new Proxy(client as object, {\n get(obj: object, prop: string | symbol, receiver: unknown): unknown {\n // Pass through symbols transparently (supports typeof, instanceof, etc.)\n if (typeof prop === 'symbol') {\n try {\n return Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n }\n\n let value: unknown;\n try {\n value = Reflect.get(obj, prop, receiver);\n } catch {\n return undefined;\n }\n\n // ----- .from('table') — database query builder -----\n if (prop === 'from' && typeof value === 'function' && resolved.trackQueries) {\n return function (this: unknown, ...args: unknown[]): unknown {\n const tracker = new QueryTracker();\n tracker.track('from', args);\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleQueryError(err, tracker, resolved);\n throw err;\n }\n\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n return result;\n };\n }\n\n // ----- .rpc('fn_name', params) — RPC call -----\n if (prop === 'rpc' && typeof value === 'function' && resolved.trackQueries) {\n return function (this: unknown, ...args: unknown[]): unknown {\n const tracker = new QueryTracker();\n tracker.track('rpc', args);\n\n let result: unknown;\n try {\n result = (value as Function).apply(obj, args);\n } catch (err) {\n handleQueryError(err, tracker, resolved);\n throw err;\n }\n\n if (isThenable(result)) {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n\n if (result !== null && typeof result === 'object') {\n return createQueryBuilderProxy(result, tracker, resolved);\n }\n\n return result;\n };\n }\n\n // ----- .auth — auth operations -----\n if (prop === 'auth' && resolved.trackAuth) {\n if (value !== null && typeof value === 'object') {\n return createAuthProxy(value as object, resolved);\n }\n }\n\n // ----- .functions — edge function invocations -----\n if (prop === 'functions' && resolved.trackFunctions) {\n if (value !== null && typeof value === 'object') {\n return createFunctionsProxy(value as object, resolved);\n }\n }\n\n // ----- .storage — storage operations -----\n if (prop === 'storage' && resolved.trackStorage) {\n if (value !== null && typeof value === 'object') {\n return createStorageProxy(value as object, resolved);\n }\n }\n\n // ----- Everything else passes through -----\n return value;\n },\n\n // Ensure all other traps pass through transparently\n set(obj: object, prop: string | symbol, value: unknown, receiver: unknown): boolean {\n return Reflect.set(obj, prop, value, receiver);\n },\n\n has(obj: object, prop: string | symbol): boolean {\n return Reflect.has(obj, prop);\n },\n\n deleteProperty(obj: object, prop: string | symbol): boolean {\n return Reflect.deleteProperty(obj, prop);\n },\n\n ownKeys(obj: object): ArrayLike<string | symbol> {\n return Reflect.ownKeys(obj);\n },\n\n getOwnPropertyDescriptor(\n obj: object,\n prop: string | symbol,\n ): PropertyDescriptor | undefined {\n return Reflect.getOwnPropertyDescriptor(obj, prop);\n },\n\n getPrototypeOf(obj: object): object | null {\n return Reflect.getPrototypeOf(obj);\n },\n\n isExtensible(obj: object): boolean {\n return Reflect.isExtensible(obj);\n },\n\n preventExtensions(obj: object): boolean {\n return Reflect.preventExtensions(obj);\n },\n\n defineProperty(\n obj: object,\n prop: string | symbol,\n descriptor: PropertyDescriptor,\n ): boolean {\n return Reflect.defineProperty(obj, prop, descriptor);\n },\n\n setPrototypeOf(obj: object, proto: object | null): boolean {\n return Reflect.setPrototypeOf(obj, proto);\n },\n });\n}\n","// ---------------------------------------------------------------------------\n// @uncaughtdev/supabase — public API\n// ---------------------------------------------------------------------------\n//\n// Minimal surface: one function, one type export. Wrap your Supabase client\n// to automatically capture failed queries, auth errors, and edge function\n// invocations via the Uncaught error monitoring SDK.\n//\n// Usage:\n// import { createClient } from '@supabase/supabase-js';\n// import { wrapSupabase } from '@uncaughtdev/supabase';\n//\n// const supabase = wrapSupabase(\n// createClient(SUPABASE_URL, SUPABASE_ANON_KEY),\n// { trackStorage: true }\n// );\n//\n// // Use supabase exactly as before — errors are captured automatically.\n// const { data, error } = await supabase.from('todos').select('*');\n// ---------------------------------------------------------------------------\n\nimport { createSupabaseProxy } from './proxy';\nimport type { WrapSupabaseOptions } from './types';\n\nexport type { WrapSupabaseOptions } from './types';\nexport type { TrackedQuery, QueryChainStep, ParsedSupabaseError } from './types';\n\n/**\n * Wrap a Supabase client with transparent error interception.\n *\n * The returned client has the exact same type and behavior as the original.\n * All Supabase operations work identically — the wrapper only observes\n * results and captures errors through the @uncaughtdev/core client.\n *\n * @param client - A SupabaseClient instance from `createClient()`.\n * @param options - Optional configuration for which subsystems to track.\n * By default, queries, auth, and functions are tracked.\n * Storage and realtime are opt-in.\n * @returns The same client, wrapped with transparent error interception.\n *\n * @example\n * ```ts\n * import { createClient } from '@supabase/supabase-js';\n * import { initUncaught } from '@uncaughtdev/core';\n * import { wrapSupabase } from '@uncaughtdev/supabase';\n *\n * initUncaught({ projectKey: 'my-project' });\n *\n * const supabase = wrapSupabase(\n * createClient(SUPABASE_URL, SUPABASE_ANON_KEY),\n * { trackQueries: true, trackAuth: true, trackFunctions: true }\n * );\n * ```\n */\nexport function wrapSupabase<T>(client: T, options?: WrapSupabaseOptions): T {\n return createSupabaseProxy(client, options ?? {}) as T;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uncaughtdev/supabase",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Supabase client wrapper for Uncaught — captures failed queries, auth errors, and function invocations",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Uncaught",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/AjeeshDevops/uncaught.git",
|
|
10
|
+
"directory": "packages/supabase"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/AjeeshDevops/uncaught#readme",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"supabase",
|
|
15
|
+
"error-monitoring",
|
|
16
|
+
"query-tracking",
|
|
17
|
+
"rls",
|
|
18
|
+
"debugging"
|
|
19
|
+
],
|
|
20
|
+
"main": "./dist/index.cjs",
|
|
21
|
+
"module": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"require": "./dist/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@supabase/supabase-js": ">=2.0.0",
|
|
36
|
+
"@uncaughtdev/core": "0.1.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@uncaughtdev/core": "0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@supabase/supabase-js": "^2.43.0",
|
|
43
|
+
"tsup": "^8.0.0",
|
|
44
|
+
"typescript": "^5.4.0",
|
|
45
|
+
"vitest": "^1.6.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"dev": "tsup --watch",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"lint": "eslint src/",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"clean": "rm -rf dist"
|
|
54
|
+
}
|
|
55
|
+
}
|