@ezcoder.dev/sdk 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -69,14 +69,24 @@ interface OrderOption {
69
69
  type FilterValue = string | number | boolean | null;
70
70
 
71
71
  interface ServerProxy {
72
- serverQuery: (sql: string) => Promise<{
72
+ serverQuery?: (sql: string) => Promise<{
73
73
  success: boolean;
74
74
  data?: unknown[];
75
75
  rowCount?: number;
76
76
  error?: string;
77
77
  schema?: string;
78
78
  }>;
79
- serverExec: (sql: string) => Promise<{
79
+ serverExec?: (sql: string) => Promise<{
80
+ success: boolean;
81
+ data?: unknown[];
82
+ rowCount?: number;
83
+ error?: string;
84
+ schema?: string;
85
+ }>;
86
+ /** Browser-mode READ fallback: routes through the platform public proxy
87
+ * (public-class token) when the direct RPC needs an authenticated session
88
+ * the visitor doesn't have. Reads only — writes never fall back. */
89
+ publicQuery?: (sql: string) => Promise<{
80
90
  success: boolean;
81
91
  data?: unknown[];
82
92
  rowCount?: number;
@@ -134,6 +144,8 @@ declare class QueryBuilder<T = Record<string, unknown>> {
134
144
  private buildUpdateSql;
135
145
  private buildDeleteSql;
136
146
  private executeQuery;
147
+ /** Execute a read through the platform public proxy (anonymous-visitor path). */
148
+ private runPublicQuery;
137
149
  then<TResult1 = DatabaseResult<T> | SingleResult<T>, TResult2 = never>(onfulfilled?: ((value: DatabaseResult<T> | SingleResult<T>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
138
150
  }
139
151
 
@@ -147,6 +159,8 @@ declare class DatabaseClient {
147
159
  static createServerClient(projectId: string, apiKey: string, platformUrl?: string): DatabaseClient;
148
160
  from<T = Record<string, unknown>>(table: string): QueryBuilder<T>;
149
161
  sql<T = Record<string, unknown>>(query: string): Promise<DatabaseResult<T>>;
162
+ /** Read via the platform public proxy (anonymous-visitor path). */
163
+ private _publicFallback;
150
164
  execute(sql: string): Promise<MutationResult>;
151
165
  getSchema(): Promise<SchemaInfo>;
152
166
  private _serverRequest;
@@ -56,6 +56,58 @@ function mapRpcError(rpcResult) {
56
56
  return new QueryError(msg);
57
57
  }
58
58
 
59
+ // src/database/publicReadProxy.ts
60
+ var PROXY_TIMEOUT_MS = 1e4;
61
+ var AUTH_FAILURE_PATTERN = /authentication required|permission denied|project binding|unauthorized|jwt|42501/i;
62
+ function isAuthShapedFailure(message) {
63
+ return typeof message === "string" && AUTH_FAILURE_PATTERN.test(message);
64
+ }
65
+ function publicReadToken() {
66
+ return env.EZC_PROJECT_TOKEN_PUBLIC || env.EZC_PROJECT_TOKEN_LEGACY || "";
67
+ }
68
+ function publicReadAvailable() {
69
+ return Boolean(publicReadToken() && env.EZCODER_API_URL);
70
+ }
71
+ var stickyPublicMode = false;
72
+ function shouldSkipRpc() {
73
+ return stickyPublicMode && publicReadAvailable();
74
+ }
75
+ async function hasActiveSession(supabase2) {
76
+ try {
77
+ if (!supabase2?.auth?.getSession) return false;
78
+ const { data } = await supabase2.auth.getSession();
79
+ return Boolean(data?.session);
80
+ } catch {
81
+ return true;
82
+ }
83
+ }
84
+ async function publicReadQuery(projectId, sql) {
85
+ if (!publicReadAvailable()) {
86
+ return { success: false, error: "Public read proxy not configured (missing public token or API URL)" };
87
+ }
88
+ try {
89
+ const base = env.EZCODER_API_URL.replace(/\/$/, "");
90
+ const res = await fetch(`${base}/api/platform/db/${encodeURIComponent(projectId)}/query`, {
91
+ method: "POST",
92
+ headers: {
93
+ "Content-Type": "application/json",
94
+ "X-EzCoder-Public-Token": publicReadToken()
95
+ },
96
+ body: JSON.stringify({ sql }),
97
+ signal: typeof AbortSignal !== "undefined" && AbortSignal.timeout ? AbortSignal.timeout(PROXY_TIMEOUT_MS) : void 0
98
+ });
99
+ const payload = await res.json().catch(() => null);
100
+ if (!res.ok || !payload) {
101
+ return { success: false, error: payload?.error || `Public read proxy HTTP ${res.status}` };
102
+ }
103
+ if (payload.success) stickyPublicMode = true;
104
+ return payload;
105
+ } catch (err) {
106
+ const message = err instanceof Error ? err.message : "Public read proxy request failed";
107
+ return { success: false, error: message };
108
+ }
109
+ }
110
+
59
111
  // src/database/QueryBuilder.ts
60
112
  function escapeSqlValue(value) {
61
113
  if (value === null) return "NULL";
@@ -278,7 +330,7 @@ var QueryBuilder = class {
278
330
  default:
279
331
  throw new QueryError(`Unknown operation: ${this.operation}`);
280
332
  }
281
- if (this.serverProxy) {
333
+ if (this.serverProxy?.serverQuery && this.serverProxy?.serverExec) {
282
334
  const fn = isRead ? this.serverProxy.serverQuery : this.serverProxy.serverExec;
283
335
  const data2 = await fn(sql);
284
336
  if (!data2.success) {
@@ -293,15 +345,25 @@ var QueryBuilder = class {
293
345
  schema: data2.schema
294
346
  };
295
347
  }
348
+ const publicQuery = this.serverProxy?.publicQuery;
349
+ if (isRead && publicQuery && shouldSkipRpc() && !await hasActiveSession(this.supabase)) {
350
+ return this.runPublicQuery(publicQuery, sql);
351
+ }
296
352
  const rpcName = isRead ? "sdk_query_project" : "sdk_exec_project";
297
353
  const { data, error } = await this.supabase.rpc(rpcName, {
298
354
  p_project_id: this.projectId,
299
355
  p_sql: sql
300
356
  });
301
357
  if (error) {
358
+ if (isRead && publicQuery && isAuthShapedFailure(error.message) && !await hasActiveSession(this.supabase)) {
359
+ return this.runPublicQuery(publicQuery, sql, error.message);
360
+ }
302
361
  throw new QueryError(error.message, sql);
303
362
  }
304
363
  if (!data.success) {
364
+ if (isRead && publicQuery && isAuthShapedFailure(data.error) && !await hasActiveSession(this.supabase)) {
365
+ return this.runPublicQuery(publicQuery, sql, data.error);
366
+ }
305
367
  const dbError = mapRpcError(data);
306
368
  if (dbError) throw dbError;
307
369
  throw new QueryError(data.error || "Query failed", sql);
@@ -321,6 +383,21 @@ var QueryBuilder = class {
321
383
  schema: data.schema
322
384
  };
323
385
  }
386
+ /** Execute a read through the platform public proxy (anonymous-visitor path). */
387
+ async runPublicQuery(publicQuery, sql, rpcError) {
388
+ const data = await publicQuery(sql);
389
+ if (!data.success) {
390
+ const dbError = mapRpcError(data);
391
+ if (dbError) throw dbError;
392
+ throw new QueryError(data.error || rpcError || "Query failed", sql);
393
+ }
394
+ return {
395
+ success: true,
396
+ data: data.data || [],
397
+ rowCount: data.rowCount ?? (data.data?.length || 0),
398
+ schema: data.schema
399
+ };
400
+ }
324
401
  then(onfulfilled, onrejected) {
325
402
  const promise = this.executeQuery().then((result) => {
326
403
  if (this.singleMode) {
@@ -372,7 +449,9 @@ var DatabaseClient = class _DatabaseClient {
372
449
  serverExec: (sql) => this._serverRequest("/execute", sql)
373
450
  });
374
451
  }
375
- return new QueryBuilder(this.supabase, this.projectId, table);
452
+ return new QueryBuilder(this.supabase, this.projectId, table, {
453
+ publicQuery: (sql) => publicReadQuery(this.projectId, sql)
454
+ });
376
455
  }
377
456
  async sql(query) {
378
457
  const trimmed = query.trim().toLowerCase();
@@ -383,16 +462,25 @@ var DatabaseClient = class _DatabaseClient {
383
462
  return this._serverQuery(query);
384
463
  }
385
464
  const start = Date.now();
465
+ if (shouldSkipRpc() && !await hasActiveSession(this.supabase)) {
466
+ return this._publicFallback(query, start, null);
467
+ }
386
468
  const { data, error } = await this.supabase.rpc("sdk_query_project", {
387
469
  p_project_id: this.projectId,
388
470
  p_sql: query
389
471
  });
390
472
  const latencyMs = Date.now() - start;
391
473
  if (error) {
474
+ if (publicReadAvailable() && isAuthShapedFailure(error.message) && !await hasActiveSession(this.supabase)) {
475
+ return this._publicFallback(query, start, error.message);
476
+ }
392
477
  trackDbEvent("db_query", { projectId: this.projectId, latencyMs, success: false, error: error.message });
393
478
  throw new QueryError(error.message, query);
394
479
  }
395
480
  if (!data.success) {
481
+ if (publicReadAvailable() && isAuthShapedFailure(data.error) && !await hasActiveSession(this.supabase)) {
482
+ return this._publicFallback(query, start, data.error);
483
+ }
396
484
  trackDbEvent("db_query", { projectId: this.projectId, latencyMs, success: false, error: data.error });
397
485
  throw new QueryError(data.error || "Query failed", query);
398
486
  }
@@ -404,6 +492,22 @@ var DatabaseClient = class _DatabaseClient {
404
492
  schema: data.schema
405
493
  };
406
494
  }
495
+ /** Read via the platform public proxy (anonymous-visitor path). */
496
+ async _publicFallback(query, start, rpcError) {
497
+ const data = await publicReadQuery(this.projectId, query);
498
+ const latencyMs = Date.now() - start;
499
+ if (!data.success) {
500
+ trackDbEvent("db_query", { projectId: this.projectId, latencyMs, success: false, error: data.error, publicProxy: true });
501
+ throw new QueryError(data.error || rpcError || "Query failed", query);
502
+ }
503
+ trackDbEvent("db_query", { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0, publicProxy: true });
504
+ return {
505
+ success: true,
506
+ data: data.data || [],
507
+ rowCount: data.rowCount ?? (data.data?.length || 0),
508
+ schema: data.schema
509
+ };
510
+ }
407
511
  async execute(sql) {
408
512
  if (this.serverMode) {
409
513
  return this._serverExecute(sql);
@@ -639,4 +743,4 @@ export {
639
743
  useIsDatabaseConfigured,
640
744
  useRealtime
641
745
  };
642
- //# sourceMappingURL=chunk-R4MDAYFO.js.map
746
+ //# sourceMappingURL=chunk-IQNU5UD7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/database/DatabaseProvider.tsx","../src/database/errors.ts","../src/database/publicReadProxy.ts","../src/database/QueryBuilder.ts","../src/database/DatabaseClient.ts","../src/database/useRealtime.ts"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\r\nimport { env } from '../core/config';\r\nimport { DatabaseClient } from './DatabaseClient';\r\n\r\ninterface DatabaseContextValue {\r\n db: DatabaseClient | null;\r\n isConfigured: boolean;\r\n}\r\n\r\nconst DatabaseContext = createContext<DatabaseContextValue>({\r\n db: null,\r\n isConfigured: false,\r\n});\r\n\r\ninterface DatabaseProviderProps {\r\n children: ReactNode;\r\n projectId?: string;\r\n}\r\n\r\nexport function DatabaseProvider({ children, projectId }: DatabaseProviderProps) {\r\n const resolvedProjectId = projectId || env.EZC_PROJECT_ID;\r\n const configured = isSupabaseConfigured && Boolean(resolvedProjectId);\r\n\r\n const db = useMemo(\r\n () => (configured ? new DatabaseClient(supabase, resolvedProjectId) : null),\r\n [configured, resolvedProjectId],\r\n );\r\n\r\n const value = useMemo(() => ({ db, isConfigured: configured }), [db, configured]);\r\n\r\n return <DatabaseContext.Provider value={value}>{children}</DatabaseContext.Provider>;\r\n}\r\n\r\nexport function useDatabase(): DatabaseClient {\r\n const { db } = useContext(DatabaseContext);\r\n if (!db) {\r\n throw new Error(\r\n 'useDatabase() must be used within <DatabaseProvider>. ' +\r\n 'Ensure EZC_PROJECT_ID and Supabase credentials are configured.',\r\n );\r\n }\r\n return db;\r\n}\r\n\r\nexport function useDatabaseOptional(): DatabaseClient | null {\r\n const { db } = useContext(DatabaseContext);\r\n return db;\r\n}\r\n\r\nexport function useIsDatabaseConfigured(): boolean {\r\n const { isConfigured } = useContext(DatabaseContext);\r\n return isConfigured;\r\n}\r\n","export class DatabaseError extends Error {\r\n readonly code: string;\r\n readonly statusCode: number;\r\n\r\n constructor(message: string, code = 'DATABASE_ERROR', statusCode = 500) {\r\n super(message);\r\n this.name = 'DatabaseError';\r\n this.code = code;\r\n this.statusCode = statusCode;\r\n }\r\n}\r\n\r\nexport class QueryError extends DatabaseError {\r\n readonly sql?: string;\r\n\r\n constructor(message: string, sql?: string) {\r\n super(message, 'QUERY_ERROR', 400);\r\n this.name = 'QueryError';\r\n this.sql = sql;\r\n }\r\n}\r\n\r\nexport class ValidationError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'VALIDATION_ERROR', 422);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\nexport class ConnectionError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'CONNECTION_ERROR', 503);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\nexport class NotFoundError extends DatabaseError {\r\n constructor(message = 'Record not found') {\r\n super(message, 'NOT_FOUND', 404);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\nexport function mapRpcError(rpcResult: { success: boolean; error?: string; code?: string }): DatabaseError | null {\r\n if (rpcResult.success) return null;\r\n const msg = rpcResult.error || 'Unknown database error';\r\n if (msg.includes('No database schema exists')) return new NotFoundError(msg);\r\n if (msg.includes('Authentication required')) return new ConnectionError(msg);\r\n if (msg.includes('blocked') || msg.includes('forbidden')) return new ValidationError(msg);\r\n return new QueryError(msg);\r\n}\r\n","/**\n * Public read proxy — anonymous-visitor data reads for deployed sites.\n *\n * The direct browser path (supabase.rpc('sdk_query_project')) requires an\n * authenticated, project-bound session by design (tenant migrations 200/201/\n * 227: the RPC executes raw SELECTs, so anon was deliberately revoked). That\n * left every data-driven section of a deployed site empty for visitors.\n *\n * This module routes READ-ONLY queries through the platform's DB proxy\n * (`POST {EZCODER_API_URL}/api/platform/db/{projectId}/query`) authenticated\n * with the browser-safe PUBLIC-class project token (EZC_PROJECT_TOKEN_PUBLIC,\n * baked into the bundle at build time). Server-side that proxy runs the same\n * hardened tenant function (SELECT-only, project-schema-scoped, system/auth\n * schemas blocked, LIMIT-capped, rate-limited) plus a credential-table guard\n * for public-class tokens. Writes never use this path.\n */\n\nimport { env } from '../core/config';\n\nexport interface PublicProxyResult {\n success: boolean;\n data?: unknown[];\n rowCount?: number;\n error?: string;\n schema?: string;\n}\n\nconst PROXY_TIMEOUT_MS = 10000;\n\n/** Failures that mean \"the RPC path needs an authenticated session\" — the\n * signal to fall back to the public proxy rather than surface the error. */\nconst AUTH_FAILURE_PATTERN =\n /authentication required|permission denied|project binding|unauthorized|jwt|42501/i;\n\nexport function isAuthShapedFailure(message: string | null | undefined): boolean {\n return typeof message === 'string' && AUTH_FAILURE_PATTERN.test(message);\n}\n\n/**\n * The browser-safe token to authenticate public reads with. Prefer the\n * bounded-blast-radius PUBLIC-class token (ezc_pub_*); fall back to the legacy\n * single-class token (ezc_*), which is ALSO baked into every deployed bundle\n * and which the platform read proxy accepts. The fallback covers projects\n * whose B1 token-pair provisioning hasn't run or failed (the public-class env\n * var bakes empty) — without it those sites get no data (incident 2026-06-11,\n * herdmark: project_credentials empty → VITE_EZC_PROJECT_TOKEN_PUBLIC empty).\n */\nexport function publicReadToken(): string {\n return env.EZC_PROJECT_TOKEN_PUBLIC || env.EZC_PROJECT_TOKEN_LEGACY || '';\n}\n\nexport function publicReadAvailable(): boolean {\n return Boolean(publicReadToken() && env.EZCODER_API_URL);\n}\n\n// Once a query has fallen back because the visitor has no session, later\n// reads skip the doomed RPC round-trip. Never set unless the proxy SUCCEEDED,\n// so a transient RPC failure can't permanently divert an authenticated user.\nlet stickyPublicMode = false;\n\nexport function shouldSkipRpc(): boolean {\n return stickyPublicMode && publicReadAvailable();\n}\n\n/** Test seam. */\nexport function _resetStickyPublicMode(): void {\n stickyPublicMode = false;\n}\n\n/**\n * True when the supabase client holds an active auth session. The public\n * proxy is for ANONYMOUS visitors only — an authenticated user's reads must\n * always go through the RPC (their session is the authority; security review\n * finding 2026-06-11: an anonymous page load must not divert a subsequently\n * signed-in user to the session-less proxy). Fail-safe: on any error, report\n * a session as PRESENT so the caller refuses the fallback.\n */\nexport async function hasActiveSession(supabase: { auth?: { getSession?: () => Promise<{ data?: { session?: unknown } }> } } | null | undefined): Promise<boolean> {\n try {\n if (!supabase?.auth?.getSession) return false;\n const { data } = await supabase.auth.getSession();\n return Boolean(data?.session);\n } catch {\n return true;\n }\n}\n\nexport async function publicReadQuery(projectId: string, sql: string): Promise<PublicProxyResult> {\n if (!publicReadAvailable()) {\n return { success: false, error: 'Public read proxy not configured (missing public token or API URL)' };\n }\n try {\n const base = env.EZCODER_API_URL.replace(/\\/$/, '');\n const res = await fetch(`${base}/api/platform/db/${encodeURIComponent(projectId)}/query`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-EzCoder-Public-Token': publicReadToken(),\n },\n body: JSON.stringify({ sql }),\n signal: typeof AbortSignal !== 'undefined' && AbortSignal.timeout\n ? AbortSignal.timeout(PROXY_TIMEOUT_MS)\n : undefined,\n });\n const payload = (await res.json().catch(() => null)) as PublicProxyResult | null;\n if (!res.ok || !payload) {\n return { success: false, error: payload?.error || `Public read proxy HTTP ${res.status}` };\n }\n if (payload.success) stickyPublicMode = true;\n return payload;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Public read proxy request failed';\n return { success: false, error: message };\n }\n}\n","import type { SupabaseClient } from '@supabase/supabase-js';\r\nimport type { DatabaseResult, SingleResult, MutationResult, FilterValue, OrderOption } from './types';\r\nimport { QueryError, ValidationError, mapRpcError } from './errors';\r\nimport { isAuthShapedFailure, shouldSkipRpc, hasActiveSession } from './publicReadProxy';\r\n\r\nfunction escapeSqlValue(value: FilterValue): string {\r\n if (value === null) return 'NULL';\r\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\r\n if (typeof value === 'number') {\r\n if (!Number.isFinite(value)) throw new ValidationError('Non-finite numbers are not allowed');\r\n return String(value);\r\n }\r\n return `'${String(value).replace(/'/g, \"''\")}'`;\r\n}\r\n\r\nfunction escapeIdentifier(name: string): string {\r\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\r\n throw new ValidationError(`Invalid identifier: ${name}`);\r\n }\r\n return `\"${name}\"`;\r\n}\r\n\r\ntype Operation = 'select' | 'insert' | 'update' | 'delete' | 'count' | 'upsert';\r\n\r\ninterface Filter {\r\n column: string;\r\n op: string;\r\n value: FilterValue | FilterValue[];\r\n}\r\n\r\nexport interface ServerProxy {\r\n serverQuery?: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n serverExec?: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n /** Browser-mode READ fallback: routes through the platform public proxy\r\n * (public-class token) when the direct RPC needs an authenticated session\r\n * the visitor doesn't have. Reads only — writes never fall back. */\r\n publicQuery?: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n}\r\n\r\nexport class QueryBuilder<T = Record<string, unknown>> {\r\n private readonly supabase: SupabaseClient;\r\n private readonly projectId: string;\r\n private readonly table: string;\r\n private readonly serverProxy?: ServerProxy;\r\n\r\n private operation: Operation = 'select';\r\n private selectColumns = '*';\r\n private filters: Filter[] = [];\r\n private orderClauses: string[] = [];\r\n private limitValue: number | null = null;\r\n private offsetValue: number | null = null;\r\n private insertData: Record<string, FilterValue>[] | null = null;\r\n private updateData: Record<string, FilterValue> | null = null;\r\n private upsertConflict: string | null = null;\r\n private singleMode = false;\r\n private maybeSingleMode = false;\r\n\r\n constructor(supabase: SupabaseClient, projectId: string, table: string, serverProxy?: ServerProxy) {\r\n this.supabase = supabase;\r\n this.projectId = projectId;\r\n this.table = table;\r\n this.serverProxy = serverProxy;\r\n }\r\n\r\n select(columns = '*'): this {\r\n this.operation = 'select';\r\n this.selectColumns = columns;\r\n return this;\r\n }\r\n\r\n // --- Filters ---\r\n\r\n eq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '=', value });\r\n return this;\r\n }\r\n\r\n neq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '!=', value });\r\n return this;\r\n }\r\n\r\n gt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>', value });\r\n return this;\r\n }\r\n\r\n lt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<', value });\r\n return this;\r\n }\r\n\r\n gte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>=', value });\r\n return this;\r\n }\r\n\r\n lte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<=', value });\r\n return this;\r\n }\r\n\r\n like(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'LIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n ilike(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'ILIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n in(column: string, values: FilterValue[]): this {\r\n this.filters.push({ column, op: 'IN', value: values });\r\n return this;\r\n }\r\n\r\n is(column: string, value: null | boolean): this {\r\n this.filters.push({ column, op: 'IS', value });\r\n return this;\r\n }\r\n\r\n // --- Ordering & Pagination ---\r\n\r\n order(column: string, options: OrderOption = {}): this {\r\n const dir = options.ascending === false ? 'DESC' : 'ASC';\r\n const nulls = options.nullsFirst ? 'NULLS FIRST' : 'NULLS LAST';\r\n this.orderClauses.push(`${escapeIdentifier(column)} ${dir} ${nulls}`);\r\n return this;\r\n }\r\n\r\n limit(count: number): this {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n offset(count: number): this {\r\n this.offsetValue = count;\r\n return this;\r\n }\r\n\r\n // --- Mutations ---\r\n\r\n insert(records: Record<string, FilterValue> | Record<string, FilterValue>[]): this {\r\n this.operation = 'insert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n return this;\r\n }\r\n\r\n update(values: Record<string, FilterValue>): this {\r\n this.operation = 'update';\r\n this.updateData = values;\r\n return this;\r\n }\r\n\r\n delete(): this {\r\n this.operation = 'delete';\r\n return this;\r\n }\r\n\r\n upsert(records: Record<string, FilterValue> | Record<string, FilterValue>[], options?: { onConflict?: string }): this {\r\n this.operation = 'upsert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n this.upsertConflict = options?.onConflict || null;\r\n return this;\r\n }\r\n\r\n // --- Result Helpers ---\r\n\r\n count(): QueryBuilder<{ count: number }> {\r\n this.operation = 'count';\r\n return this as unknown as QueryBuilder<{ count: number }>;\r\n }\r\n\r\n single(): QueryBuilder<T> {\r\n this.singleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n maybeSingle(): QueryBuilder<T> {\r\n this.maybeSingleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n // --- SQL Building ---\r\n\r\n private buildWhereClause(): string {\r\n if (this.filters.length === 0) return '';\r\n const conditions = this.filters.map((f) => {\r\n const col = escapeIdentifier(f.column);\r\n if (f.op === 'IS') {\r\n const val = f.value === null ? 'NULL' : f.value ? 'TRUE' : 'FALSE';\r\n return `${col} IS ${val}`;\r\n }\r\n if (f.op === 'IN') {\r\n const vals = (f.value as FilterValue[]).map(escapeSqlValue).join(', ');\r\n return `${col} IN (${vals})`;\r\n }\r\n return `${col} ${f.op} ${escapeSqlValue(f.value as FilterValue)}`;\r\n });\r\n return ` WHERE ${conditions.join(' AND ')}`;\r\n }\r\n\r\n private buildSelectSql(): string {\r\n let sql = `SELECT ${this.selectColumns} FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n if (this.orderClauses.length > 0) sql += ` ORDER BY ${this.orderClauses.join(', ')}`;\r\n if (this.limitValue !== null) sql += ` LIMIT ${this.limitValue}`;\r\n if (this.offsetValue !== null && this.offsetValue > 0) sql += ` OFFSET ${this.offsetValue}`;\r\n return sql;\r\n }\r\n\r\n private buildCountSql(): string {\r\n let sql = `SELECT COUNT(*) as count FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n return sql;\r\n }\r\n\r\n private buildInsertSql(): string {\r\n if (!this.insertData || this.insertData.length === 0) {\r\n throw new ValidationError('No data provided for insert');\r\n }\r\n const columns = Object.keys(this.insertData[0]);\r\n const colList = columns.map(escapeIdentifier).join(', ');\r\n const rows = this.insertData.map(\r\n (row) => `(${columns.map((c) => escapeSqlValue(row[c] ?? null)).join(', ')})`\r\n );\r\n return `INSERT INTO \"${this.table}\" (${colList}) VALUES ${rows.join(', ')}`;\r\n }\r\n\r\n private buildUpsertSql(): string {\r\n let sql = this.buildInsertSql();\r\n const conflict = this.upsertConflict || 'id';\r\n const columns = Object.keys(this.insertData![0]);\r\n const updateCols = columns\r\n .filter((c) => c !== conflict)\r\n .map((c) => `${escapeIdentifier(c)} = EXCLUDED.${escapeIdentifier(c)}`)\r\n .join(', ');\r\n sql += ` ON CONFLICT (${escapeIdentifier(conflict)}) DO UPDATE SET ${updateCols}`;\r\n return sql;\r\n }\r\n\r\n private buildUpdateSql(): string {\r\n if (!this.updateData || Object.keys(this.updateData).length === 0) {\r\n throw new ValidationError('No data provided for update');\r\n }\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('UPDATE without filters is not allowed — add .eq() or other filters');\r\n }\r\n const setClauses = Object.entries(this.updateData)\r\n .map(([col, val]) => `${escapeIdentifier(col)} = ${escapeSqlValue(val)}`)\r\n .join(', ');\r\n return `UPDATE \"${this.table}\" SET ${setClauses}${this.buildWhereClause()}`;\r\n }\r\n\r\n private buildDeleteSql(): string {\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('DELETE without filters is not allowed — add .eq() or other filters');\r\n }\r\n return `DELETE FROM \"${this.table}\"${this.buildWhereClause()}`;\r\n }\r\n\r\n // --- Execution ---\r\n\r\n private async executeQuery(): Promise<DatabaseResult<T>> {\r\n const isRead = this.operation === 'select' || this.operation === 'count';\r\n\r\n let sql: string;\r\n switch (this.operation) {\r\n case 'select': sql = this.buildSelectSql(); break;\r\n case 'count': sql = this.buildCountSql(); break;\r\n case 'insert': sql = this.buildInsertSql(); break;\r\n case 'upsert': sql = this.buildUpsertSql(); break;\r\n case 'update': sql = this.buildUpdateSql(); break;\r\n case 'delete': sql = this.buildDeleteSql(); break;\r\n default: throw new QueryError(`Unknown operation: ${this.operation}`);\r\n }\r\n\r\n // Server mode (secret-key proxy): full read/write via the platform.\r\n if (this.serverProxy?.serverQuery && this.serverProxy?.serverExec) {\r\n const fn = isRead ? this.serverProxy.serverQuery : this.serverProxy.serverExec;\r\n const data = await fn(sql);\r\n if (!data.success) {\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || 'Query failed', sql);\r\n }\r\n return {\r\n success: true,\r\n data: (isRead ? data.data || [] : []) as T[],\r\n rowCount: data.rowCount ?? (isRead ? (data.data?.length || 0) : 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n // Browser mode, anonymous visitors ONLY: skip the doomed RPC once a read\r\n // has already fallen back to the public proxy. A signed-in user always\r\n // goes through the RPC — their session is the authority.\r\n const publicQuery = this.serverProxy?.publicQuery;\r\n if (isRead && publicQuery && shouldSkipRpc() && !(await hasActiveSession(this.supabase))) {\r\n return this.runPublicQuery(publicQuery, sql);\r\n }\r\n\r\n const rpcName = isRead ? 'sdk_query_project' : 'sdk_exec_project';\r\n const { data, error } = await this.supabase.rpc(rpcName, {\r\n p_project_id: this.projectId,\r\n p_sql: sql,\r\n });\r\n\r\n if (error) {\r\n if (isRead && publicQuery && isAuthShapedFailure(error.message) && !(await hasActiveSession(this.supabase))) {\r\n return this.runPublicQuery(publicQuery, sql, error.message);\r\n }\r\n throw new QueryError(error.message, sql);\r\n }\r\n\r\n if (!data.success) {\r\n if (isRead && publicQuery && isAuthShapedFailure(data.error) && !(await hasActiveSession(this.supabase))) {\r\n return this.runPublicQuery(publicQuery, sql, data.error);\r\n }\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || 'Query failed', sql);\r\n }\r\n\r\n if (isRead) {\r\n return {\r\n success: true,\r\n data: data.data || [],\r\n rowCount: data.rowCount ?? (data.data?.length || 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n return {\r\n success: true,\r\n data: [],\r\n rowCount: data.rowCount ?? 0,\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n /** Execute a read through the platform public proxy (anonymous-visitor path). */\r\n private async runPublicQuery(\r\n publicQuery: NonNullable<ServerProxy['publicQuery']>,\r\n sql: string,\r\n rpcError?: string,\r\n ): Promise<DatabaseResult<T>> {\r\n const data = await publicQuery(sql);\r\n if (!data.success) {\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || rpcError || 'Query failed', sql);\r\n }\r\n return {\r\n success: true,\r\n data: (data.data || []) as T[],\r\n rowCount: data.rowCount ?? (data.data?.length || 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n then<TResult1 = DatabaseResult<T> | SingleResult<T>, TResult2 = never>(\r\n onfulfilled?: ((value: DatabaseResult<T> | SingleResult<T>) => TResult1 | PromiseLike<TResult1>) | null,\r\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\r\n ): Promise<TResult1 | TResult2> {\r\n const promise = this.executeQuery().then((result) => {\r\n if (this.singleMode) {\r\n if (result.data.length === 0) {\r\n throw new QueryError('Expected exactly one row, got 0');\r\n }\r\n return { success: true, data: result.data[0], error: undefined } as SingleResult<T>;\r\n }\r\n if (this.maybeSingleMode) {\r\n return {\r\n success: true,\r\n data: result.data.length > 0 ? result.data[0] : null,\r\n error: undefined,\r\n } as SingleResult<T>;\r\n }\r\n return result;\r\n });\r\n return promise.then(onfulfilled, onrejected);\r\n }\r\n}\r\n","import type { SupabaseClient } from '@supabase/supabase-js';\nimport type { DatabaseResult, MutationResult, SchemaInfo } from './types';\nimport { QueryBuilder, type ServerProxy } from './QueryBuilder';\nimport { QueryError, ConnectionError } from './errors';\nimport { ezcoder } from '../core/platform';\nimport { features } from '../core/config';\nimport { publicReadQuery, publicReadAvailable, isAuthShapedFailure, shouldSkipRpc, hasActiveSession } from './publicReadProxy';\n\nfunction trackDbEvent(event: string, props: Record<string, unknown>) {\n if (!features.analytics) return;\n try { ezcoder.analytics.track(event, props); } catch { /* non-critical */ }\n}\n\ninterface ServerProxyResult {\n success: boolean;\n data?: unknown[];\n rowCount?: number;\n error?: string;\n schema?: string;\n exists?: boolean;\n tables?: unknown[];\n tablesCount?: number;\n createdAt?: string;\n lastAccessedAt?: string;\n executed_sql?: string;\n}\n\nconst MAX_RETRIES = 3;\nconst SERVER_TIMEOUT_MS = 5000;\n\nexport class DatabaseClient {\n private readonly supabase: SupabaseClient | null;\n private readonly projectId: string;\n private apiKey?: string;\n private platformUrl?: string;\n private serverMode: boolean = false;\n\n constructor(supabase: SupabaseClient | null, projectId: string) {\n this.supabase = supabase;\n this.projectId = projectId;\n }\n\n static createServerClient(\n projectId: string,\n apiKey: string,\n platformUrl?: string\n ): DatabaseClient {\n const client = new DatabaseClient(null, projectId);\n client.apiKey = apiKey;\n client.platformUrl = platformUrl\n || (typeof process !== 'undefined' && process.env?.EZCODER_API_URL)\n || 'https://ezcoder.app';\n client.serverMode = true;\n return client;\n }\n\n from<T = Record<string, unknown>>(table: string): QueryBuilder<T> {\n if (this.serverMode) {\n return new QueryBuilder<T>(null as unknown as SupabaseClient, this.projectId, table, {\n serverQuery: (sql: string) => this._serverRequest('/query', sql),\n serverExec: (sql: string) => this._serverRequest('/execute', sql),\n });\n }\n // Browser mode: reads get the public-proxy fallback so anonymous visitors\n // on deployed sites see data (the direct RPC requires a signed-in,\n // project-bound session). Writes intentionally have no fallback.\n return new QueryBuilder<T>(this.supabase!, this.projectId, table, {\n publicQuery: (sql: string) => publicReadQuery(this.projectId, sql),\n });\n }\n\n async sql<T = Record<string, unknown>>(query: string): Promise<DatabaseResult<T>> {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed.startsWith('select')) {\n throw new QueryError('sql() is for read-only queries. Use execute() for mutations.');\n }\n\n if (this.serverMode) {\n return this._serverQuery<T>(query);\n }\n\n const start = Date.now();\n\n // Anonymous visitors ONLY: once a read has fallen back to the public\n // proxy, skip the doomed RPC round-trip on subsequent reads. A signed-in\n // user always goes through the RPC — their session is the authority.\n if (shouldSkipRpc() && !(await hasActiveSession(this.supabase))) {\n return this._publicFallback<T>(query, start, null);\n }\n\n const { data, error } = await this.supabase!.rpc('sdk_query_project', {\n p_project_id: this.projectId,\n p_sql: query,\n });\n const latencyMs = Date.now() - start;\n\n if (error) {\n if (publicReadAvailable() && isAuthShapedFailure(error.message) && !(await hasActiveSession(this.supabase))) {\n return this._publicFallback<T>(query, start, error.message);\n }\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: error.message });\n throw new QueryError(error.message, query);\n }\n if (!data.success) {\n if (publicReadAvailable() && isAuthShapedFailure(data.error) && !(await hasActiveSession(this.supabase))) {\n return this._publicFallback<T>(query, start, data.error);\n }\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: data.error });\n throw new QueryError(data.error || 'Query failed', query);\n }\n\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0 });\n\n return {\n success: true,\n data: data.data || [],\n rowCount: data.rowCount ?? (data.data?.length || 0),\n schema: data.schema,\n };\n }\n\n /** Read via the platform public proxy (anonymous-visitor path). */\n private async _publicFallback<T>(query: string, start: number, rpcError: string | null): Promise<DatabaseResult<T>> {\n const data = await publicReadQuery(this.projectId, query);\n const latencyMs = Date.now() - start;\n if (!data.success) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: data.error, publicProxy: true });\n // Surface the proxy's error (it is the actionable one); note the RPC error for diagnosis.\n throw new QueryError(data.error || rpcError || 'Query failed', query);\n }\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0, publicProxy: true });\n return {\n success: true,\n data: (data.data || []) as T[],\n rowCount: data.rowCount ?? (data.data?.length || 0),\n schema: data.schema,\n };\n }\n\n async execute(sql: string): Promise<MutationResult> {\n if (this.serverMode) {\n return this._serverExecute(sql);\n }\n\n const start = Date.now();\n const { data, error } = await this.supabase!.rpc('sdk_exec_project', {\n p_project_id: this.projectId,\n p_sql: sql,\n });\n const latencyMs = Date.now() - start;\n\n if (error) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: error.message });\n throw new QueryError(error.message, sql);\n }\n if (!data.success) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: data.error });\n throw new QueryError(data.error || 'Execution failed', sql);\n }\n\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0 });\n\n return {\n success: true,\n rowCount: data.rowCount ?? 0,\n schema: data.schema,\n executed_sql: data.executed_sql,\n };\n }\n\n async getSchema(): Promise<SchemaInfo> {\n if (this.serverMode) {\n return this._serverGetSchema();\n }\n\n const { data, error } = await this.supabase!.rpc('sdk_get_schema_info', {\n p_project_id: this.projectId,\n });\n\n if (error) throw new ConnectionError(error.message);\n\n return {\n exists: data.exists ?? false,\n schema: data.schema,\n tables: data.tables || [],\n tablesCount: data.tablesCount ?? 0,\n createdAt: data.createdAt,\n lastAccessedAt: data.lastAccessedAt,\n };\n }\n\n private async _serverRequest(endpoint: string, sql: string): Promise<ServerProxyResult> {\n const url = `${this.platformUrl}/api/platform/db/${this.projectId}${endpoint}`;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ sql }),\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n\n if (res.status === 429) {\n const retryAfter = parseInt(res.headers.get('retry-after') || '60', 10);\n await new Promise(r => setTimeout(r, retryAfter * 1000));\n continue;\n }\n if (res.status === 503) {\n await new Promise(r => setTimeout(r, (attempt + 1) * 2000));\n continue;\n }\n\n return await res.json() as ServerProxyResult;\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n return { success: false, error: lastError?.message || 'Request failed after retries' };\n }\n\n private async _serverQuery<T>(query: string): Promise<DatabaseResult<T>> {\n const start = Date.now();\n const result = await this._serverRequest('/query', query);\n const latencyMs = Date.now() - start;\n\n if (!result.success) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: result.error, serverMode: true });\n throw new QueryError(result.error || 'Query failed', query);\n }\n\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0, serverMode: true });\n\n return {\n success: true,\n data: (result.data || []) as T[],\n rowCount: result.rowCount ?? ((result.data as unknown[])?.length || 0),\n schema: result.schema,\n };\n }\n\n private async _serverExecute(sql: string): Promise<MutationResult> {\n const start = Date.now();\n const result = await this._serverRequest('/execute', sql);\n const latencyMs = Date.now() - start;\n\n if (!result.success) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: result.error, serverMode: true });\n throw new QueryError(result.error || 'Execution failed', sql);\n }\n\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0, serverMode: true });\n\n return {\n success: true,\n rowCount: result.rowCount ?? 0,\n schema: result.schema,\n executed_sql: result.executed_sql,\n };\n }\n\n private async _serverGetSchema(): Promise<SchemaInfo> {\n const url = `${this.platformUrl}/api/platform/db/${this.projectId}/schema`;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${this.apiKey}` },\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n\n if (res.status === 503) {\n await new Promise(r => setTimeout(r, (attempt + 1) * 2000));\n continue;\n }\n\n const data = await res.json() as ServerProxyResult;\n if (!data.success) throw new ConnectionError(data.error || 'Schema fetch failed');\n\n return {\n exists: data.exists ?? false,\n schema: data.schema,\n tables: (data.tables || []) as SchemaInfo['tables'],\n tablesCount: data.tablesCount ?? 0,\n createdAt: data.createdAt,\n lastAccessedAt: data.lastAccessedAt,\n };\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n throw new ConnectionError(lastError?.message || 'Schema request failed after retries');\n }\n}\n","import { useEffect, useState, useRef } from 'react';\r\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\r\nimport { env } from '../core/config';\r\n\r\ntype RealtimeEvent = 'INSERT' | 'UPDATE' | 'DELETE' | '*';\r\n\r\ninterface RealtimeOptions {\r\n event?: RealtimeEvent;\r\n filter?: string;\r\n}\r\n\r\ninterface UseRealtimeReturn<T> {\r\n data: T[];\r\n status: 'connecting' | 'connected' | 'error' | 'disabled';\r\n setData: React.Dispatch<React.SetStateAction<T[]>>;\r\n}\r\n\r\nexport function useRealtime<T extends Record<string, unknown> = Record<string, unknown>>(\r\n table: string,\r\n options: RealtimeOptions = {},\r\n): UseRealtimeReturn<T> {\r\n const [data, setData] = useState<T[]>([]);\r\n const [status, setStatus] = useState<UseRealtimeReturn<T>['status']>('connecting');\r\n const optionsRef = useRef(options);\r\n optionsRef.current = options;\r\n\r\n const projectId = env.EZC_PROJECT_ID;\r\n\r\n useEffect(() => {\r\n if (!isSupabaseConfigured || !projectId) {\r\n setStatus('disabled');\r\n return;\r\n }\r\n\r\n const schemaName = `proj_${projectId.replace(/-/g, '_')}`;\r\n const channelName = `${schemaName}_${table}_${optionsRef.current.event || 'all'}`;\r\n\r\n const channel = supabase\r\n .channel(channelName)\r\n .on(\r\n 'postgres_changes' as never,\r\n {\r\n event: optionsRef.current.event || '*',\r\n schema: schemaName,\r\n table,\r\n filter: optionsRef.current.filter,\r\n } as never,\r\n (payload: { eventType: string; new: Record<string, unknown>; old: Record<string, unknown> }) => {\r\n if (payload.eventType === 'INSERT') {\r\n setData((prev) => [...prev, payload.new as T]);\r\n } else if (payload.eventType === 'UPDATE') {\r\n setData((prev) =>\r\n prev.map((item) =>\r\n (item as Record<string, unknown>).id === (payload.new as Record<string, unknown>).id\r\n ? (payload.new as T)\r\n : item,\r\n ),\r\n );\r\n } else if (payload.eventType === 'DELETE') {\r\n setData((prev) =>\r\n prev.filter(\r\n (item) =>\r\n (item as Record<string, unknown>).id !== (payload.old as Record<string, unknown>).id,\r\n ),\r\n );\r\n }\r\n },\r\n )\r\n .subscribe((subStatus: string) => {\r\n setStatus(subStatus === 'SUBSCRIBED' ? 'connected' : 'connecting');\r\n });\r\n\r\n return () => {\r\n supabase.removeChannel(channel);\r\n };\r\n }, [projectId, table]);\r\n\r\n return { data, status, setData };\r\n}\r\n"],"mappings":"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","names":["supabase","supabase","data","supabase"]}
@@ -1,4 +1,4 @@
1
- export { C as ColumnInfo, D as DatabaseClient, a as DatabaseProvider, b as DatabaseResult, F as FilterValue, c as ForeignKeyInfo, I as IndexInfo, M as MutationResult, O as OrderOption, P as PolicyInfo, Q as QueryBuilder, S as SchemaInfo, d as SingleResult, T as TableInfo, u as useDatabase, e as useDatabaseOptional, f as useIsDatabaseConfigured } from '../DatabaseProvider-DalP-KHC.js';
1
+ export { C as ColumnInfo, D as DatabaseClient, a as DatabaseProvider, b as DatabaseResult, F as FilterValue, c as ForeignKeyInfo, I as IndexInfo, M as MutationResult, O as OrderOption, P as PolicyInfo, Q as QueryBuilder, S as SchemaInfo, d as SingleResult, T as TableInfo, u as useDatabase, e as useDatabaseOptional, f as useIsDatabaseConfigured } from '../DatabaseProvider-DaBP5XUs.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
4
4
  import '@supabase/supabase-js';
@@ -11,7 +11,7 @@ import {
11
11
  useDatabaseOptional,
12
12
  useIsDatabaseConfigured,
13
13
  useRealtime
14
- } from "../chunk-R4MDAYFO.js";
14
+ } from "../chunk-IQNU5UD7.js";
15
15
  import "../chunk-HJ2EIZ4S.js";
16
16
  import "../chunk-I2YGB7Z6.js";
17
17
  import "../chunk-LIUE7M7K.js";
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
2
  import { E as EzcoderClient, A as AuthIntegration } from './types-1uP3V_pe.js';
3
3
  export { a as AnalyticsResult, b as AuthUser, C as CheckoutOptions, S as StorageFile, c as StorageResult, d as SubscriptionStatus, e as SubscriptionTier, U as UserProfile } from './types-1uP3V_pe.js';
4
- export { D as DatabaseClient, a as DatabaseProvider, u as useDatabase } from './DatabaseProvider-DalP-KHC.js';
4
+ export { D as DatabaseClient, a as DatabaseProvider, u as useDatabase } from './DatabaseProvider-DaBP5XUs.js';
5
5
  import 'react/jsx-runtime';
6
6
  import 'react';
7
7
 
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  DatabaseClient,
3
3
  DatabaseProvider,
4
4
  useDatabase
5
- } from "./chunk-R4MDAYFO.js";
5
+ } from "./chunk-IQNU5UD7.js";
6
6
  import {
7
7
  ezcoder,
8
8
  ezcoderAuthIntegration
package/package.json CHANGED
@@ -1,120 +1,148 @@
1
- {
2
- "name": "@ezcoder.dev/sdk",
3
- "version": "1.2.0",
4
- "description": "EzCoder Platform SDK — auth, payments, storage, analytics, and more with zero configuration",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- },
13
- "./auth": {
14
- "types": "./dist/auth/index.d.ts",
15
- "import": "./dist/auth/index.js"
16
- },
17
- "./payments": {
18
- "types": "./dist/payments/index.d.ts",
19
- "import": "./dist/payments/index.js"
20
- },
21
- "./storage": {
22
- "types": "./dist/storage/index.d.ts",
23
- "import": "./dist/storage/index.js"
24
- },
25
- "./analytics": {
26
- "types": "./dist/analytics/index.d.ts",
27
- "import": "./dist/analytics/index.js"
28
- },
29
- "./roles": {
30
- "types": "./dist/roles/index.d.ts",
31
- "import": "./dist/roles/index.js"
32
- },
33
- "./seo": {
34
- "types": "./dist/seo/index.d.ts",
35
- "import": "./dist/seo/index.js"
36
- },
37
- "./errors": {
38
- "types": "./dist/errors/index.d.ts",
39
- "import": "./dist/errors/index.js"
40
- },
41
- "./notifications": {
42
- "types": "./dist/notifications/index.d.ts",
43
- "import": "./dist/notifications/index.js"
44
- },
45
- "./cms": {
46
- "types": "./dist/cms/index.d.ts",
47
- "import": "./dist/cms/index.js"
48
- },
49
- "./animation": {
50
- "types": "./dist/animation/index.d.ts",
51
- "import": "./dist/animation/index.js"
52
- },
53
- "./database": {
54
- "types": "./dist/database/index.d.ts",
55
- "import": "./dist/database/index.js"
56
- },
57
- "./email": {
58
- "types": "./dist/email/index.d.ts",
59
- "import": "./dist/email/index.js"
60
- },
61
- "./cron": {
62
- "types": "./dist/cron/index.d.ts",
63
- "import": "./dist/cron/index.js"
64
- },
65
- "./server": {
66
- "types": "./dist/server/index.d.ts",
67
- "import": "./dist/server/index.js"
68
- }
69
- },
70
- "typesVersions": {
71
- "*": {
72
- "auth": ["dist/auth/index.d.ts"],
73
- "payments": ["dist/payments/index.d.ts"],
74
- "storage": ["dist/storage/index.d.ts"],
75
- "analytics": ["dist/analytics/index.d.ts"],
76
- "roles": ["dist/roles/index.d.ts"],
77
- "seo": ["dist/seo/index.d.ts"],
78
- "errors": ["dist/errors/index.d.ts"],
79
- "notifications": ["dist/notifications/index.d.ts"],
80
- "cms": ["dist/cms/index.d.ts"],
81
- "animation": ["dist/animation/index.d.ts"],
82
- "database": ["dist/database/index.d.ts"],
83
- "email": ["dist/email/index.d.ts"],
84
- "cron": ["dist/cron/index.d.ts"],
85
- "server": ["dist/server/index.d.ts"]
86
- }
87
- },
88
- "files": [
89
- "dist"
90
- ],
91
- "scripts": {
92
- "build": "tsup",
93
- "dev": "tsup --watch",
94
- "typecheck": "tsc --noEmit",
95
- "clean": "rm -rf dist"
96
- },
97
- "peerDependencies": {
98
- "react": "^18.0.0",
99
- "react-dom": "^18.0.0",
100
- "@supabase/supabase-js": "^2.0.0"
101
- },
102
- "peerDependenciesMeta": {
103
- "framer-motion": {
104
- "optional": true
105
- },
106
- "react-helmet-async": {
107
- "optional": true
108
- },
109
- "stripe": {
110
- "optional": true
111
- }
112
- },
113
- "devDependencies": {
114
- "tsup": "^8.0.0",
115
- "typescript": "^5.5.0",
116
- "@types/react": "^18.0.0",
117
- "@types/react-dom": "^18.0.0"
118
- },
119
- "license": "MIT"
120
- }
1
+ {
2
+ "name": "@ezcoder.dev/sdk",
3
+ "version": "1.3.1",
4
+ "description": "EzCoder Platform SDK — auth, payments, storage, analytics, and more with zero configuration",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./auth": {
14
+ "types": "./dist/auth/index.d.ts",
15
+ "import": "./dist/auth/index.js"
16
+ },
17
+ "./payments": {
18
+ "types": "./dist/payments/index.d.ts",
19
+ "import": "./dist/payments/index.js"
20
+ },
21
+ "./storage": {
22
+ "types": "./dist/storage/index.d.ts",
23
+ "import": "./dist/storage/index.js"
24
+ },
25
+ "./analytics": {
26
+ "types": "./dist/analytics/index.d.ts",
27
+ "import": "./dist/analytics/index.js"
28
+ },
29
+ "./roles": {
30
+ "types": "./dist/roles/index.d.ts",
31
+ "import": "./dist/roles/index.js"
32
+ },
33
+ "./seo": {
34
+ "types": "./dist/seo/index.d.ts",
35
+ "import": "./dist/seo/index.js"
36
+ },
37
+ "./errors": {
38
+ "types": "./dist/errors/index.d.ts",
39
+ "import": "./dist/errors/index.js"
40
+ },
41
+ "./notifications": {
42
+ "types": "./dist/notifications/index.d.ts",
43
+ "import": "./dist/notifications/index.js"
44
+ },
45
+ "./cms": {
46
+ "types": "./dist/cms/index.d.ts",
47
+ "import": "./dist/cms/index.js"
48
+ },
49
+ "./animation": {
50
+ "types": "./dist/animation/index.d.ts",
51
+ "import": "./dist/animation/index.js"
52
+ },
53
+ "./database": {
54
+ "types": "./dist/database/index.d.ts",
55
+ "import": "./dist/database/index.js"
56
+ },
57
+ "./email": {
58
+ "types": "./dist/email/index.d.ts",
59
+ "import": "./dist/email/index.js"
60
+ },
61
+ "./cron": {
62
+ "types": "./dist/cron/index.d.ts",
63
+ "import": "./dist/cron/index.js"
64
+ },
65
+ "./server": {
66
+ "types": "./dist/server/index.d.ts",
67
+ "import": "./dist/server/index.js"
68
+ }
69
+ },
70
+ "typesVersions": {
71
+ "*": {
72
+ "auth": [
73
+ "dist/auth/index.d.ts"
74
+ ],
75
+ "payments": [
76
+ "dist/payments/index.d.ts"
77
+ ],
78
+ "storage": [
79
+ "dist/storage/index.d.ts"
80
+ ],
81
+ "analytics": [
82
+ "dist/analytics/index.d.ts"
83
+ ],
84
+ "roles": [
85
+ "dist/roles/index.d.ts"
86
+ ],
87
+ "seo": [
88
+ "dist/seo/index.d.ts"
89
+ ],
90
+ "errors": [
91
+ "dist/errors/index.d.ts"
92
+ ],
93
+ "notifications": [
94
+ "dist/notifications/index.d.ts"
95
+ ],
96
+ "cms": [
97
+ "dist/cms/index.d.ts"
98
+ ],
99
+ "animation": [
100
+ "dist/animation/index.d.ts"
101
+ ],
102
+ "database": [
103
+ "dist/database/index.d.ts"
104
+ ],
105
+ "email": [
106
+ "dist/email/index.d.ts"
107
+ ],
108
+ "cron": [
109
+ "dist/cron/index.d.ts"
110
+ ],
111
+ "server": [
112
+ "dist/server/index.d.ts"
113
+ ]
114
+ }
115
+ },
116
+ "files": [
117
+ "dist"
118
+ ],
119
+ "scripts": {
120
+ "build": "tsup",
121
+ "dev": "tsup --watch",
122
+ "typecheck": "tsc --noEmit",
123
+ "clean": "rm -rf dist"
124
+ },
125
+ "peerDependencies": {
126
+ "react": "^18.0.0",
127
+ "react-dom": "^18.0.0",
128
+ "@supabase/supabase-js": "^2.0.0"
129
+ },
130
+ "peerDependenciesMeta": {
131
+ "framer-motion": {
132
+ "optional": true
133
+ },
134
+ "react-helmet-async": {
135
+ "optional": true
136
+ },
137
+ "stripe": {
138
+ "optional": true
139
+ }
140
+ },
141
+ "devDependencies": {
142
+ "tsup": "^8.0.0",
143
+ "typescript": "^5.5.0",
144
+ "@types/react": "^18.0.0",
145
+ "@types/react-dom": "^18.0.0"
146
+ },
147
+ "license": "MIT"
148
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/database/DatabaseProvider.tsx","../src/database/errors.ts","../src/database/QueryBuilder.ts","../src/database/DatabaseClient.ts","../src/database/useRealtime.ts"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\r\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\r\nimport { env } from '../core/config';\r\nimport { DatabaseClient } from './DatabaseClient';\r\n\r\ninterface DatabaseContextValue {\r\n db: DatabaseClient | null;\r\n isConfigured: boolean;\r\n}\r\n\r\nconst DatabaseContext = createContext<DatabaseContextValue>({\r\n db: null,\r\n isConfigured: false,\r\n});\r\n\r\ninterface DatabaseProviderProps {\r\n children: ReactNode;\r\n projectId?: string;\r\n}\r\n\r\nexport function DatabaseProvider({ children, projectId }: DatabaseProviderProps) {\r\n const resolvedProjectId = projectId || env.EZC_PROJECT_ID;\r\n const configured = isSupabaseConfigured && Boolean(resolvedProjectId);\r\n\r\n const db = useMemo(\r\n () => (configured ? new DatabaseClient(supabase, resolvedProjectId) : null),\r\n [configured, resolvedProjectId],\r\n );\r\n\r\n const value = useMemo(() => ({ db, isConfigured: configured }), [db, configured]);\r\n\r\n return <DatabaseContext.Provider value={value}>{children}</DatabaseContext.Provider>;\r\n}\r\n\r\nexport function useDatabase(): DatabaseClient {\r\n const { db } = useContext(DatabaseContext);\r\n if (!db) {\r\n throw new Error(\r\n 'useDatabase() must be used within <DatabaseProvider>. ' +\r\n 'Ensure EZC_PROJECT_ID and Supabase credentials are configured.',\r\n );\r\n }\r\n return db;\r\n}\r\n\r\nexport function useDatabaseOptional(): DatabaseClient | null {\r\n const { db } = useContext(DatabaseContext);\r\n return db;\r\n}\r\n\r\nexport function useIsDatabaseConfigured(): boolean {\r\n const { isConfigured } = useContext(DatabaseContext);\r\n return isConfigured;\r\n}\r\n","export class DatabaseError extends Error {\r\n readonly code: string;\r\n readonly statusCode: number;\r\n\r\n constructor(message: string, code = 'DATABASE_ERROR', statusCode = 500) {\r\n super(message);\r\n this.name = 'DatabaseError';\r\n this.code = code;\r\n this.statusCode = statusCode;\r\n }\r\n}\r\n\r\nexport class QueryError extends DatabaseError {\r\n readonly sql?: string;\r\n\r\n constructor(message: string, sql?: string) {\r\n super(message, 'QUERY_ERROR', 400);\r\n this.name = 'QueryError';\r\n this.sql = sql;\r\n }\r\n}\r\n\r\nexport class ValidationError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'VALIDATION_ERROR', 422);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\nexport class ConnectionError extends DatabaseError {\r\n constructor(message: string) {\r\n super(message, 'CONNECTION_ERROR', 503);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\nexport class NotFoundError extends DatabaseError {\r\n constructor(message = 'Record not found') {\r\n super(message, 'NOT_FOUND', 404);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\nexport function mapRpcError(rpcResult: { success: boolean; error?: string; code?: string }): DatabaseError | null {\r\n if (rpcResult.success) return null;\r\n const msg = rpcResult.error || 'Unknown database error';\r\n if (msg.includes('No database schema exists')) return new NotFoundError(msg);\r\n if (msg.includes('Authentication required')) return new ConnectionError(msg);\r\n if (msg.includes('blocked') || msg.includes('forbidden')) return new ValidationError(msg);\r\n return new QueryError(msg);\r\n}\r\n","import type { SupabaseClient } from '@supabase/supabase-js';\r\nimport type { DatabaseResult, SingleResult, MutationResult, FilterValue, OrderOption } from './types';\r\nimport { QueryError, ValidationError, mapRpcError } from './errors';\r\n\r\nfunction escapeSqlValue(value: FilterValue): string {\r\n if (value === null) return 'NULL';\r\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\r\n if (typeof value === 'number') {\r\n if (!Number.isFinite(value)) throw new ValidationError('Non-finite numbers are not allowed');\r\n return String(value);\r\n }\r\n return `'${String(value).replace(/'/g, \"''\")}'`;\r\n}\r\n\r\nfunction escapeIdentifier(name: string): string {\r\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\r\n throw new ValidationError(`Invalid identifier: ${name}`);\r\n }\r\n return `\"${name}\"`;\r\n}\r\n\r\ntype Operation = 'select' | 'insert' | 'update' | 'delete' | 'count' | 'upsert';\r\n\r\ninterface Filter {\r\n column: string;\r\n op: string;\r\n value: FilterValue | FilterValue[];\r\n}\r\n\r\nexport interface ServerProxy {\r\n serverQuery: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n serverExec: (sql: string) => Promise<{ success: boolean; data?: unknown[]; rowCount?: number; error?: string; schema?: string }>;\r\n}\r\n\r\nexport class QueryBuilder<T = Record<string, unknown>> {\r\n private readonly supabase: SupabaseClient;\r\n private readonly projectId: string;\r\n private readonly table: string;\r\n private readonly serverProxy?: ServerProxy;\r\n\r\n private operation: Operation = 'select';\r\n private selectColumns = '*';\r\n private filters: Filter[] = [];\r\n private orderClauses: string[] = [];\r\n private limitValue: number | null = null;\r\n private offsetValue: number | null = null;\r\n private insertData: Record<string, FilterValue>[] | null = null;\r\n private updateData: Record<string, FilterValue> | null = null;\r\n private upsertConflict: string | null = null;\r\n private singleMode = false;\r\n private maybeSingleMode = false;\r\n\r\n constructor(supabase: SupabaseClient, projectId: string, table: string, serverProxy?: ServerProxy) {\r\n this.supabase = supabase;\r\n this.projectId = projectId;\r\n this.table = table;\r\n this.serverProxy = serverProxy;\r\n }\r\n\r\n select(columns = '*'): this {\r\n this.operation = 'select';\r\n this.selectColumns = columns;\r\n return this;\r\n }\r\n\r\n // --- Filters ---\r\n\r\n eq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '=', value });\r\n return this;\r\n }\r\n\r\n neq(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '!=', value });\r\n return this;\r\n }\r\n\r\n gt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>', value });\r\n return this;\r\n }\r\n\r\n lt(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<', value });\r\n return this;\r\n }\r\n\r\n gte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '>=', value });\r\n return this;\r\n }\r\n\r\n lte(column: string, value: FilterValue): this {\r\n this.filters.push({ column, op: '<=', value });\r\n return this;\r\n }\r\n\r\n like(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'LIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n ilike(column: string, pattern: string): this {\r\n this.filters.push({ column, op: 'ILIKE', value: pattern });\r\n return this;\r\n }\r\n\r\n in(column: string, values: FilterValue[]): this {\r\n this.filters.push({ column, op: 'IN', value: values });\r\n return this;\r\n }\r\n\r\n is(column: string, value: null | boolean): this {\r\n this.filters.push({ column, op: 'IS', value });\r\n return this;\r\n }\r\n\r\n // --- Ordering & Pagination ---\r\n\r\n order(column: string, options: OrderOption = {}): this {\r\n const dir = options.ascending === false ? 'DESC' : 'ASC';\r\n const nulls = options.nullsFirst ? 'NULLS FIRST' : 'NULLS LAST';\r\n this.orderClauses.push(`${escapeIdentifier(column)} ${dir} ${nulls}`);\r\n return this;\r\n }\r\n\r\n limit(count: number): this {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n offset(count: number): this {\r\n this.offsetValue = count;\r\n return this;\r\n }\r\n\r\n // --- Mutations ---\r\n\r\n insert(records: Record<string, FilterValue> | Record<string, FilterValue>[]): this {\r\n this.operation = 'insert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n return this;\r\n }\r\n\r\n update(values: Record<string, FilterValue>): this {\r\n this.operation = 'update';\r\n this.updateData = values;\r\n return this;\r\n }\r\n\r\n delete(): this {\r\n this.operation = 'delete';\r\n return this;\r\n }\r\n\r\n upsert(records: Record<string, FilterValue> | Record<string, FilterValue>[], options?: { onConflict?: string }): this {\r\n this.operation = 'upsert';\r\n this.insertData = Array.isArray(records) ? records : [records];\r\n this.upsertConflict = options?.onConflict || null;\r\n return this;\r\n }\r\n\r\n // --- Result Helpers ---\r\n\r\n count(): QueryBuilder<{ count: number }> {\r\n this.operation = 'count';\r\n return this as unknown as QueryBuilder<{ count: number }>;\r\n }\r\n\r\n single(): QueryBuilder<T> {\r\n this.singleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n maybeSingle(): QueryBuilder<T> {\r\n this.maybeSingleMode = true;\r\n this.limitValue = 1;\r\n return this;\r\n }\r\n\r\n // --- SQL Building ---\r\n\r\n private buildWhereClause(): string {\r\n if (this.filters.length === 0) return '';\r\n const conditions = this.filters.map((f) => {\r\n const col = escapeIdentifier(f.column);\r\n if (f.op === 'IS') {\r\n const val = f.value === null ? 'NULL' : f.value ? 'TRUE' : 'FALSE';\r\n return `${col} IS ${val}`;\r\n }\r\n if (f.op === 'IN') {\r\n const vals = (f.value as FilterValue[]).map(escapeSqlValue).join(', ');\r\n return `${col} IN (${vals})`;\r\n }\r\n return `${col} ${f.op} ${escapeSqlValue(f.value as FilterValue)}`;\r\n });\r\n return ` WHERE ${conditions.join(' AND ')}`;\r\n }\r\n\r\n private buildSelectSql(): string {\r\n let sql = `SELECT ${this.selectColumns} FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n if (this.orderClauses.length > 0) sql += ` ORDER BY ${this.orderClauses.join(', ')}`;\r\n if (this.limitValue !== null) sql += ` LIMIT ${this.limitValue}`;\r\n if (this.offsetValue !== null && this.offsetValue > 0) sql += ` OFFSET ${this.offsetValue}`;\r\n return sql;\r\n }\r\n\r\n private buildCountSql(): string {\r\n let sql = `SELECT COUNT(*) as count FROM \"${this.table}\"`;\r\n sql += this.buildWhereClause();\r\n return sql;\r\n }\r\n\r\n private buildInsertSql(): string {\r\n if (!this.insertData || this.insertData.length === 0) {\r\n throw new ValidationError('No data provided for insert');\r\n }\r\n const columns = Object.keys(this.insertData[0]);\r\n const colList = columns.map(escapeIdentifier).join(', ');\r\n const rows = this.insertData.map(\r\n (row) => `(${columns.map((c) => escapeSqlValue(row[c] ?? null)).join(', ')})`\r\n );\r\n return `INSERT INTO \"${this.table}\" (${colList}) VALUES ${rows.join(', ')}`;\r\n }\r\n\r\n private buildUpsertSql(): string {\r\n let sql = this.buildInsertSql();\r\n const conflict = this.upsertConflict || 'id';\r\n const columns = Object.keys(this.insertData![0]);\r\n const updateCols = columns\r\n .filter((c) => c !== conflict)\r\n .map((c) => `${escapeIdentifier(c)} = EXCLUDED.${escapeIdentifier(c)}`)\r\n .join(', ');\r\n sql += ` ON CONFLICT (${escapeIdentifier(conflict)}) DO UPDATE SET ${updateCols}`;\r\n return sql;\r\n }\r\n\r\n private buildUpdateSql(): string {\r\n if (!this.updateData || Object.keys(this.updateData).length === 0) {\r\n throw new ValidationError('No data provided for update');\r\n }\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('UPDATE without filters is not allowed — add .eq() or other filters');\r\n }\r\n const setClauses = Object.entries(this.updateData)\r\n .map(([col, val]) => `${escapeIdentifier(col)} = ${escapeSqlValue(val)}`)\r\n .join(', ');\r\n return `UPDATE \"${this.table}\" SET ${setClauses}${this.buildWhereClause()}`;\r\n }\r\n\r\n private buildDeleteSql(): string {\r\n if (this.filters.length === 0) {\r\n throw new ValidationError('DELETE without filters is not allowed — add .eq() or other filters');\r\n }\r\n return `DELETE FROM \"${this.table}\"${this.buildWhereClause()}`;\r\n }\r\n\r\n // --- Execution ---\r\n\r\n private async executeQuery(): Promise<DatabaseResult<T>> {\r\n const isRead = this.operation === 'select' || this.operation === 'count';\r\n\r\n let sql: string;\r\n switch (this.operation) {\r\n case 'select': sql = this.buildSelectSql(); break;\r\n case 'count': sql = this.buildCountSql(); break;\r\n case 'insert': sql = this.buildInsertSql(); break;\r\n case 'upsert': sql = this.buildUpsertSql(); break;\r\n case 'update': sql = this.buildUpdateSql(); break;\r\n case 'delete': sql = this.buildDeleteSql(); break;\r\n default: throw new QueryError(`Unknown operation: ${this.operation}`);\r\n }\r\n\r\n if (this.serverProxy) {\r\n const fn = isRead ? this.serverProxy.serverQuery : this.serverProxy.serverExec;\r\n const data = await fn(sql);\r\n if (!data.success) {\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || 'Query failed', sql);\r\n }\r\n return {\r\n success: true,\r\n data: (isRead ? data.data || [] : []) as T[],\r\n rowCount: data.rowCount ?? (isRead ? (data.data?.length || 0) : 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n const rpcName = isRead ? 'sdk_query_project' : 'sdk_exec_project';\r\n const { data, error } = await this.supabase.rpc(rpcName, {\r\n p_project_id: this.projectId,\r\n p_sql: sql,\r\n });\r\n\r\n if (error) {\r\n throw new QueryError(error.message, sql);\r\n }\r\n\r\n if (!data.success) {\r\n const dbError = mapRpcError(data);\r\n if (dbError) throw dbError;\r\n throw new QueryError(data.error || 'Query failed', sql);\r\n }\r\n\r\n if (isRead) {\r\n return {\r\n success: true,\r\n data: data.data || [],\r\n rowCount: data.rowCount ?? (data.data?.length || 0),\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n return {\r\n success: true,\r\n data: [],\r\n rowCount: data.rowCount ?? 0,\r\n schema: data.schema,\r\n };\r\n }\r\n\r\n then<TResult1 = DatabaseResult<T> | SingleResult<T>, TResult2 = never>(\r\n onfulfilled?: ((value: DatabaseResult<T> | SingleResult<T>) => TResult1 | PromiseLike<TResult1>) | null,\r\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\r\n ): Promise<TResult1 | TResult2> {\r\n const promise = this.executeQuery().then((result) => {\r\n if (this.singleMode) {\r\n if (result.data.length === 0) {\r\n throw new QueryError('Expected exactly one row, got 0');\r\n }\r\n return { success: true, data: result.data[0], error: undefined } as SingleResult<T>;\r\n }\r\n if (this.maybeSingleMode) {\r\n return {\r\n success: true,\r\n data: result.data.length > 0 ? result.data[0] : null,\r\n error: undefined,\r\n } as SingleResult<T>;\r\n }\r\n return result;\r\n });\r\n return promise.then(onfulfilled, onrejected);\r\n }\r\n}\r\n","import type { SupabaseClient } from '@supabase/supabase-js';\nimport type { DatabaseResult, MutationResult, SchemaInfo } from './types';\nimport { QueryBuilder, type ServerProxy } from './QueryBuilder';\nimport { QueryError, ConnectionError } from './errors';\nimport { ezcoder } from '../core/platform';\nimport { features } from '../core/config';\n\nfunction trackDbEvent(event: string, props: Record<string, unknown>) {\n if (!features.analytics) return;\n try { ezcoder.analytics.track(event, props); } catch { /* non-critical */ }\n}\n\ninterface ServerProxyResult {\n success: boolean;\n data?: unknown[];\n rowCount?: number;\n error?: string;\n schema?: string;\n exists?: boolean;\n tables?: unknown[];\n tablesCount?: number;\n createdAt?: string;\n lastAccessedAt?: string;\n executed_sql?: string;\n}\n\nconst MAX_RETRIES = 3;\nconst SERVER_TIMEOUT_MS = 5000;\n\nexport class DatabaseClient {\n private readonly supabase: SupabaseClient | null;\n private readonly projectId: string;\n private apiKey?: string;\n private platformUrl?: string;\n private serverMode: boolean = false;\n\n constructor(supabase: SupabaseClient | null, projectId: string) {\n this.supabase = supabase;\n this.projectId = projectId;\n }\n\n static createServerClient(\n projectId: string,\n apiKey: string,\n platformUrl?: string\n ): DatabaseClient {\n const client = new DatabaseClient(null, projectId);\n client.apiKey = apiKey;\n client.platformUrl = platformUrl\n || (typeof process !== 'undefined' && process.env?.EZCODER_API_URL)\n || 'https://ezcoder.app';\n client.serverMode = true;\n return client;\n }\n\n from<T = Record<string, unknown>>(table: string): QueryBuilder<T> {\n if (this.serverMode) {\n return new QueryBuilder<T>(null as unknown as SupabaseClient, this.projectId, table, {\n serverQuery: (sql: string) => this._serverRequest('/query', sql),\n serverExec: (sql: string) => this._serverRequest('/execute', sql),\n });\n }\n return new QueryBuilder<T>(this.supabase!, this.projectId, table);\n }\n\n async sql<T = Record<string, unknown>>(query: string): Promise<DatabaseResult<T>> {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed.startsWith('select')) {\n throw new QueryError('sql() is for read-only queries. Use execute() for mutations.');\n }\n\n if (this.serverMode) {\n return this._serverQuery<T>(query);\n }\n\n const start = Date.now();\n const { data, error } = await this.supabase!.rpc('sdk_query_project', {\n p_project_id: this.projectId,\n p_sql: query,\n });\n const latencyMs = Date.now() - start;\n\n if (error) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: error.message });\n throw new QueryError(error.message, query);\n }\n if (!data.success) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: data.error });\n throw new QueryError(data.error || 'Query failed', query);\n }\n\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0 });\n\n return {\n success: true,\n data: data.data || [],\n rowCount: data.rowCount ?? (data.data?.length || 0),\n schema: data.schema,\n };\n }\n\n async execute(sql: string): Promise<MutationResult> {\n if (this.serverMode) {\n return this._serverExecute(sql);\n }\n\n const start = Date.now();\n const { data, error } = await this.supabase!.rpc('sdk_exec_project', {\n p_project_id: this.projectId,\n p_sql: sql,\n });\n const latencyMs = Date.now() - start;\n\n if (error) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: error.message });\n throw new QueryError(error.message, sql);\n }\n if (!data.success) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: data.error });\n throw new QueryError(data.error || 'Execution failed', sql);\n }\n\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: true, rowCount: data.rowCount ?? 0 });\n\n return {\n success: true,\n rowCount: data.rowCount ?? 0,\n schema: data.schema,\n executed_sql: data.executed_sql,\n };\n }\n\n async getSchema(): Promise<SchemaInfo> {\n if (this.serverMode) {\n return this._serverGetSchema();\n }\n\n const { data, error } = await this.supabase!.rpc('sdk_get_schema_info', {\n p_project_id: this.projectId,\n });\n\n if (error) throw new ConnectionError(error.message);\n\n return {\n exists: data.exists ?? false,\n schema: data.schema,\n tables: data.tables || [],\n tablesCount: data.tablesCount ?? 0,\n createdAt: data.createdAt,\n lastAccessedAt: data.lastAccessedAt,\n };\n }\n\n private async _serverRequest(endpoint: string, sql: string): Promise<ServerProxyResult> {\n const url = `${this.platformUrl}/api/platform/db/${this.projectId}${endpoint}`;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ sql }),\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n\n if (res.status === 429) {\n const retryAfter = parseInt(res.headers.get('retry-after') || '60', 10);\n await new Promise(r => setTimeout(r, retryAfter * 1000));\n continue;\n }\n if (res.status === 503) {\n await new Promise(r => setTimeout(r, (attempt + 1) * 2000));\n continue;\n }\n\n return await res.json() as ServerProxyResult;\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n return { success: false, error: lastError?.message || 'Request failed after retries' };\n }\n\n private async _serverQuery<T>(query: string): Promise<DatabaseResult<T>> {\n const start = Date.now();\n const result = await this._serverRequest('/query', query);\n const latencyMs = Date.now() - start;\n\n if (!result.success) {\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: false, error: result.error, serverMode: true });\n throw new QueryError(result.error || 'Query failed', query);\n }\n\n trackDbEvent('db_query', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0, serverMode: true });\n\n return {\n success: true,\n data: (result.data || []) as T[],\n rowCount: result.rowCount ?? ((result.data as unknown[])?.length || 0),\n schema: result.schema,\n };\n }\n\n private async _serverExecute(sql: string): Promise<MutationResult> {\n const start = Date.now();\n const result = await this._serverRequest('/execute', sql);\n const latencyMs = Date.now() - start;\n\n if (!result.success) {\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: false, error: result.error, serverMode: true });\n throw new QueryError(result.error || 'Execution failed', sql);\n }\n\n trackDbEvent('db_mutation', { projectId: this.projectId, latencyMs, success: true, rowCount: result.rowCount ?? 0, serverMode: true });\n\n return {\n success: true,\n rowCount: result.rowCount ?? 0,\n schema: result.schema,\n executed_sql: result.executed_sql,\n };\n }\n\n private async _serverGetSchema(): Promise<SchemaInfo> {\n const url = `${this.platformUrl}/api/platform/db/${this.projectId}/schema`;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${this.apiKey}` },\n signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),\n });\n\n if (res.status === 503) {\n await new Promise(r => setTimeout(r, (attempt + 1) * 2000));\n continue;\n }\n\n const data = await res.json() as ServerProxyResult;\n if (!data.success) throw new ConnectionError(data.error || 'Schema fetch failed');\n\n return {\n exists: data.exists ?? false,\n schema: data.schema,\n tables: (data.tables || []) as SchemaInfo['tables'],\n tablesCount: data.tablesCount ?? 0,\n createdAt: data.createdAt,\n lastAccessedAt: data.lastAccessedAt,\n };\n } catch (e) {\n lastError = e instanceof Error ? e : new Error(String(e));\n }\n }\n\n throw new ConnectionError(lastError?.message || 'Schema request failed after retries');\n }\n}\n","import { useEffect, useState, useRef } from 'react';\r\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\r\nimport { env } from '../core/config';\r\n\r\ntype RealtimeEvent = 'INSERT' | 'UPDATE' | 'DELETE' | '*';\r\n\r\ninterface RealtimeOptions {\r\n event?: RealtimeEvent;\r\n filter?: string;\r\n}\r\n\r\ninterface UseRealtimeReturn<T> {\r\n data: T[];\r\n status: 'connecting' | 'connected' | 'error' | 'disabled';\r\n setData: React.Dispatch<React.SetStateAction<T[]>>;\r\n}\r\n\r\nexport function useRealtime<T extends Record<string, unknown> = Record<string, unknown>>(\r\n table: string,\r\n options: RealtimeOptions = {},\r\n): UseRealtimeReturn<T> {\r\n const [data, setData] = useState<T[]>([]);\r\n const [status, setStatus] = useState<UseRealtimeReturn<T>['status']>('connecting');\r\n const optionsRef = useRef(options);\r\n optionsRef.current = options;\r\n\r\n const projectId = env.EZC_PROJECT_ID;\r\n\r\n useEffect(() => {\r\n if (!isSupabaseConfigured || !projectId) {\r\n setStatus('disabled');\r\n return;\r\n }\r\n\r\n const schemaName = `proj_${projectId.replace(/-/g, '_')}`;\r\n const channelName = `${schemaName}_${table}_${optionsRef.current.event || 'all'}`;\r\n\r\n const channel = supabase\r\n .channel(channelName)\r\n .on(\r\n 'postgres_changes' as never,\r\n {\r\n event: optionsRef.current.event || '*',\r\n schema: schemaName,\r\n table,\r\n filter: optionsRef.current.filter,\r\n } as never,\r\n (payload: { eventType: string; new: Record<string, unknown>; old: Record<string, unknown> }) => {\r\n if (payload.eventType === 'INSERT') {\r\n setData((prev) => [...prev, payload.new as T]);\r\n } else if (payload.eventType === 'UPDATE') {\r\n setData((prev) =>\r\n prev.map((item) =>\r\n (item as Record<string, unknown>).id === (payload.new as Record<string, unknown>).id\r\n ? (payload.new as T)\r\n : item,\r\n ),\r\n );\r\n } else if (payload.eventType === 'DELETE') {\r\n setData((prev) =>\r\n prev.filter(\r\n (item) =>\r\n (item as Record<string, unknown>).id !== (payload.old as Record<string, unknown>).id,\r\n ),\r\n );\r\n }\r\n },\r\n )\r\n .subscribe((subStatus: string) => {\r\n setStatus(subStatus === 'SUBSCRIBED' ? 'connected' : 'connecting');\r\n });\r\n\r\n return () => {\r\n supabase.removeChannel(channel);\r\n };\r\n }, [projectId, table]);\r\n\r\n return { data, status, setData };\r\n}\r\n"],"mappings":"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","names":["supabase","data","supabase"]}