@base44-preview/sdk 0.8.20-pr.143.d04635a → 0.8.21-pr.141.dd114e6

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/client.js CHANGED
@@ -3,7 +3,7 @@ import { createEntitiesModule } from "./modules/entities.js";
3
3
  import { createIntegrationsModule } from "./modules/integrations.js";
4
4
  import { createAuthModule } from "./modules/auth.js";
5
5
  import { createSsoModule } from "./modules/sso.js";
6
- import { createConnectorsModule } from "./modules/connectors.js";
6
+ import { createConnectorsModule, createUserConnectorsModule, } from "./modules/connectors.js";
7
7
  import { getAccessToken } from "./utils/auth-utils.js";
8
8
  import { createFunctionsModule } from "./modules/functions.js";
9
9
  import { createAgentsModule } from "./modules/agents.js";
@@ -49,6 +49,7 @@ import { createAnalyticsModule } from "./modules/analytics.js";
49
49
  * ```
50
50
  */
51
51
  export function createClient(config) {
52
+ var _a, _b;
52
53
  const { serverUrl = "https://base44.app", appId, token, serviceToken, requiresAuth = false, appBaseUrl, options, functionsVersion, headers: optionalHeaders, } = config;
53
54
  // Normalize appBaseUrl to always be a string (empty if not provided or invalid)
54
55
  const normalizedAppBaseUrl = typeof appBaseUrl === "string" ? appBaseUrl : "";
@@ -114,8 +115,20 @@ export function createClient(config) {
114
115
  getSocket,
115
116
  }),
116
117
  integrations: createIntegrationsModule(axiosClient, appId),
118
+ connectors: createUserConnectorsModule(axiosClient, appId),
117
119
  auth: userAuthModule,
118
- functions: createFunctionsModule(functionsAxiosClient, appId),
120
+ functions: createFunctionsModule(functionsAxiosClient, appId, {
121
+ getAuthHeaders: () => {
122
+ const headers = {};
123
+ // Get current token from storage or initial config
124
+ const currentToken = token || getAccessToken();
125
+ if (currentToken) {
126
+ headers["Authorization"] = `Bearer ${currentToken}`;
127
+ }
128
+ return headers;
129
+ },
130
+ baseURL: (_a = functionsAxiosClient.defaults) === null || _a === void 0 ? void 0 : _a.baseURL,
131
+ }),
119
132
  agents: createAgentsModule({
120
133
  axios: axiosClient,
121
134
  getSocket,
@@ -147,7 +160,17 @@ export function createClient(config) {
147
160
  integrations: createIntegrationsModule(serviceRoleAxiosClient, appId),
148
161
  sso: createSsoModule(serviceRoleAxiosClient, appId, token),
149
162
  connectors: createConnectorsModule(serviceRoleAxiosClient, appId),
150
- functions: createFunctionsModule(serviceRoleFunctionsAxiosClient, appId),
163
+ functions: createFunctionsModule(serviceRoleFunctionsAxiosClient, appId, {
164
+ getAuthHeaders: () => {
165
+ const headers = {};
166
+ // Use service token for authorization
167
+ if (serviceToken) {
168
+ headers["Authorization"] = `Bearer ${serviceToken}`;
169
+ }
170
+ return headers;
171
+ },
172
+ baseURL: (_b = serviceRoleFunctionsAxiosClient.defaults) === null || _b === void 0 ? void 0 : _b.baseURL,
173
+ }),
151
174
  agents: createAgentsModule({
152
175
  axios: serviceRoleAxiosClient,
153
176
  getSocket,
@@ -2,7 +2,7 @@ import type { EntitiesModule } from "./modules/entities.types.js";
2
2
  import type { IntegrationsModule } from "./modules/integrations.types.js";
3
3
  import type { AuthModule } from "./modules/auth.types.js";
4
4
  import type { SsoModule } from "./modules/sso.types.js";
5
- import type { ConnectorsModule } from "./modules/connectors.types.js";
5
+ import type { ConnectorsModule, UserConnectorsModule } from "./modules/connectors.types.js";
6
6
  import type { FunctionsModule } from "./modules/functions.types.js";
7
7
  import type { AgentsModule } from "./modules/agents.types.js";
8
8
  import type { AppLogsModule } from "./modules/app-logs.types.js";
@@ -87,6 +87,8 @@ export interface Base44Client {
87
87
  appLogs: AppLogsModule;
88
88
  /** {@link AuthModule | Auth module} for user authentication and management. */
89
89
  auth: AuthModule;
90
+ /** {@link UserConnectorsModule | Connectors module} for app-user OAuth flows. */
91
+ connectors: UserConnectorsModule;
90
92
  /** {@link EntitiesModule | Entities module} for CRUD operations on your data models. */
91
93
  entities: EntitiesModule;
92
94
  /** {@link FunctionsModule | Functions module} for invoking custom backend functions. */
package/dist/index.d.ts CHANGED
@@ -11,6 +11,6 @@ export type { FunctionsModule, FunctionName, FunctionNameRegistry, } from "./mod
11
11
  export type { AgentsModule, AgentName, AgentNameRegistry, AgentConversation, AgentMessage, AgentMessageReasoning, AgentMessageToolCall, AgentMessageUsage, AgentMessageCustomContext, AgentMessageMetadata, CreateConversationParams, } from "./modules/agents.types.js";
12
12
  export type { AppLogsModule } from "./modules/app-logs.types.js";
13
13
  export type { SsoModule, SsoAccessTokenResponse } from "./modules/sso.types.js";
14
- export type { ConnectorsModule } from "./modules/connectors.types.js";
14
+ export type { ConnectorsModule, UserConnectorsModule, } from "./modules/connectors.types.js";
15
15
  export type { CustomIntegrationsModule, CustomIntegrationCallParams, CustomIntegrationCallResponse, } from "./modules/custom-integrations.types.js";
16
16
  export type { GetAccessTokenOptions, SaveAccessTokenOptions, RemoveAccessTokenOptions, GetLoginUrlOptions, } from "./utils/auth-utils.types.js";
@@ -1,5 +1,5 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { ConnectorsModule } from "./connectors.types.js";
2
+ import { ConnectorsModule, UserConnectorsModule } from "./connectors.types.js";
3
3
  /**
4
4
  * Creates the Connectors module for the Base44 SDK.
5
5
  *
@@ -9,3 +9,12 @@ import { ConnectorsModule } from "./connectors.types.js";
9
9
  * @internal
10
10
  */
11
11
  export declare function createConnectorsModule(axios: AxiosInstance, appId: string): ConnectorsModule;
12
+ /**
13
+ * Creates the user-scoped Connectors module (app-user OAuth flows).
14
+ *
15
+ * @param axios - Axios instance (user-scoped client)
16
+ * @param appId - Application ID
17
+ * @returns User connectors module with app-user OAuth methods
18
+ * @internal
19
+ */
20
+ export declare function createUserConnectorsModule(axios: AxiosInstance, appId: string): UserConnectorsModule;
@@ -35,3 +35,37 @@ export function createConnectorsModule(axios, appId) {
35
35
  },
36
36
  };
37
37
  }
38
+ /**
39
+ * Creates the user-scoped Connectors module (app-user OAuth flows).
40
+ *
41
+ * @param axios - Axios instance (user-scoped client)
42
+ * @param appId - Application ID
43
+ * @returns User connectors module with app-user OAuth methods
44
+ * @internal
45
+ */
46
+ export function createUserConnectorsModule(axios, appId) {
47
+ return {
48
+ async getCurrentAppUserAccessToken(connectorId) {
49
+ if (!connectorId || typeof connectorId !== "string") {
50
+ throw new Error("Connector ID is required and must be a string");
51
+ }
52
+ const response = await axios.get(`/apps/${appId}/app-user-auth/connectors/${connectorId}/token`);
53
+ const data = response;
54
+ return data.access_token;
55
+ },
56
+ async connectAppUser(connectorId) {
57
+ if (!connectorId || typeof connectorId !== "string") {
58
+ throw new Error("Connector ID is required and must be a string");
59
+ }
60
+ const response = await axios.post(`/apps/${appId}/app-user-auth/connectors/${connectorId}/initiate`);
61
+ const data = response;
62
+ return data.redirect_url;
63
+ },
64
+ async disconnectAppUser(connectorId) {
65
+ if (!connectorId || typeof connectorId !== "string") {
66
+ throw new Error("Connector ID is required and must be a string");
67
+ }
68
+ await axios.delete(`/apps/${appId}/app-user-auth/connectors/${connectorId}`);
69
+ },
70
+ };
71
+ }
@@ -33,7 +33,7 @@ export interface ConnectorConnectionResponse {
33
33
  connectionConfig: Record<string, string> | null;
34
34
  }
35
35
  /**
36
- * Connectors module for managing OAuth tokens for external services.
36
+ * Connectors module for managing app-scoped OAuth tokens for external services.
37
37
  *
38
38
  * This module allows you to retrieve OAuth access tokens for external services that the app has connected to. Connectors are app-scoped. When an app builder connects an integration like Google Calendar, Slack, or GitHub, all users of the app share that same connection.
39
39
  *
@@ -224,3 +224,73 @@ export interface ConnectorsModule {
224
224
  */
225
225
  getConnection(integrationType: ConnectorIntegrationType): Promise<ConnectorConnectionResponse>;
226
226
  }
227
+ /**
228
+ * User-scoped connectors module for managing app-user OAuth connections.
229
+ *
230
+ * This module provides methods for app-user OAuth flows: initiating an OAuth connection,
231
+ * retrieving the end user's access token, and disconnecting the end user's connection.
232
+ *
233
+ * Unlike {@link ConnectorsModule | ConnectorsModule} which manages app-scoped tokens,
234
+ * this module manages tokens scoped to individual end users. Methods are keyed on
235
+ * the connector ID (the OrgConnector's database ID) rather than the integration type.
236
+ *
237
+ * Available via `base44.connectors`.
238
+ */
239
+ export interface UserConnectorsModule {
240
+ /**
241
+ * Retrieves an OAuth access token for an end user's connection to a specific connector.
242
+ *
243
+ * Returns the OAuth token string that belongs to the currently authenticated end user
244
+ * for the specified connector.
245
+ *
246
+ * @param connectorId - The connector ID (OrgConnector database ID).
247
+ * @returns Promise resolving to the access token string.
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * // Get the end user's access token for a connector
252
+ * const token = await base44.connectors.getCurrentAppUserAccessToken('abc123def');
253
+ *
254
+ * const response = await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
255
+ * headers: { 'Authorization': `Bearer ${token}` }
256
+ * });
257
+ * ```
258
+ */
259
+ getCurrentAppUserAccessToken(connectorId: string): Promise<string>;
260
+ /**
261
+ * Initiates the app-user OAuth flow for a specific connector.
262
+ *
263
+ * Returns a redirect URL that the end user should be navigated to in order to
264
+ * authenticate with the external service. The scopes and integration type are
265
+ * derived from the connector configuration server-side.
266
+ *
267
+ * @param connectorId - The connector ID (OrgConnector database ID).
268
+ * @returns Promise resolving to the redirect URL string.
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * // Start OAuth for the end user
273
+ * const redirectUrl = await base44.connectors.connectAppUser('abc123def');
274
+ *
275
+ * // Redirect the user to the OAuth provider
276
+ * window.location.href = redirectUrl;
277
+ * ```
278
+ */
279
+ connectAppUser(connectorId: string): Promise<string>;
280
+ /**
281
+ * Disconnects an end user's OAuth connection for a specific connector.
282
+ *
283
+ * Removes the stored OAuth credentials for the currently authenticated end user's
284
+ * connection to the specified connector.
285
+ *
286
+ * @param connectorId - The connector ID (OrgConnector database ID).
287
+ * @returns Promise resolving when the connection has been removed.
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * // Disconnect the end user's connection
292
+ * await base44.connectors.disconnectAppUser('abc123def');
293
+ * ```
294
+ */
295
+ disconnectAppUser(connectorId: string): Promise<void>;
296
+ }
@@ -363,15 +363,18 @@ export interface EntityHandler<T = any> {
363
363
  * Updates multiple records matching a query using a MongoDB update operator.
364
364
  *
365
365
  * Applies the same update operation to all records matching the query.
366
- * The `data` parameter must contain exactly one MongoDB update operator
367
- * (e.g., `$set`, `$inc`, `$push`).
366
+ * The `data` parameter must contain one or more MongoDB update operators
367
+ * (e.g., `$set`, `$inc`, `$push`). Multiple operators can be combined in a
368
+ * single call, but each field may only appear in one operator.
368
369
  *
369
- * Results are batched — when `has_more` is `true` in the response, call
370
- * `updateMany` again with the same query to update the next batch.
370
+ * Results are batched in groups of up to 500 — when `has_more` is `true`
371
+ * in the response, call `updateMany` again with the same query to update
372
+ * the next batch.
371
373
  *
372
374
  * @param query - Query object to filter which records to update. Records matching all
373
375
  * specified criteria will be updated.
374
- * @param data - Update operation object containing exactly one MongoDB update operator.
376
+ * @param data - Update operation object containing one or more MongoDB update operators.
377
+ * Each field may only appear in one operator per call.
375
378
  * Supported operators: `$set`, `$rename`, `$unset`, `$inc`, `$mul`, `$min`, `$max`,
376
379
  * `$currentDate`, `$addToSet`, `$push`, `$pull`.
377
380
  * @returns Promise resolving to the update result.
@@ -388,10 +391,10 @@ export interface EntityHandler<T = any> {
388
391
  *
389
392
  * @example
390
393
  * ```typescript
391
- * // Increment a counter on all matching records
394
+ * // Combine multiple operators in a single call
392
395
  * const result = await base44.entities.MyEntity.updateMany(
393
396
  * { category: 'sales' },
394
- * { $inc: { view_count: 1 } }
397
+ * { $set: { status: 'done' }, $inc: { view_count: 1 } }
395
398
  * );
396
399
  * ```
397
400
  *
@@ -418,7 +421,9 @@ export interface EntityHandler<T = any> {
418
421
  * `bulkUpdate` allows different updates for each record. Each item in the
419
422
  * array must include an `id` field identifying which record to update.
420
423
  *
421
- * @param data - Array of update objects. Each object must have an `id` field
424
+ * **Note:** Maximum 500 items per request.
425
+ *
426
+ * @param data - Array of update objects (max 500). Each object must have an `id` field
422
427
  * and any number of fields to update.
423
428
  * @returns Promise resolving to an array of updated records.
424
429
  *
@@ -1,11 +1,12 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { FunctionsModule } from "./functions.types";
2
+ import { FunctionsModule, FunctionsModuleConfig } from "./functions.types";
3
3
  /**
4
4
  * Creates the functions module for the Base44 SDK.
5
5
  *
6
6
  * @param axios - Axios instance
7
7
  * @param appId - Application ID
8
+ * @param config - Optional configuration for fetch functionality
8
9
  * @returns Functions module with methods to invoke custom backend functions
9
10
  * @internal
10
11
  */
11
- export declare function createFunctionsModule(axios: AxiosInstance, appId: string): FunctionsModule;
12
+ export declare function createFunctionsModule(axios: AxiosInstance, appId: string, config?: FunctionsModuleConfig): FunctionsModule;
@@ -3,10 +3,34 @@
3
3
  *
4
4
  * @param axios - Axios instance
5
5
  * @param appId - Application ID
6
+ * @param config - Optional configuration for fetch functionality
6
7
  * @returns Functions module with methods to invoke custom backend functions
7
8
  * @internal
8
9
  */
9
- export function createFunctionsModule(axios, appId) {
10
+ export function createFunctionsModule(axios, appId, config) {
11
+ const joinBaseUrl = (base, path) => {
12
+ if (!base)
13
+ return path;
14
+ return `${String(base).replace(/\/$/, "")}${path}`;
15
+ };
16
+ const toHeaders = (inputHeaders) => {
17
+ const headers = new Headers();
18
+ // Get auth headers from the getter function if provided
19
+ if (config === null || config === void 0 ? void 0 : config.getAuthHeaders) {
20
+ const authHeaders = config.getAuthHeaders();
21
+ Object.entries(authHeaders).forEach(([key, value]) => {
22
+ if (value !== undefined && value !== null) {
23
+ headers.set(key, String(value));
24
+ }
25
+ });
26
+ }
27
+ if (inputHeaders) {
28
+ new Headers(inputHeaders).forEach((value, key) => {
29
+ headers.set(key, value);
30
+ });
31
+ }
32
+ return headers;
33
+ };
10
34
  return {
11
35
  // Invoke a custom backend function by name
12
36
  async invoke(functionName, data) {
@@ -39,5 +63,17 @@ export function createFunctionsModule(axios, appId) {
39
63
  }
40
64
  return axios.post(`/apps/${appId}/functions/${functionName}`, formData || data, { headers: { "Content-Type": contentType } });
41
65
  },
66
+ // Fetch a backend function endpoint directly.
67
+ async fetch(path, init = {}) {
68
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
69
+ const primaryPath = `/functions${normalizedPath}`;
70
+ const headers = toHeaders(init.headers);
71
+ const requestInit = {
72
+ ...init,
73
+ headers,
74
+ };
75
+ const response = await fetch(joinBaseUrl(config === null || config === void 0 ? void 0 : config.baseURL, primaryPath), requestInit);
76
+ return response;
77
+ },
42
78
  };
43
79
  }
@@ -14,6 +14,20 @@ export interface FunctionNameRegistry {
14
14
  * ```
15
15
  */
16
16
  export type FunctionName = keyof FunctionNameRegistry extends never ? string : keyof FunctionNameRegistry;
17
+ /**
18
+ * Options for {@linkcode FunctionsModule.fetch}.
19
+ *
20
+ * Uses native `fetch` options directly.
21
+ */
22
+ export type FunctionsFetchInit = RequestInit;
23
+ /**
24
+ * Configuration for the functions module.
25
+ * @internal
26
+ */
27
+ export interface FunctionsModuleConfig {
28
+ getAuthHeaders?: () => Record<string, string>;
29
+ baseURL?: string;
30
+ }
17
31
  /**
18
32
  * Functions module for invoking custom backend functions.
19
33
  *
@@ -68,4 +82,22 @@ export interface FunctionsModule {
68
82
  * ```
69
83
  */
70
84
  invoke(functionName: FunctionName, data?: Record<string, any>): Promise<any>;
85
+ /**
86
+ * Performs a direct HTTP request to a backend function path and returns the native `Response`.
87
+ *
88
+ * Use this method when you need low-level control over the request/response that the higher-level
89
+ * `invoke()` abstraction doesn't provide, such as:
90
+ * - Streaming responses (SSE, chunked text, NDJSON)
91
+ * - Custom HTTP methods (PUT, PATCH, DELETE, etc.)
92
+ * - Custom headers or request configuration
93
+ * - Access to raw response metadata (status, headers)
94
+ * - Direct control over request/response bodies
95
+ *
96
+ * Requests are sent to `/api/functions/<path>`.
97
+ *
98
+ * @param path - Function path, e.g. `/streaming_demo` or `/streaming_demo/deep/path`
99
+ * @param init - Native fetch options.
100
+ * @returns Promise resolving to a native fetch `Response`
101
+ */
102
+ fetch(path: string, init?: FunctionsFetchInit): Promise<Response>;
71
103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/sdk",
3
- "version": "0.8.20-pr.143.d04635a",
3
+ "version": "0.8.21-pr.141.dd114e6",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",