@insforge/sdk 1.0.3-refresh.1 → 1.0.4
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/README.md +10 -0
- package/dist/index.d.mts +54 -32
- package/dist/index.d.ts +54 -32
- package/dist/index.js +142 -139
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -139
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/browser.mjs +0 -3059
- package/dist/browser.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -64,6 +64,16 @@ await insforge.auth.signInWithOAuth({
|
|
|
64
64
|
// Get current user
|
|
65
65
|
const { data: user } = await insforge.auth.getCurrentUser();
|
|
66
66
|
|
|
67
|
+
// Get any user's profile by ID (public endpoint)
|
|
68
|
+
const { data: profile, error } = await insforge.auth.getProfile('user-id-here');
|
|
69
|
+
|
|
70
|
+
// Update current user's profile (requires authentication)
|
|
71
|
+
const { data: updatedProfile, error } = await insforge.auth.setProfile({
|
|
72
|
+
displayName: 'John Doe',
|
|
73
|
+
bio: 'Software developer',
|
|
74
|
+
avatarUrl: 'https://example.com/avatar.jpg'
|
|
75
|
+
});
|
|
76
|
+
|
|
67
77
|
// Sign out
|
|
68
78
|
await insforge.auth.signOut();
|
|
69
79
|
```
|
package/dist/index.d.mts
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)
|
|
@@ -761,6 +741,47 @@ declare class Realtime {
|
|
|
761
741
|
getSubscribedChannels(): string[];
|
|
762
742
|
}
|
|
763
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Emails client for sending custom emails
|
|
746
|
+
*
|
|
747
|
+
* @example
|
|
748
|
+
* ```typescript
|
|
749
|
+
* // Send a simple email
|
|
750
|
+
* const { data, error } = await client.emails.send({
|
|
751
|
+
* to: 'user@example.com',
|
|
752
|
+
* subject: 'Welcome!',
|
|
753
|
+
* html: '<h1>Welcome to our platform</h1>'
|
|
754
|
+
* });
|
|
755
|
+
*
|
|
756
|
+
* if (error) {
|
|
757
|
+
* console.error('Failed to send:', error.message);
|
|
758
|
+
* return;
|
|
759
|
+
* }
|
|
760
|
+
* // Email sent successfully - data is {} (empty object)
|
|
761
|
+
*
|
|
762
|
+
* // Send to multiple recipients with CC
|
|
763
|
+
* const { data, error } = await client.emails.send({
|
|
764
|
+
* to: ['user1@example.com', 'user2@example.com'],
|
|
765
|
+
* cc: 'manager@example.com',
|
|
766
|
+
* subject: 'Team Update',
|
|
767
|
+
* html: '<p>Here is the latest update...</p>',
|
|
768
|
+
* replyTo: 'support@example.com'
|
|
769
|
+
* });
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
declare class Emails {
|
|
773
|
+
private http;
|
|
774
|
+
constructor(http: HttpClient);
|
|
775
|
+
/**
|
|
776
|
+
* Send a custom HTML email
|
|
777
|
+
* @param options Email options including recipients, subject, and HTML content
|
|
778
|
+
*/
|
|
779
|
+
send(options: SendRawEmailRequest): Promise<{
|
|
780
|
+
data: SendEmailResponse | null;
|
|
781
|
+
error: Error | null;
|
|
782
|
+
}>;
|
|
783
|
+
}
|
|
784
|
+
|
|
764
785
|
/**
|
|
765
786
|
* Main InsForge SDK Client
|
|
766
787
|
*
|
|
@@ -808,6 +829,7 @@ declare class InsForgeClient {
|
|
|
808
829
|
readonly ai: AI;
|
|
809
830
|
readonly functions: Functions;
|
|
810
831
|
readonly realtime: Realtime;
|
|
832
|
+
readonly emails: Emails;
|
|
811
833
|
constructor(config?: InsForgeConfig);
|
|
812
834
|
/**
|
|
813
835
|
* Get the underlying HTTP client for custom requests
|
|
@@ -829,4 +851,4 @@ declare class InsForgeClient {
|
|
|
829
851
|
|
|
830
852
|
declare function createClient(config: InsForgeConfig): InsForgeClient;
|
|
831
853
|
|
|
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,
|
|
854
|
+
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.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)
|
|
@@ -761,6 +741,47 @@ declare class Realtime {
|
|
|
761
741
|
getSubscribedChannels(): string[];
|
|
762
742
|
}
|
|
763
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Emails client for sending custom emails
|
|
746
|
+
*
|
|
747
|
+
* @example
|
|
748
|
+
* ```typescript
|
|
749
|
+
* // Send a simple email
|
|
750
|
+
* const { data, error } = await client.emails.send({
|
|
751
|
+
* to: 'user@example.com',
|
|
752
|
+
* subject: 'Welcome!',
|
|
753
|
+
* html: '<h1>Welcome to our platform</h1>'
|
|
754
|
+
* });
|
|
755
|
+
*
|
|
756
|
+
* if (error) {
|
|
757
|
+
* console.error('Failed to send:', error.message);
|
|
758
|
+
* return;
|
|
759
|
+
* }
|
|
760
|
+
* // Email sent successfully - data is {} (empty object)
|
|
761
|
+
*
|
|
762
|
+
* // Send to multiple recipients with CC
|
|
763
|
+
* const { data, error } = await client.emails.send({
|
|
764
|
+
* to: ['user1@example.com', 'user2@example.com'],
|
|
765
|
+
* cc: 'manager@example.com',
|
|
766
|
+
* subject: 'Team Update',
|
|
767
|
+
* html: '<p>Here is the latest update...</p>',
|
|
768
|
+
* replyTo: 'support@example.com'
|
|
769
|
+
* });
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
declare class Emails {
|
|
773
|
+
private http;
|
|
774
|
+
constructor(http: HttpClient);
|
|
775
|
+
/**
|
|
776
|
+
* Send a custom HTML email
|
|
777
|
+
* @param options Email options including recipients, subject, and HTML content
|
|
778
|
+
*/
|
|
779
|
+
send(options: SendRawEmailRequest): Promise<{
|
|
780
|
+
data: SendEmailResponse | null;
|
|
781
|
+
error: Error | null;
|
|
782
|
+
}>;
|
|
783
|
+
}
|
|
784
|
+
|
|
764
785
|
/**
|
|
765
786
|
* Main InsForge SDK Client
|
|
766
787
|
*
|
|
@@ -808,6 +829,7 @@ declare class InsForgeClient {
|
|
|
808
829
|
readonly ai: AI;
|
|
809
830
|
readonly functions: Functions;
|
|
810
831
|
readonly realtime: Realtime;
|
|
832
|
+
readonly emails: Emails;
|
|
811
833
|
constructor(config?: InsForgeConfig);
|
|
812
834
|
/**
|
|
813
835
|
* Get the underlying HTTP client for custom requests
|
|
@@ -829,4 +851,4 @@ declare class InsForgeClient {
|
|
|
829
851
|
|
|
830
852
|
declare function createClient(config: InsForgeConfig): InsForgeClient;
|
|
831
853
|
|
|
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,
|
|
854
|
+
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) {
|
|
@@ -1751,6 +1729,29 @@ var Realtime = class {
|
|
|
1751
1729
|
}
|
|
1752
1730
|
};
|
|
1753
1731
|
|
|
1732
|
+
// src/modules/email.ts
|
|
1733
|
+
var Emails = class {
|
|
1734
|
+
constructor(http) {
|
|
1735
|
+
this.http = http;
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Send a custom HTML email
|
|
1739
|
+
* @param options Email options including recipients, subject, and HTML content
|
|
1740
|
+
*/
|
|
1741
|
+
async send(options) {
|
|
1742
|
+
try {
|
|
1743
|
+
const data = await this.http.post(
|
|
1744
|
+
"/api/email/send-raw",
|
|
1745
|
+
options
|
|
1746
|
+
);
|
|
1747
|
+
return { data, error: null };
|
|
1748
|
+
} catch (error) {
|
|
1749
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
1750
|
+
return { data: null, error: normalizedError };
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1754
1755
|
// src/client.ts
|
|
1755
1756
|
var InsForgeClient = class {
|
|
1756
1757
|
constructor(config = {}) {
|
|
@@ -1774,6 +1775,7 @@ var InsForgeClient = class {
|
|
|
1774
1775
|
this.ai = new AI(this.http);
|
|
1775
1776
|
this.functions = new Functions(this.http);
|
|
1776
1777
|
this.realtime = new Realtime(this.http.baseUrl, this.tokenManager);
|
|
1778
|
+
this.emails = new Emails(this.http);
|
|
1777
1779
|
}
|
|
1778
1780
|
/**
|
|
1779
1781
|
* Get the underlying HTTP client for custom requests
|
|
@@ -1807,6 +1809,7 @@ var index_default = InsForgeClient;
|
|
|
1807
1809
|
AI,
|
|
1808
1810
|
Auth,
|
|
1809
1811
|
Database,
|
|
1812
|
+
Emails,
|
|
1810
1813
|
Functions,
|
|
1811
1814
|
HttpClient,
|
|
1812
1815
|
InsForgeClient,
|