@base44-preview/sdk 0.8.40-pr.240.b2b8abe → 0.8.40-pr.242.b74cef0

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.
@@ -139,9 +139,7 @@ export interface Base44Client {
139
139
  functions: FunctionsModule;
140
140
  /** {@link IntegrationsModule | Integrations module} with elevated permissions. */
141
141
  integrations: IntegrationsModule;
142
- /** {@link SsoModule | SSO module} for generating SSO tokens.
143
- * @internal
144
- */
142
+ /** {@link SsoModule | SSO module} for generating SSO tokens. */
145
143
  sso: SsoModule;
146
144
  /** Cleanup function to disconnect WebSocket connections. */
147
145
  cleanup: () => void;
@@ -1,13 +1,13 @@
1
1
  /**
2
- * A connection to the Base44 AI Gateway.
3
- *
4
- * Contains the base URL and bearer token to use with any OpenAI-compatible
5
- * client pointed at the Base44 AI Gateway.
2
+ * Connection details for the Base44 AI Gateway.
6
3
  */
7
4
  export interface AiGatewayConnection {
8
- /** Base URL of the gateway's OpenAI-compatible endpoint. */
5
+ /** Base URL of the gateway's OpenAI-compatible Chat Completions endpoint. */
9
6
  baseURL: string;
10
- /** Bearer token used to authenticate requests to the gateway. */
7
+ /**
8
+ * Bearer token that authenticates the request. Empty string when the caller is
9
+ * unauthenticated.
10
+ */
11
11
  token: string;
12
12
  }
13
13
  /**
@@ -25,13 +25,45 @@ export interface AiGatewayModuleConfig {
25
25
  /**
26
26
  * AI Gateway module for calling Base44's managed AI models from your own code.
27
27
  *
28
- * The gateway exposes an OpenAI-compatible Chat Completions endpoint, so any
29
- * OpenAI-compatible SDK works against it:
30
- * - Build custom AI agents or call models directly from your backend code
31
- * - Uses your app's models, billing, and credit quota, no API key to manage
28
+ * `connection()` hands you a `baseURL` and `token` that authenticate as your
29
+ * Base44 app. An OpenAI-compatible client is any library, such as the `openai`
30
+ * SDK or the Vercel AI SDK, that has the same request and response format
31
+ * as OpenAI's Chat Completions API and lets you point it at a custom `baseURL`
32
+ * instead of OpenAI's own servers. Pass `connection()`'s values to one of
33
+ * these clients and it works against Base44's gateway exactly as it would
34
+ * against the provider directly, no separate account, API key, or billing
35
+ * setup with the underlying model provider required.
36
+ *
37
+ * Call `connection()` from a backend function rather than the browser. This
38
+ * keeps your instructions, tools, and business logic server-side, and lets
39
+ * you enforce your own auth, rate, and spend limits around the call. The
40
+ * `token` it returns is the caller's regular session token, the same one
41
+ * used for every other SDK call.
42
+ *
43
+ * ## Models
44
+ *
45
+ * You can use any of the [models available through `InvokeLLM`](/developers/references/sdk/docs/type-aliases/integrations#invokellm).
46
+ * Pass `'automatic'` to let Base44 choose one, or pin a specific model such
47
+ * as `'claude_sonnet_4_6'`, `'gpt_5_5'`, or `'gemini_3_1_pro'`.
48
+ *
49
+ * ## Authentication Modes
50
+ *
51
+ * There's no permission difference between modes. Both just determine which
52
+ * token `connection()` returns:
53
+ *
54
+ * - **User authentication** (`base44.aiGateway`): Returns the signed-in app user's token.
55
+ * - **Service role authentication** (`base44.asServiceRole.aiGateway`): Returns the service-role token instead, for calling the gateway when there's no signed-in user, such as from a scheduled automation.
56
+ *
57
+ * ## Billing and limits
58
+ *
59
+ * Requests are billed to your app's credit quota, which is the same shared
60
+ * quota your app's built-in AI features use, and isn't split per user. If the
61
+ * app runs out of credits, the gateway stops working for every user of the
62
+ * app until the quota resets. A request is rejected before the model runs if
63
+ * the app is out of credits. If you need to cap usage per user, build that
64
+ * check yourself, for example by tracking calls per user in your own entity.
32
65
  *
33
- * Available in user authentication mode (`base44.aiGateway`) and with the
34
- * service-role token via `base44.asServiceRole.aiGateway`.
66
+ * Streaming responses aren't supported yet, so leave `stream` unset on your requests.
35
67
  */
36
68
  export interface AiGatewayModule {
37
69
  /**
@@ -39,19 +71,38 @@ export interface AiGatewayModule {
39
71
  *
40
72
  * Returns the `baseURL` and `token` to pass to any OpenAI-compatible client.
41
73
  *
42
- * The `token` is the current caller's bearer token: the app user's token for
43
- * `base44.aiGateway`, or the service-role token for `base44.asServiceRole.aiGateway`.
44
- * When the caller is unauthenticated, `token` is an empty string.
45
- *
46
74
  * @returns The gateway {@linkcode AiGatewayConnection | connection} (`baseURL` and `token`).
47
75
  *
48
76
  * @example
49
77
  * ```typescript
78
+ * // Call a model directly
79
+ * import { createClientFromRequest } from "@base44/sdk";
80
+ * import OpenAI from "openai";
81
+ *
82
+ * // Runs inside a backend function
83
+ * const base44 = createClientFromRequest(request);
84
+ * const { baseURL, token } = base44.aiGateway.connection();
85
+ * const openai = new OpenAI({ baseURL, apiKey: token });
86
+ *
87
+ * const response = await openai.chat.completions.create({
88
+ * model: "automatic",
89
+ * messages: [{ role: "user", content: "Summarize this week's top support tickets." }],
90
+ * });
91
+ *
92
+ * console.log(response.choices[0].message.content);
93
+ * ```
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // Use a tool-calling agent
98
+ * import { createClientFromRequest } from "@base44/sdk";
50
99
  * import { ToolLoopAgent, tool, stepCountIs, hasToolCall } from "ai";
51
100
  * import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
52
101
  * import { z } from "zod";
53
102
  *
54
- * const request = await base44.entities.ReturnRequest.get(returnId);
103
+ * // Runs inside a backend function, reviewing a return request
104
+ * const base44 = createClientFromRequest(request);
105
+ * const returnRequest = await base44.entities.ReturnRequest.get(returnId);
55
106
  * const { baseURL, token } = base44.aiGateway.connection();
56
107
  * // Point any OpenAI-compatible client at `baseURL` with `apiKey: token`.
57
108
  * const models = createOpenAICompatible({ name: "base44", baseURL, apiKey: token });
@@ -66,7 +117,7 @@ export interface AiGatewayModule {
66
117
  * description: "This customer's past orders, optionally filtered by status",
67
118
  * inputSchema: z.object({ status: z.string().optional() }),
68
119
  * execute: ({ status }) => {
69
- * const query = { customer_email: request.customer_email };
120
+ * const query = { customer_email: returnRequest.customer_email };
70
121
  * if (status) query.status = status;
71
122
  * return base44.entities.Order.filter(query, "-created_date", 50);
72
123
  * },
@@ -81,7 +132,7 @@ export interface AiGatewayModule {
81
132
  * stopWhen: [stepCountIs(8), hasToolCall("submitVerdict")],
82
133
  * });
83
134
  *
84
- * await agent.generate({ prompt: `Review this return request: ${JSON.stringify(request)}` });
135
+ * await agent.generate({ prompt: `Review this return request: ${JSON.stringify(returnRequest)}` });
85
136
  * ```
86
137
  */
87
138
  connection(): AiGatewayConnection;
@@ -1,3 +1,4 @@
1
+ import { getLoginUrl } from "../utils/auth-utils.js";
1
2
  function isInsideIframe() {
2
3
  if (typeof window === "undefined")
3
4
  return false;
@@ -82,8 +83,11 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
82
83
  const redirectUrl = nextUrl
83
84
  ? new URL(nextUrl, window.location.origin).toString()
84
85
  : window.location.href;
85
- // Build the login URL
86
- const loginUrl = `${options.appBaseUrl}/login?from_url=${encodeURIComponent(redirectUrl)}`;
86
+ // A foreign origin (e.g. local dev) can't resolve the app by Host, so
87
+ // the login URL must carry the app id; same-origin keeps the bare path.
88
+ const loginUrl = options.appBaseUrl
89
+ ? getLoginUrl(redirectUrl, { serverUrl: options.appBaseUrl, appId })
90
+ : `/login?from_url=${encodeURIComponent(redirectUrl)}`;
87
91
  // Redirect to the login page
88
92
  window.location.href = loginUrl;
89
93
  },
@@ -12,40 +12,48 @@ export interface SsoAccessTokenResponse {
12
12
  * services.
13
13
  *
14
14
  * This module is only available to use with a client in service role authentication mode, which means it can only be used in backend environments.
15
- *
16
- * @example
17
- * ```typescript
18
- * // Access SSO module with service role
19
- * const response = await base44.asServiceRole.sso.getAccessToken('user_123');
20
- * console.log(response.data.access_token);
21
- * ```
22
15
  */
23
16
  export interface SsoModule {
24
17
  /**
25
- * Gets SSO access token for a specific user.
18
+ * Gets an SSO access token for the user who made the current request.
26
19
  *
27
- * Retrieves a Single Sign-On access token that can be used to authenticate
28
- * a user with external services or systems.
20
+ * Use this token to authenticate the user with external systems or services.
21
+ * This only works for that same user. Create the client with
22
+ * {@link createClientFromRequest} so it acts on behalf of the request's user,
23
+ * then pass that user's ID as `userid`. If `userid` is any other user, the
24
+ * call fails. An expired token is refreshed automatically when a refresh token
25
+ * is available.
29
26
  *
30
- * @param userid - The user ID to get the access token for.
27
+ * @param userid - The ID of the user who made the current request, such as the
28
+ * `id` returned by {@link AuthModule | base44.auth.me()}.
31
29
  * @returns Promise resolving to the SSO access token response.
32
30
  *
33
31
  * @example
34
32
  * ```typescript
35
- * // Get SSO access token for a user
36
- * const response = await base44.asServiceRole.sso.getAccessToken('user_123');
37
- * console.log(response.access_token);
33
+ * // Get the user's SSO access token to call an external system
34
+ * import { createClientFromRequest } from 'npm:@base44/sdk';
35
+ *
36
+ * Deno.serve(async (req) => {
37
+ * const base44 = createClientFromRequest(req);
38
+ * const user = await base44.auth.me();
39
+ * const { access_token } = await base44.asServiceRole.sso.getAccessToken(user.id);
40
+ *
41
+ * return Response.json({ access_token });
42
+ * });
38
43
  * ```
39
44
  */
40
45
  getAccessToken(userid: string): Promise<SsoAccessTokenResponse>;
41
46
  /**
42
- * Gets the stored SSO OIDC ID token for the current app user.
47
+ * Gets the stored SSO OIDC ID token for the user who made the current request.
43
48
  *
44
- * The service-role client must include an on-behalf-of token for the same
45
- * user specified by `userid`. This method returns the stored token as-is and
46
- * does not refresh it.
49
+ * This only works for that same user, not for arbitrary users. Create the
50
+ * client with {@link createClientFromRequest} so it acts on behalf of the
51
+ * request's user, then pass that user's ID as `userid`. If `userid` is any
52
+ * other user, the call fails. The stored token is returned as-is and is never
53
+ * refreshed, so the call fails if the token has already expired.
47
54
  *
48
- * @param userid - The current app user's ID.
55
+ * @param userid - The ID of the user who made the current request, such as the
56
+ * `id` returned by {@link AuthModule | base44.auth.me()}.
49
57
  * @returns Promise resolving to the raw ID-token string.
50
58
  *
51
59
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/sdk",
3
- "version": "0.8.40-pr.240.b2b8abe",
3
+ "version": "0.8.40-pr.242.b74cef0",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",