@base44-preview/sdk 0.8.20-pr.143.d04635a → 0.8.20-pr.146.0ca6206

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
@@ -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 : "";
@@ -115,7 +116,18 @@ export function createClient(config) {
115
116
  }),
116
117
  integrations: createIntegrationsModule(axiosClient, appId),
117
118
  auth: userAuthModule,
118
- functions: createFunctionsModule(functionsAxiosClient, appId),
119
+ functions: createFunctionsModule(functionsAxiosClient, appId, {
120
+ getAuthHeaders: () => {
121
+ const headers = {};
122
+ // Get current token from storage or initial config
123
+ const currentToken = token || getAccessToken();
124
+ if (currentToken) {
125
+ headers["Authorization"] = `Bearer ${currentToken}`;
126
+ }
127
+ return headers;
128
+ },
129
+ baseURL: (_a = functionsAxiosClient.defaults) === null || _a === void 0 ? void 0 : _a.baseURL,
130
+ }),
119
131
  agents: createAgentsModule({
120
132
  axios: axiosClient,
121
133
  getSocket,
@@ -147,7 +159,17 @@ export function createClient(config) {
147
159
  integrations: createIntegrationsModule(serviceRoleAxiosClient, appId),
148
160
  sso: createSsoModule(serviceRoleAxiosClient, appId, token),
149
161
  connectors: createConnectorsModule(serviceRoleAxiosClient, appId),
150
- functions: createFunctionsModule(serviceRoleFunctionsAxiosClient, appId),
162
+ functions: createFunctionsModule(serviceRoleFunctionsAxiosClient, appId, {
163
+ getAuthHeaders: () => {
164
+ const headers = {};
165
+ // Use service token for authorization
166
+ if (serviceToken) {
167
+ headers["Authorization"] = `Bearer ${serviceToken}`;
168
+ }
169
+ return headers;
170
+ },
171
+ baseURL: (_b = serviceRoleFunctionsAxiosClient.defaults) === null || _b === void 0 ? void 0 : _b.baseURL,
172
+ }),
151
173
  agents: createAgentsModule({
152
174
  axios: serviceRoleAxiosClient,
153
175
  getSocket,
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl } from
4
4
  export { createClient, createClientFromRequest, Base44Error, getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
5
5
  export type { Base44Client, CreateClientConfig, CreateClientOptions, Base44ErrorJSON, };
6
6
  export * from "./types.js";
7
- export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityHandler, EntityRecord, EntityTypeRegistry, ImportResult, RealtimeEventType, RealtimeEvent, RealtimeCallback, SortField, UpdateManyResult, } from "./modules/entities.types.js";
7
+ export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityHandler, EntityRecord, EntityTypeRegistry, ImportResult, RealtimeEventType, RealtimeEvent, RealtimeCallback, SortField, } from "./modules/entities.types.js";
8
8
  export type { AuthModule, LoginResponse, RegisterParams, VerifyOtpParams, ChangePasswordParams, ResetPasswordParams, User, } from "./modules/auth.types.js";
9
9
  export type { IntegrationsModule, IntegrationEndpointFunction, CoreIntegrations, InvokeLLMParams, GenerateImageParams, GenerateImageResult, UploadFileParams, UploadFileResult, SendEmailParams, SendEmailResult, ExtractDataFromUploadedFileParams, ExtractDataFromUploadedFileResult, UploadPrivateFileParams, UploadPrivateFileResult, CreateFileSignedUrlParams, CreateFileSignedUrlResult, } from "./modules/integrations.types.js";
10
10
  export type { FunctionsModule, FunctionName, FunctionNameRegistry, } from "./modules/functions.types.js";
@@ -48,42 +48,30 @@ export interface ConnectorConnectionResponse {
48
48
  *
49
49
  * | Service | Type identifier |
50
50
  * |---|---|
51
- * | Airtable | `airtable` |
52
51
  * | Box | `box` |
53
52
  * | ClickUp | `clickup` |
54
53
  * | Discord | `discord` |
55
- * | Dropbox | `dropbox` |
56
54
  * | GitHub | `github` |
57
55
  * | Gmail | `gmail` |
58
56
  * | Google Analytics | `google_analytics` |
59
57
  * | Google BigQuery | `googlebigquery` |
60
58
  * | Google Calendar | `googlecalendar` |
61
- * | Google Classroom | `google_classroom` |
62
59
  * | Google Docs | `googledocs` |
63
60
  * | Google Drive | `googledrive` |
64
- * | Google Search Console | `google_search_console` |
65
61
  * | Google Sheets | `googlesheets` |
66
62
  * | Google Slides | `googleslides` |
67
63
  * | HubSpot | `hubspot` |
68
- * | Linear | `linear` |
69
64
  * | LinkedIn | `linkedin` |
70
- * | Microsoft Teams | `microsoft_teams` |
71
- * | Microsoft OneDrive | `one_drive` |
72
65
  * | Notion | `notion` |
73
- * | Outlook | `outlook` |
74
66
  * | Salesforce | `salesforce` |
75
- * | SharePoint | `share_point` |
76
67
  * | Slack User | `slack` |
77
68
  * | Slack Bot | `slackbot` |
78
- * | Splitwise | `splitwise` |
79
69
  * | TikTok | `tiktok` |
80
- * | Typeform | `typeform` |
81
- * | Wix | `wix` |
82
70
  * | Wrike | `wrike` |
83
71
  *
84
72
  * See the integration guides for more details:
85
73
  *
86
- * - **Scopes and permissions**: {@link https://docs.base44.com/Integrations/gmail-connector#gmail-scopes-and-permissions | Gmail}, {@link https://docs.base44.com/Integrations/linkedin-connector#linkedin-scopes-and-permissions | LinkedIn}, {@link https://docs.base44.com/Integrations/slack-connector#slack-scopes-and-permissions | Slack}, {@link https://docs.base44.com/Integrations/github-connector#github-scopes-and-permissions | GitHub}
74
+ * - **Scopes and permissions**: {@link https://docs.base44.com/Integrations/gmail-connector#gmail-scopes-and-permissions | Gmail}, {@link https://docs.base44.com/Integrations/linkedin-connector#linkedin-scopes-and-permissions | LinkedIn}, {@link https://docs.base44.com/Integrations/slack-connector#slack-scopes-and-permissions | Slack}
87
75
  * - **Slack connector types**: {@link https://docs.base44.com/Integrations/slack-connector#about-the-slack-connectors | About the Slack connectors} explains the difference between `slack` and `slackbot`
88
76
  *
89
77
  * ## Authentication Modes
@@ -106,14 +106,6 @@ function createEntityHandler(axios, appId, entityName, getSocket) {
106
106
  async bulkCreate(data) {
107
107
  return axios.post(`${baseURL}/bulk`, data);
108
108
  },
109
- // Update multiple entities matching a query using a MongoDB update operator
110
- async updateMany(query, data) {
111
- return axios.patch(`${baseURL}/update-many`, { query, data });
112
- },
113
- // Update multiple entities by ID, each with its own update data
114
- async bulkUpdate(data) {
115
- return axios.put(`${baseURL}/bulk`, data);
116
- },
117
109
  // Import entities from a file
118
110
  async importEntities(file) {
119
111
  const formData = new FormData();
@@ -39,17 +39,6 @@ export interface DeleteManyResult {
39
39
  /** Number of entities that were deleted. */
40
40
  deleted: number;
41
41
  }
42
- /**
43
- * Result returned when updating multiple entities via a query.
44
- */
45
- export interface UpdateManyResult {
46
- /** Whether the operation was successful. */
47
- success: boolean;
48
- /** Number of entities that were updated. */
49
- updated: number;
50
- /** Whether there are more entities matching the query that were not updated in this batch. When `true`, call `updateMany` again with the same query to update the next batch. */
51
- has_more: boolean;
52
- }
53
42
  /**
54
43
  * Result returned when importing entities from a file.
55
44
  *
@@ -359,82 +348,6 @@ export interface EntityHandler<T = any> {
359
348
  * ```
360
349
  */
361
350
  bulkCreate(data: Partial<T>[]): Promise<T[]>;
362
- /**
363
- * Updates multiple records matching a query using a MongoDB update operator.
364
- *
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`).
368
- *
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.
371
- *
372
- * @param query - Query object to filter which records to update. Records matching all
373
- * specified criteria will be updated.
374
- * @param data - Update operation object containing exactly one MongoDB update operator.
375
- * Supported operators: `$set`, `$rename`, `$unset`, `$inc`, `$mul`, `$min`, `$max`,
376
- * `$currentDate`, `$addToSet`, `$push`, `$pull`.
377
- * @returns Promise resolving to the update result.
378
- *
379
- * @example
380
- * ```typescript
381
- * // Set status to 'archived' for all completed records
382
- * const result = await base44.entities.MyEntity.updateMany(
383
- * { status: 'completed' },
384
- * { $set: { status: 'archived' } }
385
- * );
386
- * console.log(`Updated ${result.updated} records`);
387
- * ```
388
- *
389
- * @example
390
- * ```typescript
391
- * // Increment a counter on all matching records
392
- * const result = await base44.entities.MyEntity.updateMany(
393
- * { category: 'sales' },
394
- * { $inc: { view_count: 1 } }
395
- * );
396
- * ```
397
- *
398
- * @example
399
- * ```typescript
400
- * // Handle batched updates for large datasets
401
- * let hasMore = true;
402
- * let totalUpdated = 0;
403
- * while (hasMore) {
404
- * const result = await base44.entities.MyEntity.updateMany(
405
- * { status: 'pending' },
406
- * { $set: { status: 'processed' } }
407
- * );
408
- * totalUpdated += result.updated;
409
- * hasMore = result.has_more;
410
- * }
411
- * ```
412
- */
413
- updateMany(query: Partial<T>, data: Record<string, Record<string, any>>): Promise<UpdateManyResult>;
414
- /**
415
- * Updates multiple records in a single request, each with its own update data.
416
- *
417
- * Unlike `updateMany` which applies the same update to all matching records,
418
- * `bulkUpdate` allows different updates for each record. Each item in the
419
- * array must include an `id` field identifying which record to update.
420
- *
421
- * @param data - Array of update objects. Each object must have an `id` field
422
- * and any number of fields to update.
423
- * @returns Promise resolving to an array of updated records.
424
- *
425
- * @example
426
- * ```typescript
427
- * // Update multiple records with different data
428
- * const updated = await base44.entities.MyEntity.bulkUpdate([
429
- * { id: 'entity-1', status: 'paid', amount: 999 },
430
- * { id: 'entity-2', status: 'cancelled' },
431
- * { id: 'entity-3', name: 'Renamed Item' }
432
- * ]);
433
- * ```
434
- */
435
- bulkUpdate(data: (Partial<T> & {
436
- id: string;
437
- })[]): Promise<T[]>;
438
351
  /**
439
352
  * Imports records from a file.
440
353
  *
@@ -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,22 @@ 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
+ * Alias of the native [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) type.
21
+ * Any option accepted by the browser `fetch` API is valid (`method`, `headers`, `body`, `signal`, etc.).
22
+ * Auth headers are merged in automatically; you do not need to set them.
23
+ */
24
+ export type FunctionsFetchInit = RequestInit;
25
+ /**
26
+ * Configuration for the functions module.
27
+ * @internal
28
+ */
29
+ export interface FunctionsModuleConfig {
30
+ getAuthHeaders?: () => Record<string, string>;
31
+ baseURL?: string;
32
+ }
17
33
  /**
18
34
  * Functions module for invoking custom backend functions.
19
35
  *
@@ -34,11 +50,13 @@ export interface FunctionsModule {
34
50
  /**
35
51
  * Invokes a custom backend function by name.
36
52
  *
37
- * Calls a custom backend function deployed to the app.
53
+ * Sends a POST request to a custom backend function deployed to the app.
38
54
  * The function receives the provided data as named parameters and returns
39
55
  * the result. If any parameter is a `File` object, the request will automatically be
40
56
  * sent as `multipart/form-data`. Otherwise, it will be sent as JSON.
41
57
  *
58
+ * For streaming responses, non-POST methods, or raw response access, use {@linkcode fetch | fetch()} instead.
59
+ *
42
60
  * @param functionName - The name of the function to invoke.
43
61
  * @param data - An object containing named parameters for the function.
44
62
  * @returns Promise resolving to the function's response. The `data` property contains the data returned by the function, if there is any.
@@ -68,4 +86,65 @@ export interface FunctionsModule {
68
86
  * ```
69
87
  */
70
88
  invoke(functionName: FunctionName, data?: Record<string, any>): Promise<any>;
89
+ /**
90
+ * Performs a direct HTTP request to a backend function path and returns the native `Response`.
91
+ *
92
+ * Use `fetch()` when you need low-level control that {@linkcode invoke | invoke()} doesn't provide, such as:
93
+ * - Streaming responses, like SSE, chunked text, or NDJSON
94
+ * - Custom HTTP methods, like PUT, PATCH, or DELETE
95
+ * - Raw response access, including status codes, headers, and binary bodies
96
+ *
97
+ * @param path - Function path. Leading slash is optional, so `/chat` and `chat` are equivalent. For example, `'/streaming_demo'` or `'reports/export'`.
98
+ * @param init - Optional [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) options such as `method`, `headers`, `body`, and `signal`. Auth headers are added automatically.
99
+ * @returns Promise resolving to a native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * // Stream an SSE response
104
+ * const response = await base44.functions.fetch('/chat', {
105
+ * method: 'POST',
106
+ * headers: { 'Content-Type': 'application/json' },
107
+ * body: JSON.stringify({ prompt: 'Hello!' }),
108
+ * });
109
+ *
110
+ * const reader = response.body!.getReader();
111
+ * const decoder = new TextDecoder();
112
+ *
113
+ * while (true) {
114
+ * const { done, value } = await reader.read();
115
+ * if (done) break;
116
+ * console.log(decoder.decode(value, { stream: true }));
117
+ * }
118
+ * ```
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * // PUT request
123
+ * const response = await base44.functions.fetch('/users/profile', {
124
+ * method: 'PUT',
125
+ * headers: { 'Content-Type': 'application/json' },
126
+ * body: JSON.stringify({ name: 'Jane', role: 'admin' }),
127
+ * });
128
+ *
129
+ * if (!response.ok) {
130
+ * throw new Error(`Request failed: ${response.status}`);
131
+ * }
132
+ *
133
+ * const updated = await response.json();
134
+ * ```
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * // Download a binary file
139
+ * const response = await base44.functions.fetch('/export/report');
140
+ * const blob = await response.blob();
141
+ *
142
+ * const url = URL.createObjectURL(blob);
143
+ * const a = document.createElement('a');
144
+ * a.href = url;
145
+ * a.download = 'report.pdf';
146
+ * a.click();
147
+ * ```
148
+ */
149
+ fetch(path: string, init?: FunctionsFetchInit): Promise<Response>;
71
150
  }
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.20-pr.146.0ca6206",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",