@insforge/sdk 1.0.3-refresh.1 → 1.0.5-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +259 -249
- package/dist/index.d.mts +56 -33
- package/dist/index.d.ts +56 -33
- package/dist/index.js +146 -142
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -142
- package/dist/index.mjs.map +1 -1
- package/package.json +68 -68
- package/dist/browser.mjs +0 -3059
- package/dist/browser.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, OAuthProvidersSchema, GetPublicAuthConfigResponse,
|
|
2
|
-
export { AuthErrorResponse, CreateSessionRequest, CreateUserRequest, RealtimeErrorPayload, SocketMessage, SubscribeResponse, UserSchema } from '@insforge/shared-schemas';
|
|
1
|
+
import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, OAuthProvidersSchema, GetPublicAuthConfigResponse, GetProfileResponse, SendVerificationEmailRequest, SendResetPasswordEmailRequest, ExchangeResetPasswordTokenRequest, VerifyEmailRequest, VerifyEmailResponse, StorageFileSchema, ListObjectsResponseSchema, ChatCompletionRequest, ImageGenerationRequest, SubscribeResponse, SocketMessage, SendRawEmailRequest, SendEmailResponse } from '@insforge/shared-schemas';
|
|
2
|
+
export { AuthErrorResponse, CreateSessionRequest, CreateUserRequest, RealtimeErrorPayload, SendRawEmailRequest as SendEmailOptions, SendEmailResponse, SocketMessage, SubscribeResponse, UserSchema } from '@insforge/shared-schemas';
|
|
3
3
|
import * as _supabase_postgrest_js from '@supabase/postgrest-js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -162,29 +162,13 @@ declare class TokenManager {
|
|
|
162
162
|
* Uses shared schemas for type safety
|
|
163
163
|
*/
|
|
164
164
|
|
|
165
|
-
/**
|
|
166
|
-
* Dynamic profile type - represents flexible profile data from database
|
|
167
|
-
* Fields can vary based on database schema configuration.
|
|
168
|
-
* All fields are converted from snake_case (database) to camelCase (API)
|
|
169
|
-
*/
|
|
170
|
-
type ProfileData = Record<string, any> & {
|
|
171
|
-
id: string;
|
|
172
|
-
createdAt?: string;
|
|
173
|
-
updatedAt?: string;
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* Dynamic profile update type - for updating profile fields
|
|
177
|
-
* Supports any fields that exist in the profile table
|
|
178
|
-
*/
|
|
179
|
-
type UpdateProfileData = Partial<Record<string, any>>;
|
|
180
165
|
declare class Auth {
|
|
181
166
|
private http;
|
|
182
167
|
private tokenManager;
|
|
183
|
-
private database;
|
|
184
168
|
constructor(http: HttpClient, tokenManager: TokenManager);
|
|
185
169
|
/**
|
|
186
170
|
* Automatically detect and handle OAuth callback parameters in the URL
|
|
187
|
-
* This runs
|
|
171
|
+
* This runs after initialization to seamlessly complete the OAuth flow
|
|
188
172
|
* Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
|
|
189
173
|
*/
|
|
190
174
|
private detectAuthCallback;
|
|
@@ -248,22 +232,17 @@ declare class Auth {
|
|
|
248
232
|
*/
|
|
249
233
|
getCurrentUser(): Promise<{
|
|
250
234
|
data: {
|
|
251
|
-
user:
|
|
252
|
-
id: UserIdSchema;
|
|
253
|
-
email: EmailSchema;
|
|
254
|
-
role: RoleSchema;
|
|
255
|
-
};
|
|
256
|
-
profile: ProfileData | null;
|
|
235
|
+
user: UserSchema;
|
|
257
236
|
} | null;
|
|
258
237
|
error: any | null;
|
|
259
238
|
}>;
|
|
260
239
|
/**
|
|
261
240
|
* Get any user's profile by ID
|
|
262
|
-
* Returns profile information from the users table
|
|
241
|
+
* Returns profile information from the users table
|
|
263
242
|
*/
|
|
264
243
|
getProfile(userId: string): Promise<{
|
|
265
|
-
data:
|
|
266
|
-
error:
|
|
244
|
+
data: GetProfileResponse | null;
|
|
245
|
+
error: InsForgeError | null;
|
|
267
246
|
}>;
|
|
268
247
|
/**
|
|
269
248
|
* Get the current session (only session data, no API call)
|
|
@@ -278,10 +257,11 @@ declare class Auth {
|
|
|
278
257
|
/**
|
|
279
258
|
* Set/Update the current user's profile
|
|
280
259
|
* Updates profile information in the users table (supports any dynamic fields)
|
|
260
|
+
* Requires authentication
|
|
281
261
|
*/
|
|
282
|
-
setProfile(profile:
|
|
283
|
-
data:
|
|
284
|
-
error:
|
|
262
|
+
setProfile(profile: Record<string, unknown>): Promise<{
|
|
263
|
+
data: GetProfileResponse | null;
|
|
264
|
+
error: InsForgeError | null;
|
|
285
265
|
}>;
|
|
286
266
|
/**
|
|
287
267
|
* Send email verification (code or link based on config)
|
|
@@ -678,7 +658,8 @@ declare class Realtime {
|
|
|
678
658
|
private connectPromise;
|
|
679
659
|
private subscribedChannels;
|
|
680
660
|
private eventListeners;
|
|
681
|
-
|
|
661
|
+
private anonKey?;
|
|
662
|
+
constructor(baseUrl: string, tokenManager: TokenManager, anonKey?: string);
|
|
682
663
|
private notifyListeners;
|
|
683
664
|
/**
|
|
684
665
|
* Connect to the realtime server
|
|
@@ -761,6 +742,47 @@ declare class Realtime {
|
|
|
761
742
|
getSubscribedChannels(): string[];
|
|
762
743
|
}
|
|
763
744
|
|
|
745
|
+
/**
|
|
746
|
+
* Emails client for sending custom emails
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```typescript
|
|
750
|
+
* // Send a simple email
|
|
751
|
+
* const { data, error } = await client.emails.send({
|
|
752
|
+
* to: 'user@example.com',
|
|
753
|
+
* subject: 'Welcome!',
|
|
754
|
+
* html: '<h1>Welcome to our platform</h1>'
|
|
755
|
+
* });
|
|
756
|
+
*
|
|
757
|
+
* if (error) {
|
|
758
|
+
* console.error('Failed to send:', error.message);
|
|
759
|
+
* return;
|
|
760
|
+
* }
|
|
761
|
+
* // Email sent successfully - data is {} (empty object)
|
|
762
|
+
*
|
|
763
|
+
* // Send to multiple recipients with CC
|
|
764
|
+
* const { data, error } = await client.emails.send({
|
|
765
|
+
* to: ['user1@example.com', 'user2@example.com'],
|
|
766
|
+
* cc: 'manager@example.com',
|
|
767
|
+
* subject: 'Team Update',
|
|
768
|
+
* html: '<p>Here is the latest update...</p>',
|
|
769
|
+
* replyTo: 'support@example.com'
|
|
770
|
+
* });
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
declare class Emails {
|
|
774
|
+
private http;
|
|
775
|
+
constructor(http: HttpClient);
|
|
776
|
+
/**
|
|
777
|
+
* Send a custom HTML email
|
|
778
|
+
* @param options Email options including recipients, subject, and HTML content
|
|
779
|
+
*/
|
|
780
|
+
send(options: SendRawEmailRequest): Promise<{
|
|
781
|
+
data: SendEmailResponse | null;
|
|
782
|
+
error: Error | null;
|
|
783
|
+
}>;
|
|
784
|
+
}
|
|
785
|
+
|
|
764
786
|
/**
|
|
765
787
|
* Main InsForge SDK Client
|
|
766
788
|
*
|
|
@@ -808,6 +830,7 @@ declare class InsForgeClient {
|
|
|
808
830
|
readonly ai: AI;
|
|
809
831
|
readonly functions: Functions;
|
|
810
832
|
readonly realtime: Realtime;
|
|
833
|
+
readonly emails: Emails;
|
|
811
834
|
constructor(config?: InsForgeConfig);
|
|
812
835
|
/**
|
|
813
836
|
* Get the underlying HTTP client for custom requests
|
|
@@ -829,4 +852,4 @@ declare class InsForgeClient {
|
|
|
829
852
|
|
|
830
853
|
declare function createClient(config: InsForgeConfig): InsForgeClient;
|
|
831
854
|
|
|
832
|
-
export { AI, type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, type ConnectionState, Database, type EventCallback, type FunctionInvokeOptions, Functions, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError,
|
|
855
|
+
export { AI, type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, type ConnectionState, Database, Emails, type EventCallback, type FunctionInvokeOptions, Functions, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, Realtime, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
AI: () => AI,
|
|
24
24
|
Auth: () => Auth,
|
|
25
25
|
Database: () => Database,
|
|
26
|
+
Emails: () => Emails,
|
|
26
27
|
Functions: () => Functions,
|
|
27
28
|
HttpClient: () => HttpClient,
|
|
28
29
|
InsForgeClient: () => InsForgeClient,
|
|
@@ -328,98 +329,7 @@ var TokenManager = class {
|
|
|
328
329
|
}
|
|
329
330
|
};
|
|
330
331
|
|
|
331
|
-
// src/modules/database-postgrest.ts
|
|
332
|
-
var import_postgrest_js = require("@supabase/postgrest-js");
|
|
333
|
-
function createInsForgePostgrestFetch(httpClient, tokenManager) {
|
|
334
|
-
return async (input, init) => {
|
|
335
|
-
const url = typeof input === "string" ? input : input.toString();
|
|
336
|
-
const urlObj = new URL(url);
|
|
337
|
-
const tableName = urlObj.pathname.slice(1);
|
|
338
|
-
const insforgeUrl = `${httpClient.baseUrl}/api/database/records/${tableName}${urlObj.search}`;
|
|
339
|
-
const token = tokenManager.getAccessToken();
|
|
340
|
-
const httpHeaders = httpClient.getHeaders();
|
|
341
|
-
const authToken = token || httpHeaders["Authorization"]?.replace("Bearer ", "");
|
|
342
|
-
const headers = new Headers(init?.headers);
|
|
343
|
-
if (authToken && !headers.has("Authorization")) {
|
|
344
|
-
headers.set("Authorization", `Bearer ${authToken}`);
|
|
345
|
-
}
|
|
346
|
-
const response = await fetch(insforgeUrl, {
|
|
347
|
-
...init,
|
|
348
|
-
headers
|
|
349
|
-
});
|
|
350
|
-
return response;
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
var Database = class {
|
|
354
|
-
constructor(httpClient, tokenManager) {
|
|
355
|
-
this.postgrest = new import_postgrest_js.PostgrestClient("http://dummy", {
|
|
356
|
-
fetch: createInsForgePostgrestFetch(httpClient, tokenManager),
|
|
357
|
-
headers: {}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Create a query builder for a table
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* // Basic query
|
|
365
|
-
* const { data, error } = await client.database
|
|
366
|
-
* .from('posts')
|
|
367
|
-
* .select('*')
|
|
368
|
-
* .eq('user_id', userId);
|
|
369
|
-
*
|
|
370
|
-
* // With count (Supabase style!)
|
|
371
|
-
* const { data, error, count } = await client.database
|
|
372
|
-
* .from('posts')
|
|
373
|
-
* .select('*', { count: 'exact' })
|
|
374
|
-
* .range(0, 9);
|
|
375
|
-
*
|
|
376
|
-
* // Just get count, no data
|
|
377
|
-
* const { count } = await client.database
|
|
378
|
-
* .from('posts')
|
|
379
|
-
* .select('*', { count: 'exact', head: true });
|
|
380
|
-
*
|
|
381
|
-
* // Complex queries with OR
|
|
382
|
-
* const { data } = await client.database
|
|
383
|
-
* .from('posts')
|
|
384
|
-
* .select('*, users!inner(*)')
|
|
385
|
-
* .or('status.eq.active,status.eq.pending');
|
|
386
|
-
*
|
|
387
|
-
* // All features work:
|
|
388
|
-
* - Nested selects
|
|
389
|
-
* - Foreign key expansion
|
|
390
|
-
* - OR/AND/NOT conditions
|
|
391
|
-
* - Count with head
|
|
392
|
-
* - Range pagination
|
|
393
|
-
* - Upserts
|
|
394
|
-
*/
|
|
395
|
-
from(table) {
|
|
396
|
-
return this.postgrest.from(table);
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
|
|
400
332
|
// src/modules/auth.ts
|
|
401
|
-
function convertDbProfileToCamelCase(dbProfile) {
|
|
402
|
-
const result = {
|
|
403
|
-
id: dbProfile.id
|
|
404
|
-
};
|
|
405
|
-
Object.keys(dbProfile).forEach((key) => {
|
|
406
|
-
result[key] = dbProfile[key];
|
|
407
|
-
if (key.includes("_")) {
|
|
408
|
-
const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
409
|
-
result[camelKey] = dbProfile[key];
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
return result;
|
|
413
|
-
}
|
|
414
|
-
function convertCamelCaseToDbProfile(profile) {
|
|
415
|
-
const dbProfile = {};
|
|
416
|
-
Object.keys(profile).forEach((key) => {
|
|
417
|
-
if (profile[key] === void 0) return;
|
|
418
|
-
const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
419
|
-
dbProfile[snakeKey] = profile[key];
|
|
420
|
-
});
|
|
421
|
-
return dbProfile;
|
|
422
|
-
}
|
|
423
333
|
function isHostedAuthEnvironment() {
|
|
424
334
|
if (typeof window === "undefined") {
|
|
425
335
|
return false;
|
|
@@ -437,12 +347,11 @@ var Auth = class {
|
|
|
437
347
|
constructor(http, tokenManager) {
|
|
438
348
|
this.http = http;
|
|
439
349
|
this.tokenManager = tokenManager;
|
|
440
|
-
this.database = new Database(http, tokenManager);
|
|
441
350
|
this.detectAuthCallback();
|
|
442
351
|
}
|
|
443
352
|
/**
|
|
444
353
|
* Automatically detect and handle OAuth callback parameters in the URL
|
|
445
|
-
* This runs
|
|
354
|
+
* This runs after initialization to seamlessly complete the OAuth flow
|
|
446
355
|
* Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
|
|
447
356
|
*/
|
|
448
357
|
detectAuthCallback() {
|
|
@@ -464,7 +373,8 @@ var Auth = class {
|
|
|
464
373
|
user: {
|
|
465
374
|
id: userId,
|
|
466
375
|
email,
|
|
467
|
-
name: name || "",
|
|
376
|
+
profile: { name: name || "" },
|
|
377
|
+
metadata: null,
|
|
468
378
|
// These fields are not provided by backend OAuth callback
|
|
469
379
|
// They'll be populated when calling getCurrentUser()
|
|
470
380
|
emailVerified: false,
|
|
@@ -659,20 +569,19 @@ var Auth = class {
|
|
|
659
569
|
*/
|
|
660
570
|
async getCurrentUser() {
|
|
661
571
|
try {
|
|
662
|
-
const
|
|
663
|
-
if (
|
|
572
|
+
const user = this.tokenManager.getUser();
|
|
573
|
+
if (user) {
|
|
574
|
+
return { data: { user }, error: null };
|
|
575
|
+
}
|
|
576
|
+
const accessToken = this.tokenManager.getAccessToken();
|
|
577
|
+
if (!accessToken) {
|
|
664
578
|
return { data: null, error: null };
|
|
665
579
|
}
|
|
666
|
-
this.http.setAuthToken(
|
|
580
|
+
this.http.setAuthToken(accessToken);
|
|
667
581
|
const authResponse = await this.http.get("/api/auth/sessions/current");
|
|
668
|
-
const { data: profile, error: profileError } = await this.database.from("users").select("*").eq("id", authResponse.user.id).single();
|
|
669
|
-
if (profileError && profileError.code !== "PGRST116") {
|
|
670
|
-
return { data: null, error: profileError };
|
|
671
|
-
}
|
|
672
582
|
return {
|
|
673
583
|
data: {
|
|
674
|
-
user: authResponse.user
|
|
675
|
-
profile: profile ? convertDbProfileToCamelCase(profile) : null
|
|
584
|
+
user: authResponse.user
|
|
676
585
|
},
|
|
677
586
|
error: null
|
|
678
587
|
};
|
|
@@ -696,17 +605,28 @@ var Auth = class {
|
|
|
696
605
|
}
|
|
697
606
|
/**
|
|
698
607
|
* Get any user's profile by ID
|
|
699
|
-
* Returns profile information from the users table
|
|
608
|
+
* Returns profile information from the users table
|
|
700
609
|
*/
|
|
701
610
|
async getProfile(userId) {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
return {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
611
|
+
try {
|
|
612
|
+
const response = await this.http.get(`/api/auth/profiles/${userId}`);
|
|
613
|
+
return {
|
|
614
|
+
data: response,
|
|
615
|
+
error: null
|
|
616
|
+
};
|
|
617
|
+
} catch (error) {
|
|
618
|
+
if (error instanceof InsForgeError) {
|
|
619
|
+
return { data: null, error };
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
data: null,
|
|
623
|
+
error: new InsForgeError(
|
|
624
|
+
"An unexpected error occurred while fetching user profile",
|
|
625
|
+
500,
|
|
626
|
+
"UNEXPECTED_ERROR"
|
|
627
|
+
)
|
|
628
|
+
};
|
|
708
629
|
}
|
|
709
|
-
return { data: null, error };
|
|
710
630
|
}
|
|
711
631
|
/**
|
|
712
632
|
* Get the current session (only session data, no API call)
|
|
@@ -777,42 +697,31 @@ var Auth = class {
|
|
|
777
697
|
/**
|
|
778
698
|
* Set/Update the current user's profile
|
|
779
699
|
* Updates profile information in the users table (supports any dynamic fields)
|
|
700
|
+
* Requires authentication
|
|
780
701
|
*/
|
|
781
702
|
async setProfile(profile) {
|
|
782
|
-
|
|
783
|
-
|
|
703
|
+
try {
|
|
704
|
+
const response = await this.http.patch(
|
|
705
|
+
"/api/auth/profiles/current",
|
|
706
|
+
{ profile }
|
|
707
|
+
);
|
|
708
|
+
return {
|
|
709
|
+
data: response,
|
|
710
|
+
error: null
|
|
711
|
+
};
|
|
712
|
+
} catch (error) {
|
|
713
|
+
if (error instanceof InsForgeError) {
|
|
714
|
+
return { data: null, error };
|
|
715
|
+
}
|
|
784
716
|
return {
|
|
785
717
|
data: null,
|
|
786
718
|
error: new InsForgeError(
|
|
787
|
-
"
|
|
788
|
-
|
|
789
|
-
"
|
|
719
|
+
"An unexpected error occurred while updating user profile",
|
|
720
|
+
500,
|
|
721
|
+
"UNEXPECTED_ERROR"
|
|
790
722
|
)
|
|
791
723
|
};
|
|
792
724
|
}
|
|
793
|
-
if (!session.user?.id) {
|
|
794
|
-
const { data: data2, error: error2 } = await this.getCurrentUser();
|
|
795
|
-
if (error2) {
|
|
796
|
-
return { data: null, error: error2 };
|
|
797
|
-
}
|
|
798
|
-
if (data2?.user) {
|
|
799
|
-
session.user = {
|
|
800
|
-
id: data2.user.id,
|
|
801
|
-
email: data2.user.email,
|
|
802
|
-
name: "",
|
|
803
|
-
emailVerified: false,
|
|
804
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
805
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
806
|
-
};
|
|
807
|
-
this.tokenManager.saveSession(session);
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
const dbProfile = convertCamelCaseToDbProfile(profile);
|
|
811
|
-
const { data, error } = await this.database.from("users").update(dbProfile).eq("id", session.user.id).select().single();
|
|
812
|
-
if (data) {
|
|
813
|
-
return { data: convertDbProfileToCamelCase(data), error: null };
|
|
814
|
-
}
|
|
815
|
-
return { data: null, error };
|
|
816
725
|
}
|
|
817
726
|
/**
|
|
818
727
|
* Send email verification (code or link based on config)
|
|
@@ -997,6 +906,75 @@ var Auth = class {
|
|
|
997
906
|
}
|
|
998
907
|
};
|
|
999
908
|
|
|
909
|
+
// src/modules/database-postgrest.ts
|
|
910
|
+
var import_postgrest_js = require("@supabase/postgrest-js");
|
|
911
|
+
function createInsForgePostgrestFetch(httpClient, tokenManager) {
|
|
912
|
+
return async (input, init) => {
|
|
913
|
+
const url = typeof input === "string" ? input : input.toString();
|
|
914
|
+
const urlObj = new URL(url);
|
|
915
|
+
const tableName = urlObj.pathname.slice(1);
|
|
916
|
+
const insforgeUrl = `${httpClient.baseUrl}/api/database/records/${tableName}${urlObj.search}`;
|
|
917
|
+
const token = tokenManager.getAccessToken();
|
|
918
|
+
const httpHeaders = httpClient.getHeaders();
|
|
919
|
+
const authToken = token || httpHeaders["Authorization"]?.replace("Bearer ", "");
|
|
920
|
+
const headers = new Headers(init?.headers);
|
|
921
|
+
if (authToken && !headers.has("Authorization")) {
|
|
922
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
923
|
+
}
|
|
924
|
+
const response = await fetch(insforgeUrl, {
|
|
925
|
+
...init,
|
|
926
|
+
headers
|
|
927
|
+
});
|
|
928
|
+
return response;
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
var Database = class {
|
|
932
|
+
constructor(httpClient, tokenManager) {
|
|
933
|
+
this.postgrest = new import_postgrest_js.PostgrestClient("http://dummy", {
|
|
934
|
+
fetch: createInsForgePostgrestFetch(httpClient, tokenManager),
|
|
935
|
+
headers: {}
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Create a query builder for a table
|
|
940
|
+
*
|
|
941
|
+
* @example
|
|
942
|
+
* // Basic query
|
|
943
|
+
* const { data, error } = await client.database
|
|
944
|
+
* .from('posts')
|
|
945
|
+
* .select('*')
|
|
946
|
+
* .eq('user_id', userId);
|
|
947
|
+
*
|
|
948
|
+
* // With count (Supabase style!)
|
|
949
|
+
* const { data, error, count } = await client.database
|
|
950
|
+
* .from('posts')
|
|
951
|
+
* .select('*', { count: 'exact' })
|
|
952
|
+
* .range(0, 9);
|
|
953
|
+
*
|
|
954
|
+
* // Just get count, no data
|
|
955
|
+
* const { count } = await client.database
|
|
956
|
+
* .from('posts')
|
|
957
|
+
* .select('*', { count: 'exact', head: true });
|
|
958
|
+
*
|
|
959
|
+
* // Complex queries with OR
|
|
960
|
+
* const { data } = await client.database
|
|
961
|
+
* .from('posts')
|
|
962
|
+
* .select('*, users!inner(*)')
|
|
963
|
+
* .or('status.eq.active,status.eq.pending');
|
|
964
|
+
*
|
|
965
|
+
* // All features work:
|
|
966
|
+
* - Nested selects
|
|
967
|
+
* - Foreign key expansion
|
|
968
|
+
* - OR/AND/NOT conditions
|
|
969
|
+
* - Count with head
|
|
970
|
+
* - Range pagination
|
|
971
|
+
* - Upserts
|
|
972
|
+
*/
|
|
973
|
+
from(table) {
|
|
974
|
+
return this.postgrest.from(table);
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
|
|
1000
978
|
// src/modules/storage.ts
|
|
1001
979
|
var StorageBucket = class {
|
|
1002
980
|
constructor(bucketName, http) {
|
|
@@ -1522,13 +1500,14 @@ var Functions = class {
|
|
|
1522
1500
|
var import_socket = require("socket.io-client");
|
|
1523
1501
|
var CONNECT_TIMEOUT = 1e4;
|
|
1524
1502
|
var Realtime = class {
|
|
1525
|
-
constructor(baseUrl, tokenManager) {
|
|
1503
|
+
constructor(baseUrl, tokenManager, anonKey) {
|
|
1526
1504
|
this.socket = null;
|
|
1527
1505
|
this.connectPromise = null;
|
|
1528
1506
|
this.subscribedChannels = /* @__PURE__ */ new Set();
|
|
1529
1507
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1530
1508
|
this.baseUrl = baseUrl;
|
|
1531
1509
|
this.tokenManager = tokenManager;
|
|
1510
|
+
this.anonKey = anonKey;
|
|
1532
1511
|
}
|
|
1533
1512
|
notifyListeners(event, payload) {
|
|
1534
1513
|
const listeners = this.eventListeners.get(event);
|
|
@@ -1554,7 +1533,7 @@ var Realtime = class {
|
|
|
1554
1533
|
}
|
|
1555
1534
|
this.connectPromise = new Promise((resolve, reject) => {
|
|
1556
1535
|
const session = this.tokenManager.getSession();
|
|
1557
|
-
const token = session?.accessToken;
|
|
1536
|
+
const token = session?.accessToken ?? this.anonKey;
|
|
1558
1537
|
this.socket = (0, import_socket.io)(this.baseUrl, {
|
|
1559
1538
|
transports: ["websocket"],
|
|
1560
1539
|
auth: token ? { token } : void 0
|
|
@@ -1751,6 +1730,29 @@ var Realtime = class {
|
|
|
1751
1730
|
}
|
|
1752
1731
|
};
|
|
1753
1732
|
|
|
1733
|
+
// src/modules/email.ts
|
|
1734
|
+
var Emails = class {
|
|
1735
|
+
constructor(http) {
|
|
1736
|
+
this.http = http;
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Send a custom HTML email
|
|
1740
|
+
* @param options Email options including recipients, subject, and HTML content
|
|
1741
|
+
*/
|
|
1742
|
+
async send(options) {
|
|
1743
|
+
try {
|
|
1744
|
+
const data = await this.http.post(
|
|
1745
|
+
"/api/email/send-raw",
|
|
1746
|
+
options
|
|
1747
|
+
);
|
|
1748
|
+
return { data, error: null };
|
|
1749
|
+
} catch (error) {
|
|
1750
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
1751
|
+
return { data: null, error: normalizedError };
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1754
1756
|
// src/client.ts
|
|
1755
1757
|
var InsForgeClient = class {
|
|
1756
1758
|
constructor(config = {}) {
|
|
@@ -1773,7 +1775,8 @@ var InsForgeClient = class {
|
|
|
1773
1775
|
this.storage = new Storage(this.http);
|
|
1774
1776
|
this.ai = new AI(this.http);
|
|
1775
1777
|
this.functions = new Functions(this.http);
|
|
1776
|
-
this.realtime = new Realtime(this.http.baseUrl, this.tokenManager);
|
|
1778
|
+
this.realtime = new Realtime(this.http.baseUrl, this.tokenManager, config.anonKey);
|
|
1779
|
+
this.emails = new Emails(this.http);
|
|
1777
1780
|
}
|
|
1778
1781
|
/**
|
|
1779
1782
|
* Get the underlying HTTP client for custom requests
|
|
@@ -1807,6 +1810,7 @@ var index_default = InsForgeClient;
|
|
|
1807
1810
|
AI,
|
|
1808
1811
|
Auth,
|
|
1809
1812
|
Database,
|
|
1813
|
+
Emails,
|
|
1810
1814
|
Functions,
|
|
1811
1815
|
HttpClient,
|
|
1812
1816
|
InsForgeClient,
|