@resultdev/sdk 0.1.0 → 0.3.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.
@@ -0,0 +1,1087 @@
1
+ import { e as AuthSession, U as UserSchema, a as ResultConfig, G as AuthRefreshResponse, C as ChatCompletionRequest, B as ToolCall, H as Annotation, I as ImageGenerationRequest, j as EmbeddingsRequest, J as EmbeddingObject, h as CreateUserRequest, K as CreateUserResponse, o as ResultError, g as CreateSessionRequest, L as CreateSessionResponse, l as OAuthProvidersSchema, M as RefreshSessionResponse, N as GetProfileResponse, Q as SendVerificationEmailRequest, V as VerifyEmailRequest, W as VerifyEmailResponse, X as SendResetPasswordEmailRequest, Y as ExchangeResetPasswordTokenRequest, Z as ExchangeResetPasswordTokenResponse, _ as ResetPasswordResponse, $ as GetPublicAuthConfigResponse, S as SendRawEmailRequest, q as SendEmailResponse, v as SubscribeResponse, r as SocketMessage, P as PresenceMember, u as StorageFileSchema, a0 as ListObjectsResponseSchema, i as DeleteObjectsResponse, A as Analytics, w as Support } from './types-DSVtGaIA.js';
2
+ import * as _supabase_postgrest_js from '@supabase/postgrest-js';
3
+ import { PostgrestClient } from '@supabase/postgrest-js';
4
+
5
+ type LogFunction = (message: string, ...args: any[]) => void;
6
+ /**
7
+ * Debug logger for the Result SDK.
8
+ * Logs HTTP request/response details with automatic redaction of sensitive data.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Enable via SDK config
13
+ * const client = new ResultClient({ debug: true });
14
+ *
15
+ * // Or with a custom log function
16
+ * const client = new ResultClient({
17
+ * debug: (msg) => myLogger.info(msg)
18
+ * });
19
+ * ```
20
+ */
21
+ declare class Logger {
22
+ /** Whether debug logging is currently enabled */
23
+ enabled: boolean;
24
+ private customLog;
25
+ /**
26
+ * Creates a new Logger instance.
27
+ * @param debug - Set to true to enable console logging, or pass a custom log function
28
+ */
29
+ constructor(debug?: boolean | LogFunction);
30
+ /**
31
+ * Logs a debug message at the info level.
32
+ * @param message - The message to log
33
+ * @param args - Additional arguments to pass to the log function
34
+ */
35
+ log(message: string, ...args: any[]): void;
36
+ /**
37
+ * Logs a debug message at the warning level.
38
+ * @param message - The message to log
39
+ * @param args - Additional arguments to pass to the log function
40
+ */
41
+ warn(message: string, ...args: any[]): void;
42
+ /**
43
+ * Logs a debug message at the error level.
44
+ * @param message - The message to log
45
+ * @param args - Additional arguments to pass to the log function
46
+ */
47
+ error(message: string, ...args: any[]): void;
48
+ /**
49
+ * Logs an outgoing HTTP request with method, URL, headers, and body.
50
+ * Sensitive headers and body fields are automatically redacted.
51
+ * @param method - HTTP method (GET, POST, etc.)
52
+ * @param url - The full request URL
53
+ * @param headers - Request headers (sensitive values will be redacted)
54
+ * @param body - Request body (sensitive fields will be masked)
55
+ */
56
+ logRequest(method: string, url: string, headers?: Record<string, string>, body?: any): void;
57
+ /**
58
+ * Logs an incoming HTTP response with method, URL, status, duration, and body.
59
+ * Error responses (4xx/5xx) are logged at the error level.
60
+ * @param method - HTTP method (GET, POST, etc.)
61
+ * @param url - The full request URL
62
+ * @param status - HTTP response status code
63
+ * @param durationMs - Request duration in milliseconds
64
+ * @param body - Response body (sensitive fields will be masked, large bodies truncated)
65
+ */
66
+ logResponse(method: string, url: string, status: number, durationMs: number, body?: any): void;
67
+ }
68
+
69
+ /**
70
+ * Token Manager for Result SDK
71
+ *
72
+ * Memory-only token storage.
73
+ */
74
+
75
+ declare const AuthChangeEvent: {
76
+ readonly SIGNED_IN: "signedIn";
77
+ readonly SIGNED_OUT: "signedOut";
78
+ readonly TOKEN_REFRESHED: "tokenRefreshed";
79
+ };
80
+ type AuthChangeEvent = (typeof AuthChangeEvent)[keyof typeof AuthChangeEvent];
81
+ type AuthStateChangeCallback = (event: AuthChangeEvent) => void;
82
+ declare class TokenManager {
83
+ private accessToken;
84
+ private user;
85
+ private authStateChangeCallbacks;
86
+ /**
87
+ * Save session in memory
88
+ */
89
+ saveSession(session: AuthSession, event?: AuthChangeEvent): void;
90
+ /**
91
+ * Get current session
92
+ */
93
+ getSession(): AuthSession | null;
94
+ /**
95
+ * Get access token
96
+ */
97
+ getAccessToken(): string | null;
98
+ /**
99
+ * Set access token
100
+ */
101
+ setAccessToken(token: string, event?: AuthChangeEvent): void;
102
+ /**
103
+ * Get user
104
+ */
105
+ getUser(): UserSchema | null;
106
+ /**
107
+ * Set user
108
+ */
109
+ setUser(user: UserSchema): void;
110
+ /**
111
+ * Clear in-memory session
112
+ */
113
+ clearSession(): void;
114
+ onAuthStateChange(callback: AuthStateChangeCallback): () => void;
115
+ private notifyAuthStateChange;
116
+ }
117
+
118
+ type JsonRequestBody = Record<string, unknown> | unknown[] | null;
119
+ interface RequestOptions extends Omit<RequestInit, "body"> {
120
+ params?: Record<string, string>;
121
+ body?: RequestInit["body"] | JsonRequestBody;
122
+ /** Allow retrying non-idempotent requests (POST, PATCH). Off by default to prevent duplicate writes. */
123
+ idempotent?: boolean;
124
+ /** Disable automatic access-token refresh for auth/control-flow requests. */
125
+ skipAuthRefresh?: boolean;
126
+ }
127
+ /**
128
+ * HTTP client with built-in retry, timeout, and exponential backoff support.
129
+ * Handles authentication, request serialization, and error normalization.
130
+ */
131
+ declare class HttpClient {
132
+ readonly baseUrl: string;
133
+ readonly fetch: typeof fetch;
134
+ private readonly config;
135
+ private defaultHeaders;
136
+ private anonKey;
137
+ private userToken;
138
+ private logger;
139
+ private isRefreshing;
140
+ private refreshPromise;
141
+ private tokenManager;
142
+ private refreshToken;
143
+ private timeout;
144
+ private retryCount;
145
+ private retryDelay;
146
+ /**
147
+ * Creates a new HttpClient instance.
148
+ * @param config - SDK configuration including baseUrl, timeout, retry settings, and fetch implementation.
149
+ * @param tokenManager - Token manager for session persistence.
150
+ * @param logger - Optional logger instance for request/response debugging.
151
+ */
152
+ constructor(config: ResultConfig, tokenManager?: TokenManager, logger?: Logger);
153
+ /**
154
+ * Builds a full URL from a path and optional query parameters.
155
+ * Normalizes PostgREST select parameters for proper syntax.
156
+ */
157
+ private buildUrl;
158
+ /** Checks if an HTTP status code is eligible for retry (5xx server errors). */
159
+ private isRetryableStatus;
160
+ /**
161
+ * Computes the delay before the next retry using exponential backoff with jitter.
162
+ * @param attempt - The current retry attempt number (1-based).
163
+ * @returns Delay in milliseconds.
164
+ */
165
+ private computeRetryDelay;
166
+ private shouldRefreshAccessToken;
167
+ private fetchWithRetry;
168
+ /**
169
+ * Performs an HTTP request with automatic retry and timeout handling.
170
+ * Retries on network errors and 5xx server errors with exponential backoff.
171
+ * Client errors (4xx) and timeouts are thrown immediately without retry.
172
+ * @param method - HTTP method (GET, POST, PUT, PATCH, DELETE).
173
+ * @param path - API path relative to the base URL.
174
+ * @param options - Optional request configuration including headers, body, and query params.
175
+ * @returns Parsed response data.
176
+ * @throws {ResultError} On timeout, network failure, or HTTP error responses.
177
+ */
178
+ private handleRequest;
179
+ request<T>(method: string, path: string, options?: RequestOptions): Promise<T>;
180
+ /**
181
+ * Performs an SDK-configured fetch and returns the raw Response.
182
+ * This is used by clients such as postgrest-js that need to own response
183
+ * parsing while still sharing SDK auth and refresh behavior.
184
+ */
185
+ rawFetch(input: RequestInfo | URL, init?: RequestInit, options?: {
186
+ skipAuthRefresh?: boolean;
187
+ }): Promise<Response>;
188
+ /** Performs a GET request. */
189
+ get<T>(path: string, options?: RequestOptions): Promise<T>;
190
+ /** Performs a POST request with an optional JSON body. */
191
+ post<T>(path: string, body?: any, options?: RequestOptions): Promise<T>;
192
+ /** Performs a PUT request with an optional JSON body. */
193
+ put<T>(path: string, body?: any, options?: RequestOptions): Promise<T>;
194
+ /** Performs a PATCH request with an optional JSON body. */
195
+ patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T>;
196
+ /** Performs a DELETE request. */
197
+ delete<T>(path: string, options?: RequestOptions): Promise<T>;
198
+ /** Sets or clears the user authentication token for subsequent requests. */
199
+ setAuthToken(token: string | null): void;
200
+ setRefreshToken(token: string | null): void;
201
+ /** Returns the current default headers including the authorization header if set. */
202
+ getHeaders(): Record<string, string>;
203
+ refreshAccessToken(): Promise<AuthRefreshResponse>;
204
+ /** Returns a token safe to use for a new connection handshake. */
205
+ getValidAccessToken(leewaySeconds?: number): Promise<string | null>;
206
+ private refreshAndSaveSession;
207
+ private clearAuthSession;
208
+ }
209
+
210
+ /**
211
+ * AI Module for Result SDK
212
+ * Response format roughly matches OpenAI SDK for compatibility
213
+ *
214
+ * The backend handles all the complexity of different AI providers
215
+ * and returns a unified format. This SDK transforms responses to match OpenAI-like format.
216
+ */
217
+
218
+ interface ChatCompletionUsage {
219
+ prompt_tokens: number;
220
+ completion_tokens: number;
221
+ total_tokens: number;
222
+ }
223
+ interface ChatCompletionChoice {
224
+ index: number;
225
+ message: {
226
+ role: "assistant";
227
+ content: string;
228
+ tool_calls?: ToolCall[];
229
+ annotations?: Annotation[];
230
+ };
231
+ finish_reason: "stop" | "tool_calls";
232
+ }
233
+ interface ChatCompletion {
234
+ id: string;
235
+ object: "chat.completion";
236
+ created: number;
237
+ model?: string;
238
+ choices: ChatCompletionChoice[];
239
+ usage: ChatCompletionUsage;
240
+ }
241
+ interface ChatCompletionChunk {
242
+ id: string;
243
+ object: "chat.completion.chunk";
244
+ created: number;
245
+ model: string;
246
+ choices: {
247
+ index: number;
248
+ delta: {
249
+ content?: string;
250
+ tool_calls?: ToolCall[];
251
+ /** Web-search/file citations; arrives in a trailing chunk. */
252
+ annotations?: Annotation[];
253
+ };
254
+ finish_reason: "tool_calls" | null;
255
+ }[];
256
+ /** Token usage; arrives in a trailing chunk with empty choices. */
257
+ usage?: ChatCompletionUsage;
258
+ }
259
+ interface EmbeddingsResult {
260
+ object: "list";
261
+ data: EmbeddingObject[];
262
+ model?: string;
263
+ usage: {
264
+ prompt_tokens: number;
265
+ total_tokens: number;
266
+ };
267
+ }
268
+ interface ImageGenerationResult {
269
+ created: number;
270
+ data: {
271
+ b64_json?: string;
272
+ content?: string;
273
+ }[];
274
+ usage?: {
275
+ total_tokens: number;
276
+ input_tokens: number;
277
+ output_tokens: number;
278
+ };
279
+ }
280
+ declare class AI {
281
+ readonly chat: Chat;
282
+ readonly images: Images;
283
+ readonly embeddings: Embeddings;
284
+ constructor(http: HttpClient);
285
+ }
286
+ declare class Chat {
287
+ readonly completions: ChatCompletions;
288
+ constructor(http: HttpClient);
289
+ }
290
+ declare class ChatCompletions {
291
+ private http;
292
+ constructor(http: HttpClient);
293
+ /**
294
+ * Create a chat completion - OpenAI-like response format
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * // Non-streaming
299
+ * const completion = await client.ai.chat.completions.create({
300
+ * model: 'openai/gpt-4o-mini',
301
+ * messages: [{ role: 'user', content: 'Hello!' }]
302
+ * });
303
+ * console.log(completion.choices[0].message.content);
304
+ *
305
+ * // With images. google/gemini-2.5-flash is the verified multimodal
306
+ * // model (openai/gpt-4o and gpt-4o-mini also accept images, but audio
307
+ * // requires gemini). URLs and base64 data URIs both work.
308
+ * const response = await client.ai.chat.completions.create({
309
+ * model: 'google/gemini-2.5-flash',
310
+ * messages: [{
311
+ * role: 'user',
312
+ * content: [
313
+ * { type: 'text', text: 'What is in this image?' },
314
+ * { type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }
315
+ * ]
316
+ * }]
317
+ * });
318
+ *
319
+ * // With audio. Base64 data in wav/mp3/aiff/aac/ogg/flac/m4a only -
320
+ * // browser MediaRecorder's webm/opus is rejected; record PCM via the
321
+ * // Web Audio API and encode a 16 kHz mono WAV instead.
322
+ * const audioResponse = await client.ai.chat.completions.create({
323
+ * model: 'google/gemini-2.5-flash',
324
+ * messages: [{
325
+ * role: 'user',
326
+ * content: [
327
+ * { type: 'text', text: 'Transcribe this recording' },
328
+ * { type: 'input_audio', input_audio: { data: base64Wav, format: 'wav' } }
329
+ * ]
330
+ * }]
331
+ * });
332
+ *
333
+ * // With web search. Non-streaming: citations arrive on
334
+ * // response.choices[0].message.annotations. Streaming: they arrive in a
335
+ * // trailing chunk as chunk.choices[0].delta.annotations.
336
+ * const searchResponse = await client.ai.chat.completions.create({
337
+ * model: 'openai/gpt-4o-mini',
338
+ * messages: [{ role: 'user', content: 'What are the latest news about AI?' }],
339
+ * webSearch: { enabled: true, maxResults: 5 }
340
+ * });
341
+ *
342
+ * // Streaming - returns async iterable
343
+ * const stream = await client.ai.chat.completions.create({
344
+ * model: 'openai/gpt-4o-mini',
345
+ * messages: [{ role: 'user', content: 'Tell me a story' }],
346
+ * stream: true
347
+ * });
348
+ *
349
+ * for await (const chunk of stream) {
350
+ * if (chunk.choices[0]?.delta?.content) {
351
+ * process.stdout.write(chunk.choices[0].delta.content);
352
+ * }
353
+ * }
354
+ * ```
355
+ */
356
+ create(params: ChatCompletionRequest & {
357
+ stream: true;
358
+ }): Promise<AsyncIterableIterator<ChatCompletionChunk>>;
359
+ create(params: ChatCompletionRequest & {
360
+ stream?: false;
361
+ }): Promise<ChatCompletion>;
362
+ create(params: ChatCompletionRequest): Promise<ChatCompletion | AsyncIterableIterator<ChatCompletionChunk>>;
363
+ /**
364
+ * Parse SSE stream into async iterable of OpenAI-like chunks
365
+ */
366
+ private parseSSEStream;
367
+ }
368
+ declare class Embeddings {
369
+ private http;
370
+ constructor(http: HttpClient);
371
+ /**
372
+ * Create embeddings for text input - OpenAI-like response format
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * // Single text input
377
+ * const response = await client.ai.embeddings.create({
378
+ * model: 'openai/text-embedding-3-small',
379
+ * input: 'Hello world'
380
+ * });
381
+ * console.log(response.data[0].embedding); // number[]
382
+ *
383
+ * // Multiple text inputs
384
+ * const response = await client.ai.embeddings.create({
385
+ * model: 'openai/text-embedding-3-small',
386
+ * input: ['Hello world', 'Goodbye world']
387
+ * });
388
+ * response.data.forEach((item, i) => {
389
+ * console.log(`Embedding ${i}:`, item.embedding.slice(0, 5)); // First 5 dimensions
390
+ * });
391
+ *
392
+ * // With custom dimensions (if supported by model)
393
+ * const response = await client.ai.embeddings.create({
394
+ * model: 'openai/text-embedding-3-small',
395
+ * input: 'Hello world',
396
+ * dimensions: 256
397
+ * });
398
+ *
399
+ * // With base64 encoding format
400
+ * const response = await client.ai.embeddings.create({
401
+ * model: 'openai/text-embedding-3-small',
402
+ * input: 'Hello world',
403
+ * encoding_format: 'base64'
404
+ * });
405
+ * ```
406
+ */
407
+ create(params: EmbeddingsRequest): Promise<EmbeddingsResult>;
408
+ }
409
+ declare class Images {
410
+ private http;
411
+ constructor(http: HttpClient);
412
+ /**
413
+ * Generate images - OpenAI-like response format
414
+ *
415
+ * @example
416
+ * ```typescript
417
+ * // Text-to-image
418
+ * const response = await client.ai.images.generate({
419
+ * model: 'dall-e-3',
420
+ * prompt: 'A sunset over mountains',
421
+ * });
422
+ * console.log(response.data[0].b64_json);
423
+ *
424
+ * // Image-to-image (with input images)
425
+ * const response = await client.ai.images.generate({
426
+ * model: 'stable-diffusion-xl',
427
+ * prompt: 'Transform this into a watercolor painting',
428
+ * images: [
429
+ * { url: 'https://example.com/input.jpg' },
430
+ * // or base64-encoded Data URI:
431
+ * { url: 'data:image/jpeg;base64,/9j/4AAQ...' }
432
+ * ]
433
+ * });
434
+ * ```
435
+ */
436
+ generate(params: ImageGenerationRequest): Promise<ImageGenerationResult>;
437
+ }
438
+
439
+ /**
440
+ * Auth module for Result SDK
441
+ * Handles authentication, sessions, profiles, and email verification
442
+ */
443
+
444
+ interface AuthOptions {
445
+ isServerMode?: boolean;
446
+ detectOAuthCallback?: boolean;
447
+ }
448
+ type OAuthSignInOptions = {
449
+ redirectTo: string;
450
+ additionalParams?: Record<string, string>;
451
+ skipBrowserRedirect?: boolean;
452
+ };
453
+ type OAuthSignInLegacyOptions = OAuthSignInOptions & {
454
+ provider: OAuthProvidersSchema | string;
455
+ };
456
+ /**
457
+ * Authentication client.
458
+ *
459
+ * Session model: the refresh token lives in an httpOnly cookie set by the
460
+ * backend (plus a CSRF cookie); the access token is held in memory and
461
+ * refreshed from that cookie. Nothing auth-related is written to
462
+ * localStorage, so an empty localStorage does NOT mean the user is signed
463
+ * out. Check state with getCurrentUser() or onAuthStateChange(), never by
464
+ * reading browser storage.
465
+ */
466
+ declare class Auth {
467
+ private http;
468
+ private tokenManager;
469
+ private options;
470
+ private authCallbackHandled;
471
+ constructor(http: HttpClient, tokenManager: TokenManager, options?: AuthOptions);
472
+ private isServerMode;
473
+ /** Subscribe to SDK authentication state changes. */
474
+ onAuthStateChange(callback: AuthStateChangeCallback): () => void;
475
+ /**
476
+ * Save session from API response
477
+ * Handles token storage, CSRF token, and HTTP auth header
478
+ */
479
+ private saveSessionFromResponse;
480
+ /**
481
+ * Detect and handle OAuth callback parameters in URL
482
+ * Supports the PKCE flow (OAuth callback code in the URL)
483
+ */
484
+ private detectAuthCallback;
485
+ signUp(request: CreateUserRequest): Promise<{
486
+ data: CreateUserResponse | null;
487
+ error: ResultError | null;
488
+ }>;
489
+ signInWithPassword(request: CreateSessionRequest): Promise<{
490
+ data: CreateSessionResponse | null;
491
+ error: ResultError | null;
492
+ }>;
493
+ signOut(): Promise<{
494
+ error: ResultError | null;
495
+ }>;
496
+ /**
497
+ * Sign in with OAuth provider using PKCE flow
498
+ */
499
+ signInWithOAuth(provider: OAuthProvidersSchema | string, options: OAuthSignInOptions): Promise<{
500
+ data: {
501
+ url?: string;
502
+ provider?: string;
503
+ codeVerifier?: string;
504
+ };
505
+ error: ResultError | null;
506
+ }>;
507
+ /**
508
+ * @deprecated Use signInWithOAuth(provider, { redirectTo, additionalParams, skipBrowserRedirect }).
509
+ */
510
+ signInWithOAuth(options: OAuthSignInLegacyOptions): Promise<{
511
+ data: {
512
+ url?: string;
513
+ provider?: string;
514
+ codeVerifier?: string;
515
+ };
516
+ error: ResultError | null;
517
+ }>;
518
+ /**
519
+ * Exchange OAuth authorization code for tokens (PKCE flow)
520
+ * Called automatically on initialization when the OAuth callback code is in the URL
521
+ */
522
+ exchangeOAuthCode(code: string, codeVerifier?: string): Promise<{
523
+ data: CreateSessionResponse | null;
524
+ error: ResultError | null;
525
+ }>;
526
+ /**
527
+ * Sign in with an ID token from a native SDK (Google One Tap, etc.)
528
+ * Use this for native mobile apps or Google One Tap on web.
529
+ *
530
+ * @param credentials.provider - The identity provider (currently only 'google' is supported)
531
+ * @param credentials.token - The ID token from the native SDK
532
+ */
533
+ signInWithIdToken(credentials: {
534
+ provider: "google";
535
+ token: string;
536
+ }): Promise<{
537
+ data: CreateSessionResponse | null;
538
+ error: ResultError | null;
539
+ }>;
540
+ /**
541
+ * Refresh the current auth session.
542
+ *
543
+ * Browser mode:
544
+ * - Uses httpOnly refresh cookie and optional CSRF header.
545
+ *
546
+ * Legacy server mode (`isServerMode: true`):
547
+ * - Uses mobile auth flow and requires `refreshToken` in request body.
548
+ *
549
+ * SSR apps should prefer `createRefreshAuthRouter()` / `refreshAuth()` from
550
+ * `@resultdev/sdk/ssr`.
551
+ */
552
+ refreshSession(options?: {
553
+ refreshToken?: string;
554
+ }): Promise<{
555
+ data: RefreshSessionResponse | null;
556
+ error: ResultError | null;
557
+ }>;
558
+ /**
559
+ * Get current user, automatically waits for pending OAuth callback
560
+ */
561
+ getCurrentUser(): Promise<{
562
+ data: {
563
+ user: UserSchema | null;
564
+ };
565
+ error: ResultError | null;
566
+ }>;
567
+ getProfile(userId: string): Promise<{
568
+ data: GetProfileResponse | null;
569
+ error: ResultError | null;
570
+ }>;
571
+ setProfile(profile: Record<string, unknown>): Promise<{
572
+ data: GetProfileResponse | null;
573
+ error: ResultError | null;
574
+ }>;
575
+ resendVerificationEmail(request: SendVerificationEmailRequest): Promise<{
576
+ data: {
577
+ success: boolean;
578
+ message: string;
579
+ } | null;
580
+ error: ResultError | null;
581
+ }>;
582
+ verifyEmail(request: VerifyEmailRequest): Promise<{
583
+ data: VerifyEmailResponse | null;
584
+ error: ResultError | null;
585
+ }>;
586
+ sendResetPasswordEmail(request: SendResetPasswordEmailRequest): Promise<{
587
+ data: {
588
+ success: boolean;
589
+ message: string;
590
+ } | null;
591
+ error: ResultError | null;
592
+ }>;
593
+ exchangeResetPasswordToken(request: ExchangeResetPasswordTokenRequest): Promise<{
594
+ data: ExchangeResetPasswordTokenResponse | null;
595
+ error: ResultError | null;
596
+ }>;
597
+ resetPassword(request: {
598
+ newPassword: string;
599
+ otp: string;
600
+ }): Promise<{
601
+ data: ResetPasswordResponse | null;
602
+ error: ResultError | null;
603
+ }>;
604
+ getPublicAuthConfig(): Promise<{
605
+ data: GetPublicAuthConfigResponse | null;
606
+ error: ResultError | null;
607
+ }>;
608
+ }
609
+
610
+ /**
611
+ * Database client using postgrest-js
612
+ * Drop-in replacement with FULL PostgREST capabilities
613
+ */
614
+ declare class Database {
615
+ private postgrest;
616
+ constructor(httpClient: HttpClient, defaultSchema?: string);
617
+ /**
618
+ * Select a non-default Postgres schema for the chained query. Maps to
619
+ * PostgREST's `Accept-Profile` (reads) / `Content-Profile` (writes) header.
620
+ * The schema must be exposed by the backend.
621
+ *
622
+ * @example
623
+ * const { data } = await client.database
624
+ * .schema('analytics')
625
+ * .from('events')
626
+ * .select('*');
627
+ *
628
+ * @example
629
+ * await client.database.schema('analytics').rpc('rollup', { day: '2026-01-01' });
630
+ */
631
+ schema(schemaName: string): PostgrestClient<any, any, string, any>;
632
+ /**
633
+ * Create a query builder for a table
634
+ *
635
+ * @example
636
+ * // Basic query
637
+ * const { data, error } = await client.database
638
+ * .from('posts')
639
+ * .select('*')
640
+ * .eq('user_id', userId);
641
+ *
642
+ * // With count (Supabase style!)
643
+ * const { data, error, count } = await client.database
644
+ * .from('posts')
645
+ * .select('*', { count: 'exact' })
646
+ * .range(0, 9);
647
+ *
648
+ * // Just get count, no data
649
+ * const { count } = await client.database
650
+ * .from('posts')
651
+ * .select('*', { count: 'exact', head: true });
652
+ *
653
+ * // Complex queries with OR
654
+ * const { data } = await client.database
655
+ * .from('posts')
656
+ * .select('*, users!inner(*)')
657
+ * .or('status.eq.active,status.eq.pending');
658
+ *
659
+ * // All features work:
660
+ * - Nested selects
661
+ * - Foreign key expansion
662
+ * - OR/AND/NOT conditions
663
+ * - Count with head
664
+ * - Range pagination
665
+ * - Upserts
666
+ */
667
+ from(table: string): _supabase_postgrest_js.PostgrestQueryBuilder<any, any, any, string, unknown>;
668
+ /**
669
+ * Call a PostgreSQL function (RPC)
670
+ *
671
+ * @example
672
+ * // Call a function with parameters
673
+ * const { data, error } = await client.database
674
+ * .rpc('get_user_stats', { user_id: 123 });
675
+ *
676
+ * // Call a function with no parameters
677
+ * const { data, error } = await client.database
678
+ * .rpc('get_all_active_users');
679
+ *
680
+ * // With options (head, count, get)
681
+ * const { data, count } = await client.database
682
+ * .rpc('search_posts', { query: 'hello' }, { count: 'exact' });
683
+ */
684
+ rpc(fn: string, args?: Record<string, unknown>, options?: {
685
+ head?: boolean;
686
+ get?: boolean;
687
+ count?: "exact" | "planned" | "estimated";
688
+ }): _supabase_postgrest_js.PostgrestFilterBuilder<any, any, any, any, string, null, "RPC">;
689
+ }
690
+
691
+ /**
692
+ * Emails client for sending custom emails
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * // Send a simple email
697
+ * const { data, error } = await client.emails.send({
698
+ * to: 'user@example.com',
699
+ * subject: 'Welcome!',
700
+ * html: '<h1>Welcome to our platform</h1>'
701
+ * });
702
+ *
703
+ * if (error) {
704
+ * console.error('Failed to send:', error.message);
705
+ * return;
706
+ * }
707
+ * // Email sent successfully - data is {} (empty object)
708
+ *
709
+ * // Send to multiple recipients with CC
710
+ * const { data, error } = await client.emails.send({
711
+ * to: ['user1@example.com', 'user2@example.com'],
712
+ * cc: 'manager@example.com',
713
+ * subject: 'Team Update',
714
+ * html: '<p>Here is the latest update...</p>',
715
+ * replyTo: 'support@example.com'
716
+ * });
717
+ * ```
718
+ */
719
+ declare class Emails {
720
+ private http;
721
+ constructor(http: HttpClient);
722
+ /**
723
+ * Send a custom HTML email
724
+ * @param options Email options including recipients, subject, and HTML content
725
+ */
726
+ send(options: SendRawEmailRequest): Promise<{
727
+ data: SendEmailResponse | null;
728
+ error: ResultError | null;
729
+ }>;
730
+ }
731
+
732
+ interface FunctionInvokeOptions {
733
+ /**
734
+ * The body of the request: a JSON-serializable value, or any fetch
735
+ * BodyInit (FormData, Blob, string, ...)
736
+ */
737
+ body?: BodyInit | JsonRequestBody;
738
+ /**
739
+ * Custom headers to send with the request
740
+ */
741
+ headers?: Record<string, string>;
742
+ /**
743
+ * HTTP method (default: POST)
744
+ */
745
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
746
+ }
747
+ /**
748
+ * Edge Functions client for invoking serverless functions.
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * const { data, error } = await client.functions.invoke('hello-world', {
753
+ * body: { name: 'World' }
754
+ * });
755
+ * ```
756
+ */
757
+ declare class Functions {
758
+ private http;
759
+ private functionsUrl;
760
+ constructor(http: HttpClient, functionsUrl?: string);
761
+ /**
762
+ * Derive the legacy subhosting URL from the base URL
763
+ * ({appKey}.{region}.<domain> -> {appKey}.functions.<domain>).
764
+ * Only used to recognize when a configured functionsUrl still points at
765
+ * the local deployment, so in-process dispatch can short-circuit it.
766
+ */
767
+ private static deriveSubhostingUrl;
768
+ /**
769
+ * Build a Request for in-process dispatch. The host is a non-routable
770
+ * placeholder; the router only reads pathname.
771
+ */
772
+ private buildInProcessRequest;
773
+ /**
774
+ * Invoke an Edge Function.
775
+ *
776
+ * Dispatch order:
777
+ * 1. If the platform's in-process dispatch hook is present and no foreign
778
+ * functionsUrl is configured, call it directly (function-to-function
779
+ * calls inside the same deployment).
780
+ * 2. If a custom functionsUrl is configured, try it; fall back to the
781
+ * proxy path on 404 or network failure.
782
+ * 3. Otherwise, invoke through the main host's /functions/{slug} proxy.
783
+ * This route works from browsers too (correct CORS).
784
+ *
785
+ * @param slug The function slug to invoke
786
+ * @param options Request options
787
+ */
788
+ invoke<T = any>(slug: string, options?: FunctionInvokeOptions): Promise<{
789
+ data: T | null;
790
+ error: ResultError | null;
791
+ }>;
792
+ }
793
+
794
+ type ConnectionState = "disconnected" | "connecting" | "connected";
795
+ type EventCallback<T = unknown> = (payload: T) => void;
796
+ /**
797
+ * Socket.IO realtime client. Authentication is evaluated for every handshake,
798
+ * while an established socket remains authenticated until it disconnects.
799
+ */
800
+ declare class Realtime {
801
+ private baseUrl;
802
+ private tokenManager;
803
+ private anonKey?;
804
+ private getValidAccessToken;
805
+ private socket;
806
+ private connectPromise;
807
+ private connectionAttempt;
808
+ private nextConnectionAttemptId;
809
+ private subscriptions;
810
+ private eventListeners;
811
+ constructor(baseUrl: string, tokenManager: TokenManager, anonKey?: string | undefined, getValidAccessToken?: () => Promise<string | null>);
812
+ private notifyListeners;
813
+ private getHandshakeToken;
814
+ connect(): Promise<void>;
815
+ disconnect(): void;
816
+ private reconnectForAuthChange;
817
+ private handleDisconnect;
818
+ private resubscribeChannels;
819
+ private requestSubscription;
820
+ private settleSubscription;
821
+ private applyPresenceEvent;
822
+ get isConnected(): boolean;
823
+ get connectionState(): ConnectionState;
824
+ get socketId(): string | undefined;
825
+ subscribe(channel: string): Promise<SubscribeResponse>;
826
+ unsubscribe(channel: string): void;
827
+ /**
828
+ * Publish an event to a channel.
829
+ *
830
+ * Delivery notes (verified against a live backend):
831
+ * - Payload fields arrive spread onto the received message itself, next to
832
+ * `meta` - not nested under a `payload` key. Publishing `{ text: "hi" }`
833
+ * means receivers read `msg.text`.
834
+ * - The sender receives its own message too. Deduplicate with
835
+ * `msg.meta.messageId` (or `msg.meta.senderId`) if you also update local
836
+ * state optimistically.
837
+ */
838
+ publish<T = unknown>(channel: string, event: string, payload: T): Promise<void>;
839
+ /**
840
+ * Listen for an event by name, across all subscribed channels.
841
+ * Filter by channel inside the callback: `msg.meta.channel` always matches
842
+ * the exact name passed to subscribe() (the SDK strips the server's
843
+ * transport prefix before delivery).
844
+ */
845
+ on<T = SocketMessage>(event: string, callback: EventCallback<T>): void;
846
+ off<T = SocketMessage>(event: string, callback: EventCallback<T>): void;
847
+ once<T = SocketMessage>(event: string, callback: EventCallback<T>): void;
848
+ getSubscribedChannels(): string[];
849
+ getPresenceState(channel: string): PresenceMember[];
850
+ }
851
+
852
+ /**
853
+ * Storage module for Result SDK
854
+ * Handles file uploads, downloads, and bucket management
855
+ */
856
+
857
+ interface StorageResponse<T> {
858
+ data: T | null;
859
+ error: ResultError | null;
860
+ }
861
+ /**
862
+ * Storage bucket operations
863
+ */
864
+ declare class StorageBucket {
865
+ private bucketName;
866
+ private http;
867
+ constructor(bucketName: string, http: HttpClient);
868
+ /**
869
+ * Upload a file to a specific key.
870
+ * Uses the upload strategy from the backend (direct or presigned).
871
+ * Standard PUT semantics: uploading to an existing key replaces the
872
+ * current object in place.
873
+ * @param path - The object key/path
874
+ * @param file - File or Blob to upload
875
+ */
876
+ upload(path: string, file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
877
+ /**
878
+ * Upload a file under an automatically generated, collision-free key.
879
+ * The key is derived client-side from the filename (sanitized base +
880
+ * timestamp + random suffix) and uploaded through the standard
881
+ * {@link upload} path, so repeated uploads of the same file never
882
+ * overwrite each other. Reads the filename structurally to avoid assuming
883
+ * a global `File` (which Node 18 does not expose).
884
+ * @param file - File or Blob to upload
885
+ */
886
+ uploadAuto(file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
887
+ /**
888
+ * Internal method to handle presigned URL uploads
889
+ */
890
+ private uploadWithPresignedUrl;
891
+ /**
892
+ * Download a file
893
+ * Uses the download strategy from backend (direct or presigned)
894
+ * @param path - The object key/path
895
+ * Returns the file as a Blob
896
+ */
897
+ download(path: string): Promise<{
898
+ data: Blob | null;
899
+ error: ResultError | null;
900
+ }>;
901
+ /**
902
+ * Get the public URL for an object in a public bucket.
903
+ *
904
+ * Pure string construction — no network call, no auth. The URL only resolves
905
+ * if the bucket is public; for private objects use {@link createSignedUrl}.
906
+ *
907
+ * @param path - The object key/path
908
+ * @returns `{ data: { publicUrl }, error }` — matches the external SDK pattern,
909
+ * so `const { data } = getPublicUrl(path)` then `data.publicUrl`.
910
+ */
911
+ getPublicUrl(path: string): StorageResponse<{
912
+ publicUrl: string;
913
+ }>;
914
+ /**
915
+ * Resolve a download strategy (signed or direct URL) for an object with a
916
+ * caller-supplied TTL. Prefers the canonical GET route and falls back to the
917
+ * legacy POST alias so signed-URL creation still works against older backends
918
+ * that predate the GET route (they return 404/405 for it). A genuine
919
+ * "object not found" (STORAGE_NOT_FOUND) is not retried.
920
+ */
921
+ private requestDownloadStrategy;
922
+ /**
923
+ * Create a signed URL for an object.
924
+ *
925
+ * Returns a time-limited, credential-free URL that can be handed directly to
926
+ * a browser (`<img src>`), an email, or a third party — no SDK or session is
927
+ * needed to fetch it. Authorization is enforced when the URL is minted (the
928
+ * caller must be allowed to read the object), so the resulting link is a
929
+ * pre-authorized capability scoped to this one object until it expires.
930
+ *
931
+ * @param path - The object key/path
932
+ * @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d).
933
+ * Honored for private buckets; public buckets return their long-lived URL.
934
+ */
935
+ createSignedUrl(path: string, expiresIn?: number): Promise<StorageResponse<{
936
+ signedUrl: string;
937
+ expiresAt: string | null;
938
+ }>>;
939
+ /**
940
+ * Create signed URLs for multiple objects in a single call.
941
+ *
942
+ * Each entry resolves independently: a failure on one key (not found / not
943
+ * permitted) is reported on that entry's `error` without failing the rest.
944
+ *
945
+ * @param paths - The object keys/paths
946
+ * @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d)
947
+ */
948
+ createSignedUrls(paths: string[], expiresIn?: number): Promise<StorageResponse<Array<{
949
+ path: string;
950
+ signedUrl: string | null;
951
+ error: string | null;
952
+ }>>>;
953
+ /**
954
+ * List objects in the bucket
955
+ * @param prefix - Filter by key prefix
956
+ * @param search - Search in file names
957
+ * @param limit - Maximum number of results (default: 100, max: 1000)
958
+ * @param offset - Number of results to skip
959
+ */
960
+ list(options?: {
961
+ prefix?: string;
962
+ search?: string;
963
+ limit?: number;
964
+ offset?: number;
965
+ }): Promise<StorageResponse<ListObjectsResponseSchema>>;
966
+ /** Delete a single file. */
967
+ remove(path: string): Promise<StorageResponse<{
968
+ message: string;
969
+ }>>;
970
+ /** Delete multiple files in a single request. */
971
+ remove(paths: string[]): Promise<StorageResponse<DeleteObjectsResponse>>;
972
+ /** Delete one or more files when the input type is not narrowed. */
973
+ remove(pathOrPaths: string | string[]): Promise<StorageResponse<{
974
+ message: string;
975
+ } | DeleteObjectsResponse>>;
976
+ }
977
+ /**
978
+ * Storage module for file operations
979
+ */
980
+ declare class Storage {
981
+ private http;
982
+ constructor(http: HttpClient);
983
+ /**
984
+ * Get a bucket instance for operations
985
+ * @param bucketName - Name of the bucket
986
+ */
987
+ from(bucketName: string): StorageBucket;
988
+ }
989
+
990
+ type AccessTokenChangeEvent = typeof AuthChangeEvent.SIGNED_IN | typeof AuthChangeEvent.TOKEN_REFRESHED;
991
+ /**
992
+ * Main Result SDK Client
993
+ *
994
+ * @example
995
+ * ```typescript
996
+ * import { ResultClient } from '@resultdev/sdk';
997
+ *
998
+ * const client = new ResultClient({
999
+ * baseUrl: 'http://localhost:7130'
1000
+ * });
1001
+ *
1002
+ * // Authentication
1003
+ * const { data, error } = await client.auth.signUp({
1004
+ * email: 'user@example.com',
1005
+ * password: 'password123',
1006
+ * name: 'John Doe'
1007
+ * });
1008
+ *
1009
+ * // Database operations
1010
+ * const { data, error } = await client.database
1011
+ * .from('posts')
1012
+ * .select('*')
1013
+ * .eq('user_id', session.user.id)
1014
+ * .order('created_at', { ascending: false })
1015
+ * .limit(10);
1016
+ *
1017
+ * // Insert data
1018
+ * const { data: newPost } = await client.database
1019
+ * .from('posts')
1020
+ * .insert({ title: 'Hello', content: 'World' })
1021
+ * .single();
1022
+ *
1023
+ * // Invoke edge functions
1024
+ * const { data, error } = await client.functions.invoke('my-function', {
1025
+ * body: { message: 'Hello from SDK' }
1026
+ * });
1027
+ *
1028
+ * // Enable debug logging
1029
+ * const debugClient = new ResultClient({
1030
+ * baseUrl: 'http://localhost:7130',
1031
+ * debug: true
1032
+ * });
1033
+ * ```
1034
+ */
1035
+ declare class ResultClient {
1036
+ private http;
1037
+ private tokenManager;
1038
+ readonly auth: Auth;
1039
+ readonly database: Database;
1040
+ readonly storage: Storage;
1041
+ readonly ai: AI;
1042
+ readonly functions: Functions;
1043
+ readonly realtime: Realtime;
1044
+ readonly emails: Emails;
1045
+ readonly analytics: Analytics;
1046
+ readonly support: Support;
1047
+ constructor(config?: ResultConfig);
1048
+ /**
1049
+ * Get the underlying HTTP client for custom requests
1050
+ *
1051
+ * @example
1052
+ * ```typescript
1053
+ * const httpClient = client.getHttpClient();
1054
+ * const customData = await httpClient.get('/api/custom-endpoint');
1055
+ * ```
1056
+ */
1057
+ getHttpClient(): HttpClient;
1058
+ /**
1059
+ * Set the access token used by every SDK surface. Updates both the HTTP
1060
+ * client (database / storage / functions / AI / emails) and the realtime
1061
+ * token manager. Pass `null` to sign out. By default a token replacement is
1062
+ * treated as a sign-in boundary and reconnects realtime. Pass
1063
+ * `AuthChangeEvent.TOKEN_REFRESHED` for a same-identity refresh to preserve a live socket; the
1064
+ * refreshed token is then used at the next handshake.
1065
+ *
1066
+ * Use this when an external auth provider (Better Auth, Clerk, Auth0,
1067
+ * WorkOS, Kinde, Stytch, …) issues the JWT and you need to keep the
1068
+ * long-lived Result client in sync. Without this, you'd have to call
1069
+ * `client.getHttpClient().setAuthToken(token)` AND reach into the private
1070
+ * realtime token manager separately.
1071
+ *
1072
+ * @example
1073
+ * ```typescript
1074
+ * import { AuthChangeEvent } from '@resultdev/sdk';
1075
+ *
1076
+ * // Refresh a third-party-issued JWT periodically
1077
+ * const { token } = await fetch('/api/backend-token').then((r) => r.json());
1078
+ * client.setAccessToken(token, AuthChangeEvent.TOKEN_REFRESHED);
1079
+ *
1080
+ * // Sign-out
1081
+ * client.setAccessToken(null);
1082
+ * ```
1083
+ */
1084
+ setAccessToken(token: string | null, event?: AccessTokenChangeEvent): void;
1085
+ }
1086
+
1087
+ export { AI as A, type ChatCompletion as C, Database as D, Emails as E, type FunctionInvokeOptions as F, HttpClient as H, type ImageGenerationResult as I, Logger as L, ResultClient as R, Storage as S, type AccessTokenChangeEvent as a, Auth as b, AuthChangeEvent as c, type AuthStateChangeCallback as d, type ChatCompletionChoice as e, type ChatCompletionChunk as f, type ChatCompletionUsage as g, type ConnectionState as h, type EmbeddingsResult as i, type EventCallback as j, Functions as k, Realtime as l, StorageBucket as m, type StorageResponse as n };