@base44/sdk 0.1.2 → 0.2.1
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.d.ts +50 -0
- package/dist/client.js +98 -0
- package/dist/index.d.ts +4 -86
- package/dist/index.js +6 -1
- package/dist/modules/auth.d.ts +56 -0
- package/dist/modules/auth.js +137 -0
- package/dist/modules/entities.d.ts +8 -0
- package/dist/modules/entities.js +139 -0
- package/dist/modules/functions.d.ts +10 -0
- package/dist/modules/functions.js +41 -0
- package/dist/modules/integrations.d.ts +8 -0
- package/dist/modules/integrations.js +68 -0
- package/dist/utils/auth-utils.d.ts +55 -0
- package/dist/utils/auth-utils.js +113 -0
- package/dist/utils/axios-client.d.ts +34 -0
- package/dist/utils/axios-client.js +114 -0
- package/package.json +13 -25
- package/dist/index.esm.js +0 -1
- package/dist/index.umd.js +0 -1
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a Base44 client instance
|
|
3
|
+
* @param {Object} config - Client configuration
|
|
4
|
+
* @param {string} [config.serverUrl='https://base44.app'] - API server URL
|
|
5
|
+
* @param {string|number} config.appId - Application ID
|
|
6
|
+
* @param {string} [config.env='prod'] - Environment ('prod' or 'dev')
|
|
7
|
+
* @param {string} [config.token] - Authentication token
|
|
8
|
+
* @param {boolean} [config.requiresAuth=false] - Whether the app requires authentication
|
|
9
|
+
* @returns {Object} Base44 client instance
|
|
10
|
+
*/
|
|
11
|
+
export declare function createClient(config: {
|
|
12
|
+
serverUrl?: string;
|
|
13
|
+
appId: string;
|
|
14
|
+
env?: string;
|
|
15
|
+
token?: string;
|
|
16
|
+
requiresAuth?: boolean;
|
|
17
|
+
}): {
|
|
18
|
+
entities: {};
|
|
19
|
+
integrations: {};
|
|
20
|
+
auth: {
|
|
21
|
+
me(): Promise<import("axios").AxiosResponse<any, any>>;
|
|
22
|
+
updateMe(data: Record<string, any>): Promise<import("axios").AxiosResponse<any, any>>;
|
|
23
|
+
redirectToLogin(nextUrl: string): void;
|
|
24
|
+
logout(redirectUrl?: string): void;
|
|
25
|
+
setToken(token: string, saveToStorage?: boolean): void;
|
|
26
|
+
loginViaUsernamePassword(email: string, password: string, turnstileToken?: string): Promise<{
|
|
27
|
+
access_token: string;
|
|
28
|
+
user: any;
|
|
29
|
+
}>;
|
|
30
|
+
isAuthenticated(): Promise<boolean>;
|
|
31
|
+
};
|
|
32
|
+
functions: {
|
|
33
|
+
invoke(functionName: string, data: Record<string, any>): Promise<import("axios").AxiosResponse<any, any>>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Set authentication token for all requests
|
|
37
|
+
* @param {string} newToken - New auth token
|
|
38
|
+
*/
|
|
39
|
+
setToken(newToken: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get current configuration
|
|
42
|
+
* @returns {Object} Current configuration
|
|
43
|
+
*/
|
|
44
|
+
getConfig(): {
|
|
45
|
+
serverUrl: string;
|
|
46
|
+
appId: string;
|
|
47
|
+
env: string;
|
|
48
|
+
requiresAuth: boolean;
|
|
49
|
+
};
|
|
50
|
+
};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createAxiosClient } from "./utils/axios-client.js";
|
|
2
|
+
import { createEntitiesModule } from "./modules/entities.js";
|
|
3
|
+
import { createIntegrationsModule } from "./modules/integrations.js";
|
|
4
|
+
import { createAuthModule } from "./modules/auth.js";
|
|
5
|
+
import { getAccessToken } from "./utils/auth-utils.js";
|
|
6
|
+
import { createFunctionsModule } from "./modules/functions.js";
|
|
7
|
+
/**
|
|
8
|
+
* Create a Base44 client instance
|
|
9
|
+
* @param {Object} config - Client configuration
|
|
10
|
+
* @param {string} [config.serverUrl='https://base44.app'] - API server URL
|
|
11
|
+
* @param {string|number} config.appId - Application ID
|
|
12
|
+
* @param {string} [config.env='prod'] - Environment ('prod' or 'dev')
|
|
13
|
+
* @param {string} [config.token] - Authentication token
|
|
14
|
+
* @param {boolean} [config.requiresAuth=false] - Whether the app requires authentication
|
|
15
|
+
* @returns {Object} Base44 client instance
|
|
16
|
+
*/
|
|
17
|
+
export function createClient(config) {
|
|
18
|
+
const { serverUrl = "https://base44.app", appId, env = "prod", token, requiresAuth = false, } = config;
|
|
19
|
+
// Create the base axios client
|
|
20
|
+
const axiosClient = createAxiosClient({
|
|
21
|
+
baseURL: `${serverUrl}/api`,
|
|
22
|
+
headers: {
|
|
23
|
+
"X-App-Id": String(appId),
|
|
24
|
+
"X-Environment": env,
|
|
25
|
+
},
|
|
26
|
+
token,
|
|
27
|
+
requiresAuth, // Pass requiresAuth to axios client
|
|
28
|
+
appId, // Pass appId for login redirect
|
|
29
|
+
serverUrl, // Pass serverUrl for login redirect
|
|
30
|
+
});
|
|
31
|
+
const functionsAxiosClient = createAxiosClient({
|
|
32
|
+
baseURL: `${serverUrl}/api`,
|
|
33
|
+
headers: {
|
|
34
|
+
"X-App-Id": String(appId),
|
|
35
|
+
"X-Environment": env,
|
|
36
|
+
},
|
|
37
|
+
token,
|
|
38
|
+
requiresAuth,
|
|
39
|
+
appId,
|
|
40
|
+
serverUrl,
|
|
41
|
+
interceptResponses: false,
|
|
42
|
+
});
|
|
43
|
+
// Create modules
|
|
44
|
+
const entities = createEntitiesModule(axiosClient, appId);
|
|
45
|
+
const integrations = createIntegrationsModule(axiosClient, appId);
|
|
46
|
+
const auth = createAuthModule(axiosClient, appId, serverUrl);
|
|
47
|
+
const functions = createFunctionsModule(functionsAxiosClient, appId);
|
|
48
|
+
// Always try to get token from localStorage or URL parameters
|
|
49
|
+
if (typeof window !== "undefined") {
|
|
50
|
+
// Get token from URL or localStorage
|
|
51
|
+
const accessToken = token || getAccessToken();
|
|
52
|
+
if (accessToken) {
|
|
53
|
+
auth.setToken(accessToken);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// If authentication is required, verify token and redirect to login if needed
|
|
57
|
+
if (requiresAuth && typeof window !== "undefined") {
|
|
58
|
+
// We perform this check asynchronously to not block client creation
|
|
59
|
+
setTimeout(async () => {
|
|
60
|
+
try {
|
|
61
|
+
const isAuthenticated = await auth.isAuthenticated();
|
|
62
|
+
if (!isAuthenticated) {
|
|
63
|
+
auth.redirectToLogin(window.location.href);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error("Authentication check failed:", error);
|
|
68
|
+
auth.redirectToLogin(window.location.href);
|
|
69
|
+
}
|
|
70
|
+
}, 0);
|
|
71
|
+
}
|
|
72
|
+
// Assemble and return the client
|
|
73
|
+
return {
|
|
74
|
+
entities,
|
|
75
|
+
integrations,
|
|
76
|
+
auth,
|
|
77
|
+
functions,
|
|
78
|
+
/**
|
|
79
|
+
* Set authentication token for all requests
|
|
80
|
+
* @param {string} newToken - New auth token
|
|
81
|
+
*/
|
|
82
|
+
setToken(newToken) {
|
|
83
|
+
auth.setToken(newToken);
|
|
84
|
+
},
|
|
85
|
+
/**
|
|
86
|
+
* Get current configuration
|
|
87
|
+
* @returns {Object} Current configuration
|
|
88
|
+
*/
|
|
89
|
+
getConfig() {
|
|
90
|
+
return {
|
|
91
|
+
serverUrl,
|
|
92
|
+
appId,
|
|
93
|
+
env,
|
|
94
|
+
requiresAuth,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,86 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
token?: string;
|
|
6
|
-
requiresAuth?: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface Entity {
|
|
10
|
-
id: string;
|
|
11
|
-
[key: string]: any;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface FilterOptions {
|
|
15
|
-
sort?: string;
|
|
16
|
-
limit?: number;
|
|
17
|
-
skip?: number;
|
|
18
|
-
fields?: string[] | string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface EntityMethods {
|
|
22
|
-
list(sort?: string, limit?: number, skip?: number, fields?: string[] | string): Promise<Entity[]>;
|
|
23
|
-
filter(query: any, sort?: string, limit?: number, skip?: number, fields?: string[] | string): Promise<Entity[]>;
|
|
24
|
-
get(id: string): Promise<Entity>;
|
|
25
|
-
create(data: Record<string, any>): Promise<Entity>;
|
|
26
|
-
update(id: string, data: Record<string, any>): Promise<Entity>;
|
|
27
|
-
delete(id: string): Promise<void>;
|
|
28
|
-
deleteMany(query: Record<string, any>): Promise<void>;
|
|
29
|
-
bulkCreate(data: Record<string, any>[]): Promise<Entity[]>;
|
|
30
|
-
importEntities(file: File): Promise<any>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface EntitiesModule {
|
|
34
|
-
[entityName: string]: EntityMethods;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface IntegrationEndpoint {
|
|
38
|
-
(data: Record<string, any>): Promise<any>;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface IntegrationsPackage {
|
|
42
|
-
[endpointName: string]: IntegrationEndpoint;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface IntegrationsModule {
|
|
46
|
-
[packageName: string]: IntegrationsPackage;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface AuthModule {
|
|
50
|
-
me(): Promise<Entity>;
|
|
51
|
-
updateMe(data: Record<string, any>): Promise<Entity>;
|
|
52
|
-
login(nextUrl?: string): void;
|
|
53
|
-
logout(redirectUrl?: string): Promise<void>;
|
|
54
|
-
setToken(token: string, saveToStorage?: boolean): void;
|
|
55
|
-
isAuthenticated(): Promise<boolean>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface Base44Client {
|
|
59
|
-
entities: EntitiesModule;
|
|
60
|
-
integrations: IntegrationsModule;
|
|
61
|
-
auth: AuthModule;
|
|
62
|
-
setToken(token: string): void;
|
|
63
|
-
getConfig(): {
|
|
64
|
-
serverUrl: string;
|
|
65
|
-
appId: string | number;
|
|
66
|
-
env: string;
|
|
67
|
-
requiresAuth: boolean;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export class Base44Error extends Error {
|
|
72
|
-
status?: number;
|
|
73
|
-
code?: string;
|
|
74
|
-
data?: any;
|
|
75
|
-
originalError?: Error;
|
|
76
|
-
|
|
77
|
-
constructor(
|
|
78
|
-
message: string,
|
|
79
|
-
status?: number,
|
|
80
|
-
code?: string,
|
|
81
|
-
data?: any,
|
|
82
|
-
originalError?: Error
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function createClient(config: ClientConfig): Base44Client;
|
|
1
|
+
import { createClient } from "./client.js";
|
|
2
|
+
import { Base44Error } from "./utils/axios-client.js";
|
|
3
|
+
import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl } from "./utils/auth-utils.js";
|
|
4
|
+
export { createClient, Base44Error, getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { createClient } from "./client.js";
|
|
2
|
+
import { Base44Error } from "./utils/axios-client.js";
|
|
3
|
+
import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, } from "./utils/auth-utils.js";
|
|
4
|
+
export { createClient, Base44Error,
|
|
5
|
+
// Export auth utilities for easier access
|
|
6
|
+
getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the auth module for the Base44 SDK
|
|
4
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
5
|
+
* @param {string|number} appId - Application ID
|
|
6
|
+
* @param {string} serverUrl - Server URL
|
|
7
|
+
* @returns {Object} Auth module with authentication methods
|
|
8
|
+
*/
|
|
9
|
+
export declare function createAuthModule(axios: AxiosInstance, appId: string, serverUrl: string): {
|
|
10
|
+
/**
|
|
11
|
+
* Get current user information
|
|
12
|
+
* @returns {Promise<Object>} Current user data
|
|
13
|
+
*/
|
|
14
|
+
me(): Promise<import("axios").AxiosResponse<any, any>>;
|
|
15
|
+
/**
|
|
16
|
+
* Update current user data
|
|
17
|
+
* @param {Object} data - Updated user data
|
|
18
|
+
* @returns {Promise<Object>} Updated user
|
|
19
|
+
*/
|
|
20
|
+
updateMe(data: Record<string, any>): Promise<import("axios").AxiosResponse<any, any>>;
|
|
21
|
+
/**
|
|
22
|
+
* Redirects the user to the app's login page
|
|
23
|
+
* @param {string} nextUrl - URL to redirect to after successful login
|
|
24
|
+
* @throws {Error} When not in a browser environment
|
|
25
|
+
*/
|
|
26
|
+
redirectToLogin(nextUrl: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Logout the current user
|
|
29
|
+
* Removes the token from localStorage and optionally redirects to a URL or reloads the page
|
|
30
|
+
* @param redirectUrl - Optional URL to redirect to after logout. Reloads the page if not provided
|
|
31
|
+
* @returns {Promise<void>}
|
|
32
|
+
*/
|
|
33
|
+
logout(redirectUrl?: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Set authentication token
|
|
36
|
+
* @param {string} token - Auth token
|
|
37
|
+
* @param {boolean} [saveToStorage=true] - Whether to save the token to localStorage
|
|
38
|
+
*/
|
|
39
|
+
setToken(token: string, saveToStorage?: boolean): void;
|
|
40
|
+
/**
|
|
41
|
+
* Login via username and password
|
|
42
|
+
* @param email - User email
|
|
43
|
+
* @param password - User password
|
|
44
|
+
* @param turnstileToken - Optional Turnstile captcha token
|
|
45
|
+
* @returns Login response with access_token and user
|
|
46
|
+
*/
|
|
47
|
+
loginViaUsernamePassword(email: string, password: string, turnstileToken?: string): Promise<{
|
|
48
|
+
access_token: string;
|
|
49
|
+
user: any;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Verify if the current token is valid
|
|
53
|
+
* @returns {Promise<boolean>} True if token is valid
|
|
54
|
+
*/
|
|
55
|
+
isAuthenticated(): Promise<boolean>;
|
|
56
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the auth module for the Base44 SDK
|
|
3
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
4
|
+
* @param {string|number} appId - Application ID
|
|
5
|
+
* @param {string} serverUrl - Server URL
|
|
6
|
+
* @returns {Object} Auth module with authentication methods
|
|
7
|
+
*/
|
|
8
|
+
export function createAuthModule(axios, appId, serverUrl) {
|
|
9
|
+
return {
|
|
10
|
+
/**
|
|
11
|
+
* Get current user information
|
|
12
|
+
* @returns {Promise<Object>} Current user data
|
|
13
|
+
*/
|
|
14
|
+
async me() {
|
|
15
|
+
return axios.get(`/apps/${appId}/entities/User/me`);
|
|
16
|
+
},
|
|
17
|
+
/**
|
|
18
|
+
* Update current user data
|
|
19
|
+
* @param {Object} data - Updated user data
|
|
20
|
+
* @returns {Promise<Object>} Updated user
|
|
21
|
+
*/
|
|
22
|
+
async updateMe(data) {
|
|
23
|
+
return axios.put(`/apps/${appId}/entities/User/me`, data);
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* Redirects the user to the app's login page
|
|
27
|
+
* @param {string} nextUrl - URL to redirect to after successful login
|
|
28
|
+
* @throws {Error} When not in a browser environment
|
|
29
|
+
*/
|
|
30
|
+
redirectToLogin(nextUrl) {
|
|
31
|
+
// This function only works in a browser environment
|
|
32
|
+
if (typeof window === "undefined") {
|
|
33
|
+
throw new Error("Login method can only be used in a browser environment");
|
|
34
|
+
}
|
|
35
|
+
// If nextUrl is not provided, use the current URL
|
|
36
|
+
const redirectUrl = nextUrl || window.location.href;
|
|
37
|
+
// Build the login URL
|
|
38
|
+
const loginUrl = `/login?from_url=${encodeURIComponent(redirectUrl)}`;
|
|
39
|
+
// Redirect to the login page
|
|
40
|
+
window.location.href = loginUrl;
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Logout the current user
|
|
44
|
+
* Removes the token from localStorage and optionally redirects to a URL or reloads the page
|
|
45
|
+
* @param redirectUrl - Optional URL to redirect to after logout. Reloads the page if not provided
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
logout(redirectUrl) {
|
|
49
|
+
// Remove token from axios headers
|
|
50
|
+
delete axios.defaults.headers.common["Authorization"];
|
|
51
|
+
// Remove token from localStorage
|
|
52
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
53
|
+
try {
|
|
54
|
+
window.localStorage.removeItem("base44_access_token");
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.error("Failed to remove token from localStorage:", e);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Redirect if a URL is provided
|
|
61
|
+
if (typeof window !== "undefined") {
|
|
62
|
+
if (redirectUrl) {
|
|
63
|
+
window.location.href = redirectUrl;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
window.location.reload();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Set authentication token
|
|
72
|
+
* @param {string} token - Auth token
|
|
73
|
+
* @param {boolean} [saveToStorage=true] - Whether to save the token to localStorage
|
|
74
|
+
*/
|
|
75
|
+
setToken(token, saveToStorage = true) {
|
|
76
|
+
if (!token)
|
|
77
|
+
return;
|
|
78
|
+
axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
|
|
79
|
+
// Save token to localStorage if requested
|
|
80
|
+
if (saveToStorage &&
|
|
81
|
+
typeof window !== "undefined" &&
|
|
82
|
+
window.localStorage) {
|
|
83
|
+
try {
|
|
84
|
+
window.localStorage.setItem("base44_access_token", token);
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
console.error("Failed to save token to localStorage:", e);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* Login via username and password
|
|
93
|
+
* @param email - User email
|
|
94
|
+
* @param password - User password
|
|
95
|
+
* @param turnstileToken - Optional Turnstile captcha token
|
|
96
|
+
* @returns Login response with access_token and user
|
|
97
|
+
*/
|
|
98
|
+
async loginViaUsernamePassword(email, password, turnstileToken) {
|
|
99
|
+
var _a;
|
|
100
|
+
try {
|
|
101
|
+
const response = await axios.post(`/apps/${appId}/auth/login`, {
|
|
102
|
+
email,
|
|
103
|
+
password,
|
|
104
|
+
...(turnstileToken && { turnstile_token: turnstileToken }),
|
|
105
|
+
});
|
|
106
|
+
const { access_token, user } = response;
|
|
107
|
+
if (access_token) {
|
|
108
|
+
this.setToken(access_token);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
access_token,
|
|
112
|
+
user,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
// Handle authentication errors and cleanup
|
|
117
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401) {
|
|
118
|
+
await this.logout();
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Verify if the current token is valid
|
|
125
|
+
* @returns {Promise<boolean>} True if token is valid
|
|
126
|
+
*/
|
|
127
|
+
async isAuthenticated() {
|
|
128
|
+
try {
|
|
129
|
+
await this.me();
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the entities module for the Base44 SDK
|
|
4
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
5
|
+
* @param {string|number} appId - Application ID
|
|
6
|
+
* @returns {Object} Entities module
|
|
7
|
+
*/
|
|
8
|
+
export declare function createEntitiesModule(axios: AxiosInstance, appId: string): {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the entities module for the Base44 SDK
|
|
3
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
4
|
+
* @param {string|number} appId - Application ID
|
|
5
|
+
* @returns {Object} Entities module
|
|
6
|
+
*/
|
|
7
|
+
export function createEntitiesModule(axios, appId) {
|
|
8
|
+
// Using Proxy to dynamically handle entity names
|
|
9
|
+
return new Proxy({}, {
|
|
10
|
+
get(target, entityName) {
|
|
11
|
+
// Don't create handlers for internal properties
|
|
12
|
+
if (typeof entityName !== "string" ||
|
|
13
|
+
entityName === "then" ||
|
|
14
|
+
entityName.startsWith("_")) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
// Create entity handler
|
|
18
|
+
return createEntityHandler(axios, appId, entityName);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a handler for a specific entity
|
|
24
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
25
|
+
* @param {string|number} appId - Application ID
|
|
26
|
+
* @param {string} entityName - Entity name
|
|
27
|
+
* @returns {Object} Entity handler with CRUD methods
|
|
28
|
+
*/
|
|
29
|
+
function createEntityHandler(axios, appId, entityName) {
|
|
30
|
+
const baseURL = `/apps/${appId}/entities/${entityName}`;
|
|
31
|
+
return {
|
|
32
|
+
/**
|
|
33
|
+
* List entities with optional pagination and sorting
|
|
34
|
+
* @param {string} [sort] - Sort parameter
|
|
35
|
+
* @param {number} [limit] - Limit results
|
|
36
|
+
* @param {number} [skip] - Skip results (pagination)
|
|
37
|
+
* @param {string[]} [fields] - Fields to include
|
|
38
|
+
* @returns {Promise<Array>} List of entities
|
|
39
|
+
*/
|
|
40
|
+
async list(sort, limit, skip, fields) {
|
|
41
|
+
const params = {};
|
|
42
|
+
if (sort)
|
|
43
|
+
params.sort = sort;
|
|
44
|
+
if (limit)
|
|
45
|
+
params.limit = limit;
|
|
46
|
+
if (skip)
|
|
47
|
+
params.skip = skip;
|
|
48
|
+
if (fields)
|
|
49
|
+
params.fields = Array.isArray(fields) ? fields.join(",") : fields;
|
|
50
|
+
return axios.get(baseURL, { params });
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* Filter entities based on query
|
|
54
|
+
* @param {Object} query - Filter query
|
|
55
|
+
* @param {string} [sort] - Sort parameter
|
|
56
|
+
* @param {number} [limit] - Limit results
|
|
57
|
+
* @param {number} [skip] - Skip results (pagination)
|
|
58
|
+
* @param {string[]} [fields] - Fields to include
|
|
59
|
+
* @returns {Promise<Array>} Filtered entities
|
|
60
|
+
*/
|
|
61
|
+
async filter(query, sort, limit, skip, fields) {
|
|
62
|
+
const params = {
|
|
63
|
+
q: JSON.stringify(query),
|
|
64
|
+
};
|
|
65
|
+
if (sort)
|
|
66
|
+
params.sort = sort;
|
|
67
|
+
if (limit)
|
|
68
|
+
params.limit = limit;
|
|
69
|
+
if (skip)
|
|
70
|
+
params.skip = skip;
|
|
71
|
+
if (fields)
|
|
72
|
+
params.fields = Array.isArray(fields) ? fields.join(",") : fields;
|
|
73
|
+
return axios.get(baseURL, { params });
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Get entity by ID
|
|
77
|
+
* @param {string} id - Entity ID
|
|
78
|
+
* @returns {Promise<Object>} Entity
|
|
79
|
+
*/
|
|
80
|
+
async get(id) {
|
|
81
|
+
return axios.get(`${baseURL}/${id}`);
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Create new entity
|
|
85
|
+
* @param {Object} data - Entity data
|
|
86
|
+
* @returns {Promise<Object>} Created entity
|
|
87
|
+
*/
|
|
88
|
+
async create(data) {
|
|
89
|
+
return axios.post(baseURL, data);
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* Update entity by ID
|
|
93
|
+
* @param {string} id - Entity ID
|
|
94
|
+
* @param {Object} data - Updated entity data
|
|
95
|
+
* @returns {Promise<Object>} Updated entity
|
|
96
|
+
*/
|
|
97
|
+
async update(id, data) {
|
|
98
|
+
return axios.put(`${baseURL}/${id}`, data);
|
|
99
|
+
},
|
|
100
|
+
/**
|
|
101
|
+
* Delete entity by ID
|
|
102
|
+
* @param {string} id - Entity ID
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
async delete(id) {
|
|
106
|
+
return axios.delete(`${baseURL}/${id}`);
|
|
107
|
+
},
|
|
108
|
+
/**
|
|
109
|
+
* Delete multiple entities based on query
|
|
110
|
+
* @param {Object} query - Delete query
|
|
111
|
+
* @returns {Promise<void>}
|
|
112
|
+
*/
|
|
113
|
+
async deleteMany(query) {
|
|
114
|
+
return axios.delete(baseURL, { data: query });
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Create multiple entities in a single request
|
|
118
|
+
* @param {Array} data - Array of entity data
|
|
119
|
+
* @returns {Promise<Array>} Created entities
|
|
120
|
+
*/
|
|
121
|
+
async bulkCreate(data) {
|
|
122
|
+
return axios.post(`${baseURL}/bulk`, data);
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* Import entities from a file
|
|
126
|
+
* @param {File} file - File to import
|
|
127
|
+
* @returns {Promise<Object>} Import result
|
|
128
|
+
*/
|
|
129
|
+
async importEntities(file) {
|
|
130
|
+
const formData = new FormData();
|
|
131
|
+
formData.append("file", file, file.name);
|
|
132
|
+
return axios.post(`${baseURL}/import`, formData, {
|
|
133
|
+
headers: {
|
|
134
|
+
"Content-Type": "multipart/form-data",
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the functions module for the Base44 SDK
|
|
4
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
5
|
+
* @param {string|number} appId - Application ID
|
|
6
|
+
* @returns {Object} Functions module
|
|
7
|
+
*/
|
|
8
|
+
export declare function createFunctionsModule(axios: AxiosInstance, appId: string): {
|
|
9
|
+
invoke(functionName: string, data: Record<string, any>): Promise<import("axios").AxiosResponse<any, any>>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the functions module for the Base44 SDK
|
|
3
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
4
|
+
* @param {string|number} appId - Application ID
|
|
5
|
+
* @returns {Object} Functions module
|
|
6
|
+
*/
|
|
7
|
+
export function createFunctionsModule(axios, appId) {
|
|
8
|
+
// Using nested Proxy objects to handle dynamic function names
|
|
9
|
+
return {
|
|
10
|
+
async invoke(functionName, data) {
|
|
11
|
+
// Validate input
|
|
12
|
+
if (typeof data === "string") {
|
|
13
|
+
throw new Error(`Function ${functionName} must receive an object with named parameters, received: ${data}`);
|
|
14
|
+
}
|
|
15
|
+
let formData;
|
|
16
|
+
let contentType;
|
|
17
|
+
// Handle file uploads with FormData
|
|
18
|
+
if (data instanceof FormData ||
|
|
19
|
+
(data && Object.values(data).some((value) => value instanceof File))) {
|
|
20
|
+
formData = new FormData();
|
|
21
|
+
Object.keys(data).forEach((key) => {
|
|
22
|
+
if (data[key] instanceof File) {
|
|
23
|
+
formData.append(key, data[key], data[key].name);
|
|
24
|
+
}
|
|
25
|
+
else if (typeof data[key] === "object" && data[key] !== null) {
|
|
26
|
+
formData.append(key, JSON.stringify(data[key]));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
formData.append(key, data[key]);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
contentType = "multipart/form-data";
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
formData = data;
|
|
36
|
+
contentType = "application/json";
|
|
37
|
+
}
|
|
38
|
+
return axios.post(`/apps/${appId}/functions/${functionName}`, formData || data, { headers: { "Content-Type": contentType } });
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the integrations module for the Base44 SDK
|
|
4
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
5
|
+
* @param {string|number} appId - Application ID
|
|
6
|
+
* @returns {Object} Integrations module
|
|
7
|
+
*/
|
|
8
|
+
export declare function createIntegrationsModule(axios: AxiosInstance, appId: string): {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the integrations module for the Base44 SDK
|
|
3
|
+
* @param {import('axios').AxiosInstance} axios - Axios instance
|
|
4
|
+
* @param {string|number} appId - Application ID
|
|
5
|
+
* @returns {Object} Integrations module
|
|
6
|
+
*/
|
|
7
|
+
export function createIntegrationsModule(axios, appId) {
|
|
8
|
+
// Using nested Proxy objects to handle dynamic package and endpoint names
|
|
9
|
+
return new Proxy({}, {
|
|
10
|
+
get(target, packageName) {
|
|
11
|
+
// Skip internal properties
|
|
12
|
+
if (typeof packageName !== "string" ||
|
|
13
|
+
packageName === "then" ||
|
|
14
|
+
packageName.startsWith("_")) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
// Create a proxy for integration endpoints
|
|
18
|
+
return new Proxy({}, {
|
|
19
|
+
get(target, endpointName) {
|
|
20
|
+
// Skip internal properties
|
|
21
|
+
if (typeof endpointName !== "string" ||
|
|
22
|
+
endpointName === "then" ||
|
|
23
|
+
endpointName.startsWith("_")) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
// Return a function that calls the integration endpoint
|
|
27
|
+
return async (data) => {
|
|
28
|
+
// Validate input
|
|
29
|
+
if (typeof data === "string") {
|
|
30
|
+
throw new Error(`Integration ${endpointName} must receive an object with named parameters, received: ${data}`);
|
|
31
|
+
}
|
|
32
|
+
let formData;
|
|
33
|
+
let contentType;
|
|
34
|
+
// Handle file uploads with FormData
|
|
35
|
+
if (data instanceof FormData ||
|
|
36
|
+
(data &&
|
|
37
|
+
Object.values(data).some((value) => value instanceof File))) {
|
|
38
|
+
formData = new FormData();
|
|
39
|
+
Object.keys(data).forEach((key) => {
|
|
40
|
+
if (data[key] instanceof File) {
|
|
41
|
+
formData.append(key, data[key], data[key].name);
|
|
42
|
+
}
|
|
43
|
+
else if (typeof data[key] === "object" &&
|
|
44
|
+
data[key] !== null) {
|
|
45
|
+
formData.append(key, JSON.stringify(data[key]));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
formData.append(key, data[key]);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
contentType = "multipart/form-data";
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
formData = data;
|
|
55
|
+
contentType = "application/json";
|
|
56
|
+
}
|
|
57
|
+
// For Core package
|
|
58
|
+
if (packageName === "Core") {
|
|
59
|
+
return axios.post(`/apps/${appId}/integration-endpoints/Core/${endpointName}`, formData || data, { headers: { "Content-Type": contentType } });
|
|
60
|
+
}
|
|
61
|
+
// For other packages
|
|
62
|
+
return axios.post(`/apps/${appId}/integration-endpoints/installable/${packageName}/integration-endpoints/${endpointName}`, formData || data, { headers: { "Content-Type": contentType } });
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for authentication and token handling
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves an access token from either localStorage or URL parameters
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} options - Configuration options
|
|
8
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
9
|
+
* @param {string} [options.paramName='access_token'] - The URL parameter name
|
|
10
|
+
* @param {boolean} [options.saveToStorage=true] - Whether to save the token to localStorage if found in URL
|
|
11
|
+
* @param {boolean} [options.removeFromUrl=true] - Whether to remove the token from URL after retrieval
|
|
12
|
+
* @returns {string|null} The access token or null if not found
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAccessToken(options?: {
|
|
15
|
+
storageKey?: string;
|
|
16
|
+
paramName?: string;
|
|
17
|
+
saveToStorage?: boolean;
|
|
18
|
+
removeFromUrl?: boolean;
|
|
19
|
+
}): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Saves an access token to localStorage
|
|
22
|
+
*
|
|
23
|
+
* @param {string} token - The access token to save
|
|
24
|
+
* @param {Object} options - Configuration options
|
|
25
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
26
|
+
* @returns {boolean} Success status
|
|
27
|
+
*/
|
|
28
|
+
export declare function saveAccessToken(token: string, options: {
|
|
29
|
+
storageKey?: string;
|
|
30
|
+
}): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Removes the access token from localStorage
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} options - Configuration options
|
|
35
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
36
|
+
* @returns {boolean} Success status
|
|
37
|
+
*/
|
|
38
|
+
export declare function removeAccessToken(options: {
|
|
39
|
+
storageKey?: string;
|
|
40
|
+
}): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Constructs the absolute URL for the login page
|
|
43
|
+
*
|
|
44
|
+
* @param {string} nextUrl - URL to redirect back to after login
|
|
45
|
+
* @param {Object} options - Configuration options
|
|
46
|
+
* @param {string} options.serverUrl - Server URL (e.g., 'https://base44.app')
|
|
47
|
+
* @param {string|number} options.appId - Application ID
|
|
48
|
+
* @param {string} [options.loginPath='/login'] - Path to the login endpoint
|
|
49
|
+
* @returns {string} The complete login URL
|
|
50
|
+
*/
|
|
51
|
+
export declare function getLoginUrl(nextUrl: string, options: {
|
|
52
|
+
serverUrl: string;
|
|
53
|
+
appId: string;
|
|
54
|
+
loginPath?: string;
|
|
55
|
+
}): string;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for authentication and token handling
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves an access token from either localStorage or URL parameters
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} options - Configuration options
|
|
8
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
9
|
+
* @param {string} [options.paramName='access_token'] - The URL parameter name
|
|
10
|
+
* @param {boolean} [options.saveToStorage=true] - Whether to save the token to localStorage if found in URL
|
|
11
|
+
* @param {boolean} [options.removeFromUrl=true] - Whether to remove the token from URL after retrieval
|
|
12
|
+
* @returns {string|null} The access token or null if not found
|
|
13
|
+
*/
|
|
14
|
+
export function getAccessToken(options = {}) {
|
|
15
|
+
const { storageKey = "base44_access_token", paramName = "access_token", saveToStorage = true, removeFromUrl = true, } = options;
|
|
16
|
+
let token = null;
|
|
17
|
+
// Try to get token from URL parameters
|
|
18
|
+
if (typeof window !== "undefined" && window.location) {
|
|
19
|
+
try {
|
|
20
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
21
|
+
token = urlParams.get(paramName);
|
|
22
|
+
// If token found in URL
|
|
23
|
+
if (token) {
|
|
24
|
+
// Save token to localStorage if requested
|
|
25
|
+
if (saveToStorage) {
|
|
26
|
+
saveAccessToken(token, { storageKey });
|
|
27
|
+
}
|
|
28
|
+
// Remove token from URL for security if requested
|
|
29
|
+
if (removeFromUrl) {
|
|
30
|
+
urlParams.delete(paramName);
|
|
31
|
+
const newUrl = `${window.location.pathname}${urlParams.toString() ? `?${urlParams.toString()}` : ""}${window.location.hash}`;
|
|
32
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
33
|
+
}
|
|
34
|
+
return token;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.error("Error retrieving token from URL:", e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// If no token in URL, try localStorage
|
|
42
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
43
|
+
try {
|
|
44
|
+
token = window.localStorage.getItem(storageKey);
|
|
45
|
+
return token;
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
console.error("Error retrieving token from localStorage:", e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Saves an access token to localStorage
|
|
55
|
+
*
|
|
56
|
+
* @param {string} token - The access token to save
|
|
57
|
+
* @param {Object} options - Configuration options
|
|
58
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
59
|
+
* @returns {boolean} Success status
|
|
60
|
+
*/
|
|
61
|
+
export function saveAccessToken(token, options) {
|
|
62
|
+
const { storageKey = "base44_access_token" } = options;
|
|
63
|
+
if (typeof window === "undefined" || !window.localStorage || !token) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
window.localStorage.setItem(storageKey, token);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.error("Error saving token to localStorage:", e);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Removes the access token from localStorage
|
|
77
|
+
*
|
|
78
|
+
* @param {Object} options - Configuration options
|
|
79
|
+
* @param {string} [options.storageKey='base44_access_token'] - The key to use in localStorage
|
|
80
|
+
* @returns {boolean} Success status
|
|
81
|
+
*/
|
|
82
|
+
export function removeAccessToken(options) {
|
|
83
|
+
const { storageKey = "base44_access_token" } = options;
|
|
84
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
window.localStorage.removeItem(storageKey);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
console.error("Error removing token from localStorage:", e);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Constructs the absolute URL for the login page
|
|
98
|
+
*
|
|
99
|
+
* @param {string} nextUrl - URL to redirect back to after login
|
|
100
|
+
* @param {Object} options - Configuration options
|
|
101
|
+
* @param {string} options.serverUrl - Server URL (e.g., 'https://base44.app')
|
|
102
|
+
* @param {string|number} options.appId - Application ID
|
|
103
|
+
* @param {string} [options.loginPath='/login'] - Path to the login endpoint
|
|
104
|
+
* @returns {string} The complete login URL
|
|
105
|
+
*/
|
|
106
|
+
export function getLoginUrl(nextUrl, options) {
|
|
107
|
+
const { serverUrl, appId, loginPath = "/login" } = options;
|
|
108
|
+
if (!serverUrl || !appId) {
|
|
109
|
+
throw new Error("serverUrl and appId are required to construct login URL");
|
|
110
|
+
}
|
|
111
|
+
const encodedRedirectUrl = encodeURIComponent(nextUrl || (typeof window !== "undefined" ? window.location.href : ""));
|
|
112
|
+
return `${serverUrl}${loginPath}?from_url=${encodedRedirectUrl}&app_id=${appId}`;
|
|
113
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare class Base44Error extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
code: string;
|
|
4
|
+
data: any;
|
|
5
|
+
originalError: unknown;
|
|
6
|
+
constructor(message: string, status: number, code: string, data: any, originalError: unknown);
|
|
7
|
+
toJSON(): {
|
|
8
|
+
name: string;
|
|
9
|
+
message: string;
|
|
10
|
+
status: number;
|
|
11
|
+
code: string;
|
|
12
|
+
data: any;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates an axios client with default configuration and interceptors
|
|
17
|
+
* @param {Object} options - Client configuration options
|
|
18
|
+
* @param {string} options.baseURL - Base URL for all requests
|
|
19
|
+
* @param {Object} options.headers - Additional headers
|
|
20
|
+
* @param {string} options.token - Auth token
|
|
21
|
+
* @param {boolean} options.requiresAuth - Whether the application requires authentication
|
|
22
|
+
* @param {string|number} options.appId - Application ID (needed for login redirect)
|
|
23
|
+
* @param {string} options.serverUrl - Server URL (needed for login redirect)
|
|
24
|
+
* @returns {import('axios').AxiosInstance} Configured axios instance
|
|
25
|
+
*/
|
|
26
|
+
export declare function createAxiosClient({ baseURL, headers, token, requiresAuth, appId, serverUrl, interceptResponses, }: {
|
|
27
|
+
baseURL: string;
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
token?: string;
|
|
30
|
+
requiresAuth?: boolean;
|
|
31
|
+
appId: string;
|
|
32
|
+
serverUrl: string;
|
|
33
|
+
interceptResponses?: boolean;
|
|
34
|
+
}): import("axios").AxiosInstance;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
export class Base44Error extends Error {
|
|
3
|
+
constructor(message, status, code, data, originalError) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "Base44Error";
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.data = data;
|
|
9
|
+
this.originalError = originalError;
|
|
10
|
+
}
|
|
11
|
+
// Add a method to safely serialize this error without circular references
|
|
12
|
+
toJSON() {
|
|
13
|
+
return {
|
|
14
|
+
name: this.name,
|
|
15
|
+
message: this.message,
|
|
16
|
+
status: this.status,
|
|
17
|
+
code: this.code,
|
|
18
|
+
data: this.data,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Safely logs error information without circular references
|
|
24
|
+
* @param {string} prefix - Prefix for the log message
|
|
25
|
+
* @param {Error} error - The error to log
|
|
26
|
+
*/
|
|
27
|
+
function safeErrorLog(prefix, error) {
|
|
28
|
+
if (error instanceof Base44Error) {
|
|
29
|
+
console.error(`${prefix} ${error.status}: ${error.message}`);
|
|
30
|
+
if (error.data) {
|
|
31
|
+
try {
|
|
32
|
+
console.error("Error data:", JSON.stringify(error.data, null, 2));
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
console.error("Error data: [Cannot stringify error data]");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.error(`${prefix} ${error instanceof Error ? error.message : String(error)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Redirects to the login page with the current URL as return destination
|
|
45
|
+
* @param {string} serverUrl - Base server URL
|
|
46
|
+
* @param {string|number} appId - Application ID
|
|
47
|
+
*/
|
|
48
|
+
function redirectToLogin(serverUrl, appId) {
|
|
49
|
+
if (typeof window === "undefined") {
|
|
50
|
+
return; // Can't redirect in non-browser environment
|
|
51
|
+
}
|
|
52
|
+
const currentUrl = encodeURIComponent(window.location.href);
|
|
53
|
+
const loginUrl = `${serverUrl}/login?from_url=${currentUrl}&app_id=${appId}`;
|
|
54
|
+
window.location.href = loginUrl;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Creates an axios client with default configuration and interceptors
|
|
58
|
+
* @param {Object} options - Client configuration options
|
|
59
|
+
* @param {string} options.baseURL - Base URL for all requests
|
|
60
|
+
* @param {Object} options.headers - Additional headers
|
|
61
|
+
* @param {string} options.token - Auth token
|
|
62
|
+
* @param {boolean} options.requiresAuth - Whether the application requires authentication
|
|
63
|
+
* @param {string|number} options.appId - Application ID (needed for login redirect)
|
|
64
|
+
* @param {string} options.serverUrl - Server URL (needed for login redirect)
|
|
65
|
+
* @returns {import('axios').AxiosInstance} Configured axios instance
|
|
66
|
+
*/
|
|
67
|
+
export function createAxiosClient({ baseURL, headers = {}, token, requiresAuth = false, appId, serverUrl, interceptResponses = true, }) {
|
|
68
|
+
const client = axios.create({
|
|
69
|
+
baseURL,
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
Accept: "application/json",
|
|
73
|
+
...headers,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
// Add token to requests if available
|
|
77
|
+
if (token) {
|
|
78
|
+
client.defaults.headers.common["Authorization"] = `Bearer ${token}`;
|
|
79
|
+
}
|
|
80
|
+
// Add origin URL in browser environment
|
|
81
|
+
client.interceptors.request.use((config) => {
|
|
82
|
+
if (typeof window !== "undefined") {
|
|
83
|
+
config.headers.set("X-Origin-URL", window.location.href);
|
|
84
|
+
}
|
|
85
|
+
return config;
|
|
86
|
+
});
|
|
87
|
+
// Handle responses
|
|
88
|
+
if (interceptResponses) {
|
|
89
|
+
client.interceptors.response.use((response) => response.data, (error) => {
|
|
90
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
91
|
+
const message = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) ||
|
|
92
|
+
((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.detail) ||
|
|
93
|
+
error.message;
|
|
94
|
+
const base44Error = new Base44Error(message, (_e = error.response) === null || _e === void 0 ? void 0 : _e.status, (_g = (_f = error.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.code, (_h = error.response) === null || _h === void 0 ? void 0 : _h.data, error);
|
|
95
|
+
// Log errors in development
|
|
96
|
+
if (process.env.NODE_ENV !== "production") {
|
|
97
|
+
safeErrorLog("[Base44 SDK Error]", base44Error);
|
|
98
|
+
}
|
|
99
|
+
// Check for 403 Forbidden (authentication required) and redirect to login if requiresAuth is true
|
|
100
|
+
console.log(requiresAuth, (_j = error.response) === null || _j === void 0 ? void 0 : _j.status, typeof window !== "undefined");
|
|
101
|
+
if (requiresAuth &&
|
|
102
|
+
((_k = error.response) === null || _k === void 0 ? void 0 : _k.status) === 403 &&
|
|
103
|
+
typeof window !== "undefined") {
|
|
104
|
+
console.log("Authentication required. Redirecting to login...");
|
|
105
|
+
// Use a slight delay to allow the error to propagate first
|
|
106
|
+
setTimeout(() => {
|
|
107
|
+
redirectToLogin(serverUrl, appId);
|
|
108
|
+
}, 100);
|
|
109
|
+
}
|
|
110
|
+
return Promise.reject(base44Error);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return client;
|
|
114
|
+
}
|
package/package.json
CHANGED
|
@@ -1,49 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@base44/sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "JavaScript SDK for Base44 API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.esm.js",
|
|
7
6
|
"types": "dist/index.d.ts",
|
|
8
|
-
"browser": "dist/index.umd.js",
|
|
9
7
|
"type": "module",
|
|
10
8
|
"files": [
|
|
11
9
|
"dist"
|
|
12
10
|
],
|
|
13
11
|
"scripts": {
|
|
14
|
-
"build": "
|
|
15
|
-
"build:types": "tsc --emitDeclarationOnly",
|
|
16
|
-
"copy:types": "cp src/types.d.ts dist/index.d.ts",
|
|
12
|
+
"build": "tsc",
|
|
17
13
|
"lint": "eslint src",
|
|
18
|
-
"test": "
|
|
19
|
-
"test:unit": "
|
|
20
|
-
"test:e2e": "
|
|
21
|
-
"test:watch": "
|
|
22
|
-
"test:coverage": "
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:unit": "vitest run tests/unit",
|
|
16
|
+
"test:e2e": "vitest run tests/e2e",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"test:coverage": "vitest run --coverage",
|
|
23
19
|
"prepublishOnly": "npm run build"
|
|
24
20
|
},
|
|
25
21
|
"dependencies": {
|
|
26
22
|
"axios": "^1.6.2"
|
|
27
23
|
},
|
|
28
24
|
"devDependencies": {
|
|
29
|
-
"
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
33
|
-
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
34
|
-
"@rollup/plugin-terser": "^0.4.4",
|
|
35
|
-
"@types/jest": "^29.5.10",
|
|
36
|
-
"babel-jest": "^29.7.0",
|
|
25
|
+
"vitest": "^1.0.0",
|
|
26
|
+
"@vitest/ui": "^1.0.0",
|
|
27
|
+
"@vitest/coverage-istanbul": "^1.0.0",
|
|
28
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
37
29
|
"dotenv": "^16.3.1",
|
|
38
30
|
"eslint": "^8.54.0",
|
|
39
|
-
"jest": "^29.7.0",
|
|
40
31
|
"nock": "^13.4.0",
|
|
41
|
-
"rollup": "^4.5.2",
|
|
42
32
|
"typescript": "^5.3.2"
|
|
43
33
|
},
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
"typescript": ">=4.0.0"
|
|
46
|
-
},
|
|
47
34
|
"keywords": [
|
|
48
35
|
"base44",
|
|
49
36
|
"api",
|
|
@@ -58,5 +45,6 @@
|
|
|
58
45
|
"bugs": {
|
|
59
46
|
"url": "https://github.com/base44/sdk/issues"
|
|
60
47
|
},
|
|
61
|
-
"homepage": "https://github.com/base44/sdk#readme"
|
|
48
|
+
"homepage": "https://github.com/base44/sdk#readme",
|
|
49
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
62
50
|
}
|
package/dist/index.esm.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"axios";class t extends Error{constructor(e,t,o,n,r){super(e),this.name="Base44Error",this.status=t,this.code=o,this.data=n,this.originalError=r}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,data:this.data}}}function o(o){let{baseURL:n,headers:r={},token:a,requiresAuth:i=!1,appId:s,serverUrl:c}=o;const d=e.create({baseURL:n,headers:{"Content-Type":"application/json",Accept:"application/json",...r}});return a&&(d.defaults.headers.common.Authorization=`Bearer ${a}`),d.interceptors.request.use((e=>("undefined"!=typeof window&&(e.headers={...e.headers,"X-Origin-URL":window.location.href}),e))),d.interceptors.response.use((e=>e.data),(e=>{const o=e.response?.data?.message||e.response?.data?.detail||e.message,n=new t(o,e.response?.status,e.response?.data?.code,e.response?.data,e);return"production"!==process.env.NODE_ENV&&function(e,o){if(o instanceof t){if(console.error(`${e} ${o.status}: ${o.message}`),o.data)try{console.error("Error data:",JSON.stringify(o.data,null,2))}catch(e){console.error("Error data: [Cannot stringify error data]")}}else console.error(`${e} ${o.message}`)}("[Base44 SDK Error]",n),console.log(i,e.response?.status,"undefined"!=typeof window),i&&403===e.response?.status&&"undefined"!=typeof window&&(console.log("Authentication required. Redirecting to login..."),setTimeout((()=>{!function(e,t){if("undefined"==typeof window)return;const o=`${e}/login?from_url=${encodeURIComponent(window.location.href)}&app_id=${t}`;window.location.href=o}(c,s)}),100)),Promise.reject(n)})),d}function n(e,t){return new Proxy({},{get(o,n){if("string"==typeof n&&"then"!==n&&!n.startsWith("_"))return function(e,t,o){const n=`/apps/${t}/entities/${o}`;return{async list(t,o,r,a){const i={};return t&&(i.sort=t),o&&(i.limit=o),r&&(i.skip=r),a&&(i.fields=Array.isArray(a)?a.join(","):a),e.get(n,{params:i})},async filter(t,o,r,a,i){const s={q:JSON.stringify(t)};return o&&(s.sort=o),r&&(s.limit=r),a&&(s.skip=a),i&&(s.fields=Array.isArray(i)?i.join(","):i),e.get(n,{params:s})},get:async t=>e.get(`${n}/${t}`),create:async t=>e.post(n,t),update:async(t,o)=>e.put(`${n}/${t}`,o),delete:async t=>e.delete(`${n}/${t}`),deleteMany:async t=>e.delete(n,{data:t}),bulkCreate:async t=>e.post(`${n}/bulk`,t),async importEntities(t){const o=new FormData;return o.append("file",t,t.name),e.post(`${n}/import`,o,{headers:{"Content-Type":"multipart/form-data"}})}}}(e,t,n)}})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{storageKey:t="base44_access_token",paramName:o="access_token",saveToStorage:n=!0,removeFromUrl:r=!0}=e;let i=null;if("undefined"!=typeof window&&window.location)try{const e=new URLSearchParams(window.location.search);if(i=e.get(o),i){if(n&&a(i,{storageKey:t}),r){e.delete(o);const t=`${window.location.pathname}${e.toString()?`?${e.toString()}`:""}${window.location.hash}`;window.history.replaceState({},document.title,t)}return i}}catch(e){console.error("Error retrieving token from URL:",e)}if("undefined"!=typeof window&&window.localStorage)try{return i=window.localStorage.getItem(t),i}catch(e){console.error("Error retrieving token from localStorage:",e)}return null}function a(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{storageKey:o="base44_access_token"}=t;if("undefined"==typeof window||!window.localStorage||!e)return!1;try{return window.localStorage.setItem(o,e),!0}catch(e){return console.error("Error saving token to localStorage:",e),!1}}function i(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{storageKey:t="base44_access_token"}=e;if("undefined"==typeof window||!window.localStorage)return!1;try{return window.localStorage.removeItem(t),!0}catch(e){return console.error("Error removing token from localStorage:",e),!1}}function s(e,t){const{serverUrl:o,appId:n,loginPath:r="/login"}=t;if(!o||!n)throw new Error("serverUrl and appId are required to construct login URL");return`${o}${r}?from_url=${encodeURIComponent(e||("undefined"!=typeof window?window.location.href:""))}&app_id=${n}`}function c(e){if(!e||!e.appId)throw new Error("appId is required");const{serverUrl:t="https://base44.app",appId:a,env:i="prod",token:s,requiresAuth:c=!1}=e,d=o({baseURL:`${t}/api`,headers:{"X-App-Id":String(a),"X-Environment":i},token:s,requiresAuth:c,appId:a,serverUrl:t}),l=n(d,a),p=function(e,t){return new Proxy({},{get(o,n){if("string"==typeof n&&"then"!==n&&!n.startsWith("_"))return new Proxy({},{get(o,r){if("string"==typeof r&&"then"!==r&&!r.startsWith("_"))return async o=>{if("string"==typeof o)throw new Error(`Integration ${r} must receive an object with named parameters, received: ${o}`);let a,i;return o instanceof FormData||o&&Object.values(o).some((e=>e instanceof File))?(a=new FormData,Object.keys(o).forEach((e=>{o[e]instanceof File?a.append(e,o[e],o[e].name):"object"==typeof o[e]&&null!==o[e]?a.append(e,JSON.stringify(o[e])):a.append(e,o[e])})),i="multipart/form-data"):(a=o,i="application/json"),"Core"===n?e.post(`/apps/${t}/integration-endpoints/Core/${r}`,a||o,{headers:{"Content-Type":i}}):e.post(`/apps/${t}/integration-endpoints/installable/${n}/integration-endpoints/${r}`,a||o,{headers:{"Content-Type":i}})}}})}})}(d,a),u=function(e,t,o){return{me:async()=>e.get(`/apps/${t}/entities/User/me`),updateMe:async o=>e.put(`/apps/${t}/entities/User/me`,o),login(e){if("undefined"==typeof window)throw new Error("Login method can only be used in a browser environment");const n=e||window.location.href,r=`${o}/login?from_url=${encodeURIComponent(n)}&app_id=${t}`;window.location.href=r},async logout(t){if(delete e.defaults.headers.common.Authorization,"undefined"!=typeof window&&window.localStorage)try{window.localStorage.removeItem("base44_access_token")}catch(e){console.error("Failed to remove token from localStorage:",e)}return t&&"undefined"!=typeof window&&(window.location.href=t),Promise.resolve()},setToken(t){let o=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(t&&(e.defaults.headers.common.Authorization=`Bearer ${t}`,o&&"undefined"!=typeof window&&window.localStorage))try{window.localStorage.setItem("base44_access_token",t)}catch(e){console.error("Failed to save token to localStorage:",e)}},async isAuthenticated(){try{return await this.me(),!0}catch(e){return!1}}}}(d,a,t);if("undefined"!=typeof window){const e=s||r();e&&u.setToken(e)}return c&&"undefined"!=typeof window&&setTimeout((async()=>{try{await u.isAuthenticated()||u.login(window.location.href)}catch(e){console.error("Authentication check failed:",e),u.login(window.location.href)}}),0),{entities:l,integrations:p,auth:u,setToken(e){u.setToken(e)},getConfig:()=>({serverUrl:t,appId:a,env:i,requiresAuth:c})}}export{t as Base44Error,c as createClient,r as getAccessToken,s as getLoginUrl,i as removeAccessToken,a as saveAccessToken};
|
package/dist/index.umd.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("axios")):"function"==typeof define&&define.amd?define(["exports","axios"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).base44SDK={},e.axios)}(this,(function(e,t){"use strict";class o extends Error{constructor(e,t,o,n,r){super(e),this.name="Base44Error",this.status=t,this.code=o,this.data=n,this.originalError=r}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,data:this.data}}}function n(e){let{baseURL:n,headers:r={},token:a,requiresAuth:i=!1,appId:s,serverUrl:c}=e;const d=t.create({baseURL:n,headers:{"Content-Type":"application/json",Accept:"application/json",...r}});return a&&(d.defaults.headers.common.Authorization=`Bearer ${a}`),d.interceptors.request.use((e=>("undefined"!=typeof window&&(e.headers={...e.headers,"X-Origin-URL":window.location.href}),e))),d.interceptors.response.use((e=>e.data),(e=>{const t=e.response?.data?.message||e.response?.data?.detail||e.message,n=new o(t,e.response?.status,e.response?.data?.code,e.response?.data,e);return"production"!==process.env.NODE_ENV&&function(e,t){if(t instanceof o){if(console.error(`${e} ${t.status}: ${t.message}`),t.data)try{console.error("Error data:",JSON.stringify(t.data,null,2))}catch(e){console.error("Error data: [Cannot stringify error data]")}}else console.error(`${e} ${t.message}`)}("[Base44 SDK Error]",n),console.log(i,e.response?.status,"undefined"!=typeof window),i&&403===e.response?.status&&"undefined"!=typeof window&&(console.log("Authentication required. Redirecting to login..."),setTimeout((()=>{!function(e,t){if("undefined"==typeof window)return;const o=`${e}/login?from_url=${encodeURIComponent(window.location.href)}&app_id=${t}`;window.location.href=o}(c,s)}),100)),Promise.reject(n)})),d}function r(e,t){return new Proxy({},{get(o,n){if("string"==typeof n&&"then"!==n&&!n.startsWith("_"))return function(e,t,o){const n=`/apps/${t}/entities/${o}`;return{async list(t,o,r,a){const i={};return t&&(i.sort=t),o&&(i.limit=o),r&&(i.skip=r),a&&(i.fields=Array.isArray(a)?a.join(","):a),e.get(n,{params:i})},async filter(t,o,r,a,i){const s={q:JSON.stringify(t)};return o&&(s.sort=o),r&&(s.limit=r),a&&(s.skip=a),i&&(s.fields=Array.isArray(i)?i.join(","):i),e.get(n,{params:s})},get:async t=>e.get(`${n}/${t}`),create:async t=>e.post(n,t),update:async(t,o)=>e.put(`${n}/${t}`,o),delete:async t=>e.delete(`${n}/${t}`),deleteMany:async t=>e.delete(n,{data:t}),bulkCreate:async t=>e.post(`${n}/bulk`,t),async importEntities(t){const o=new FormData;return o.append("file",t,t.name),e.post(`${n}/import`,o,{headers:{"Content-Type":"multipart/form-data"}})}}}(e,t,n)}})}function a(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{storageKey:t="base44_access_token",paramName:o="access_token",saveToStorage:n=!0,removeFromUrl:r=!0}=e;let a=null;if("undefined"!=typeof window&&window.location)try{const e=new URLSearchParams(window.location.search);if(a=e.get(o),a){if(n&&i(a,{storageKey:t}),r){e.delete(o);const t=`${window.location.pathname}${e.toString()?`?${e.toString()}`:""}${window.location.hash}`;window.history.replaceState({},document.title,t)}return a}}catch(e){console.error("Error retrieving token from URL:",e)}if("undefined"!=typeof window&&window.localStorage)try{return a=window.localStorage.getItem(t),a}catch(e){console.error("Error retrieving token from localStorage:",e)}return null}function i(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{storageKey:o="base44_access_token"}=t;if("undefined"==typeof window||!window.localStorage||!e)return!1;try{return window.localStorage.setItem(o,e),!0}catch(e){return console.error("Error saving token to localStorage:",e),!1}}e.Base44Error=o,e.createClient=function(e){if(!e||!e.appId)throw new Error("appId is required");const{serverUrl:t="https://base44.app",appId:o,env:i="prod",token:s,requiresAuth:c=!1}=e,d=n({baseURL:`${t}/api`,headers:{"X-App-Id":String(o),"X-Environment":i},token:s,requiresAuth:c,appId:o,serverUrl:t}),l=r(d,o),p=function(e,t){return new Proxy({},{get(o,n){if("string"==typeof n&&"then"!==n&&!n.startsWith("_"))return new Proxy({},{get(o,r){if("string"==typeof r&&"then"!==r&&!r.startsWith("_"))return async o=>{if("string"==typeof o)throw new Error(`Integration ${r} must receive an object with named parameters, received: ${o}`);let a,i;return o instanceof FormData||o&&Object.values(o).some((e=>e instanceof File))?(a=new FormData,Object.keys(o).forEach((e=>{o[e]instanceof File?a.append(e,o[e],o[e].name):"object"==typeof o[e]&&null!==o[e]?a.append(e,JSON.stringify(o[e])):a.append(e,o[e])})),i="multipart/form-data"):(a=o,i="application/json"),"Core"===n?e.post(`/apps/${t}/integration-endpoints/Core/${r}`,a||o,{headers:{"Content-Type":i}}):e.post(`/apps/${t}/integration-endpoints/installable/${n}/integration-endpoints/${r}`,a||o,{headers:{"Content-Type":i}})}}})}})}(d,o),u=function(e,t,o){return{me:async()=>e.get(`/apps/${t}/entities/User/me`),updateMe:async o=>e.put(`/apps/${t}/entities/User/me`,o),login(e){if("undefined"==typeof window)throw new Error("Login method can only be used in a browser environment");const n=e||window.location.href,r=`${o}/login?from_url=${encodeURIComponent(n)}&app_id=${t}`;window.location.href=r},async logout(t){if(delete e.defaults.headers.common.Authorization,"undefined"!=typeof window&&window.localStorage)try{window.localStorage.removeItem("base44_access_token")}catch(e){console.error("Failed to remove token from localStorage:",e)}return t&&"undefined"!=typeof window&&(window.location.href=t),Promise.resolve()},setToken(t){let o=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(t&&(e.defaults.headers.common.Authorization=`Bearer ${t}`,o&&"undefined"!=typeof window&&window.localStorage))try{window.localStorage.setItem("base44_access_token",t)}catch(e){console.error("Failed to save token to localStorage:",e)}},async isAuthenticated(){try{return await this.me(),!0}catch(e){return!1}}}}(d,o,t);if("undefined"!=typeof window){const e=s||a();e&&u.setToken(e)}return c&&"undefined"!=typeof window&&setTimeout((async()=>{try{await u.isAuthenticated()||u.login(window.location.href)}catch(e){console.error("Authentication check failed:",e),u.login(window.location.href)}}),0),{entities:l,integrations:p,auth:u,setToken(e){u.setToken(e)},getConfig:()=>({serverUrl:t,appId:o,env:i,requiresAuth:c})}},e.getAccessToken=a,e.getLoginUrl=function(e,t){const{serverUrl:o,appId:n,loginPath:r="/login"}=t;if(!o||!n)throw new Error("serverUrl and appId are required to construct login URL");return`${o}${r}?from_url=${encodeURIComponent(e||("undefined"!=typeof window?window.location.href:""))}&app_id=${n}`},e.removeAccessToken=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{storageKey:t="base44_access_token"}=e;if("undefined"==typeof window||!window.localStorage)return!1;try{return window.localStorage.removeItem(t),!0}catch(e){return console.error("Error removing token from localStorage:",e),!1}},e.saveAccessToken=i}));
|