@blinkdotnew/dev-sdk 0.0.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.
@@ -0,0 +1,2365 @@
1
+ /**
2
+ * Storage adapter for cross-platform compatibility
3
+ * Allows using AsyncStorage on React Native and localStorage on web
4
+ */
5
+ /**
6
+ * Storage adapter interface
7
+ * Supports both synchronous (web localStorage) and asynchronous (React Native AsyncStorage) implementations
8
+ */
9
+ interface StorageAdapter {
10
+ getItem(key: string): Promise<string | null> | string | null;
11
+ setItem(key: string, value: string): Promise<void> | void;
12
+ removeItem(key: string): Promise<void> | void;
13
+ clear(): Promise<void> | void;
14
+ }
15
+ /**
16
+ * Web localStorage adapter (synchronous)
17
+ * Used automatically on web browsers
18
+ */
19
+ declare class WebStorageAdapter implements StorageAdapter {
20
+ getItem(key: string): string | null;
21
+ setItem(key: string, value: string): void;
22
+ removeItem(key: string): void;
23
+ clear(): void;
24
+ }
25
+ /**
26
+ * Async storage adapter wrapper (for React Native AsyncStorage)
27
+ * Usage:
28
+ * ```typescript
29
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
30
+ * const storage = new AsyncStorageAdapter(AsyncStorage)
31
+ * ```
32
+ */
33
+ declare class AsyncStorageAdapter implements StorageAdapter {
34
+ private asyncStorage;
35
+ constructor(asyncStorage: any);
36
+ getItem(key: string): Promise<string | null>;
37
+ setItem(key: string, value: string): Promise<void>;
38
+ removeItem(key: string): Promise<void>;
39
+ clear(): Promise<void>;
40
+ }
41
+ /**
42
+ * No-op storage adapter (for server-side or when storage is disabled)
43
+ * Used automatically on Node.js or when no storage is available
44
+ */
45
+ declare class NoOpStorageAdapter implements StorageAdapter {
46
+ getItem(_key: string): null;
47
+ setItem(_key: string, _value: string): void;
48
+ removeItem(_key: string): void;
49
+ clear(): void;
50
+ }
51
+ /**
52
+ * Get default storage adapter based on platform
53
+ */
54
+ declare function getDefaultStorageAdapter(): StorageAdapter;
55
+
56
+ /**
57
+ * Core type definitions for Blink SDK
58
+ */
59
+
60
+ interface BlinkClientConfig {
61
+ projectId: string;
62
+ authRequired?: boolean;
63
+ auth?: BlinkAuthConfig;
64
+ /**
65
+ * Storage adapter for cross-platform token persistence
66
+ *
67
+ * Web: Uses localStorage by default
68
+ * React Native: Pass AsyncStorageAdapter(AsyncStorage)
69
+ * Node.js: Uses NoOpStorageAdapter by default
70
+ *
71
+ * @example
72
+ * // React Native
73
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
74
+ * import { AsyncStorageAdapter } from '@blinkdotnew/sdk'
75
+ *
76
+ * const blink = createClient({
77
+ * projectId: 'your-project',
78
+ * storage: new AsyncStorageAdapter(AsyncStorage)
79
+ * })
80
+ */
81
+ storage?: StorageAdapter;
82
+ }
83
+ interface BlinkAuthConfig {
84
+ mode?: 'managed' | 'headless';
85
+ /**
86
+ * Automatically detect and extract auth tokens from URL parameters
87
+ *
88
+ * - Web: Set to `true` (default) to handle OAuth redirects
89
+ * - React Native: Set to `false` to use deep links instead
90
+ *
91
+ * @default true
92
+ *
93
+ * @example
94
+ * // React Native - disable URL detection, use deep links
95
+ * {
96
+ * auth: {
97
+ * detectSessionInUrl: false,
98
+ * storage: AsyncStorageAdapter(AsyncStorage)
99
+ * }
100
+ * }
101
+ */
102
+ detectSessionInUrl?: boolean;
103
+ /**
104
+ * WebBrowser module for React Native OAuth (expo-web-browser)
105
+ *
106
+ * When provided, `signInWithGoogle()` and other OAuth methods will
107
+ * automatically use the mobile session-based flow on React Native,
108
+ * so you don't need platform-specific code.
109
+ *
110
+ * @example
111
+ * // React Native setup (configure once)
112
+ * import * as WebBrowser from 'expo-web-browser'
113
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
114
+ *
115
+ * const blink = createClient({
116
+ * projectId: 'your-project',
117
+ * auth: {
118
+ * mode: 'headless',
119
+ * webBrowser: WebBrowser // Pass the module here
120
+ * },
121
+ * storage: new AsyncStorageAdapter(AsyncStorage)
122
+ * })
123
+ *
124
+ * // Now this works on both web and mobile!
125
+ * const user = await blink.auth.signInWithGoogle()
126
+ */
127
+ webBrowser?: WebBrowserModule;
128
+ email?: {
129
+ requireVerification?: boolean;
130
+ allowSignUp?: boolean;
131
+ passwordRules?: {
132
+ minLength?: number;
133
+ requireUppercase?: boolean;
134
+ requireLowercase?: boolean;
135
+ requireNumbers?: boolean;
136
+ requireSpecialChars?: boolean;
137
+ };
138
+ };
139
+ roles?: {
140
+ [role: string]: {
141
+ permissions: string[];
142
+ inherit?: string[];
143
+ };
144
+ };
145
+ defaultRole?: string;
146
+ session?: {
147
+ duration?: number;
148
+ refreshThreshold?: number;
149
+ multiDevice?: boolean;
150
+ };
151
+ redirectUrl?: string;
152
+ authUrl?: string;
153
+ coreUrl?: string;
154
+ /**
155
+ * Storage adapter for auth token persistence (overrides global storage)
156
+ * If not provided, uses the global storage from BlinkClientConfig
157
+ */
158
+ storage?: StorageAdapter;
159
+ }
160
+ type AuthProvider = 'email' | 'google' | 'github' | 'apple' | 'microsoft' | 'twitter' | 'linkedin' | 'discord';
161
+ interface AuthOptions {
162
+ redirectUrl?: string;
163
+ metadata?: Record<string, any>;
164
+ useMobileSession?: boolean;
165
+ }
166
+ interface SignUpData {
167
+ email: string;
168
+ password: string;
169
+ metadata?: {
170
+ displayName?: string;
171
+ avatar?: string;
172
+ [key: string]: any;
173
+ };
174
+ }
175
+ interface MagicLinkOptions {
176
+ redirectUrl?: string;
177
+ }
178
+ /**
179
+ * WebBrowser interface for React Native OAuth
180
+ * Compatible with expo-web-browser module
181
+ *
182
+ * Simply pass the expo-web-browser module directly:
183
+ * ```typescript
184
+ * import * as WebBrowser from 'expo-web-browser'
185
+ * const blink = createClient({ auth: { webBrowser: WebBrowser } })
186
+ * ```
187
+ */
188
+ interface WebBrowserModule {
189
+ openAuthSessionAsync(url: string, redirectUrl?: string, options?: unknown): Promise<{
190
+ type: string;
191
+ url?: string;
192
+ }>;
193
+ }
194
+ interface BlinkUser {
195
+ id: string;
196
+ email: string;
197
+ displayName?: string;
198
+ photoURL?: string;
199
+ emailVerified?: boolean;
200
+ createdAt?: string;
201
+ lastSignInAt?: string;
202
+ role?: string;
203
+ }
204
+ interface AuthTokens {
205
+ access_token: string;
206
+ refresh_token?: string;
207
+ token_type: 'Bearer';
208
+ expires_in: number;
209
+ refresh_expires_in?: number;
210
+ issued_at?: number;
211
+ }
212
+ interface AuthState {
213
+ user: BlinkUser | null;
214
+ tokens: AuthTokens | null;
215
+ isAuthenticated: boolean;
216
+ isLoading: boolean;
217
+ }
218
+ interface FilterOperators {
219
+ eq?: any;
220
+ neq?: any;
221
+ gt?: any;
222
+ gte?: any;
223
+ lt?: any;
224
+ lte?: any;
225
+ in?: any[];
226
+ not_in?: any[];
227
+ like?: string;
228
+ ilike?: string;
229
+ is?: null | boolean;
230
+ not?: any;
231
+ }
232
+ interface LogicalOperators {
233
+ AND?: FilterCondition[];
234
+ OR?: FilterCondition[];
235
+ }
236
+ type FilterCondition = Record<string, any> | FilterOperators | LogicalOperators;
237
+ interface QueryOptions {
238
+ where?: FilterCondition;
239
+ orderBy?: Record<string, 'asc' | 'desc'> | string;
240
+ limit?: number;
241
+ offset?: number;
242
+ cursor?: string;
243
+ select?: string[];
244
+ }
245
+ interface CreateOptions {
246
+ returning?: boolean;
247
+ }
248
+ interface UpdateOptions {
249
+ returning?: boolean;
250
+ }
251
+ interface UpsertOptions {
252
+ onConflict?: string;
253
+ returning?: boolean;
254
+ }
255
+ interface TableOperations<T = any> {
256
+ create(data: Partial<T>, options?: CreateOptions): Promise<T>;
257
+ createMany(data: Partial<T>[], options?: CreateOptions): Promise<T[]>;
258
+ upsert(data: Partial<T>, options?: UpsertOptions): Promise<T>;
259
+ upsertMany(data: Partial<T>[], options?: UpsertOptions): Promise<T[]>;
260
+ get(id: string): Promise<T | null>;
261
+ list(options?: QueryOptions): Promise<T[]>;
262
+ update(id: string, data: Partial<T>, options?: UpdateOptions): Promise<T>;
263
+ updateMany(updates: Array<{
264
+ id: string;
265
+ } & Partial<T>>, options?: UpdateOptions): Promise<T[]>;
266
+ delete(id: string): Promise<void>;
267
+ deleteMany(options: {
268
+ where: FilterCondition;
269
+ }): Promise<void>;
270
+ count(options?: {
271
+ where?: FilterCondition;
272
+ }): Promise<number>;
273
+ exists(options: {
274
+ where: FilterCondition;
275
+ }): Promise<boolean>;
276
+ }
277
+ declare class BlinkError extends Error {
278
+ code?: string | undefined;
279
+ status?: number | undefined;
280
+ details?: any;
281
+ constructor(message: string, code?: string | undefined, status?: number | undefined, details?: any);
282
+ }
283
+ interface StorageUploadOptions {
284
+ upsert?: boolean;
285
+ onProgress?: (percent: number) => void;
286
+ }
287
+ interface StorageUploadResponse {
288
+ publicUrl: string;
289
+ }
290
+ interface FileObject {
291
+ id: string;
292
+ name: string;
293
+ bucket_id: string;
294
+ owner?: string | null;
295
+ owner_id?: string | null;
296
+ version?: string | null;
297
+ created_at: string;
298
+ updated_at: string;
299
+ last_accessed_at: string;
300
+ metadata: {
301
+ size: number;
302
+ mimetype: string;
303
+ cacheControl?: string;
304
+ };
305
+ user_metadata?: Record<string, any>;
306
+ }
307
+ interface BlinkStorage {
308
+ upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
309
+ download(path: string, options?: {
310
+ filename?: string;
311
+ }): Promise<StorageDownloadResponse>;
312
+ remove(...paths: string[]): Promise<void>;
313
+ }
314
+ interface StorageDownloadResponse {
315
+ downloadUrl: string;
316
+ filename: string;
317
+ contentType?: string;
318
+ size?: number;
319
+ }
320
+ interface TokenUsage {
321
+ promptTokens: number;
322
+ completionTokens: number;
323
+ totalTokens: number;
324
+ }
325
+ interface TextContent {
326
+ type: 'text';
327
+ text: string;
328
+ }
329
+ interface ImageContent {
330
+ type: 'image';
331
+ image: string;
332
+ }
333
+ type MessageContent = TextContent | ImageContent;
334
+ interface Message {
335
+ role: 'system' | 'user' | 'assistant';
336
+ content: string | MessageContent[];
337
+ }
338
+ interface TextGenerationRequest {
339
+ model?: string;
340
+ prompt?: string;
341
+ messages?: Message[];
342
+ stream?: boolean;
343
+ search?: boolean;
344
+ maxSteps?: number;
345
+ experimental_continueSteps?: boolean;
346
+ maxTokens?: number;
347
+ temperature?: number;
348
+ signal?: AbortSignal;
349
+ }
350
+ interface TextGenerationResponse {
351
+ text: string;
352
+ finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls';
353
+ usage?: TokenUsage;
354
+ files?: any[];
355
+ reasoningDetails?: any[];
356
+ toolCalls?: any[];
357
+ toolResults?: any[];
358
+ warnings?: string[];
359
+ request?: {
360
+ body?: string;
361
+ };
362
+ response?: any;
363
+ steps?: Array<{
364
+ stepType?: string;
365
+ text?: string;
366
+ finishReason?: string;
367
+ usage?: TokenUsage;
368
+ }>;
369
+ sources?: any[];
370
+ providerMetadata?: any;
371
+ experimental_providerMetadata?: any;
372
+ }
373
+ interface ObjectGenerationRequest {
374
+ model?: string;
375
+ prompt: string;
376
+ output?: 'object' | 'array' | 'enum';
377
+ schema?: any;
378
+ enum?: string[];
379
+ stream?: boolean;
380
+ signal?: AbortSignal;
381
+ }
382
+ interface ObjectGenerationResponse {
383
+ object: any;
384
+ finishReason?: 'stop' | 'length' | 'content_filter';
385
+ usage?: TokenUsage;
386
+ warnings?: string[];
387
+ providerMetadata?: {
388
+ openai?: {
389
+ reasoningTokens?: number;
390
+ acceptedPredictionTokens?: number;
391
+ rejectedPredictionTokens?: number;
392
+ cachedPromptTokens?: number;
393
+ };
394
+ };
395
+ experimental_providerMetadata?: any;
396
+ response?: {
397
+ id?: string;
398
+ timestamp?: string;
399
+ modelId?: string;
400
+ headers?: any;
401
+ body?: any;
402
+ };
403
+ request?: {
404
+ body?: string;
405
+ };
406
+ }
407
+ interface ImageGenerationRequest {
408
+ model?: string;
409
+ prompt: string;
410
+ images?: string[];
411
+ size?: string;
412
+ quality?: 'auto' | 'low' | 'medium' | 'high';
413
+ background?: 'auto' | 'transparent' | 'opaque';
414
+ n?: number;
415
+ response_format?: 'url' | 'b64_json';
416
+ output_format?: 'png' | 'jpeg' | 'webp';
417
+ output_compression?: number;
418
+ moderation?: 'auto' | 'low';
419
+ signal?: AbortSignal;
420
+ }
421
+ interface ImageGenerationResponse {
422
+ data: Array<{
423
+ url?: string;
424
+ b64_json?: string;
425
+ }>;
426
+ }
427
+ interface SpeechGenerationRequest {
428
+ model?: string;
429
+ text: string;
430
+ voice?: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
431
+ response_format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm';
432
+ speed?: number;
433
+ signal?: AbortSignal;
434
+ }
435
+ interface SpeechGenerationResponse {
436
+ url: string;
437
+ voice: string;
438
+ format: string;
439
+ mimeType: string;
440
+ }
441
+ interface TranscriptionRequest {
442
+ model?: string;
443
+ audio: string | number[] | ArrayBuffer | Uint8Array;
444
+ language?: string;
445
+ response_format?: 'json' | 'text' | 'srt' | 'verbose_json' | 'vtt';
446
+ signal?: AbortSignal;
447
+ }
448
+ interface TranscriptionResponse {
449
+ text: string;
450
+ transcript?: string;
451
+ segments?: Array<{
452
+ id: number;
453
+ seek: number;
454
+ start: number;
455
+ end: number;
456
+ text: string;
457
+ tokens: number[];
458
+ temperature: number;
459
+ avg_logprob: number;
460
+ compression_ratio: number;
461
+ no_speech_prob: number;
462
+ }>;
463
+ language?: string;
464
+ duration?: number;
465
+ words?: Array<{
466
+ word: string;
467
+ start: number;
468
+ end: number;
469
+ }>;
470
+ }
471
+ interface BlinkAI {
472
+ generateText(options: TextGenerationRequest): Promise<TextGenerationResponse>;
473
+ streamText(options: TextGenerationRequest, onChunk: (chunk: string) => void): Promise<TextGenerationResponse>;
474
+ generateObject(options: ObjectGenerationRequest): Promise<ObjectGenerationResponse>;
475
+ streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
476
+ generateImage(options: ImageGenerationRequest): Promise<ImageGenerationResponse>;
477
+ modifyImage(options: {
478
+ images: string[];
479
+ prompt: string;
480
+ size?: string;
481
+ quality?: "auto" | "low" | "medium" | "high";
482
+ n?: number;
483
+ background?: "auto" | "transparent" | "opaque";
484
+ signal?: AbortSignal;
485
+ }): Promise<ImageGenerationResponse>;
486
+ generateSpeech(options: SpeechGenerationRequest): Promise<SpeechGenerationResponse>;
487
+ transcribeAudio(options: TranscriptionRequest): Promise<TranscriptionResponse>;
488
+ }
489
+ interface DataExtraction {
490
+ chunks: string[];
491
+ }
492
+ interface ExtractFromUrlRequest {
493
+ url: string;
494
+ chunking?: boolean;
495
+ chunkSize?: number;
496
+ }
497
+ interface ExtractFromUrlResponse {
498
+ chunks?: string[];
499
+ text?: string;
500
+ }
501
+ interface ExtractFromBlobResponse {
502
+ chunks?: string[];
503
+ text?: string;
504
+ }
505
+ interface ScrapeRequest {
506
+ url: string;
507
+ formats?: ('markdown' | 'html' | 'rawHtml' | 'links' | 'extract' | 'metadata')[];
508
+ }
509
+ interface ScrapeResponse {
510
+ markdown?: string;
511
+ html?: string;
512
+ rawHtml?: string;
513
+ links?: Array<{
514
+ text: string;
515
+ url: string;
516
+ type: string;
517
+ }>;
518
+ extract?: {
519
+ title?: string;
520
+ description?: string;
521
+ headings?: string[];
522
+ text?: string;
523
+ };
524
+ metadata?: {
525
+ title?: string;
526
+ description?: string;
527
+ url?: string;
528
+ domain?: string;
529
+ favicon?: string;
530
+ image?: string;
531
+ author?: string;
532
+ publishedTime?: string;
533
+ modifiedTime?: string;
534
+ type?: string;
535
+ siteName?: string;
536
+ locale?: string;
537
+ keywords?: string[];
538
+ };
539
+ }
540
+ interface ScrapeResult {
541
+ markdown: string;
542
+ html: string;
543
+ metadata: {
544
+ title: string;
545
+ description: string;
546
+ url: string;
547
+ domain: string;
548
+ favicon?: string;
549
+ image?: string;
550
+ author?: string;
551
+ publishedTime?: string;
552
+ modifiedTime?: string;
553
+ type?: string;
554
+ siteName?: string;
555
+ locale?: string;
556
+ keywords?: string[];
557
+ };
558
+ links: Array<{
559
+ text: string;
560
+ url: string;
561
+ type: string;
562
+ }>;
563
+ extract: {
564
+ title: string;
565
+ description: string;
566
+ headings: string[];
567
+ text: string;
568
+ };
569
+ }
570
+ interface ScreenshotRequest {
571
+ url: string;
572
+ fullPage?: boolean;
573
+ width?: number;
574
+ height?: number;
575
+ }
576
+ interface ScreenshotResponse {
577
+ url: string;
578
+ }
579
+ interface FetchRequest {
580
+ url: string;
581
+ method?: string;
582
+ headers?: Record<string, string>;
583
+ body?: any;
584
+ query?: Record<string, string>;
585
+ async?: boolean;
586
+ }
587
+ interface FetchResponse {
588
+ status: number;
589
+ headers: Record<string, string>;
590
+ body: any;
591
+ durationMs: number;
592
+ }
593
+ interface AsyncFetchResponse {
594
+ status: 'triggered';
595
+ message: string;
596
+ }
597
+ interface SearchRequest {
598
+ q: string;
599
+ location?: string;
600
+ hl?: string;
601
+ tbm?: string;
602
+ num?: number;
603
+ }
604
+ interface SearchResponse {
605
+ organic_results: Array<{
606
+ position: number;
607
+ title: string;
608
+ link: string;
609
+ snippet: string;
610
+ }>;
611
+ total_results?: string;
612
+ related_searches?: string[];
613
+ people_also_ask?: Array<{
614
+ question: string;
615
+ snippet: string;
616
+ link: string;
617
+ }>;
618
+ local_results?: Array<{
619
+ title: string;
620
+ address: string;
621
+ rating: number;
622
+ reviews: number;
623
+ phone?: string;
624
+ }>;
625
+ ads?: Array<{
626
+ title: string;
627
+ link: string;
628
+ snippet: string;
629
+ }>;
630
+ shopping_results?: Array<{
631
+ title: string;
632
+ price: string;
633
+ source: string;
634
+ link: string;
635
+ }>;
636
+ news_results?: Array<{
637
+ title: string;
638
+ link: string;
639
+ snippet: string;
640
+ date: string;
641
+ source: string;
642
+ }>;
643
+ image_results?: Array<{
644
+ title: string;
645
+ link: string;
646
+ original: string;
647
+ thumbnail: string;
648
+ }>;
649
+ }
650
+ interface RealtimeMessage {
651
+ id: string;
652
+ type: string;
653
+ data: any;
654
+ timestamp: number;
655
+ userId?: string;
656
+ metadata?: Record<string, any>;
657
+ }
658
+ interface PresenceUser {
659
+ userId: string;
660
+ metadata?: Record<string, any>;
661
+ joinedAt: number;
662
+ lastSeen: number;
663
+ }
664
+ interface RealtimeChannel {
665
+ subscribe(options?: {
666
+ userId?: string;
667
+ metadata?: Record<string, any>;
668
+ }): Promise<void>;
669
+ unsubscribe(): Promise<void>;
670
+ publish(type: string, data: any, options?: {
671
+ userId?: string;
672
+ metadata?: Record<string, any>;
673
+ }): Promise<string>;
674
+ onMessage(callback: (message: RealtimeMessage) => void): () => void;
675
+ onPresence(callback: (users: PresenceUser[]) => void): () => void;
676
+ getPresence(): Promise<PresenceUser[]>;
677
+ getMessages(options?: {
678
+ limit?: number;
679
+ before?: string;
680
+ after?: string;
681
+ }): Promise<RealtimeMessage[]>;
682
+ isReady(): boolean;
683
+ }
684
+ interface RealtimeSubscribeOptions {
685
+ userId?: string;
686
+ metadata?: Record<string, any>;
687
+ }
688
+ interface RealtimePublishOptions {
689
+ userId?: string;
690
+ metadata?: Record<string, any>;
691
+ }
692
+ interface RealtimeGetMessagesOptions {
693
+ limit?: number;
694
+ before?: string;
695
+ after?: string;
696
+ }
697
+ interface BlinkRealtime {
698
+ channel(name: string): RealtimeChannel;
699
+ subscribe(channelName: string, callback: (message: RealtimeMessage) => void, options?: RealtimeSubscribeOptions): Promise<() => void>;
700
+ publish(channelName: string, type: string, data: any, options?: RealtimePublishOptions): Promise<string>;
701
+ presence(channelName: string): Promise<PresenceUser[]>;
702
+ onPresence(channelName: string, callback: (users: PresenceUser[]) => void): () => void;
703
+ }
704
+ declare class BlinkRealtimeError extends BlinkError {
705
+ constructor(message: string, status?: number, details?: any);
706
+ }
707
+ interface SendEmailAttachment {
708
+ filename: string;
709
+ url: string;
710
+ type?: string;
711
+ content?: string;
712
+ disposition?: 'attachment' | 'inline';
713
+ cid?: string;
714
+ }
715
+ interface SendEmailRequest {
716
+ to: string | string[];
717
+ subject: string;
718
+ html?: string;
719
+ text?: string;
720
+ from?: string;
721
+ replyTo?: string;
722
+ cc?: string | string[];
723
+ bcc?: string | string[];
724
+ attachments?: SendEmailAttachment[];
725
+ }
726
+ interface SendEmailResponse {
727
+ success: boolean;
728
+ messageId: string;
729
+ }
730
+ interface BlinkNotifications {
731
+ email(params: SendEmailRequest): Promise<SendEmailResponse>;
732
+ }
733
+
734
+ type ConnectorProvider = 'discord' | 'notion' | 'google_drive' | 'google_calendar' | 'ai';
735
+ type ConnectorAuthMode = 'oauth' | 'api_key' | 'blink_managed' | 'hybrid';
736
+ interface ConnectorStatusData {
737
+ connected: boolean;
738
+ provider: ConnectorProvider;
739
+ auth_mode?: ConnectorAuthMode;
740
+ account_id?: string;
741
+ metadata?: Record<string, unknown>;
742
+ expires_at?: any;
743
+ scopes?: string[];
744
+ }
745
+ interface ConnectorStatusResponse {
746
+ success: boolean;
747
+ data: ConnectorStatusData;
748
+ }
749
+ interface ConnectorExecuteRequest<TParams = Record<string, unknown>> {
750
+ method: string;
751
+ params?: TParams;
752
+ account_id?: string;
753
+ http_method?: string;
754
+ }
755
+ interface ConnectorExecuteResponse<TData = any> {
756
+ success: boolean;
757
+ data: TData;
758
+ }
759
+ interface ConnectorApiKeyRequest<TMetadata = Record<string, unknown>> {
760
+ api_key: string;
761
+ account_id?: string;
762
+ metadata?: TMetadata;
763
+ }
764
+ interface ConnectorApiKeyResponse {
765
+ success: boolean;
766
+ data: {
767
+ id: string;
768
+ account_id?: string;
769
+ };
770
+ }
771
+ interface BlinkConnectors {
772
+ status(provider: ConnectorProvider, options?: {
773
+ account_id?: string;
774
+ }): Promise<ConnectorStatusResponse>;
775
+ execute<TParams = Record<string, unknown>, TData = any>(provider: ConnectorProvider, request: ConnectorExecuteRequest<TParams>): Promise<ConnectorExecuteResponse<TData>>;
776
+ saveApiKey<TMetadata = Record<string, unknown>>(provider: ConnectorProvider, request: ConnectorApiKeyRequest<TMetadata>): Promise<ConnectorApiKeyResponse>;
777
+ }
778
+ declare class BlinkConnectorError extends BlinkError {
779
+ constructor(message: string, status?: number, details?: any);
780
+ }
781
+
782
+ /**
783
+ * HTTP client for Blink API requests
784
+ * Handles authentication, error handling, and request/response processing
785
+ */
786
+
787
+ interface RequestOptions {
788
+ method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
789
+ headers?: Record<string, string>;
790
+ body?: any;
791
+ searchParams?: Record<string, string>;
792
+ signal?: AbortSignal;
793
+ }
794
+ interface BlinkResponse<T = any> {
795
+ data: T;
796
+ status: number;
797
+ headers: Headers;
798
+ }
799
+ declare class HttpClient {
800
+ private readonly authUrl;
801
+ private readonly coreUrl;
802
+ readonly projectId: string;
803
+ private getToken;
804
+ private getValidToken?;
805
+ constructor(config: BlinkClientConfig, getToken: () => string | null, getValidToken?: () => Promise<string | null>);
806
+ /**
807
+ * Make an authenticated request to the Blink API
808
+ */
809
+ request<T = any>(path: string, options?: RequestOptions): Promise<BlinkResponse<T>>;
810
+ /**
811
+ * GET request
812
+ */
813
+ get<T = any>(path: string, searchParams?: Record<string, string>): Promise<BlinkResponse<T>>;
814
+ /**
815
+ * POST request
816
+ */
817
+ post<T = any>(path: string, body?: any, headers?: Record<string, string>): Promise<BlinkResponse<T>>;
818
+ /**
819
+ * PATCH request
820
+ */
821
+ patch<T = any>(path: string, body?: any, headers?: Record<string, string>): Promise<BlinkResponse<T>>;
822
+ /**
823
+ * DELETE request
824
+ */
825
+ delete<T = any>(path: string, searchParams?: Record<string, string>): Promise<BlinkResponse<T>>;
826
+ /**
827
+ * Database-specific requests
828
+ */
829
+ dbGet<T = any>(table: string, searchParams?: Record<string, string>): Promise<BlinkResponse<T[]>>;
830
+ dbPost<T = any>(table: string, body: any, options?: {
831
+ returning?: boolean;
832
+ }): Promise<BlinkResponse<T | T[]>>;
833
+ dbPatch<T = any>(table: string, body: any, searchParams?: Record<string, string>, options?: {
834
+ returning?: boolean;
835
+ }): Promise<BlinkResponse<T[]>>;
836
+ dbDelete<T = any>(table: string, searchParams?: Record<string, string>, options?: {
837
+ returning?: boolean;
838
+ }): Promise<BlinkResponse<T[]>>;
839
+ dbSql<T = any>(query: string, params?: any[]): Promise<BlinkResponse<{
840
+ rows: T[];
841
+ columns: string[];
842
+ rowCount: number;
843
+ executionTime: number;
844
+ }>>;
845
+ dbBatch<T = any>(statements: Array<{
846
+ sql: string;
847
+ args?: any[];
848
+ }>, mode?: 'read' | 'write'): Promise<BlinkResponse<{
849
+ results: Array<{
850
+ rows: T[];
851
+ columns: string[];
852
+ rowCount: number;
853
+ }>;
854
+ executionTime: number;
855
+ success: boolean;
856
+ }>>;
857
+ /**
858
+ * Upload file with progress tracking
859
+ */
860
+ uploadFile(path: string, file: File | Blob | Buffer, filePath: string, options?: {
861
+ upsert?: boolean;
862
+ onProgress?: (percent: number) => void;
863
+ contentType?: string;
864
+ }): Promise<BlinkResponse<any>>;
865
+ /**
866
+ * Upload with progress tracking using XMLHttpRequest
867
+ */
868
+ private uploadWithProgress;
869
+ /**
870
+ * AI-specific requests
871
+ */
872
+ aiText(prompt: string, options?: {
873
+ model?: string;
874
+ messages?: Array<{
875
+ role: string;
876
+ content: string | any[];
877
+ }>;
878
+ stream?: boolean;
879
+ search?: boolean;
880
+ maxSteps?: number;
881
+ experimental_continueSteps?: boolean;
882
+ maxTokens?: number;
883
+ temperature?: number;
884
+ signal?: AbortSignal;
885
+ }): Promise<BlinkResponse<any>>;
886
+ /**
887
+ * Stream AI text generation with Vercel AI SDK data stream format
888
+ */
889
+ streamAiText(prompt: string, options: {
890
+ model?: string | undefined;
891
+ messages?: {
892
+ role: string;
893
+ content: string | any[];
894
+ }[] | undefined;
895
+ search?: boolean | undefined;
896
+ maxSteps?: number | undefined;
897
+ experimental_continueSteps?: boolean | undefined;
898
+ maxTokens?: number | undefined;
899
+ temperature?: number | undefined;
900
+ signal?: AbortSignal | undefined;
901
+ } | undefined, onChunk: (chunk: string) => void): Promise<any>;
902
+ aiObject(prompt: string, options?: {
903
+ model?: string;
904
+ output?: 'object' | 'array' | 'enum';
905
+ schema?: any;
906
+ enum?: string[];
907
+ stream?: boolean;
908
+ signal?: AbortSignal;
909
+ }): Promise<BlinkResponse<any>>;
910
+ /**
911
+ * Stream AI object generation with Vercel AI SDK data stream format
912
+ */
913
+ streamAiObject(prompt: string, options: {
914
+ model?: string | undefined;
915
+ output?: "object" | "array" | "enum" | undefined;
916
+ schema?: any;
917
+ enum?: string[] | undefined;
918
+ signal?: AbortSignal | undefined;
919
+ } | undefined, onPartial: (partial: any) => void): Promise<any>;
920
+ aiImage(prompt: string, options?: {
921
+ model?: string;
922
+ images?: string[];
923
+ size?: string;
924
+ quality?: 'auto' | 'low' | 'medium' | 'high';
925
+ background?: 'auto' | 'transparent' | 'opaque';
926
+ n?: number;
927
+ response_format?: 'url' | 'b64_json';
928
+ output_format?: 'png' | 'jpeg' | 'webp';
929
+ output_compression?: number;
930
+ moderation?: 'auto' | 'low';
931
+ signal?: AbortSignal;
932
+ }): Promise<BlinkResponse<any>>;
933
+ aiSpeech(text: string, options?: {
934
+ model?: string;
935
+ voice?: string;
936
+ response_format?: string;
937
+ speed?: number;
938
+ signal?: AbortSignal;
939
+ }): Promise<BlinkResponse<any>>;
940
+ aiTranscribe(audio: string | number[] | ArrayBuffer | Uint8Array, options?: {
941
+ model?: string;
942
+ language?: string;
943
+ response_format?: string;
944
+ signal?: AbortSignal;
945
+ }): Promise<BlinkResponse<any>>;
946
+ /**
947
+ * Data-specific requests
948
+ */
949
+ dataExtractFromUrl(projectId: string, request: ExtractFromUrlRequest): Promise<BlinkResponse<ExtractFromUrlResponse>>;
950
+ dataExtractFromBlob(projectId: string, file: File, chunking?: boolean, chunkSize?: number): Promise<BlinkResponse<ExtractFromBlobResponse>>;
951
+ dataScrape(projectId: string, request: ScrapeRequest): Promise<BlinkResponse<ScrapeResponse>>;
952
+ dataScreenshot(projectId: string, request: ScreenshotRequest): Promise<BlinkResponse<ScreenshotResponse>>;
953
+ dataFetch(projectId: string, request: FetchRequest): Promise<BlinkResponse<FetchResponse | AsyncFetchResponse>>;
954
+ dataSearch(projectId: string, request: SearchRequest): Promise<BlinkResponse<SearchResponse>>;
955
+ /**
956
+ * Connector requests
957
+ */
958
+ private formatProviderForPath;
959
+ connectorStatus(provider: ConnectorProvider): Promise<BlinkResponse<ConnectorStatusResponse>>;
960
+ connectorExecute<TParams = Record<string, unknown>, TData = any>(provider: ConnectorProvider, request: ConnectorExecuteRequest<TParams>): Promise<BlinkResponse<ConnectorExecuteResponse<TData>>>;
961
+ connectorSaveApiKey<TMetadata = Record<string, unknown>>(provider: ConnectorProvider, request: ConnectorApiKeyRequest<TMetadata>): Promise<BlinkResponse<ConnectorApiKeyResponse>>;
962
+ /**
963
+ * Realtime-specific requests
964
+ */
965
+ realtimePublish(projectId: string, request: {
966
+ channel: string;
967
+ type: string;
968
+ data: any;
969
+ userId?: string;
970
+ metadata?: Record<string, any>;
971
+ }): Promise<BlinkResponse<{
972
+ messageId: string;
973
+ channel: string;
974
+ timestamp: number;
975
+ }>>;
976
+ realtimeGetPresence(projectId: string, channel: string): Promise<BlinkResponse<{
977
+ channel: string;
978
+ users: any[];
979
+ count: number;
980
+ }>>;
981
+ realtimeGetMessages(projectId: string, options: {
982
+ channel: string;
983
+ limit?: number;
984
+ start?: string;
985
+ end?: string;
986
+ }): Promise<BlinkResponse<{
987
+ channel: string;
988
+ messages: any[];
989
+ count: number;
990
+ hasMore: boolean;
991
+ }>>;
992
+ /**
993
+ * Private helper methods
994
+ */
995
+ private buildUrl;
996
+ private parseResponse;
997
+ private handleErrorResponse;
998
+ /**
999
+ * Parse Vercel AI SDK data stream format
1000
+ * Handles text chunks (0:"text"), partial objects (2:[...]), and metadata (d:, e:)
1001
+ */
1002
+ private parseDataStream;
1003
+ }
1004
+
1005
+ /**
1006
+ * Platform detection for cross-platform compatibility
1007
+ * Detects whether code is running on web, React Native, or Node.js
1008
+ */
1009
+ type Platform = 'web' | 'react-native' | 'node';
1010
+ /**
1011
+ * Current platform
1012
+ */
1013
+ declare const platform: Platform;
1014
+ /**
1015
+ * Platform detection helpers
1016
+ */
1017
+ declare const isWeb: boolean;
1018
+ declare const isReactNative: boolean;
1019
+ declare const isNode: boolean;
1020
+ declare const isBrowser: boolean;
1021
+
1022
+ /**
1023
+ * Blink Auth Module - Client-side authentication management
1024
+ * Handles token storage, user state, and authentication flows
1025
+ */
1026
+
1027
+ type AuthStateChangeCallback = (state: AuthState) => void;
1028
+ declare class BlinkAuth {
1029
+ private config;
1030
+ private authConfig;
1031
+ private authState;
1032
+ private listeners;
1033
+ private readonly authUrl;
1034
+ private readonly coreUrl;
1035
+ private parentWindowTokens;
1036
+ private isIframe;
1037
+ private initializationPromise;
1038
+ private isInitialized;
1039
+ private storage;
1040
+ constructor(config: BlinkClientConfig);
1041
+ /**
1042
+ * Generate project-scoped storage key
1043
+ */
1044
+ private getStorageKey;
1045
+ /**
1046
+ * Migrate existing global tokens to project-scoped storage
1047
+ * DISABLED: We don't migrate global blink_tokens anymore because:
1048
+ * 1. Platform uses blink_tokens for platform auth (different user)
1049
+ * 2. Migrating platform tokens would cause project to show wrong user
1050
+ * 3. Projects should always authenticate fresh via their own flow
1051
+ */
1052
+ private migrateExistingTokens;
1053
+ /**
1054
+ * Wait for authentication initialization to complete
1055
+ */
1056
+ private waitForInitialization;
1057
+ /**
1058
+ * Setup listener for tokens from parent window
1059
+ */
1060
+ private setupParentWindowListener;
1061
+ /**
1062
+ * Initialize authentication from stored tokens or URL fragments
1063
+ */
1064
+ initialize(): Promise<void>;
1065
+ /**
1066
+ * Redirect to Blink auth page
1067
+ */
1068
+ login(nextUrl?: string): void;
1069
+ /**
1070
+ * Logout and clear stored tokens
1071
+ */
1072
+ logout(redirectUrl?: string): void;
1073
+ /**
1074
+ * Check if user is authenticated
1075
+ */
1076
+ isAuthenticated(): boolean;
1077
+ /**
1078
+ * Get current user (sync)
1079
+ */
1080
+ currentUser(): BlinkUser | null;
1081
+ /**
1082
+ * Get current access token
1083
+ */
1084
+ getToken(): string | null;
1085
+ /**
1086
+ * Check if access token is expired based on timestamp
1087
+ */
1088
+ private isAccessTokenExpired;
1089
+ /**
1090
+ * Check if refresh token is expired based on timestamp
1091
+ */
1092
+ private isRefreshTokenExpired;
1093
+ /**
1094
+ * Get a valid access token, refreshing if necessary
1095
+ */
1096
+ getValidToken(): Promise<string | null>;
1097
+ /**
1098
+ * Fetch current user profile from API
1099
+ * Gracefully waits for auth initialization to complete before throwing errors
1100
+ */
1101
+ me(): Promise<BlinkUser>;
1102
+ /**
1103
+ * Sign up with email and password (headless mode)
1104
+ */
1105
+ signUp(data: SignUpData): Promise<BlinkUser>;
1106
+ /**
1107
+ * Sign in with email and password (headless mode)
1108
+ */
1109
+ signInWithEmail(email: string, password: string): Promise<BlinkUser>;
1110
+ /**
1111
+ * Sign in with Google (headless mode)
1112
+ *
1113
+ * **Universal OAuth** - Works on both Web and React Native!
1114
+ *
1115
+ * On React Native, requires `webBrowser` to be configured in client:
1116
+ * ```typescript
1117
+ * const blink = createClient({
1118
+ * auth: { mode: 'headless', webBrowser: WebBrowser }
1119
+ * })
1120
+ * await blink.auth.signInWithGoogle() // Works on both platforms!
1121
+ * ```
1122
+ */
1123
+ signInWithGoogle(options?: AuthOptions): Promise<BlinkUser>;
1124
+ /**
1125
+ * Sign in with GitHub (headless mode)
1126
+ *
1127
+ * **Universal OAuth** - Works on both Web and React Native!
1128
+ * See signInWithGoogle() for setup instructions.
1129
+ */
1130
+ signInWithGitHub(options?: AuthOptions): Promise<BlinkUser>;
1131
+ /**
1132
+ * Sign in with Apple (headless mode)
1133
+ *
1134
+ * **Universal OAuth** - Works on both Web and React Native!
1135
+ * See signInWithGoogle() for setup instructions.
1136
+ */
1137
+ signInWithApple(options?: AuthOptions): Promise<BlinkUser>;
1138
+ /**
1139
+ * Sign in with Microsoft (headless mode)
1140
+ *
1141
+ * **Universal OAuth** - Works on both Web and React Native!
1142
+ * See signInWithGoogle() for setup instructions.
1143
+ */
1144
+ signInWithMicrosoft(options?: AuthOptions): Promise<BlinkUser>;
1145
+ /**
1146
+ * Initiate OAuth for mobile without deep linking (expo-web-browser pattern)
1147
+ *
1148
+ * This method:
1149
+ * 1. Generates a unique session ID
1150
+ * 2. Returns OAuth URL with session parameter
1151
+ * 3. App opens URL in expo-web-browser
1152
+ * 4. App polls checkMobileOAuthSession() until complete
1153
+ *
1154
+ * @param provider - OAuth provider (google, github, apple, etc.)
1155
+ * @param options - Optional metadata
1156
+ * @returns Session ID and OAuth URL
1157
+ *
1158
+ * @example
1159
+ * // React Native with expo-web-browser
1160
+ * import * as WebBrowser from 'expo-web-browser';
1161
+ *
1162
+ * const { sessionId, authUrl } = await blink.auth.initiateMobileOAuth('google');
1163
+ *
1164
+ * // Open browser
1165
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1166
+ *
1167
+ * // Poll for completion
1168
+ * const user = await blink.auth.pollMobileOAuthSession(sessionId);
1169
+ * console.log('Authenticated:', user.email);
1170
+ */
1171
+ initiateMobileOAuth(provider: AuthProvider, options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1172
+ sessionId: string;
1173
+ authUrl: string;
1174
+ }>;
1175
+ /**
1176
+ * Check mobile OAuth session status (single check)
1177
+ *
1178
+ * @param sessionId - Session ID from initiateMobileOAuth
1179
+ * @returns Tokens if session is complete, null if still pending
1180
+ */
1181
+ checkMobileOAuthSession(sessionId: string): Promise<AuthTokens | null>;
1182
+ /**
1183
+ * Poll mobile OAuth session until complete (convenience method)
1184
+ *
1185
+ * @param sessionId - Session ID from initiateMobileOAuth
1186
+ * @param options - Polling options
1187
+ * @returns Authenticated user
1188
+ *
1189
+ * @example
1190
+ * const { sessionId, authUrl } = await blink.auth.initiateMobileOAuth('google');
1191
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1192
+ * const user = await blink.auth.pollMobileOAuthSession(sessionId, {
1193
+ * maxAttempts: 60,
1194
+ * intervalMs: 1000
1195
+ * });
1196
+ */
1197
+ pollMobileOAuthSession(sessionId: string, options?: {
1198
+ maxAttempts?: number;
1199
+ intervalMs?: number;
1200
+ }): Promise<BlinkUser>;
1201
+ /**
1202
+ * Sign in with OAuth provider using expo-web-browser (React Native)
1203
+ *
1204
+ * This is a convenience method that handles the entire flow:
1205
+ * 1. Initiates mobile OAuth session
1206
+ * 2. Returns auth URL to open in WebBrowser
1207
+ * 3. Provides polling function to call after browser opens
1208
+ *
1209
+ * @param provider - OAuth provider
1210
+ * @returns Object with authUrl and authenticate function
1211
+ *
1212
+ * @example
1213
+ * import * as WebBrowser from 'expo-web-browser';
1214
+ *
1215
+ * const { authUrl, authenticate } = await blink.auth.signInWithProviderMobile('google');
1216
+ *
1217
+ * // Open browser
1218
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1219
+ *
1220
+ * // Wait for authentication
1221
+ * const user = await authenticate();
1222
+ */
1223
+ signInWithProviderMobile(provider: AuthProvider, options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1224
+ authUrl: string;
1225
+ authenticate: () => Promise<BlinkUser>;
1226
+ }>;
1227
+ /**
1228
+ * Universal OAuth flow using session-based authentication (internal)
1229
+ * Works on ALL platforms: Web, iOS, Android
1230
+ * Uses expo-web-browser to open auth URL and polls for completion
1231
+ */
1232
+ private signInWithProviderUniversal;
1233
+ /**
1234
+ * Generic provider sign-in method (headless mode)
1235
+ *
1236
+ * **Universal OAuth** - Works seamlessly on both Web and React Native!
1237
+ *
1238
+ * When `webBrowser` is configured in the client, this method automatically
1239
+ * uses the session-based OAuth flow that works on ALL platforms.
1240
+ *
1241
+ * **Universal Setup (configure once, works everywhere):**
1242
+ * ```typescript
1243
+ * import * as WebBrowser from 'expo-web-browser'
1244
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
1245
+ *
1246
+ * const blink = createClient({
1247
+ * projectId: 'your-project',
1248
+ * auth: {
1249
+ * mode: 'headless',
1250
+ * webBrowser: WebBrowser // Pass the module here
1251
+ * },
1252
+ * storage: new AsyncStorageAdapter(AsyncStorage)
1253
+ * })
1254
+ *
1255
+ * // Now this works on ALL platforms - no platform checks needed!
1256
+ * const user = await blink.auth.signInWithGoogle()
1257
+ * ```
1258
+ *
1259
+ * @param provider - OAuth provider (google, github, apple, etc.)
1260
+ * @param options - Optional redirect URL and metadata
1261
+ * @returns Promise that resolves with authenticated user
1262
+ */
1263
+ signInWithProvider(provider: AuthProvider, options?: AuthOptions): Promise<BlinkUser>;
1264
+ /**
1265
+ * Generate password reset token (for custom email delivery)
1266
+ */
1267
+ generatePasswordResetToken(email: string): Promise<{
1268
+ token: string;
1269
+ expiresAt: string;
1270
+ resetUrl: string;
1271
+ }>;
1272
+ /**
1273
+ * Send password reset email (using Blink default email service)
1274
+ */
1275
+ sendPasswordResetEmail(email: string, options?: {
1276
+ redirectUrl?: string;
1277
+ }): Promise<void>;
1278
+ /**
1279
+ * Confirm password reset with token
1280
+ */
1281
+ confirmPasswordReset(token: string, newPassword: string): Promise<void>;
1282
+ /**
1283
+ * Change password (requires current authentication)
1284
+ */
1285
+ changePassword(oldPassword: string, newPassword: string): Promise<void>;
1286
+ /**
1287
+ * Generate email verification token (for custom email delivery)
1288
+ */
1289
+ generateEmailVerificationToken(): Promise<{
1290
+ token: string;
1291
+ expiresAt: string;
1292
+ verifyUrl: string;
1293
+ }>;
1294
+ /**
1295
+ * Send email verification (using Blink default email service)
1296
+ */
1297
+ sendEmailVerification(): Promise<void>;
1298
+ /**
1299
+ * Verify email with token
1300
+ */
1301
+ verifyEmail(token: string): Promise<void>;
1302
+ /**
1303
+ * Generate magic link token (for custom email delivery)
1304
+ */
1305
+ generateMagicLinkToken(email: string, options?: MagicLinkOptions): Promise<{
1306
+ token: string;
1307
+ expiresAt: string;
1308
+ magicUrl: string;
1309
+ }>;
1310
+ /**
1311
+ * Send magic link (using Blink default email service)
1312
+ */
1313
+ sendMagicLink(email: string, options?: MagicLinkOptions): Promise<void>;
1314
+ /**
1315
+ * Verify magic link (automatic on redirect)
1316
+ */
1317
+ verifyMagicLink(token?: string): Promise<BlinkUser>;
1318
+ /**
1319
+ * Get available providers for the current project
1320
+ */
1321
+ getAvailableProviders(): Promise<AuthProvider[]>;
1322
+ /**
1323
+ * Check if user has a specific role
1324
+ */
1325
+ hasRole(role: string | string[]): boolean;
1326
+ /**
1327
+ * Check if user can perform a specific action
1328
+ */
1329
+ can(permission: string, resource?: string): boolean;
1330
+ /**
1331
+ * Sign out (clear local tokens)
1332
+ * Note: With stateless tokens, this only clears local storage
1333
+ */
1334
+ signOut(): Promise<void>;
1335
+ /**
1336
+ * @deprecated Use signOut() instead. Kept for backward compatibility.
1337
+ */
1338
+ revokeAllSessions(): Promise<void>;
1339
+ /**
1340
+ * Recover auth state (clear corrupted tokens and re-initialize)
1341
+ */
1342
+ recoverAuthState(): Promise<void>;
1343
+ /**
1344
+ * Update user profile
1345
+ */
1346
+ updateMe(updates: Partial<BlinkUser>): Promise<BlinkUser>;
1347
+ /**
1348
+ * Manually set tokens (for server-side usage)
1349
+ */
1350
+ setToken(jwt: string, persist?: boolean): Promise<void>;
1351
+ /**
1352
+ * Manually set auth session from tokens (React Native deep link OAuth)
1353
+ *
1354
+ * Use this method to set the user session after receiving tokens from a deep link callback.
1355
+ * This is the React Native equivalent of automatic URL token detection on web.
1356
+ *
1357
+ * @param tokens - Auth tokens received from deep link or OAuth callback
1358
+ * @param persist - Whether to persist tokens to storage (default: true)
1359
+ *
1360
+ * @example
1361
+ * // React Native: Handle deep link OAuth callback
1362
+ * import * as Linking from 'expo-linking'
1363
+ *
1364
+ * Linking.addEventListener('url', async ({ url }) => {
1365
+ * const { queryParams } = Linking.parse(url)
1366
+ *
1367
+ * if (queryParams.access_token) {
1368
+ * await blink.auth.setSession({
1369
+ * access_token: queryParams.access_token,
1370
+ * refresh_token: queryParams.refresh_token,
1371
+ * expires_in: parseInt(queryParams.expires_in) || 3600,
1372
+ * refresh_expires_in: parseInt(queryParams.refresh_expires_in)
1373
+ * })
1374
+ *
1375
+ * console.log('User authenticated:', blink.auth.currentUser())
1376
+ * }
1377
+ * })
1378
+ */
1379
+ setSession(tokens: {
1380
+ access_token: string;
1381
+ refresh_token?: string;
1382
+ expires_in?: number;
1383
+ refresh_expires_in?: number;
1384
+ }, persist?: boolean): Promise<BlinkUser>;
1385
+ /**
1386
+ * Refresh access token using refresh token
1387
+ */
1388
+ refreshToken(): Promise<boolean>;
1389
+ /**
1390
+ * Add auth state change listener
1391
+ */
1392
+ onAuthStateChanged(callback: AuthStateChangeCallback): () => void;
1393
+ /**
1394
+ * Private helper methods
1395
+ */
1396
+ private validateStoredTokens;
1397
+ private setTokens;
1398
+ private clearTokens;
1399
+ private getStoredTokens;
1400
+ private extractTokensFromUrl;
1401
+ private clearUrlTokens;
1402
+ private redirectToAuth;
1403
+ private setLoading;
1404
+ private updateAuthState;
1405
+ /**
1406
+ * Generate secure random state for OAuth flows
1407
+ */
1408
+ private generateState;
1409
+ /**
1410
+ * Generate unique session ID for mobile OAuth
1411
+ */
1412
+ private generateSessionId;
1413
+ /**
1414
+ * Extract magic link token from URL
1415
+ */
1416
+ private extractMagicTokenFromUrl;
1417
+ /**
1418
+ * Map server error codes to BlinkAuthErrorCode
1419
+ */
1420
+ private mapErrorCodeFromResponse;
1421
+ /**
1422
+ * Setup cross-tab authentication synchronization
1423
+ */
1424
+ private setupCrossTabSync;
1425
+ }
1426
+
1427
+ /**
1428
+ * Blink Database Module - Table operations and query interface
1429
+ * Provides CRUD operations with PostgREST-compatible API
1430
+ */
1431
+
1432
+ declare class BlinkTable<T = any> implements TableOperations<T> {
1433
+ private tableName;
1434
+ private httpClient;
1435
+ private readonly actualTableName;
1436
+ constructor(tableName: string, httpClient: HttpClient);
1437
+ /**
1438
+ * Create a single record
1439
+ */
1440
+ create(data: Partial<T>, options?: CreateOptions): Promise<T>;
1441
+ /**
1442
+ * Create multiple records
1443
+ */
1444
+ createMany(data: Partial<T>[], options?: CreateOptions): Promise<T[]>;
1445
+ /**
1446
+ * Upsert a single record (insert or update on conflict)
1447
+ */
1448
+ upsert(data: Partial<T>, options?: UpsertOptions): Promise<T>;
1449
+ /**
1450
+ * Upsert multiple records
1451
+ */
1452
+ upsertMany(data: Partial<T>[], options?: UpsertOptions): Promise<T[]>;
1453
+ /**
1454
+ * Get a single record by ID
1455
+ */
1456
+ get(id: string): Promise<T | null>;
1457
+ /**
1458
+ * List records with filtering, sorting, and pagination
1459
+ */
1460
+ list(options?: QueryOptions): Promise<T[]>;
1461
+ /**
1462
+ * Update a single record by ID
1463
+ */
1464
+ update(id: string, data: Partial<T>, options?: UpdateOptions): Promise<T>;
1465
+ /**
1466
+ * Update multiple records
1467
+ */
1468
+ updateMany(updates: Array<{
1469
+ id: string;
1470
+ } & Partial<T>>, options?: UpdateOptions): Promise<T[]>;
1471
+ /**
1472
+ * Delete a single record by ID
1473
+ */
1474
+ delete(id: string): Promise<void>;
1475
+ /**
1476
+ * Delete multiple records based on filter
1477
+ */
1478
+ deleteMany(options: {
1479
+ where: FilterCondition;
1480
+ }): Promise<void>;
1481
+ /**
1482
+ * Count records matching filter
1483
+ */
1484
+ count(options?: {
1485
+ where?: FilterCondition;
1486
+ }): Promise<number>;
1487
+ /**
1488
+ * Check if any records exist matching filter
1489
+ */
1490
+ exists(options: {
1491
+ where: FilterCondition;
1492
+ }): Promise<boolean>;
1493
+ /**
1494
+ * Raw SQL query on this table (for advanced use cases)
1495
+ */
1496
+ sql<R = any>(query: string, params?: any[]): Promise<{
1497
+ rows: R[];
1498
+ columns: string[];
1499
+ rowCount: number;
1500
+ executionTime: number;
1501
+ }>;
1502
+ /**
1503
+ * Private helper methods
1504
+ */
1505
+ private extractCursor;
1506
+ }
1507
+ declare class BlinkDatabase {
1508
+ private httpClient;
1509
+ private tables;
1510
+ constructor(httpClient: HttpClient);
1511
+ /**
1512
+ * Get a table instance for any table name
1513
+ */
1514
+ table<T = any>(tableName: string): BlinkTable<T>;
1515
+ /**
1516
+ * Execute raw SQL query
1517
+ */
1518
+ sql<T = any>(query: string, params?: any[]): Promise<{
1519
+ rows: T[];
1520
+ columns: string[];
1521
+ rowCount: number;
1522
+ executionTime: number;
1523
+ }>;
1524
+ /**
1525
+ * Execute batch SQL operations
1526
+ */
1527
+ batch<T = any>(statements: Array<{
1528
+ sql: string;
1529
+ args?: any[];
1530
+ }>, mode?: 'read' | 'write'): Promise<{
1531
+ results: Array<{
1532
+ rows: T[];
1533
+ columns: string[];
1534
+ rowCount: number;
1535
+ }>;
1536
+ executionTime: number;
1537
+ success: boolean;
1538
+ }>;
1539
+ }
1540
+
1541
+ interface BlinkData {
1542
+ extractFromUrl(url: string, options?: {
1543
+ chunking?: boolean;
1544
+ chunkSize?: number;
1545
+ }): Promise<string | string[]>;
1546
+ extractFromBlob(file: File, options?: {
1547
+ chunking?: boolean;
1548
+ chunkSize?: number;
1549
+ }): Promise<string | string[]>;
1550
+ scrape(url: string): Promise<ScrapeResult>;
1551
+ screenshot(url: string, options?: {
1552
+ fullPage?: boolean;
1553
+ width?: number;
1554
+ height?: number;
1555
+ }): Promise<string>;
1556
+ fetch(request: FetchRequest): Promise<FetchResponse>;
1557
+ fetchAsync(request: Omit<FetchRequest, 'async'>): Promise<AsyncFetchResponse>;
1558
+ search(query: string, options?: {
1559
+ location?: string;
1560
+ type?: 'news' | 'images' | 'image' | 'videos' | 'video' | 'shopping' | 'shop';
1561
+ language?: string;
1562
+ limit?: number;
1563
+ }): Promise<SearchResponse>;
1564
+ }
1565
+ declare class BlinkDataImpl implements BlinkData {
1566
+ private httpClient;
1567
+ private projectId;
1568
+ constructor(httpClient: HttpClient, projectId: string);
1569
+ extractFromUrl(url: string, options?: {
1570
+ chunking?: boolean;
1571
+ chunkSize?: number;
1572
+ }): Promise<string | string[]>;
1573
+ extractFromBlob(file: File, options?: {
1574
+ chunking?: boolean;
1575
+ chunkSize?: number;
1576
+ }): Promise<string | string[]>;
1577
+ scrape(url: string): Promise<ScrapeResult>;
1578
+ screenshot(url: string, options?: {
1579
+ fullPage?: boolean;
1580
+ width?: number;
1581
+ height?: number;
1582
+ }): Promise<string>;
1583
+ fetch(request: FetchRequest): Promise<FetchResponse>;
1584
+ fetchAsync(request: Omit<FetchRequest, 'async'>): Promise<AsyncFetchResponse>;
1585
+ search(query: string, options?: {
1586
+ location?: string;
1587
+ type?: 'news' | 'images' | 'image' | 'videos' | 'video' | 'shopping' | 'shop';
1588
+ language?: string;
1589
+ limit?: number;
1590
+ }): Promise<SearchResponse>;
1591
+ }
1592
+
1593
+ /**
1594
+ * Blink Analytics Module
1595
+ * Provides automatic pageview tracking and custom event logging
1596
+ */
1597
+
1598
+ interface AnalyticsEvent {
1599
+ type: string;
1600
+ timestamp?: string;
1601
+ user_id?: string | null;
1602
+ user_email?: string | null;
1603
+ session_id?: string | null;
1604
+ pathname?: string | null;
1605
+ referrer?: string | null;
1606
+ screen_width?: number | null;
1607
+ channel?: string | null;
1608
+ utm_source?: string | null;
1609
+ utm_medium?: string | null;
1610
+ utm_campaign?: string | null;
1611
+ utm_content?: string | null;
1612
+ utm_term?: string | null;
1613
+ [key: string]: any;
1614
+ }
1615
+ interface BlinkAnalytics {
1616
+ log(eventName: string, data?: Record<string, any>): void;
1617
+ disable(): void;
1618
+ enable(): void;
1619
+ isEnabled(): boolean;
1620
+ setUserId(userId: string | null): void;
1621
+ setUserEmail(email: string | null): void;
1622
+ clearAttribution(): void;
1623
+ destroy(): void;
1624
+ }
1625
+ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
1626
+ private httpClient;
1627
+ private projectId;
1628
+ private queue;
1629
+ private timer;
1630
+ private enabled;
1631
+ private userId;
1632
+ private userEmail;
1633
+ private hasTrackedPageview;
1634
+ private utmParams;
1635
+ private persistedAttribution;
1636
+ constructor(httpClient: HttpClient, projectId: string);
1637
+ /**
1638
+ * Generate project-scoped storage key for analytics
1639
+ */
1640
+ private getStorageKey;
1641
+ /**
1642
+ * Log a custom analytics event
1643
+ */
1644
+ log(eventName: string, data?: Record<string, any>): void;
1645
+ /**
1646
+ * Disable analytics tracking
1647
+ */
1648
+ disable(): void;
1649
+ /**
1650
+ * Cleanup analytics instance (remove from global tracking)
1651
+ */
1652
+ destroy(): void;
1653
+ /**
1654
+ * Enable analytics tracking
1655
+ */
1656
+ enable(): void;
1657
+ /**
1658
+ * Check if analytics is enabled
1659
+ */
1660
+ isEnabled(): boolean;
1661
+ /**
1662
+ * Set the user ID for analytics events
1663
+ */
1664
+ setUserId(userId: string | null): void;
1665
+ /**
1666
+ * Set the user email for analytics events
1667
+ */
1668
+ setUserEmail(email: string | null): void;
1669
+ /**
1670
+ * Clear persisted attribution data
1671
+ */
1672
+ clearAttribution(): void;
1673
+ private buildEvent;
1674
+ private sanitizeData;
1675
+ private enqueue;
1676
+ private flush;
1677
+ private clearTimer;
1678
+ private getOrCreateSessionId;
1679
+ private createNewSession;
1680
+ private loadQueue;
1681
+ private persistQueue;
1682
+ private trackPageview;
1683
+ private setupRouteChangeListener;
1684
+ private setupUnloadListener;
1685
+ private captureUTMParams;
1686
+ private loadPersistedAttribution;
1687
+ private persistAttribution;
1688
+ private detectChannel;
1689
+ }
1690
+
1691
+ /**
1692
+ * Blink Client - Main SDK entry point
1693
+ * Factory function and client class for the Blink SDK
1694
+ */
1695
+
1696
+ interface BlinkClient {
1697
+ auth: BlinkAuth;
1698
+ db: BlinkDatabase;
1699
+ storage: BlinkStorage;
1700
+ ai: BlinkAI;
1701
+ data: BlinkData;
1702
+ realtime: BlinkRealtime;
1703
+ notifications: BlinkNotifications;
1704
+ analytics: BlinkAnalytics;
1705
+ connectors: BlinkConnectors;
1706
+ }
1707
+ /**
1708
+ * Create a new Blink client instance
1709
+ */
1710
+ declare function createClient(config: BlinkClientConfig): BlinkClient;
1711
+
1712
+ /**
1713
+ * Blink Storage Module
1714
+ * Handles file upload and file removal
1715
+ */
1716
+
1717
+ declare class BlinkStorageImpl implements BlinkStorage {
1718
+ private httpClient;
1719
+ constructor(httpClient: HttpClient);
1720
+ /**
1721
+ * Upload a file to project storage
1722
+ *
1723
+ * @param file - File, Blob, or Buffer to upload
1724
+ * @param path - Destination path within project storage (extension will be auto-corrected to match file type)
1725
+ * @param options - Upload options including upsert and progress callback
1726
+ * @returns Promise resolving to upload response with public URL
1727
+ *
1728
+ * @example
1729
+ * ```ts
1730
+ * // Extension automatically corrected to match actual file type
1731
+ * const { publicUrl } = await blink.storage.upload(
1732
+ * pngFile,
1733
+ * `avatars/${user.id}`, // No extension needed!
1734
+ * { upsert: true }
1735
+ * );
1736
+ * // If file is PNG, final path will be: avatars/user123.png
1737
+ *
1738
+ * // Or with extension (will be corrected if wrong)
1739
+ * const { publicUrl } = await blink.storage.upload(
1740
+ * pngFile,
1741
+ * `avatars/${user.id}.jpg`, // Wrong extension
1742
+ * { upsert: true }
1743
+ * );
1744
+ * // Final path will be: avatars/user123.png (auto-corrected!)
1745
+ * ```
1746
+ */
1747
+ upload(file: File | Blob | Buffer, path: string, options?: StorageUploadOptions): Promise<StorageUploadResponse>;
1748
+ /**
1749
+ * Detect file type from actual file content and correct path extension
1750
+ * This ensures the path extension always matches the actual file type
1751
+ */
1752
+ private detectFileTypeAndCorrectPath;
1753
+ /**
1754
+ * Get the first few bytes of a file to analyze its signature
1755
+ */
1756
+ private getFileSignature;
1757
+ /**
1758
+ * Detect file type from file signature (magic numbers)
1759
+ * This is the most reliable way to detect actual file type
1760
+ */
1761
+ private detectFileTypeFromSignature;
1762
+ /**
1763
+ * Get file extension from MIME type as fallback
1764
+ */
1765
+ private getExtensionFromMimeType;
1766
+ /**
1767
+ * Get a download URL for a file that triggers browser download
1768
+ *
1769
+ * @param path - Path to the file in project storage
1770
+ * @param options - Download options including custom filename
1771
+ * @returns Promise resolving to download response with download URL
1772
+ *
1773
+ * @example
1774
+ * ```ts
1775
+ * // Download with original filename
1776
+ * const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg');
1777
+ * window.open(downloadUrl, '_blank');
1778
+ *
1779
+ * // Download with custom filename
1780
+ * const { downloadUrl } = await blink.storage.download(
1781
+ * 'images/photo.jpg',
1782
+ * { filename: 'my-photo.jpg' }
1783
+ * );
1784
+ *
1785
+ * // Create download link in React
1786
+ * <a href={downloadUrl} download={filename}>Download Image</a>
1787
+ * ```
1788
+ */
1789
+ download(path: string, options?: {
1790
+ filename?: string;
1791
+ }): Promise<StorageDownloadResponse>;
1792
+ /**
1793
+ * Remove one or more files from project storage
1794
+ *
1795
+ * @param paths - File paths to remove
1796
+ * @returns Promise that resolves when files are removed
1797
+ *
1798
+ * @example
1799
+ * ```ts
1800
+ * await blink.storage.remove('avatars/user1.png');
1801
+ * await blink.storage.remove('file1.pdf', 'file2.pdf', 'file3.pdf');
1802
+ * ```
1803
+ */
1804
+ remove(...paths: string[]): Promise<void>;
1805
+ }
1806
+
1807
+ /**
1808
+ * Blink AI Module
1809
+ * Provides AI generation capabilities with Vercel AI SDK compatibility
1810
+ */
1811
+
1812
+ declare class BlinkAIImpl implements BlinkAI {
1813
+ private httpClient;
1814
+ constructor(httpClient: HttpClient);
1815
+ private readonly SUPPORTED_IMAGE_FORMATS;
1816
+ /**
1817
+ * Validates if a URL is a valid HTTPS image URL
1818
+ */
1819
+ private validateImageUrl;
1820
+ /**
1821
+ * Validates messages for image content
1822
+ */
1823
+ private validateMessages;
1824
+ /**
1825
+ * Get MIME type for audio format
1826
+ */
1827
+ private getMimeTypeForFormat;
1828
+ /**
1829
+ * Generates a text response using the Blink AI engine.
1830
+ *
1831
+ * @param options - An object containing either:
1832
+ * - `prompt`: a simple string prompt
1833
+ * - OR `messages`: an array of chat messages for conversation
1834
+ * - Plus optional model, search, maxSteps, experimental_continueSteps, maxTokens, temperature, signal parameters
1835
+ *
1836
+ * @example
1837
+ * ```ts
1838
+ * // Simple prompt
1839
+ * const { text } = await blink.ai.generateText({
1840
+ * prompt: "Write a poem about coding"
1841
+ * });
1842
+ *
1843
+ * // Chat messages (text only)
1844
+ * const { text } = await blink.ai.generateText({
1845
+ * messages: [
1846
+ * { role: "system", content: "You are a helpful assistant" },
1847
+ * { role: "user", content: "Explain quantum computing" }
1848
+ * ]
1849
+ * });
1850
+ *
1851
+ * // With image content
1852
+ * const { text } = await blink.ai.generateText({
1853
+ * messages: [
1854
+ * {
1855
+ * role: "user",
1856
+ * content: [
1857
+ * { type: "text", text: "What do you see in this image?" },
1858
+ * { type: "image", image: "https://example.com/photo.jpg" }
1859
+ * ]
1860
+ * }
1861
+ * ]
1862
+ * });
1863
+ *
1864
+ * // Mixed content with multiple images
1865
+ * const { text } = await blink.ai.generateText({
1866
+ * messages: [
1867
+ * {
1868
+ * role: "user",
1869
+ * content: [
1870
+ * { type: "text", text: "Compare these two images:" },
1871
+ * { type: "image", image: "https://example.com/image1.jpg" },
1872
+ * { type: "image", image: "https://example.com/image2.jpg" }
1873
+ * ]
1874
+ * }
1875
+ * ]
1876
+ * });
1877
+ *
1878
+ * // With options
1879
+ * const { text, usage } = await blink.ai.generateText({
1880
+ * prompt: "Summarize this article",
1881
+ * model: "gpt-4.1-mini",
1882
+ * maxTokens: 150,
1883
+ * temperature: 0.7
1884
+ * });
1885
+ *
1886
+ * // With web search (OpenAI models only)
1887
+ * const { text, sources } = await blink.ai.generateText({
1888
+ * prompt: "What are the latest developments in AI?",
1889
+ * model: "gpt-4.1-mini",
1890
+ * search: true // Enables web search
1891
+ * });
1892
+ *
1893
+ * // With advanced multi-step configuration
1894
+ * const { text } = await blink.ai.generateText({
1895
+ * prompt: "Research and analyze recent tech trends",
1896
+ * model: "gpt-4o",
1897
+ * search: true,
1898
+ * maxSteps: 10, // Allow up to 10 reasoning steps
1899
+ * experimental_continueSteps: true // Enable continued reasoning
1900
+ * });
1901
+ * ```
1902
+ *
1903
+ * @returns Promise<TextGenerationResponse> - Object containing:
1904
+ * - `text`: Generated text string
1905
+ * - `usage`: Token usage information
1906
+ * - `finishReason`: Why generation stopped ("stop", "length", etc.)
1907
+ */
1908
+ generateText(options: TextGenerationRequest): Promise<TextGenerationResponse>;
1909
+ /**
1910
+ * Streams text generation with real-time updates as the AI generates content.
1911
+ *
1912
+ * @param options - Same as generateText: either `prompt` or `messages` with optional parameters including search, maxSteps, experimental_continueSteps
1913
+ * @param onChunk - Callback function that receives each text chunk as it's generated
1914
+ *
1915
+ * @example
1916
+ * ```ts
1917
+ * // Stream with prompt
1918
+ * await blink.ai.streamText(
1919
+ * { prompt: "Write a short story about space exploration" },
1920
+ * (chunk) => {
1921
+ * process.stdout.write(chunk); // Real-time output
1922
+ * }
1923
+ * );
1924
+ *
1925
+ * // Stream with messages
1926
+ * await blink.ai.streamText(
1927
+ * {
1928
+ * messages: [
1929
+ * { role: "system", content: "You are a creative writer" },
1930
+ * { role: "user", content: "Write a haiku about programming" }
1931
+ * ]
1932
+ * },
1933
+ * (chunk) => updateUI(chunk)
1934
+ * );
1935
+ * ```
1936
+ *
1937
+ * @returns Promise<TextGenerationResponse> - Final complete response with full text and metadata
1938
+ */
1939
+ streamText(options: TextGenerationRequest, onChunk: (chunk: string) => void): Promise<TextGenerationResponse>;
1940
+ /**
1941
+ * Generates structured JSON objects using AI with schema validation.
1942
+ *
1943
+ * @param options - Object containing:
1944
+ * - `prompt`: Description of what object to generate (required)
1945
+ * - `schema`: JSON Schema to validate the generated object
1946
+ * - `output`: Type of output ("object", "array", "enum")
1947
+ * - `enum`: Array of allowed values for enum output
1948
+ * - Plus optional model, signal parameters
1949
+ *
1950
+ * @example
1951
+ * ```ts
1952
+ * // Generate user profile
1953
+ * const { object } = await blink.ai.generateObject({
1954
+ * prompt: "Generate a user profile for a software developer",
1955
+ * schema: {
1956
+ * type: "object",
1957
+ * properties: {
1958
+ * name: { type: "string" },
1959
+ * age: { type: "number" },
1960
+ * skills: { type: "array", items: { type: "string" } },
1961
+ * experience: { type: "number" }
1962
+ * },
1963
+ * required: ["name", "skills"]
1964
+ * }
1965
+ * });
1966
+ *
1967
+ * // Generate array of items
1968
+ * const { object } = await blink.ai.generateObject({
1969
+ * prompt: "List 5 programming languages",
1970
+ * output: "array",
1971
+ * schema: {
1972
+ * type: "array",
1973
+ * items: { type: "string" }
1974
+ * }
1975
+ * });
1976
+ *
1977
+ * // Generate enum value
1978
+ * const { object } = await blink.ai.generateObject({
1979
+ * prompt: "Choose the best programming language for web development",
1980
+ * output: "enum",
1981
+ * enum: ["JavaScript", "Python", "TypeScript", "Go"]
1982
+ * });
1983
+ * ```
1984
+ *
1985
+ * @returns Promise<ObjectGenerationResponse> - Object containing:
1986
+ * - `object`: The generated and validated JSON object/array/enum
1987
+ * - `usage`: Token usage information
1988
+ * - `finishReason`: Why generation stopped
1989
+ */
1990
+ generateObject(options: ObjectGenerationRequest): Promise<ObjectGenerationResponse>;
1991
+ /**
1992
+ * Streams structured object generation with real-time partial updates as the AI builds the object.
1993
+ *
1994
+ * @param options - Same as generateObject: prompt, schema, output type, etc.
1995
+ * @param onPartial - Callback function that receives partial object updates as they're generated
1996
+ *
1997
+ * @example
1998
+ * ```ts
1999
+ * // Stream object generation with schema
2000
+ * await blink.ai.streamObject(
2001
+ * {
2002
+ * prompt: "Generate a detailed product catalog entry",
2003
+ * schema: {
2004
+ * type: "object",
2005
+ * properties: {
2006
+ * name: { type: "string" },
2007
+ * price: { type: "number" },
2008
+ * description: { type: "string" },
2009
+ * features: { type: "array", items: { type: "string" } }
2010
+ * }
2011
+ * }
2012
+ * },
2013
+ * (partial) => {
2014
+ * console.log("Partial update:", partial);
2015
+ * updateProductForm(partial); // Update UI in real-time
2016
+ * }
2017
+ * );
2018
+ * ```
2019
+ *
2020
+ * @returns Promise<ObjectGenerationResponse> - Final complete object with metadata
2021
+ */
2022
+ streamObject(options: ObjectGenerationRequest, onPartial: (partial: any) => void): Promise<ObjectGenerationResponse>;
2023
+ /**
2024
+ * Generates images from text descriptions using AI image models.
2025
+ *
2026
+ * @param options - Object containing:
2027
+ * - `prompt`: Text description of the desired image (required, up to 100k characters)
2028
+ * - `model`: AI model to use (optional). Available models:
2029
+ * **Fal.ai Models (Recommended):**
2030
+ * - `"fal-ai/nano-banana"` (default) - Gemini 2.5 Flash Image (Fast)
2031
+ * - `"fal-ai/nano-banana-pro"` - Gemini 3 Pro Image (High quality)
2032
+ * - `"fal-ai/gemini-25-flash-image"` - Alias for nano-banana
2033
+ * - `"fal-ai/gemini-3-pro-image-preview"` - Alias for nano-banana-pro
2034
+ * **Legacy Gemini Models:**
2035
+ * - `"gemini-2.5-flash-image-preview"` - Direct Gemini API
2036
+ * - `"gemini-3-pro-image-preview"` - Direct Gemini API
2037
+ * - `n`: Number of images to generate (default: 1)
2038
+ * - `size`: Image dimensions (e.g., "1024x1024", "512x512")
2039
+ * - Plus optional signal parameter
2040
+ *
2041
+ * @example
2042
+ * ```ts
2043
+ * // Basic image generation (uses default fast model)
2044
+ * const { data } = await blink.ai.generateImage({
2045
+ * prompt: "A serene landscape with mountains and a lake at sunset"
2046
+ * });
2047
+ * console.log("Image URL:", data[0].url);
2048
+ *
2049
+ * // High quality generation with Pro model
2050
+ * const { data } = await blink.ai.generateImage({
2051
+ * prompt: "A detailed infographic about AI with charts and diagrams",
2052
+ * model: "fal-ai/nano-banana-pro",
2053
+ * n: 2
2054
+ * });
2055
+ *
2056
+ * // Fast generation with specific size
2057
+ * const { data } = await blink.ai.generateImage({
2058
+ * prompt: "A futuristic city skyline with flying cars",
2059
+ * model: "fal-ai/nano-banana",
2060
+ * size: "1024x1024",
2061
+ * n: 3
2062
+ * });
2063
+ * data.forEach((img, i) => console.log(`Image ${i+1}:`, img.url));
2064
+ *
2065
+ * // Using legacy Gemini model
2066
+ * const { data } = await blink.ai.generateImage({
2067
+ * prompt: "A cute robot mascot for a tech company",
2068
+ * model: "gemini-2.5-flash-image-preview"
2069
+ * });
2070
+ * ```
2071
+ *
2072
+ * @returns Promise<ImageGenerationResponse> - Object containing:
2073
+ * - `data`: Array of generated images with URLs
2074
+ * - `created`: Timestamp of generation
2075
+ * - `model`: The model used for generation
2076
+ */
2077
+ generateImage(options: {
2078
+ prompt: string;
2079
+ model?: string;
2080
+ n?: number;
2081
+ size?: string;
2082
+ signal?: AbortSignal;
2083
+ }): Promise<ImageGenerationResponse>;
2084
+ /**
2085
+ * Modifies existing images using AI image editing models with text prompts for image-to-image editing.
2086
+ *
2087
+ * @param options - Object containing:
2088
+ * - `images`: Array of public image URLs to modify (required, up to 50 images)
2089
+ * - `prompt`: Text description of desired modifications (required, up to 100k characters)
2090
+ * - `model`: AI model to use (optional). Available editing models:
2091
+ * **Fal.ai Editing Models (Recommended):**
2092
+ * - `"fal-ai/nano-banana/edit"` (default) - Flash editing (Fast)
2093
+ * - `"fal-ai/nano-banana-pro/edit"` - Pro editing (High quality)
2094
+ * - `"fal-ai/gemini-25-flash-image/edit"` - Alias for nano-banana/edit
2095
+ * - `"fal-ai/gemini-3-pro-image-preview/edit"` - Alias for nano-banana-pro/edit
2096
+ * **Legacy Gemini Models:**
2097
+ * - `"gemini-2.5-flash-image-preview"` - Direct Gemini API
2098
+ * - `"gemini-3-pro-image-preview"` - Direct Gemini API
2099
+ * - `n`: Number of output images to generate (default: 1)
2100
+ * - Plus optional signal parameter
2101
+ *
2102
+ * @example
2103
+ * ```ts
2104
+ * // Fast editing with default model
2105
+ * const { data } = await blink.ai.modifyImage({
2106
+ * images: ["https://storage.example.com/photo.jpg"],
2107
+ * prompt: "make it green"
2108
+ * });
2109
+ *
2110
+ * // High quality editing with Pro model
2111
+ * const { data } = await blink.ai.modifyImage({
2112
+ * images: ["https://storage.example.com/landscape.jpg"],
2113
+ * prompt: "add a tree in the background",
2114
+ * model: "fal-ai/nano-banana-pro/edit"
2115
+ * });
2116
+ *
2117
+ * // Professional headshots from casual photos
2118
+ * const { data } = await blink.ai.modifyImage({
2119
+ * images: [
2120
+ * "https://storage.example.com/user-photo-1.jpg",
2121
+ * "https://storage.example.com/user-photo-2.jpg"
2122
+ * ],
2123
+ * prompt: "Transform into professional business headshots with studio lighting",
2124
+ * model: "fal-ai/nano-banana/edit",
2125
+ * n: 4
2126
+ * });
2127
+ * data.forEach((img, i) => console.log(`Headshot ${i+1}:`, img.url));
2128
+ *
2129
+ * // Artistic style transformation
2130
+ * const { data } = await blink.ai.modifyImage({
2131
+ * images: ["https://storage.example.com/portrait.jpg"],
2132
+ * prompt: "Transform into oil painting style with dramatic lighting",
2133
+ * model: "fal-ai/nano-banana-pro/edit"
2134
+ * });
2135
+ *
2136
+ * // Background replacement
2137
+ * const { data } = await blink.ai.modifyImage({
2138
+ * images: ["https://storage.example.com/product.jpg"],
2139
+ * prompt: "Remove background and place on clean white studio background",
2140
+ * n: 2
2141
+ * });
2142
+ *
2143
+ * // Batch processing multiple photos
2144
+ * const userPhotos = [
2145
+ * "https://storage.example.com/photo1.jpg",
2146
+ * "https://storage.example.com/photo2.jpg",
2147
+ * "https://storage.example.com/photo3.jpg"
2148
+ * ];
2149
+ * const { data } = await blink.ai.modifyImage({
2150
+ * images: userPhotos,
2151
+ * prompt: "Convert to black and white vintage style photographs"
2152
+ * });
2153
+ *
2154
+ * // 🎨 Style Transfer - IMPORTANT: Provide all images in array
2155
+ * // ❌ WRONG - Don't reference other images in prompt
2156
+ * const wrong = await blink.ai.modifyImage({
2157
+ * images: [userPhotoUrl],
2158
+ * prompt: `Apply hairstyle from ${referenceUrl}`
2159
+ * });
2160
+ *
2161
+ * // ✅ CORRECT - Provide all images in array
2162
+ * const { data } = await blink.ai.modifyImage({
2163
+ * images: [userPhotoUrl, hairstyleReferenceUrl],
2164
+ * prompt: "Apply the hairstyle from the second image to the person in the first image"
2165
+ * });
2166
+ * ```
2167
+ *
2168
+ * @returns Promise<ImageGenerationResponse> - Object containing:
2169
+ * - `data`: Array of modified images with URLs
2170
+ * - `created`: Timestamp of generation
2171
+ * - `model`: The model used for editing
2172
+ */
2173
+ modifyImage(options: {
2174
+ images: string[];
2175
+ prompt: string;
2176
+ model?: string;
2177
+ n?: number;
2178
+ signal?: AbortSignal;
2179
+ }): Promise<ImageGenerationResponse>;
2180
+ /**
2181
+ * Converts text to speech using AI voice synthesis models.
2182
+ *
2183
+ * @param options - Object containing:
2184
+ * - `text`: Text content to convert to speech (required)
2185
+ * - `voice`: Voice to use ("alloy", "echo", "fable", "onyx", "nova", "shimmer")
2186
+ * - `response_format`: Audio format ("mp3", "opus", "aac", "flac", "wav", "pcm")
2187
+ * - `speed`: Speech speed (0.25 to 4.0, default: 1.0)
2188
+ * - Plus optional model, signal parameters
2189
+ *
2190
+ * @example
2191
+ * ```ts
2192
+ * // Basic text-to-speech
2193
+ * const { url } = await blink.ai.generateSpeech({
2194
+ * text: "Hello, welcome to our AI-powered application!"
2195
+ * });
2196
+ * console.log("Audio URL:", url);
2197
+ *
2198
+ * // Custom voice and format
2199
+ * const { url, voice, format } = await blink.ai.generateSpeech({
2200
+ * text: "This is a demonstration of our speech synthesis capabilities.",
2201
+ * voice: "nova",
2202
+ * response_format: "wav",
2203
+ * speed: 1.2
2204
+ * });
2205
+ * console.log(`Generated ${format} audio with ${voice} voice:`, url);
2206
+ *
2207
+ * // Slow, clear speech for accessibility
2208
+ * const { url } = await blink.ai.generateSpeech({
2209
+ * text: "Please listen carefully to these important instructions.",
2210
+ * voice: "echo",
2211
+ * speed: 0.8
2212
+ * });
2213
+ * ```
2214
+ *
2215
+ * @returns Promise<SpeechGenerationResponse> - Object containing:
2216
+ * - `url`: URL to the generated audio file
2217
+ * - `voice`: Voice used for generation
2218
+ * - `format`: Audio format
2219
+ * - `mimeType`: MIME type of the audio
2220
+ */
2221
+ generateSpeech(options: SpeechGenerationRequest): Promise<SpeechGenerationResponse>;
2222
+ /**
2223
+ * Transcribes audio content to text using AI speech recognition models.
2224
+ *
2225
+ * @param options - Object containing:
2226
+ * - `audio`: Audio input as URL string, base64 string, or number array buffer (required)
2227
+ * - `language`: Language code for transcription (e.g., "en", "es", "fr")
2228
+ * - `response_format`: Output format ("json", "text", "srt", "verbose_json", "vtt")
2229
+ * - Plus optional model, signal parameters
2230
+ *
2231
+ * @example
2232
+ * ```ts
2233
+ * // Transcribe from URL
2234
+ * const { text } = await blink.ai.transcribeAudio({
2235
+ * audio: "https://example.com/meeting-recording.mp3"
2236
+ * });
2237
+ * console.log("Transcription:", text);
2238
+ *
2239
+ * // Transcribe with language hint
2240
+ * const { text, language } = await blink.ai.transcribeAudio({
2241
+ * audio: "https://example.com/spanish-audio.wav",
2242
+ * language: "es"
2243
+ * });
2244
+ * console.log(`Transcribed ${language}:`, text);
2245
+ *
2246
+ * // Transcribe with timestamps (verbose format)
2247
+ * const result = await blink.ai.transcribeAudio({
2248
+ * audio: audioFileUrl,
2249
+ * response_format: "verbose_json"
2250
+ * });
2251
+ * result.segments?.forEach(segment => {
2252
+ * console.log(`${segment.start}s - ${segment.end}s: ${segment.text}`);
2253
+ * });
2254
+ *
2255
+ * // Transcribe from audio buffer
2256
+ * const audioBuffer = new Array(1024).fill(0); // Your audio data
2257
+ * const { text } = await blink.ai.transcribeAudio({
2258
+ * audio: audioBuffer,
2259
+ * language: "en"
2260
+ * });
2261
+ * ```
2262
+ *
2263
+ * @returns Promise<TranscriptionResponse> - Object containing:
2264
+ * - `text`: Transcribed text content
2265
+ * - `transcript`: Alias for text
2266
+ * - `segments`: Array of timestamped segments (if verbose format)
2267
+ * - `language`: Detected language
2268
+ * - `duration`: Audio duration in seconds
2269
+ */
2270
+ transcribeAudio(options: TranscriptionRequest): Promise<TranscriptionResponse>;
2271
+ }
2272
+
2273
+ /**
2274
+ * Blink Realtime Module - Real-time messaging and presence
2275
+ * Provides pub/sub messaging, presence tracking, and live updates
2276
+ */
2277
+
2278
+ declare class BlinkRealtimeChannel implements RealtimeChannel {
2279
+ private channelName;
2280
+ private httpClient;
2281
+ private projectId;
2282
+ private messageCallbacks;
2283
+ private presenceCallbacks;
2284
+ private websocket;
2285
+ private isSubscribed;
2286
+ private isConnected;
2287
+ private isConnecting;
2288
+ private reconnectTimer;
2289
+ private heartbeatTimer;
2290
+ private reconnectAttempts;
2291
+ private messageQueue;
2292
+ private pendingSubscription;
2293
+ private connectionPromise;
2294
+ constructor(channelName: string, httpClient: HttpClient, projectId: string);
2295
+ /**
2296
+ * Check if channel is ready for publishing
2297
+ */
2298
+ isReady(): boolean;
2299
+ subscribe(options?: {
2300
+ userId?: string;
2301
+ metadata?: Record<string, any>;
2302
+ }): Promise<void>;
2303
+ unsubscribe(): Promise<void>;
2304
+ publish(type: string, data: any, options?: {
2305
+ userId?: string;
2306
+ metadata?: Record<string, any>;
2307
+ }): Promise<string>;
2308
+ onMessage(callback: (message: RealtimeMessage) => void): () => void;
2309
+ onPresence(callback: (users: PresenceUser[]) => void): () => void;
2310
+ getPresence(): Promise<PresenceUser[]>;
2311
+ getMessages(options?: {
2312
+ limit?: number;
2313
+ before?: string;
2314
+ after?: string;
2315
+ }): Promise<RealtimeMessage[]>;
2316
+ /**
2317
+ * Ensure WebSocket connection is established and ready
2318
+ */
2319
+ private ensureConnected;
2320
+ /**
2321
+ * Send a message, queuing if socket not ready
2322
+ */
2323
+ private sendMessage;
2324
+ /**
2325
+ * Send a queued message and set up response handling
2326
+ */
2327
+ private sendQueuedMessage;
2328
+ /**
2329
+ * Flush all queued messages when connection becomes ready
2330
+ */
2331
+ private flushMessageQueue;
2332
+ private connectWebSocket;
2333
+ /**
2334
+ * Reject all queued messages with the given error
2335
+ */
2336
+ private rejectQueuedMessages;
2337
+ private handleWebSocketMessage;
2338
+ private startHeartbeat;
2339
+ private scheduleReconnect;
2340
+ private cleanup;
2341
+ }
2342
+ declare class BlinkRealtimeImpl implements BlinkRealtime {
2343
+ private httpClient;
2344
+ private projectId;
2345
+ private channels;
2346
+ private handlers;
2347
+ constructor(httpClient: HttpClient, projectId: string);
2348
+ channel(name: string): RealtimeChannel;
2349
+ subscribe(channelName: string, callback: (message: RealtimeMessage) => void, options?: RealtimeSubscribeOptions): Promise<() => void>;
2350
+ publish(channelName: string, type: string, data: any, options?: RealtimePublishOptions): Promise<string>;
2351
+ presence(channelName: string): Promise<PresenceUser[]>;
2352
+ onPresence(channelName: string, callback: (users: PresenceUser[]) => void): () => void;
2353
+ }
2354
+
2355
+ declare class BlinkConnectorsImpl implements BlinkConnectors {
2356
+ private httpClient;
2357
+ constructor(httpClient: HttpClient);
2358
+ status(provider: ConnectorProvider, options?: {
2359
+ account_id?: string;
2360
+ }): Promise<ConnectorStatusResponse>;
2361
+ execute<TParams = Record<string, unknown>, TData = any>(provider: ConnectorProvider, request: ConnectorExecuteRequest<TParams>): Promise<ConnectorExecuteResponse<TData>>;
2362
+ saveApiKey<TMetadata = Record<string, unknown>>(provider: ConnectorProvider, request: ConnectorApiKeyRequest<TMetadata>): Promise<ConnectorApiKeyResponse>;
2363
+ }
2364
+
2365
+ export { type AnalyticsEvent, AsyncStorageAdapter, type AuthState, type AuthStateChangeCallback, type AuthTokens, type BlinkAI, BlinkAIImpl, type BlinkAnalytics, BlinkAnalyticsImpl, type BlinkClient, type BlinkClientConfig, BlinkConnectorError, type BlinkConnectors, BlinkConnectorsImpl, type BlinkData, BlinkDataImpl, BlinkDatabase, type BlinkRealtime, BlinkRealtimeChannel, BlinkRealtimeError, BlinkRealtimeImpl, type BlinkStorage, BlinkStorageImpl, BlinkTable, type BlinkUser, type ConnectorApiKeyRequest, type ConnectorApiKeyResponse, type ConnectorAuthMode, type ConnectorExecuteRequest, type ConnectorExecuteResponse, type ConnectorProvider, type ConnectorStatusResponse, type CreateOptions, type DataExtraction, type FileObject, type FilterCondition, type ImageGenerationRequest, type ImageGenerationResponse, type Message, NoOpStorageAdapter, type ObjectGenerationRequest, type ObjectGenerationResponse, type PresenceUser, type QueryOptions, type RealtimeChannel, type RealtimeGetMessagesOptions, type RealtimeMessage, type RealtimePublishOptions, type RealtimeSubscribeOptions, type SearchRequest, type SearchResponse, type SpeechGenerationRequest, type SpeechGenerationResponse, type StorageAdapter, type StorageUploadOptions, type StorageUploadResponse, type TableOperations, type TextGenerationRequest, type TextGenerationResponse, type TokenUsage, type TranscriptionRequest, type TranscriptionResponse, type UpdateOptions, type UpsertOptions, type WebBrowserModule, WebStorageAdapter, createClient, getDefaultStorageAdapter, isBrowser, isNode, isReactNative, isWeb, platform };