@base44/sdk 0.8.18 → 0.8.20

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.
@@ -20,7 +20,6 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
20
20
  },
21
21
  // Redirects the user to the app's login page
22
22
  redirectToLogin(nextUrl) {
23
- var _a;
24
23
  // This function only works in a browser environment
25
24
  if (typeof window === "undefined") {
26
25
  throw new Error("Login method can only be used in a browser environment");
@@ -30,7 +29,7 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
30
29
  ? new URL(nextUrl, window.location.origin).toString()
31
30
  : window.location.href;
32
31
  // Build the login URL
33
- const loginUrl = `${(_a = options.appBaseUrl) !== null && _a !== void 0 ? _a : ""}/login?from_url=${encodeURIComponent(redirectUrl)}`;
32
+ const loginUrl = `${options.appBaseUrl}/login?from_url=${encodeURIComponent(redirectUrl)}`;
34
33
  // Redirect to the login page
35
34
  window.location.href = loginUrl;
36
35
  },
@@ -38,36 +37,43 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
38
37
  loginWithProvider(provider, fromUrl = "/") {
39
38
  // Build the full redirect URL
40
39
  const redirectUrl = new URL(fromUrl, window.location.origin).toString();
41
- // Build the provider login URL (google is the default, so no provider path needed)
42
- const providerPath = provider === "google" ? "" : `/${provider}`;
43
- const loginUrl = `${options.serverUrl}/api/apps/auth${providerPath}/login?app_id=${appId}&from_url=${encodeURIComponent(redirectUrl)}`;
40
+ const queryParams = `app_id=${appId}&from_url=${encodeURIComponent(redirectUrl)}`;
41
+ // SSO uses a different URL structure with appId in the path
42
+ let authPath;
43
+ if (provider === "sso") {
44
+ authPath = `/apps/${appId}/auth/sso/login`;
45
+ }
46
+ else {
47
+ // Google is the default provider, so no provider path segment needed
48
+ const providerPath = provider === "google" ? "" : `/${provider}`;
49
+ authPath = `/apps/auth${providerPath}/login`;
50
+ }
51
+ const loginUrl = `${options.appBaseUrl}/api${authPath}?${queryParams}`;
44
52
  // Redirect to the provider login page
45
53
  window.location.href = loginUrl;
46
54
  },
47
55
  // Logout the current user
48
- // Removes the token from localStorage and optionally redirects to a URL or reloads the page
49
56
  logout(redirectUrl) {
50
- // Remove token from axios headers
57
+ // Remove token from axios headers (always do this)
51
58
  delete axios.defaults.headers.common["Authorization"];
52
- // Remove token from localStorage
53
- if (typeof window !== "undefined" && window.localStorage) {
54
- try {
55
- window.localStorage.removeItem("base44_access_token");
56
- // Remove "token" that is set by the built-in SDK of platform version 2
57
- window.localStorage.removeItem("token");
58
- }
59
- catch (e) {
60
- console.error("Failed to remove token from localStorage:", e);
61
- }
62
- }
63
- // Redirect if a URL is provided
59
+ // Only do the rest if in a browser environment
64
60
  if (typeof window !== "undefined") {
65
- if (redirectUrl) {
66
- window.location.href = redirectUrl;
67
- }
68
- else {
69
- window.location.reload();
61
+ // Remove token from localStorage
62
+ if (window.localStorage) {
63
+ try {
64
+ window.localStorage.removeItem("base44_access_token");
65
+ // Remove "token" that is set by the built-in SDK of platform version 2
66
+ window.localStorage.removeItem("token");
67
+ }
68
+ catch (e) {
69
+ console.error("Failed to remove token from localStorage:", e);
70
+ }
70
71
  }
72
+ // Determine the from_url parameter
73
+ const fromUrl = redirectUrl || window.location.href;
74
+ // Redirect to server-side logout endpoint to clear HTTP-only cookies
75
+ const logoutUrl = `${options.appBaseUrl}/api/apps/auth/logout?from_url=${encodeURIComponent(fromUrl)}`;
76
+ window.location.href = logoutUrl;
71
77
  }
72
78
  },
73
79
  // Set authentication token
@@ -90,12 +90,14 @@ export interface ResetPasswordParams {
90
90
  export interface AuthModuleOptions {
91
91
  /** Server URL for API requests. */
92
92
  serverUrl: string;
93
- /** Optional base URL for the app (used for login redirects). */
94
- appBaseUrl?: string;
93
+ /** Base URL for the app (used for login redirects). */
94
+ appBaseUrl: string;
95
95
  }
96
96
  /**
97
97
  * Authentication module for managing user authentication and authorization. The module automatically stores tokens in local storage when available and manages authorization headers for API requests.
98
98
  *
99
+ * ## Features
100
+ *
99
101
  * This module provides comprehensive authentication functionality including:
100
102
  * - Email/password login and registration
101
103
  * - Token management
@@ -104,6 +106,8 @@ export interface AuthModuleOptions {
104
106
  * - OTP verification
105
107
  * - User invitations
106
108
  *
109
+ * ## Authentication Modes
110
+ *
107
111
  * The auth module is only available in user authentication mode (`base44.auth`).
108
112
  */
109
113
  export interface AuthModule {
@@ -174,22 +178,41 @@ export interface AuthModule {
174
178
  /**
175
179
  * Redirects the user to a third-party authentication provider's login page.
176
180
  *
177
- * Initiates OAuth/SSO login flow with providers like Google, Microsoft, etc. Requires a browser environment and can't be used in the backend.
181
+ * Initiates an OAuth login flow with one of the built-in providers. Requires a browser environment and can't be used in the backend.
182
+ *
183
+ * Supported providers:
184
+ * - `'google'` - {@link https://developers.google.com/identity/protocols/oauth2 | Google OAuth}. Enabled by default.
185
+ * - `'microsoft'` - {@link https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow | Microsoft OAuth}. Enable Microsoft in your app's authentication settings before specifying this provider.
186
+ * - `'facebook'` - {@link https://developers.facebook.com/docs/facebook-login | Facebook Login}. Enable Facebook in your app's authentication settings before using.
187
+ * - `'apple'` - {@link https://developer.apple.com/sign-in-with-apple/ | Sign in with Apple}. Enable Apple in your app's authentication settings before using this provider.
188
+ * - `'sso'` - Enterprise SSO. Enable SSO in your app's authentication settings before using this provider.
178
189
  *
179
- * @param provider - Name of the supported authentication provider (e.g., 'google', 'microsoft').
180
- * @param fromUrl - URL to redirect to after successful authentication. Defaults to '/'.
190
+ * @param provider - The authentication provider to use: `'google'`, `'microsoft'`, `'facebook'`, `'apple'`, or `'sso'`.
191
+ * @param fromUrl - URL to redirect to after successful authentication. Defaults to `'/'`.
181
192
  *
182
193
  * @example
183
194
  * ```typescript
184
- * // Login with Google and return to current page
195
+ * // Google
185
196
  * base44.auth.loginWithProvider('google', window.location.pathname);
186
197
  * ```
187
198
  *
188
199
  * @example
189
200
  * ```typescript
190
- * // Login with GitHub and redirect to dashboard
201
+ * // Microsoft
191
202
  * base44.auth.loginWithProvider('microsoft', '/dashboard');
192
203
  * ```
204
+ *
205
+ * @example
206
+ * ```typescript
207
+ * // Apple
208
+ * base44.auth.loginWithProvider('apple', '/dashboard');
209
+ * ```
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * // SSO
214
+ * base44.auth.loginWithProvider('sso', '/dashboard');
215
+ * ```
193
216
  */
194
217
  loginWithProvider(provider: string, fromUrl?: string): void;
195
218
  /**
@@ -8,8 +8,11 @@
8
8
  */
9
9
  export function createConnectorsModule(axios, appId) {
10
10
  return {
11
- // Retrieve an OAuth access token for a specific external integration type
12
- // @ts-expect-error Return type mismatch with interface - implementation returns object, interface expects string
11
+ /**
12
+ * Retrieve an OAuth access token for a specific external integration type.
13
+ * @deprecated Use getConnection(integrationType) and use the returned accessToken (and connectionConfig when needed) instead.
14
+ */
15
+ // @ts-expect-error Return type mismatch with interface - implementation returns string, interface expects string but implementation is typed as ConnectorAccessTokenResponse
13
16
  async getAccessToken(integrationType) {
14
17
  if (!integrationType || typeof integrationType !== "string") {
15
18
  throw new Error("Integration type is required and must be a string");
@@ -18,5 +21,17 @@ export function createConnectorsModule(axios, appId) {
18
21
  // @ts-expect-error
19
22
  return response.access_token;
20
23
  },
24
+ async getConnection(integrationType) {
25
+ var _a;
26
+ if (!integrationType || typeof integrationType !== "string") {
27
+ throw new Error("Integration type is required and must be a string");
28
+ }
29
+ const response = await axios.get(`/apps/${appId}/external-auth/tokens/${integrationType}`);
30
+ const data = response;
31
+ return {
32
+ accessToken: data.access_token,
33
+ connectionConfig: (_a = data.connection_config) !== null && _a !== void 0 ? _a : null,
34
+ };
35
+ },
21
36
  };
22
37
  }
@@ -1,34 +1,64 @@
1
1
  /**
2
- * The type of external integration/connector, such as `'googlecalendar'`, `'slack'`, or `'github'`.
2
+ * Registry of connector integration type names. The [`types generate`](/developers/references/cli/commands/types-generate) command fills this registry, then [`ConnectorIntegrationType`](#connectorintegrationtype) resolves to a union of the keys.
3
3
  */
4
- export type ConnectorIntegrationType = string;
4
+ export interface ConnectorIntegrationTypeRegistry {
5
+ }
6
+ /**
7
+ * Union of all connector integration type names from the [`ConnectorIntegrationTypeRegistry`](#connectorintegrationtyperegistry). Defaults to `string` when no types have been generated.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Using generated connector type names
12
+ * // With generated types, you get autocomplete on integration types
13
+ * const connection = await base44.asServiceRole.connectors.getConnection('googlecalendar');
14
+ * const token = connection.accessToken;
15
+ * ```
16
+ */
17
+ export type ConnectorIntegrationType = keyof ConnectorIntegrationTypeRegistry extends never ? string : keyof ConnectorIntegrationTypeRegistry;
5
18
  /**
6
19
  * Response from the connectors access token endpoint.
7
20
  */
8
21
  export interface ConnectorAccessTokenResponse {
9
22
  access_token: string;
23
+ integration_type: string;
24
+ connection_config: Record<string, string> | null;
25
+ }
26
+ /**
27
+ * Camel-cased connection details returned by {@linkcode ConnectorsModule.getConnection | getConnection()}.
28
+ */
29
+ export interface ConnectorConnectionResponse {
30
+ /** The OAuth access token for the external service. */
31
+ accessToken: string;
32
+ /** Key-value configuration for the connection, or `null` if the connector does not provide one. */
33
+ connectionConfig: Record<string, string> | null;
10
34
  }
11
35
  /**
12
36
  * Connectors module for managing OAuth tokens for external services.
13
37
  *
14
- * This module allows you to retrieve OAuth access tokens for external services
15
- * that the app has connected to. Use these tokens to make API
16
- * calls to external services.
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 or Slack, all users of the app share that same connection.
17
39
  *
18
40
  * Unlike the integrations module that provides pre-built functions, connectors give you
19
41
  * raw OAuth tokens so you can call external service APIs directly with full control over
20
42
  * the API calls you make. This is useful when you need custom API interactions that aren't
21
43
  * covered by Base44's pre-built integrations.
22
44
  *
45
+ * ## Authentication Modes
46
+ *
23
47
  * 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.
48
+ *
49
+ * ## Dynamic Types
50
+ *
51
+ * If you're working in a TypeScript project, you can generate types from your app's connector configurations to get autocomplete on integration type names when calling `getConnection()`. See the [Dynamic Types](/developers/references/sdk/getting-started/dynamic-types) guide to get started.
24
52
  */
25
53
  export interface ConnectorsModule {
26
54
  /**
27
55
  * Retrieves an OAuth access token for a specific external integration type.
28
56
  *
29
- * Returns the OAuth token string for an external service that the app
30
- * has connected to. You can then use this token to make authenticated API calls
31
- * to that external service.
57
+ * @deprecated Use {@link getConnection} and use the returned `accessToken` (and `connectionConfig` when needed) instead.
58
+ *
59
+ * Returns the OAuth token string for an external service that an app builder
60
+ * has connected to. This token represents the connected app builder's account
61
+ * and can be used to make authenticated API calls to that external service on behalf of the app.
32
62
  *
33
63
  * @param integrationType - The type of integration, such as `'googlecalendar'`, `'slack'`, or `'github'`.
34
64
  * @returns Promise resolving to the access token string.
@@ -67,4 +97,41 @@ export interface ConnectorsModule {
67
97
  * ```
68
98
  */
69
99
  getAccessToken(integrationType: ConnectorIntegrationType): Promise<string>;
100
+ /**
101
+ * Retrieves the OAuth access token and connection configuration for a specific external integration type.
102
+ *
103
+ * Returns both the OAuth token and any additional connection configuration
104
+ * that the connector provides. This is useful when the external service requires
105
+ * extra parameters beyond the access token (e.g., a shop domain, account ID, or API base URL).
106
+ *
107
+ * @param integrationType - The type of integration, such as `'googlecalendar'`, `'slack'`, or `'github'`.
108
+ * @returns Promise resolving to a {@link ConnectorConnectionResponse} with `accessToken` and `connectionConfig`.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Basic usage
113
+ * const connection = await base44.asServiceRole.connectors.getConnection('googlecalendar');
114
+ * console.log(connection.accessToken);
115
+ * console.log(connection.connectionConfig);
116
+ * ```
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // Shopify: connectionConfig has subdomain (e.g. "my-store" for my-store.myshopify.com)
121
+ * const connection = await base44.asServiceRole.connectors.getConnection('shopify');
122
+ * const { accessToken, connectionConfig } = connection;
123
+ * const shop = connectionConfig?.subdomain
124
+ * ? `https://${connectionConfig.subdomain}.myshopify.com`
125
+ * : null;
126
+ *
127
+ * if (shop) {
128
+ * const response = await fetch(
129
+ * `${shop}/admin/api/2024-01/products.json?limit=10`,
130
+ * { headers: { 'X-Shopify-Access-Token': accessToken } }
131
+ * );
132
+ * const { products } = await response.json();
133
+ * }
134
+ * ```
135
+ */
136
+ getConnection(integrationType: ConnectorIntegrationType): Promise<ConnectorConnectionResponse>;
70
137
  }
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Parameters for calling a custom integration endpoint.
3
+ * @internal
3
4
  */
4
5
  export interface CustomIntegrationCallParams {
5
6
  /**
@@ -7,21 +8,17 @@ export interface CustomIntegrationCallParams {
7
8
  */
8
9
  payload?: Record<string, any>;
9
10
  /**
10
- * Path parameters to substitute in the URL (e.g., `{ owner: "user", repo: "repo" }`).
11
+ * Path parameters to substitute in the URL. For example, `{ owner: "user", repo: "repo" }`.
11
12
  */
12
13
  pathParams?: Record<string, string>;
13
14
  /**
14
15
  * Query string parameters to append to the URL.
15
16
  */
16
17
  queryParams?: Record<string, any>;
17
- /**
18
- * Additional headers to send with this specific request.
19
- * These are merged with the integration's configured headers.
20
- */
21
- headers?: Record<string, string>;
22
18
  }
23
19
  /**
24
20
  * Response from a custom integration call.
21
+ * @internal
25
22
  */
26
23
  export interface CustomIntegrationCallResponse {
27
24
  /**
@@ -39,60 +36,17 @@ export interface CustomIntegrationCallResponse {
39
36
  data: any;
40
37
  }
41
38
  /**
42
- * Module for calling custom workspace-level API integrations.
43
- *
44
- * Custom integrations allow workspace administrators to connect any external API
45
- * by importing an OpenAPI specification. Apps in the workspace can then call
46
- * these integrations using this module.
47
- *
48
- * Unlike the built-in integrations (like `Core`), custom integrations:
49
- * - Are defined per-workspace by importing OpenAPI specs
50
- * - Use a slug-based identifier instead of package names
51
- * - Proxy requests through Base44's backend (credentials never exposed to frontend)
52
- *
53
- * @example
54
- * ```typescript
55
- * // Call a custom GitHub integration
56
- * const response = await base44.integrations.custom.call(
57
- * "github", // integration slug (defined by workspace admin)
58
- * "listIssues", // operation ID from the OpenAPI spec
59
- * {
60
- * pathParams: { owner: "myorg", repo: "myrepo" },
61
- * queryParams: { state: "open", per_page: 100 }
62
- * }
63
- * );
39
+ * Module for calling custom pre-configured API integrations.
64
40
  *
65
- * if (response.success) {
66
- * console.log("Issues:", response.data);
67
- * } else {
68
- * console.error("API returned error:", response.status_code);
69
- * }
70
- * ```
71
- *
72
- * @example
73
- * ```typescript
74
- * // Call with request body payload
75
- * const response = await base44.integrations.custom.call(
76
- * "github",
77
- * "createIssue",
78
- * {
79
- * pathParams: { owner: "myorg", repo: "myrepo" },
80
- * payload: {
81
- * title: "Bug report",
82
- * body: "Something is broken",
83
- * labels: ["bug"]
84
- * }
85
- * }
86
- * );
87
- * ```
41
+ * Custom integrations allow workspace administrators to connect any external API by importing an OpenAPI specification. Apps in the workspace can then call these integrations using this module.
88
42
  */
89
43
  export interface CustomIntegrationsModule {
90
44
  /**
91
45
  * Call a custom integration endpoint.
92
46
  *
93
- * @param slug - The integration's unique identifier (slug), as defined by the workspace admin.
94
- * @param operationId - The operation ID from the OpenAPI spec (e.g., "listIssues", "getUser").
95
- * @param params - Optional parameters including payload, pathParams, queryParams, and headers.
47
+ * @param slug - The integration's unique identifier, as defined by the workspace admin.
48
+ * @param operationId - The endpoint in `method:path` format. For example, `"get:/contacts"`, or `"post:/users/{id}"`. The method is the HTTP verb in lowercase and the path matches the OpenAPI specification.
49
+ * @param params - Optional parameters including payload, pathParams, and queryParams.
96
50
  * @returns Promise resolving to the integration call response.
97
51
  *
98
52
  * @throws {Error} If slug is not provided.
@@ -100,6 +54,36 @@ export interface CustomIntegrationsModule {
100
54
  * @throws {Base44Error} If the integration or operation is not found (404).
101
55
  * @throws {Base44Error} If the external API call fails (502).
102
56
  * @throws {Base44Error} If the request times out (504).
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // Call a custom CRM integration
61
+ * const response = await base44.integrations.custom.call(
62
+ * "my-crm",
63
+ * "get:/contacts",
64
+ * { queryParams: { limit: 10 } }
65
+ * );
66
+ *
67
+ * if (response.success) {
68
+ * console.log("Contacts:", response.data);
69
+ * }
70
+ * ```
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Call with path params and request body
75
+ * const response = await base44.integrations.custom.call(
76
+ * "github",
77
+ * "post:/repos/{owner}/{repo}/issues",
78
+ * {
79
+ * pathParams: { owner: "myorg", repo: "myrepo" },
80
+ * payload: {
81
+ * title: "Bug report",
82
+ * body: "Something is broken"
83
+ * }
84
+ * }
85
+ * );
86
+ * ```
103
87
  */
104
88
  call(slug: string, operationId: string, params?: CustomIntegrationCallParams): Promise<CustomIntegrationCallResponse>;
105
89
  }