@insforge/sdk 1.1.4 → 1.1.6-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/dist/index.d.mts CHANGED
@@ -24,6 +24,13 @@ interface InsForgeConfig {
24
24
  * This token will be used for all authenticated requests
25
25
  */
26
26
  edgeFunctionToken?: string;
27
+ /**
28
+ * Direct URL to Deno Subhosting functions (optional)
29
+ * When provided, SDK will try this URL first for function invocations.
30
+ * Falls back to proxy URL if subhosting returns 404.
31
+ * @example "https://{appKey}.functions.insforge.app"
32
+ */
33
+ functionsUrl?: string;
27
34
  /**
28
35
  * Custom fetch implementation (useful for Node.js environments)
29
36
  */
@@ -216,6 +223,24 @@ declare class Auth {
216
223
  } | null;
217
224
  error: InsForgeError | null;
218
225
  }>;
226
+ /**
227
+ * Sign in with an ID token from a native SDK (Google One Tap, etc.)
228
+ * Use this for native mobile apps or Google One Tap on web.
229
+ *
230
+ * @param credentials.provider - The identity provider (currently only 'google' is supported)
231
+ * @param credentials.token - The ID token from the native SDK
232
+ */
233
+ signInWithIdToken(credentials: {
234
+ provider: 'google';
235
+ token: string;
236
+ }): Promise<{
237
+ data: {
238
+ accessToken: string;
239
+ refreshToken?: string;
240
+ user: UserSchema;
241
+ } | null;
242
+ error: InsForgeError | null;
243
+ }>;
219
244
  /**
220
245
  * Get current session, automatically waits for pending OAuth callback
221
246
  * @deprecated Use `getCurrentUser` instead
@@ -637,9 +662,21 @@ interface FunctionInvokeOptions {
637
662
  */
638
663
  declare class Functions {
639
664
  private http;
640
- constructor(http: HttpClient);
665
+ private functionsUrl;
666
+ constructor(http: HttpClient, functionsUrl?: string);
667
+ /**
668
+ * Derive the subhosting URL from the base URL.
669
+ * Base URL pattern: https://{appKey}.{region}.insforge.app
670
+ * Functions URL: https://{appKey}.functions.insforge.app
671
+ * Only applies to .insforge.app domains.
672
+ */
673
+ private static deriveSubhostingUrl;
641
674
  /**
642
675
  * Invokes an Edge Function
676
+ *
677
+ * If functionsUrl is configured, tries direct subhosting first.
678
+ * Falls back to proxy URL if subhosting returns 404.
679
+ *
643
680
  * @param slug The function slug to invoke
644
681
  * @param options Request options
645
682
  */
package/dist/index.d.ts CHANGED
@@ -24,6 +24,13 @@ interface InsForgeConfig {
24
24
  * This token will be used for all authenticated requests
25
25
  */
26
26
  edgeFunctionToken?: string;
27
+ /**
28
+ * Direct URL to Deno Subhosting functions (optional)
29
+ * When provided, SDK will try this URL first for function invocations.
30
+ * Falls back to proxy URL if subhosting returns 404.
31
+ * @example "https://{appKey}.functions.insforge.app"
32
+ */
33
+ functionsUrl?: string;
27
34
  /**
28
35
  * Custom fetch implementation (useful for Node.js environments)
29
36
  */
@@ -216,6 +223,24 @@ declare class Auth {
216
223
  } | null;
217
224
  error: InsForgeError | null;
218
225
  }>;
226
+ /**
227
+ * Sign in with an ID token from a native SDK (Google One Tap, etc.)
228
+ * Use this for native mobile apps or Google One Tap on web.
229
+ *
230
+ * @param credentials.provider - The identity provider (currently only 'google' is supported)
231
+ * @param credentials.token - The ID token from the native SDK
232
+ */
233
+ signInWithIdToken(credentials: {
234
+ provider: 'google';
235
+ token: string;
236
+ }): Promise<{
237
+ data: {
238
+ accessToken: string;
239
+ refreshToken?: string;
240
+ user: UserSchema;
241
+ } | null;
242
+ error: InsForgeError | null;
243
+ }>;
219
244
  /**
220
245
  * Get current session, automatically waits for pending OAuth callback
221
246
  * @deprecated Use `getCurrentUser` instead
@@ -637,9 +662,21 @@ interface FunctionInvokeOptions {
637
662
  */
638
663
  declare class Functions {
639
664
  private http;
640
- constructor(http: HttpClient);
665
+ private functionsUrl;
666
+ constructor(http: HttpClient, functionsUrl?: string);
667
+ /**
668
+ * Derive the subhosting URL from the base URL.
669
+ * Base URL pattern: https://{appKey}.{region}.insforge.app
670
+ * Functions URL: https://{appKey}.functions.insforge.app
671
+ * Only applies to .insforge.app domains.
672
+ */
673
+ private static deriveSubhostingUrl;
641
674
  /**
642
675
  * Invokes an Edge Function
676
+ *
677
+ * If functionsUrl is configured, tries direct subhosting first.
678
+ * Falls back to proxy URL if subhosting returns 404.
679
+ *
643
680
  * @param slug The function slug to invoke
644
681
  * @param options Request options
645
682
  */
package/dist/index.js CHANGED
@@ -610,6 +610,30 @@ var Auth = class {
610
610
  return wrapError(error, "An unexpected error occurred during OAuth code exchange");
611
611
  }
612
612
  }
613
+ /**
614
+ * Sign in with an ID token from a native SDK (Google One Tap, etc.)
615
+ * Use this for native mobile apps or Google One Tap on web.
616
+ *
617
+ * @param credentials.provider - The identity provider (currently only 'google' is supported)
618
+ * @param credentials.token - The ID token from the native SDK
619
+ */
620
+ async signInWithIdToken(credentials) {
621
+ try {
622
+ const { provider, token } = credentials;
623
+ const response = await this.http.post("/api/auth/id-token?client_type=mobile", { provider, token }, { credentials: "include" });
624
+ this.saveSessionFromResponse(response);
625
+ return {
626
+ data: {
627
+ accessToken: response.accessToken,
628
+ refreshToken: response.refreshToken,
629
+ user: response.user
630
+ },
631
+ error: null
632
+ };
633
+ } catch (error) {
634
+ return wrapError(error, "An unexpected error occurred during ID token sign in");
635
+ }
636
+ }
613
637
  // ============================================================================
614
638
  // Session Management
615
639
  // ============================================================================
@@ -681,19 +705,6 @@ var Auth = class {
681
705
  const session = this.tokenManager.getSession();
682
706
  if (session) {
683
707
  this.http.setAuthToken(session.accessToken);
684
- if (!session.user || Object.keys(session.user).length === 0) {
685
- try {
686
- const authResponse = await this.http.get(
687
- "/api/auth/sessions/current",
688
- { credentials: "include" }
689
- );
690
- if (authResponse.user) {
691
- session.user = authResponse.user;
692
- this.tokenManager.setUser(authResponse.user);
693
- }
694
- } catch {
695
- }
696
- }
697
708
  return { data: { user: session.user }, error: null };
698
709
  }
699
710
  if (typeof window !== "undefined") {
@@ -1307,7 +1318,11 @@ var ChatCompletions = class {
1307
1318
  // New plugin options
1308
1319
  webSearch: params.webSearch,
1309
1320
  fileParser: params.fileParser,
1310
- thinking: params.thinking
1321
+ thinking: params.thinking,
1322
+ // Tool calling options
1323
+ tools: params.tools,
1324
+ toolChoice: params.toolChoice,
1325
+ parallelToolCalls: params.parallelToolCalls
1311
1326
  };
1312
1327
  if (params.stream) {
1313
1328
  const headers = this.http.getHeaders();
@@ -1342,10 +1357,12 @@ var ChatCompletions = class {
1342
1357
  message: {
1343
1358
  role: "assistant",
1344
1359
  content,
1360
+ // Include tool_calls if present (from tool calling)
1361
+ ...response.tool_calls?.length && { tool_calls: response.tool_calls },
1345
1362
  // Include annotations if present (from web search or file parsing)
1346
- ...response.annotations && { annotations: response.annotations }
1363
+ ...response.annotations?.length && { annotations: response.annotations }
1347
1364
  },
1348
- finish_reason: "stop"
1365
+ finish_reason: response.tool_calls?.length ? "tool_calls" : "stop"
1349
1366
  }
1350
1367
  ],
1351
1368
  usage: response.metadata?.usage || {
@@ -1387,7 +1404,24 @@ var ChatCompletions = class {
1387
1404
  delta: {
1388
1405
  content: data.chunk || data.content
1389
1406
  },
1390
- finish_reason: data.done ? "stop" : null
1407
+ finish_reason: null
1408
+ }
1409
+ ]
1410
+ };
1411
+ }
1412
+ if (data.tool_calls?.length) {
1413
+ yield {
1414
+ id: `chatcmpl-${Date.now()}`,
1415
+ object: "chat.completion.chunk",
1416
+ created: Math.floor(Date.now() / 1e3),
1417
+ model,
1418
+ choices: [
1419
+ {
1420
+ index: 0,
1421
+ delta: {
1422
+ tool_calls: data.tool_calls
1423
+ },
1424
+ finish_reason: "tool_calls"
1391
1425
  }
1392
1426
  ]
1393
1427
  };
@@ -1524,31 +1558,58 @@ var Images = class {
1524
1558
  };
1525
1559
 
1526
1560
  // src/modules/functions.ts
1527
- var Functions = class {
1528
- constructor(http) {
1561
+ var Functions = class _Functions {
1562
+ constructor(http, functionsUrl) {
1529
1563
  this.http = http;
1564
+ this.functionsUrl = functionsUrl || _Functions.deriveSubhostingUrl(http.baseUrl);
1565
+ }
1566
+ /**
1567
+ * Derive the subhosting URL from the base URL.
1568
+ * Base URL pattern: https://{appKey}.{region}.insforge.app
1569
+ * Functions URL: https://{appKey}.functions.insforge.app
1570
+ * Only applies to .insforge.app domains.
1571
+ */
1572
+ static deriveSubhostingUrl(baseUrl) {
1573
+ try {
1574
+ const { hostname } = new URL(baseUrl);
1575
+ if (!hostname.endsWith(".insforge.app")) return void 0;
1576
+ const appKey = hostname.split(".")[0];
1577
+ return `https://${appKey}.functions.insforge.app`;
1578
+ } catch {
1579
+ return void 0;
1580
+ }
1530
1581
  }
1531
1582
  /**
1532
1583
  * Invokes an Edge Function
1584
+ *
1585
+ * If functionsUrl is configured, tries direct subhosting first.
1586
+ * Falls back to proxy URL if subhosting returns 404.
1587
+ *
1533
1588
  * @param slug The function slug to invoke
1534
1589
  * @param options Request options
1535
1590
  */
1536
1591
  async invoke(slug, options = {}) {
1592
+ const { method = "POST", body, headers = {} } = options;
1593
+ if (this.functionsUrl) {
1594
+ try {
1595
+ const data = await this.http.request(method, `${this.functionsUrl}/${slug}`, {
1596
+ body,
1597
+ headers
1598
+ });
1599
+ return { data, error: null };
1600
+ } catch (error) {
1601
+ if (error?.statusCode === 404) {
1602
+ } else {
1603
+ return { data: null, error };
1604
+ }
1605
+ }
1606
+ }
1537
1607
  try {
1538
- const { method = "POST", body, headers = {} } = options;
1539
1608
  const path = `/functions/${slug}`;
1540
- const data = await this.http.request(
1541
- method,
1542
- path,
1543
- { body, headers }
1544
- );
1609
+ const data = await this.http.request(method, path, { body, headers });
1545
1610
  return { data, error: null };
1546
1611
  } catch (error) {
1547
- return {
1548
- data: null,
1549
- error
1550
- // Pass through the full error object with all properties
1551
- };
1612
+ return { data: null, error };
1552
1613
  }
1553
1614
  }
1554
1615
  };
@@ -1846,7 +1907,7 @@ var InsForgeClient = class {
1846
1907
  this.database = new Database(this.http, this.tokenManager);
1847
1908
  this.storage = new Storage(this.http);
1848
1909
  this.ai = new AI(this.http);
1849
- this.functions = new Functions(this.http);
1910
+ this.functions = new Functions(this.http, config.functionsUrl);
1850
1911
  this.realtime = new Realtime(this.http.baseUrl, this.tokenManager, config.anonKey);
1851
1912
  this.emails = new Emails(this.http);
1852
1913
  }