@base44-preview/sdk 0.8.17-pr.73.e88f2f7 → 0.8.17-pr.74.aa2810d
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/README.md +0 -130
- package/dist/client.js +2 -3
- package/dist/client.types.d.ts +3 -3
- package/dist/index.d.ts +0 -1
- package/dist/modules/recording.d.ts +8 -0
- package/dist/modules/recording.js +266 -0
- package/dist/modules/recording.types.d.ts +118 -0
- package/dist/modules/recording.types.js +1 -0
- package/dist/modules/types.d.ts +1 -0
- package/dist/modules/types.js +1 -0
- package/package.json +3 -1
- package/dist/modules/mobile.d.ts +0 -16
- package/dist/modules/mobile.js +0 -39
- package/dist/modules/mobile.types.d.ts +0 -86
- package/dist/modules/mobile.types.js +0 -7
package/README.md
CHANGED
|
@@ -13,7 +13,6 @@ The SDK provides access to Base44's functionality through the following modules:
|
|
|
13
13
|
- **[`entities`](https://docs.base44.com/sdk-docs/interfaces/entities)**: Work with your app's data entities using CRUD operations.
|
|
14
14
|
- **[`functions`](https://docs.base44.com/sdk-docs/interfaces/functions)**: Execute backend functions.
|
|
15
15
|
- **[`integrations`](https://docs.base44.com/sdk-docs/type-aliases/integrations)**: Pre-built server-side functions for external services.
|
|
16
|
-
- **[`mobile`](#mobile-native-features)**: Send push notifications and access mobile native capabilities.
|
|
17
16
|
|
|
18
17
|
## Example
|
|
19
18
|
|
|
@@ -38,135 +37,6 @@ await base44.entities.Task.update(newTask.id, {
|
|
|
38
37
|
const tasks = await base44.entities.Task.list();
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
## Mobile Native Features
|
|
42
|
-
|
|
43
|
-
The SDK provides mobile native capabilities through the `mobile` module, allowing you to send push notifications to your app users.
|
|
44
|
-
|
|
45
|
-
### Push Notifications
|
|
46
|
-
|
|
47
|
-
Send push notifications to users on mobile devices:
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { base44 } from "@/api/base44Client";
|
|
51
|
-
|
|
52
|
-
// Send a push notification to a user
|
|
53
|
-
await base44.mobile.sendNotification({
|
|
54
|
-
userId: "user_123",
|
|
55
|
-
title: "New Message!",
|
|
56
|
-
content: "You have a new message from John",
|
|
57
|
-
actionLabel: "View Message",
|
|
58
|
-
actionUrl: "/messages/456",
|
|
59
|
-
channels: ["mobile_push"], // Mobile push only
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// Send to both mobile push and in-app notifications (default)
|
|
63
|
-
await base44.mobile.sendNotification({
|
|
64
|
-
userId: "user_456",
|
|
65
|
-
title: "Order Shipped",
|
|
66
|
-
content: "Your order #12345 has been shipped and is on its way!",
|
|
67
|
-
actionLabel: "Track Order",
|
|
68
|
-
actionUrl: "/orders/12345",
|
|
69
|
-
});
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Notification Channels
|
|
73
|
-
|
|
74
|
-
The `mobile` module supports two notification channels:
|
|
75
|
-
|
|
76
|
-
- **`mobile_push`**: Sends a push notification to the user's mobile device (iOS/Android)
|
|
77
|
-
- **`in_app`**: Sends an in-app notification visible in the web interface
|
|
78
|
-
|
|
79
|
-
By default, notifications are sent to both channels. You can specify specific channels using the `channels` parameter:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
// Mobile push only - user will receive push notification on their phone
|
|
83
|
-
await base44.mobile.sendNotification({
|
|
84
|
-
userId: "user_123",
|
|
85
|
-
title: "Time-sensitive alert",
|
|
86
|
-
content: "Your session will expire in 5 minutes",
|
|
87
|
-
channels: ["mobile_push"],
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// In-app only - notification visible only in the web interface
|
|
91
|
-
await base44.mobile.sendNotification({
|
|
92
|
-
userId: "user_789",
|
|
93
|
-
title: "System Update",
|
|
94
|
-
content: "We've updated the dashboard with new features",
|
|
95
|
-
channels: ["in_app"],
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Common Use Cases
|
|
100
|
-
|
|
101
|
-
**Order & Delivery Updates**:
|
|
102
|
-
```typescript
|
|
103
|
-
// Notify user when order is ready
|
|
104
|
-
await base44.mobile.sendNotification({
|
|
105
|
-
userId: order.userId,
|
|
106
|
-
title: "Order Ready for Pickup",
|
|
107
|
-
content: `Your order #${order.id} is ready at ${store.name}`,
|
|
108
|
-
actionLabel: "View Order",
|
|
109
|
-
actionUrl: `/orders/${order.id}`,
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Chat & Messaging**:
|
|
114
|
-
```typescript
|
|
115
|
-
// Notify user of new messages
|
|
116
|
-
await base44.mobile.sendNotification({
|
|
117
|
-
userId: recipient.id,
|
|
118
|
-
title: `New message from ${sender.name}`,
|
|
119
|
-
content: message.preview,
|
|
120
|
-
actionLabel: "Reply",
|
|
121
|
-
actionUrl: `/chats/${conversation.id}`,
|
|
122
|
-
channels: ["mobile_push"], // Mobile only, avoid duplicate with in-app chat
|
|
123
|
-
});
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Reminders & Events**:
|
|
127
|
-
```typescript
|
|
128
|
-
// Send event reminder
|
|
129
|
-
await base44.mobile.sendNotification({
|
|
130
|
-
userId: attendee.userId,
|
|
131
|
-
title: "Event Starting Soon",
|
|
132
|
-
content: `${event.name} starts in 30 minutes`,
|
|
133
|
-
actionLabel: "View Details",
|
|
134
|
-
actionUrl: `/events/${event.id}`,
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### Error Handling
|
|
139
|
-
|
|
140
|
-
The notification API handles errors gracefully:
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
try {
|
|
144
|
-
const result = await base44.mobile.sendNotification({
|
|
145
|
-
userId: "user_123",
|
|
146
|
-
title: "Test Notification",
|
|
147
|
-
content: "This is a test",
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
if (result.success) {
|
|
151
|
-
console.log("Notification sent successfully");
|
|
152
|
-
console.log("Notification ID:", result.notificationId);
|
|
153
|
-
}
|
|
154
|
-
} catch (error) {
|
|
155
|
-
if (error.status === 404) {
|
|
156
|
-
console.error("User not found");
|
|
157
|
-
} else if (error.status === 403) {
|
|
158
|
-
console.error("Not authorized to send notifications");
|
|
159
|
-
} else {
|
|
160
|
-
console.error("Failed to send notification:", error.message);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
**Graceful Degradation**:
|
|
166
|
-
- If a user doesn't have mobile push enabled, the notification is still sent to other channels
|
|
167
|
-
- If one channel fails, other channels still receive the notification
|
|
168
|
-
- Notifications are queued and retried automatically for temporary failures
|
|
169
|
-
|
|
170
40
|
## Learn more
|
|
171
41
|
|
|
172
42
|
For complete documentation, guides, and API reference, visit the **[Base44 SDK Documentation](https://docs.base44.com/sdk-getting-started/overview)**.
|
package/dist/client.js
CHANGED
|
@@ -9,9 +9,9 @@ import { createFunctionsModule } from "./modules/functions.js";
|
|
|
9
9
|
import { createAgentsModule } from "./modules/agents.js";
|
|
10
10
|
import { createAppLogsModule } from "./modules/app-logs.js";
|
|
11
11
|
import { createUsersModule } from "./modules/users.js";
|
|
12
|
-
import { createMobileModule } from "./modules/mobile.js";
|
|
13
12
|
import { RoomsSocket } from "./utils/socket-utils.js";
|
|
14
13
|
import { createAnalyticsModule } from "./modules/analytics.js";
|
|
14
|
+
import { createRecordingModule } from "./modules/recording.js";
|
|
15
15
|
/**
|
|
16
16
|
* Creates a Base44 client.
|
|
17
17
|
*
|
|
@@ -122,13 +122,13 @@ export function createClient(config) {
|
|
|
122
122
|
}),
|
|
123
123
|
appLogs: createAppLogsModule(axiosClient, appId),
|
|
124
124
|
users: createUsersModule(axiosClient, appId),
|
|
125
|
-
mobile: createMobileModule(axiosClient, appId),
|
|
126
125
|
analytics: createAnalyticsModule({
|
|
127
126
|
axiosClient,
|
|
128
127
|
serverUrl,
|
|
129
128
|
appId,
|
|
130
129
|
userAuthModule,
|
|
131
130
|
}),
|
|
131
|
+
recording: createRecordingModule(),
|
|
132
132
|
cleanup: () => {
|
|
133
133
|
userModules.analytics.cleanup();
|
|
134
134
|
if (socket) {
|
|
@@ -154,7 +154,6 @@ export function createClient(config) {
|
|
|
154
154
|
token,
|
|
155
155
|
}),
|
|
156
156
|
appLogs: createAppLogsModule(serviceRoleAxiosClient, appId),
|
|
157
|
-
mobile: createMobileModule(serviceRoleAxiosClient, appId),
|
|
158
157
|
cleanup: () => {
|
|
159
158
|
if (socket) {
|
|
160
159
|
socket.disconnect();
|
package/dist/client.types.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ import type { ConnectorsModule } from "./modules/connectors.types.js";
|
|
|
6
6
|
import type { FunctionsModule } from "./modules/functions.types.js";
|
|
7
7
|
import type { AgentsModule } from "./modules/agents.types.js";
|
|
8
8
|
import type { AppLogsModule } from "./modules/app-logs.types.js";
|
|
9
|
-
import type { MobileModule } from "./modules/mobile.types.js";
|
|
10
9
|
import type { AnalyticsModule } from "./modules/analytics.types.js";
|
|
10
|
+
import type { RecordingModule } from "./modules/recording.types.js";
|
|
11
11
|
/**
|
|
12
12
|
* Options for creating a Base44 client.
|
|
13
13
|
*/
|
|
@@ -84,10 +84,10 @@ export interface Base44Client {
|
|
|
84
84
|
agents: AgentsModule;
|
|
85
85
|
/** {@link AppLogsModule | App logs module} for tracking app usage. */
|
|
86
86
|
appLogs: AppLogsModule;
|
|
87
|
-
/** {@link MobileModule | Mobile module} for mobile native capabilities like push notifications. */
|
|
88
|
-
mobile: MobileModule;
|
|
89
87
|
/** {@link AnalyticsModule | Analytics module} for tracking app usage. */
|
|
90
88
|
analytics: AnalyticsModule;
|
|
89
|
+
/** {@link RecordingModule | Recording module} for capturing debug sessions. */
|
|
90
|
+
recording: RecordingModule;
|
|
91
91
|
/** Cleanup function to disconnect WebSocket connections. Call when you're done with the client. */
|
|
92
92
|
cleanup: () => void;
|
|
93
93
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,6 @@ export type { IntegrationsModule, IntegrationPackage, IntegrationEndpointFunctio
|
|
|
10
10
|
export type { FunctionsModule } from "./modules/functions.types.js";
|
|
11
11
|
export type { AgentsModule, AgentConversation, AgentMessage, AgentMessageReasoning, AgentMessageToolCall, AgentMessageUsage, AgentMessageCustomContext, AgentMessageMetadata, CreateConversationParams, } from "./modules/agents.types.js";
|
|
12
12
|
export type { AppLogsModule } from "./modules/app-logs.types.js";
|
|
13
|
-
export type { MobileModule, SendNotificationParams, NotificationResult, NotificationChannel, ChannelResult, } from "./modules/mobile.types.js";
|
|
14
13
|
export type { SsoModule, SsoAccessTokenResponse } from "./modules/sso.types.js";
|
|
15
14
|
export type { ConnectorsModule } from "./modules/connectors.types.js";
|
|
16
15
|
export type { CustomIntegrationsModule, CustomIntegrationCallParams, CustomIntegrationCallResponse, } from "./modules/custom-integrations.types.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RecordingModule } from "./recording.types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the recording module for the Base44 SDK.
|
|
4
|
+
*
|
|
5
|
+
* @returns Recording module with methods for capturing debug sessions
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare function createRecordingModule(): RecordingModule;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { record, IncrementalSource, MouseInteractions, } from "rrweb";
|
|
2
|
+
import { getRecordConsolePlugin } from "@rrweb/rrweb-plugin-console-record";
|
|
3
|
+
import { generateUuid } from "../utils/common.js";
|
|
4
|
+
const state = {
|
|
5
|
+
isRecording: false,
|
|
6
|
+
sessionId: null,
|
|
7
|
+
startTime: null,
|
|
8
|
+
events: [],
|
|
9
|
+
stopFn: null,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Creates the recording module for the Base44 SDK.
|
|
13
|
+
*
|
|
14
|
+
* @returns Recording module with methods for capturing debug sessions
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export function createRecordingModule() {
|
|
18
|
+
return {
|
|
19
|
+
start() {
|
|
20
|
+
if (state.isRecording) {
|
|
21
|
+
throw new Error("Recording is already in progress");
|
|
22
|
+
}
|
|
23
|
+
if (typeof window === "undefined") {
|
|
24
|
+
throw new Error("Recording is only available in browser environments");
|
|
25
|
+
}
|
|
26
|
+
// Reset state
|
|
27
|
+
state.isRecording = true;
|
|
28
|
+
state.sessionId = generateUuid();
|
|
29
|
+
state.startTime = new Date().toISOString();
|
|
30
|
+
state.events = [];
|
|
31
|
+
const stopFn = record({
|
|
32
|
+
emit: (event) => {
|
|
33
|
+
state.events.push(event);
|
|
34
|
+
},
|
|
35
|
+
plugins: [
|
|
36
|
+
getRecordConsolePlugin({
|
|
37
|
+
level: ["log", "warn", "error", "info", "debug"],
|
|
38
|
+
lengthThreshold: 10000,
|
|
39
|
+
stringifyOptions: {
|
|
40
|
+
stringLengthLimit: 5000,
|
|
41
|
+
numOfKeysLimit: 100,
|
|
42
|
+
depthOfLimit: 5,
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
state.stopFn = stopFn !== null && stopFn !== void 0 ? stopFn : null;
|
|
48
|
+
},
|
|
49
|
+
stop() {
|
|
50
|
+
if (!state.isRecording) {
|
|
51
|
+
throw new Error("No recording is in progress");
|
|
52
|
+
}
|
|
53
|
+
// Stop rrweb recording
|
|
54
|
+
if (state.stopFn) {
|
|
55
|
+
state.stopFn();
|
|
56
|
+
state.stopFn = null;
|
|
57
|
+
}
|
|
58
|
+
const endTime = new Date().toISOString();
|
|
59
|
+
const startTime = state.startTime;
|
|
60
|
+
const duration = new Date(endTime).getTime() - new Date(startTime).getTime();
|
|
61
|
+
// Extract data from events
|
|
62
|
+
const consoleEntries = extractConsoleEntries(state.events);
|
|
63
|
+
const userActions = extractUserActions(state.events);
|
|
64
|
+
const report = {
|
|
65
|
+
sessionId: state.sessionId,
|
|
66
|
+
startTime,
|
|
67
|
+
endTime,
|
|
68
|
+
duration,
|
|
69
|
+
console: consoleEntries,
|
|
70
|
+
userActions,
|
|
71
|
+
};
|
|
72
|
+
// Reset state
|
|
73
|
+
state.isRecording = false;
|
|
74
|
+
state.sessionId = null;
|
|
75
|
+
state.startTime = null;
|
|
76
|
+
state.events = [];
|
|
77
|
+
return report;
|
|
78
|
+
},
|
|
79
|
+
isRecording() {
|
|
80
|
+
return state.isRecording;
|
|
81
|
+
},
|
|
82
|
+
toText(report) {
|
|
83
|
+
const lines = [
|
|
84
|
+
"## Debug Session Report",
|
|
85
|
+
`Session ID: ${report.sessionId}`,
|
|
86
|
+
`Duration: ${report.duration}ms`,
|
|
87
|
+
`Recorded: ${report.startTime} to ${report.endTime}`,
|
|
88
|
+
"",
|
|
89
|
+
`### User Actions (${report.userActions.length} actions)`,
|
|
90
|
+
];
|
|
91
|
+
if (report.userActions.length === 0) {
|
|
92
|
+
lines.push("No user actions captured.");
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
for (const action of report.userActions) {
|
|
96
|
+
const timestamp = new Date(action.timestamp).toISOString();
|
|
97
|
+
const valueStr = action.value ? ` = "${action.value}"` : "";
|
|
98
|
+
lines.push(`[${timestamp}] ${action.type}: ${action.target}${valueStr}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
lines.push("");
|
|
102
|
+
lines.push(`### Console Output (${report.console.length} entries)`);
|
|
103
|
+
if (report.console.length === 0) {
|
|
104
|
+
lines.push("No console output captured.");
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
for (const entry of report.console) {
|
|
108
|
+
const timestamp = new Date(entry.timestamp).toISOString();
|
|
109
|
+
lines.push(`[${timestamp}] [${entry.level.toUpperCase()}] ${entry.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return lines.join("\n");
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Extracts console entries from rrweb events.
|
|
118
|
+
*/
|
|
119
|
+
function extractConsoleEntries(events) {
|
|
120
|
+
var _a;
|
|
121
|
+
const consoleEntries = [];
|
|
122
|
+
for (const event of events) {
|
|
123
|
+
// rrweb plugin events have type 6
|
|
124
|
+
if (event.type === 6 && ((_a = event.data) === null || _a === void 0 ? void 0 : _a.plugin) === "rrweb/console@1") {
|
|
125
|
+
const payload = event.data.payload;
|
|
126
|
+
if (payload && payload.level && payload.payload) {
|
|
127
|
+
const message = stringifyConsolePayload(payload.payload);
|
|
128
|
+
consoleEntries.push({
|
|
129
|
+
level: payload.level,
|
|
130
|
+
message,
|
|
131
|
+
timestamp: event.timestamp,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return consoleEntries;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Converts console payload array to a readable string.
|
|
140
|
+
*/
|
|
141
|
+
function stringifyConsolePayload(payload) {
|
|
142
|
+
return payload
|
|
143
|
+
.map((item) => {
|
|
144
|
+
if (typeof item === "string") {
|
|
145
|
+
return item;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
return JSON.stringify(item);
|
|
149
|
+
}
|
|
150
|
+
catch (_a) {
|
|
151
|
+
return String(item);
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.join(" ");
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Extracts user actions from rrweb events.
|
|
158
|
+
*/
|
|
159
|
+
function extractUserActions(events) {
|
|
160
|
+
const userActions = [];
|
|
161
|
+
// Build a map of node IDs to readable descriptions from the full snapshot
|
|
162
|
+
const nodeMap = buildNodeMap(events);
|
|
163
|
+
for (const event of events) {
|
|
164
|
+
// IncrementalSnapshot events have type 3
|
|
165
|
+
if (event.type !== 3 || !event.data)
|
|
166
|
+
continue;
|
|
167
|
+
const { source, type, id, text } = event.data;
|
|
168
|
+
// Mouse interactions
|
|
169
|
+
if (source === IncrementalSource.MouseInteraction && id !== undefined) {
|
|
170
|
+
const actionType = getMouseInteractionType(type);
|
|
171
|
+
if (actionType) {
|
|
172
|
+
userActions.push({
|
|
173
|
+
type: actionType,
|
|
174
|
+
target: nodeMap.get(id) || `element#${id}`,
|
|
175
|
+
timestamp: event.timestamp,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Input events
|
|
180
|
+
if (source === IncrementalSource.Input && id !== undefined) {
|
|
181
|
+
userActions.push({
|
|
182
|
+
type: "input",
|
|
183
|
+
target: nodeMap.get(id) || `input#${id}`,
|
|
184
|
+
value: text ? truncateString(text, 100) : undefined,
|
|
185
|
+
timestamp: event.timestamp,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return userActions;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Maps mouse interaction type number to readable action type.
|
|
193
|
+
*/
|
|
194
|
+
function getMouseInteractionType(type) {
|
|
195
|
+
switch (type) {
|
|
196
|
+
case MouseInteractions.Click:
|
|
197
|
+
return "click";
|
|
198
|
+
case MouseInteractions.DblClick:
|
|
199
|
+
return "dblclick";
|
|
200
|
+
default:
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Builds a map of node IDs to readable descriptions from the full snapshot.
|
|
206
|
+
*/
|
|
207
|
+
function buildNodeMap(events) {
|
|
208
|
+
var _a;
|
|
209
|
+
const nodeMap = new Map();
|
|
210
|
+
// Find the full snapshot (type 2)
|
|
211
|
+
const fullSnapshot = events.find((e) => e.type === 2);
|
|
212
|
+
if (!fullSnapshot)
|
|
213
|
+
return nodeMap;
|
|
214
|
+
// Recursively extract node info
|
|
215
|
+
const extractNodes = (node) => {
|
|
216
|
+
if (!node || typeof node !== "object")
|
|
217
|
+
return;
|
|
218
|
+
if (node.id !== undefined && node.tagName) {
|
|
219
|
+
const parts = [`<${node.tagName.toLowerCase()}`];
|
|
220
|
+
if (node.attributes) {
|
|
221
|
+
if (node.attributes.id) {
|
|
222
|
+
parts[0] += `#${node.attributes.id}`;
|
|
223
|
+
}
|
|
224
|
+
if (node.attributes.class) {
|
|
225
|
+
const firstClass = node.attributes.class.split(" ")[0];
|
|
226
|
+
if (firstClass)
|
|
227
|
+
parts[0] += `.${firstClass}`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
parts[0] += ">";
|
|
231
|
+
// Add text content hint if available
|
|
232
|
+
if (node.childNodes) {
|
|
233
|
+
for (const child of node.childNodes) {
|
|
234
|
+
if (child.type === 3 && child.textContent) {
|
|
235
|
+
// Text node
|
|
236
|
+
const text = child.textContent.trim().slice(0, 30);
|
|
237
|
+
if (text) {
|
|
238
|
+
parts.push(`"${text}"`);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
nodeMap.set(node.id, parts.join(" "));
|
|
245
|
+
}
|
|
246
|
+
// Recurse into children
|
|
247
|
+
if (node.childNodes) {
|
|
248
|
+
for (const child of node.childNodes) {
|
|
249
|
+
extractNodes(child);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
// Start from the snapshot data
|
|
254
|
+
if ((_a = fullSnapshot.data) === null || _a === void 0 ? void 0 : _a.node) {
|
|
255
|
+
extractNodes(fullSnapshot.data.node);
|
|
256
|
+
}
|
|
257
|
+
return nodeMap;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Truncates a string to a maximum length.
|
|
261
|
+
*/
|
|
262
|
+
function truncateString(str, maxLength) {
|
|
263
|
+
if (str.length <= maxLength)
|
|
264
|
+
return str;
|
|
265
|
+
return str.slice(0, maxLength - 3) + "...";
|
|
266
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A console log entry captured during recording.
|
|
3
|
+
*/
|
|
4
|
+
export interface ConsoleEntry {
|
|
5
|
+
/** The console method that was called. */
|
|
6
|
+
level: "log" | "warn" | "error" | "info" | "debug";
|
|
7
|
+
/** The logged message content. */
|
|
8
|
+
message: string;
|
|
9
|
+
/** Unix timestamp when the log occurred. */
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A user action captured during recording.
|
|
14
|
+
*/
|
|
15
|
+
export interface UserAction {
|
|
16
|
+
/** The type of interaction. */
|
|
17
|
+
type: "click" | "dblclick" | "input";
|
|
18
|
+
/** Description of the target element. */
|
|
19
|
+
target: string;
|
|
20
|
+
/** Value entered (for input actions). */
|
|
21
|
+
value?: string;
|
|
22
|
+
/** Unix timestamp when the action occurred. */
|
|
23
|
+
timestamp: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Debug report containing captured session data.
|
|
27
|
+
*/
|
|
28
|
+
export interface DebugReport {
|
|
29
|
+
/** Unique session identifier. */
|
|
30
|
+
sessionId: string;
|
|
31
|
+
/** Recording start time (ISO 8601). */
|
|
32
|
+
startTime: string;
|
|
33
|
+
/** Recording end time (ISO 8601). */
|
|
34
|
+
endTime: string;
|
|
35
|
+
/** Duration in milliseconds. */
|
|
36
|
+
duration: number;
|
|
37
|
+
/** Captured console output. */
|
|
38
|
+
console: ConsoleEntry[];
|
|
39
|
+
/** Captured user actions (clicks, inputs, etc.). */
|
|
40
|
+
userActions: UserAction[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Recording module for capturing debug sessions.
|
|
44
|
+
*
|
|
45
|
+
* This module captures console output from the running app to help debug issues.
|
|
46
|
+
* It's designed to provide context for AI agents analyzing app problems.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // Start recording
|
|
51
|
+
* base44.recording.start();
|
|
52
|
+
*
|
|
53
|
+
* // ... user reproduces the issue ...
|
|
54
|
+
*
|
|
55
|
+
* // Stop and get the report
|
|
56
|
+
* const report = base44.recording.stop();
|
|
57
|
+
* console.log(report.console); // All console output
|
|
58
|
+
*
|
|
59
|
+
* // Get text summary for LLM
|
|
60
|
+
* const summary = base44.recording.toText(report);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export interface RecordingModule {
|
|
64
|
+
/**
|
|
65
|
+
* Starts a debug recording session.
|
|
66
|
+
*
|
|
67
|
+
* Captures console output until stopped.
|
|
68
|
+
* Only one recording can be active at a time.
|
|
69
|
+
*
|
|
70
|
+
* @throws {Error} If a recording is already in progress.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* base44.recording.start();
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
start(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Stops the current recording and returns the captured data.
|
|
80
|
+
*
|
|
81
|
+
* @returns The debug report containing all captured console output.
|
|
82
|
+
* @throws {Error} If no recording is in progress.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const report = base44.recording.stop();
|
|
87
|
+
* console.log(`Captured ${report.console.length} console entries`);
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
stop(): DebugReport;
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a recording is currently in progress.
|
|
93
|
+
*
|
|
94
|
+
* @returns True if recording, false otherwise.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* if (!base44.recording.isRecording()) {
|
|
99
|
+
* base44.recording.start();
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
isRecording(): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Generates a text summary of a debug report for LLM consumption.
|
|
106
|
+
*
|
|
107
|
+
* @param report - The debug report to summarize.
|
|
108
|
+
* @returns A formatted text summary.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const report = base44.recording.stop();
|
|
113
|
+
* const summary = base44.recording.toText(report);
|
|
114
|
+
* // Send summary to your backend for LLM processing
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
toText(report: DebugReport): string;
|
|
118
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/modules/types.d.ts
CHANGED
package/dist/modules/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@base44-preview/sdk",
|
|
3
|
-
"version": "0.8.17-pr.
|
|
3
|
+
"version": "0.8.17-pr.74.aa2810d",
|
|
4
4
|
"description": "JavaScript SDK for Base44 API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"create-docs:process": "node scripts/mintlify-post-processing/file-processing/file-processing.js"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@rrweb/rrweb-plugin-console-record": "^2.0.0-alpha.18",
|
|
27
28
|
"axios": "^1.6.2",
|
|
29
|
+
"rrweb": "^2.0.0-alpha.18",
|
|
28
30
|
"socket.io-client": "^4.7.5",
|
|
29
31
|
"uuid": "^13.0.0"
|
|
30
32
|
},
|
package/dist/modules/mobile.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mobile module for Base44 SDK.
|
|
3
|
-
*
|
|
4
|
-
* Provides mobile native capabilities like push notifications.
|
|
5
|
-
*/
|
|
6
|
-
import { AxiosInstance } from "axios";
|
|
7
|
-
import { MobileModule } from "./mobile.types";
|
|
8
|
-
/**
|
|
9
|
-
* Creates the mobile module for the Base44 SDK.
|
|
10
|
-
*
|
|
11
|
-
* @param axios - Axios instance for API requests
|
|
12
|
-
* @param appId - Application ID
|
|
13
|
-
* @returns Mobile module with native mobile capabilities
|
|
14
|
-
* @internal
|
|
15
|
-
*/
|
|
16
|
-
export declare function createMobileModule(axios: AxiosInstance, appId: string): MobileModule;
|
package/dist/modules/mobile.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mobile module for Base44 SDK.
|
|
3
|
-
*
|
|
4
|
-
* Provides mobile native capabilities like push notifications.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Validates notification parameters against character limits.
|
|
8
|
-
* @param params - Notification parameters to validate
|
|
9
|
-
* @throws Error if any parameter exceeds its limit
|
|
10
|
-
*/
|
|
11
|
-
function validateNotificationParams(params) {
|
|
12
|
-
if (params.title.length > 100) {
|
|
13
|
-
throw new Error(`Title must be 100 characters or less (current: ${params.title.length})`);
|
|
14
|
-
}
|
|
15
|
-
if (params.content.length > 500) {
|
|
16
|
-
throw new Error(`Content must be 500 characters or less (current: ${params.content.length})`);
|
|
17
|
-
}
|
|
18
|
-
if (params.actionLabel && params.actionLabel.length > 50) {
|
|
19
|
-
throw new Error(`Action label must be 50 characters or less (current: ${params.actionLabel.length})`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Creates the mobile module for the Base44 SDK.
|
|
24
|
-
*
|
|
25
|
-
* @param axios - Axios instance for API requests
|
|
26
|
-
* @param appId - Application ID
|
|
27
|
-
* @returns Mobile module with native mobile capabilities
|
|
28
|
-
* @internal
|
|
29
|
-
*/
|
|
30
|
-
export function createMobileModule(axios, appId) {
|
|
31
|
-
return {
|
|
32
|
-
async sendNotification(params) {
|
|
33
|
-
// Validate input parameters
|
|
34
|
-
validateNotificationParams(params);
|
|
35
|
-
const response = await axios.post(`/api/apps/${appId}/mobile/notifications`, params);
|
|
36
|
-
return response.data;
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript type definitions for Base44 Mobile SDK.
|
|
3
|
-
*
|
|
4
|
-
* Provides mobile native capabilities like push notifications
|
|
5
|
-
* for apps built with Base44.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Channel type for notifications.
|
|
9
|
-
* - "mobile_push": Send via mobile push notification (Ping service)
|
|
10
|
-
* - "in_app": Send via in-app notification (WebSocket + MongoDB)
|
|
11
|
-
*/
|
|
12
|
-
export type NotificationChannel = "mobile_push" | "in_app";
|
|
13
|
-
/**
|
|
14
|
-
* Parameters for sending a notification to an app user.
|
|
15
|
-
*/
|
|
16
|
-
export interface SendNotificationParams {
|
|
17
|
-
/** App user ID to notify */
|
|
18
|
-
userId: string;
|
|
19
|
-
/** Notification title (max 100 characters) */
|
|
20
|
-
title: string;
|
|
21
|
-
/** Notification content (max 500 characters, supports HTML) */
|
|
22
|
-
content: string;
|
|
23
|
-
/** Optional button text (max 50 characters) */
|
|
24
|
-
actionLabel?: string;
|
|
25
|
-
/** Optional button link */
|
|
26
|
-
actionUrl?: string;
|
|
27
|
-
/** Optional list of channels. If not specified, uses all channels (mobile_push + in_app) */
|
|
28
|
-
channels?: NotificationChannel[];
|
|
29
|
-
/** Optional custom metadata */
|
|
30
|
-
metadata?: Record<string, unknown>;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Result from a single notification channel.
|
|
34
|
-
*/
|
|
35
|
-
export interface ChannelResult {
|
|
36
|
-
/** Whether the notification was sent successfully through this channel */
|
|
37
|
-
success: boolean;
|
|
38
|
-
/** Error message if the channel failed */
|
|
39
|
-
error?: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Response from sending a notification.
|
|
43
|
-
*/
|
|
44
|
-
export interface NotificationResult {
|
|
45
|
-
/** Overall success status */
|
|
46
|
-
success: boolean;
|
|
47
|
-
/** Notification ID if in_app channel was used */
|
|
48
|
-
notificationId?: string;
|
|
49
|
-
/** Results per channel */
|
|
50
|
-
channels: {
|
|
51
|
-
in_app?: ChannelResult;
|
|
52
|
-
mobile_push?: ChannelResult;
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Mobile module interface providing mobile native capabilities.
|
|
57
|
-
*/
|
|
58
|
-
export interface MobileModule {
|
|
59
|
-
/**
|
|
60
|
-
* Send a notification to an app user.
|
|
61
|
-
*
|
|
62
|
-
* @param params - Notification parameters
|
|
63
|
-
* @returns Promise resolving to notification result
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* // Send mobile push notification only
|
|
68
|
-
* await base44.mobile.sendNotification({
|
|
69
|
-
* userId: 'app_user_123',
|
|
70
|
-
* title: 'New Message!',
|
|
71
|
-
* content: 'You have a new message from John',
|
|
72
|
-
* actionLabel: 'View Message',
|
|
73
|
-
* actionUrl: '/messages/456',
|
|
74
|
-
* channels: ['mobile_push']
|
|
75
|
-
* });
|
|
76
|
-
*
|
|
77
|
-
* // Send to both channels (default)
|
|
78
|
-
* await base44.mobile.sendNotification({
|
|
79
|
-
* userId: 'app_user_123',
|
|
80
|
-
* title: 'Order Shipped',
|
|
81
|
-
* content: 'Your order #12345 has been shipped'
|
|
82
|
-
* });
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
sendNotification(params: SendNotificationParams): Promise<NotificationResult>;
|
|
86
|
-
}
|