@baasix/sdk 0.1.6 → 0.1.8
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 +222 -2
- package/dist/index.cjs +382 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +307 -0
- package/dist/index.d.ts +307 -0
- package/dist/index.js +382 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -807,24 +807,198 @@ const categories = await baasix.reports.distinct('products', 'category');
|
|
|
807
807
|
|
|
808
808
|
## Workflows
|
|
809
809
|
|
|
810
|
+
### Basic Operations
|
|
811
|
+
|
|
812
|
+
```typescript
|
|
813
|
+
// List workflows
|
|
814
|
+
const { data: workflows } = await baasix.workflows.find();
|
|
815
|
+
|
|
816
|
+
// Get workflow by ID
|
|
817
|
+
const workflow = await baasix.workflows.findOne('workflow-uuid');
|
|
818
|
+
|
|
819
|
+
// Create workflow
|
|
820
|
+
const newWorkflow = await baasix.workflows.create({
|
|
821
|
+
name: 'Order Processing',
|
|
822
|
+
trigger: { type: 'hook', config: { collection: 'orders', event: 'items.create.after' } },
|
|
823
|
+
nodes: [...],
|
|
824
|
+
edges: [...],
|
|
825
|
+
isActive: true
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
// Update workflow
|
|
829
|
+
await baasix.workflows.update('workflow-uuid', { name: 'Updated Name' });
|
|
830
|
+
|
|
831
|
+
// Delete workflow
|
|
832
|
+
await baasix.workflows.delete('workflow-uuid');
|
|
833
|
+
|
|
834
|
+
// Enable/Disable workflow
|
|
835
|
+
await baasix.workflows.enable('workflow-uuid');
|
|
836
|
+
await baasix.workflows.disable('workflow-uuid');
|
|
837
|
+
|
|
838
|
+
// Duplicate workflow
|
|
839
|
+
const copy = await baasix.workflows.duplicate('workflow-uuid', { name: 'Copy' });
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### Execution
|
|
843
|
+
|
|
810
844
|
```typescript
|
|
811
845
|
// Execute workflow
|
|
812
846
|
const result = await baasix.workflows.execute('workflow-uuid', {
|
|
813
847
|
orderId: 'order-123',
|
|
814
848
|
});
|
|
815
849
|
|
|
850
|
+
// Execute a specific node
|
|
851
|
+
const nodeResult = await baasix.workflows.executeNode('workflow-uuid', 'node-id', {
|
|
852
|
+
inputData: 'value'
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
// Test workflow (without persisting)
|
|
856
|
+
const testResult = await baasix.workflows.test('workflow-uuid', { testData: {} });
|
|
857
|
+
|
|
816
858
|
// Get execution history
|
|
817
|
-
const { data: executions } = await baasix.workflows.getExecutions('workflow-uuid'
|
|
859
|
+
const { data: executions } = await baasix.workflows.getExecutions('workflow-uuid', {
|
|
860
|
+
limit: 50,
|
|
861
|
+
status: 'completed'
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
// Get specific execution
|
|
865
|
+
const execution = await baasix.workflows.getExecution('workflow-uuid', 'execution-uuid');
|
|
866
|
+
|
|
867
|
+
// Get execution logs
|
|
868
|
+
const logs = await baasix.workflows.getExecutionLogs('workflow-uuid', 'execution-uuid');
|
|
869
|
+
|
|
870
|
+
// Cancel running execution
|
|
871
|
+
await baasix.workflows.cancelExecution('workflow-uuid', 'execution-uuid');
|
|
818
872
|
|
|
819
873
|
// Subscribe to execution updates (requires realtime)
|
|
820
874
|
const unsubscribe = baasix.realtime.subscribeToExecution(executionId, (update) => {
|
|
821
|
-
console.log('
|
|
875
|
+
console.log('Progress:', update.progress, '%');
|
|
822
876
|
if (update.status === 'complete') {
|
|
823
877
|
console.log('Workflow finished!', update.result);
|
|
824
878
|
}
|
|
825
879
|
});
|
|
826
880
|
```
|
|
827
881
|
|
|
882
|
+
### Statistics & Validation
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
885
|
+
// Get workflow statistics
|
|
886
|
+
const stats = await baasix.workflows.getStats('workflow-uuid');
|
|
887
|
+
console.log(`Total: ${stats.totalExecutions}, Success Rate: ${stats.successRate}%`);
|
|
888
|
+
|
|
889
|
+
// Validate workflow definition
|
|
890
|
+
const validation = await baasix.workflows.validate({
|
|
891
|
+
name: 'My Workflow',
|
|
892
|
+
nodes: [...],
|
|
893
|
+
edges: [...]
|
|
894
|
+
});
|
|
895
|
+
if (!validation.valid) {
|
|
896
|
+
console.log('Errors:', validation.errors);
|
|
897
|
+
}
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
### Export/Import
|
|
901
|
+
|
|
902
|
+
```typescript
|
|
903
|
+
// Export single workflow
|
|
904
|
+
const exported = await baasix.workflows.export('workflow-uuid');
|
|
905
|
+
|
|
906
|
+
// Export all workflows
|
|
907
|
+
const allExported = await baasix.workflows.exportAll({
|
|
908
|
+
ids: ['wf-1', 'wf-2'], // Optional: specific workflows
|
|
909
|
+
includeInactive: true
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
// Preview import
|
|
913
|
+
const preview = await baasix.workflows.importPreview(file);
|
|
914
|
+
console.log('Will import:', preview.workflows.length);
|
|
915
|
+
console.log('Conflicts:', preview.conflicts);
|
|
916
|
+
|
|
917
|
+
// Import workflows
|
|
918
|
+
const result = await baasix.workflows.import(file, { overwrite: true });
|
|
919
|
+
console.log(`Imported: ${result.imported}, Skipped: ${result.skipped}`);
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
## Settings
|
|
923
|
+
|
|
924
|
+
```typescript
|
|
925
|
+
// Get all settings
|
|
926
|
+
const settings = await baasix.settings.get();
|
|
927
|
+
|
|
928
|
+
// Get a specific setting
|
|
929
|
+
const appName = await baasix.settings.getKey('appName');
|
|
930
|
+
|
|
931
|
+
// Update settings
|
|
932
|
+
await baasix.settings.update({
|
|
933
|
+
appName: 'My Application',
|
|
934
|
+
theme: 'dark'
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
// Set a specific setting
|
|
938
|
+
await baasix.settings.set('appName', 'New App Name');
|
|
939
|
+
|
|
940
|
+
// Get settings by app URL (multi-tenant)
|
|
941
|
+
const tenantSettings = await baasix.settings.getByAppUrl('https://myapp.example.com');
|
|
942
|
+
|
|
943
|
+
// Get email branding
|
|
944
|
+
const branding = await baasix.settings.getBranding();
|
|
945
|
+
|
|
946
|
+
// Test email configuration (admin only)
|
|
947
|
+
await baasix.settings.testEmail('admin@example.com');
|
|
948
|
+
|
|
949
|
+
// Reload settings cache (admin only)
|
|
950
|
+
await baasix.settings.reload();
|
|
951
|
+
|
|
952
|
+
// Delete tenant settings (admin only)
|
|
953
|
+
await baasix.settings.deleteTenant();
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
## Permissions
|
|
957
|
+
|
|
958
|
+
```typescript
|
|
959
|
+
// List all permissions
|
|
960
|
+
const { data: permissions } = await baasix.permissions.find();
|
|
961
|
+
|
|
962
|
+
// Get permissions for a role
|
|
963
|
+
const { data: rolePerms } = await baasix.permissions.findByRole('role-uuid');
|
|
964
|
+
|
|
965
|
+
// Get permissions for a collection
|
|
966
|
+
const { data: collectionPerms } = await baasix.permissions.findByCollection('products');
|
|
967
|
+
|
|
968
|
+
// Create permission
|
|
969
|
+
const permission = await baasix.permissions.create({
|
|
970
|
+
role_Id: 'editor-role-uuid',
|
|
971
|
+
collection: 'posts',
|
|
972
|
+
action: 'update',
|
|
973
|
+
fields: ['title', 'content'],
|
|
974
|
+
conditions: { author_Id: { eq: '$CURRENT_USER' } }
|
|
975
|
+
});
|
|
976
|
+
|
|
977
|
+
// Create CRUD permissions for a collection
|
|
978
|
+
await baasix.permissions.createCrudPermissions('role-uuid', 'products', {
|
|
979
|
+
create: { fields: ['name', 'price'] },
|
|
980
|
+
read: { fields: ['*'] },
|
|
981
|
+
update: { fields: ['name', 'price'] },
|
|
982
|
+
delete: false
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
// Update permission
|
|
986
|
+
await baasix.permissions.update('permission-uuid', { fields: ['*'] });
|
|
987
|
+
|
|
988
|
+
// Delete permission
|
|
989
|
+
await baasix.permissions.delete('permission-uuid');
|
|
990
|
+
|
|
991
|
+
// Reload permissions cache (admin only)
|
|
992
|
+
await baasix.permissions.reloadCache();
|
|
993
|
+
|
|
994
|
+
// Export all permissions
|
|
995
|
+
const exported = await baasix.permissions.export();
|
|
996
|
+
|
|
997
|
+
// Import permissions
|
|
998
|
+
const result = await baasix.permissions.import(exportedData, { overwrite: true });
|
|
999
|
+
console.log(`Imported: ${result.imported}`);
|
|
1000
|
+
```
|
|
1001
|
+
|
|
828
1002
|
## Realtime Subscriptions
|
|
829
1003
|
|
|
830
1004
|
The SDK supports real-time data updates via WebSocket connections.
|
|
@@ -879,6 +1053,52 @@ const channel = baasix.realtime
|
|
|
879
1053
|
channel.unsubscribe();
|
|
880
1054
|
```
|
|
881
1055
|
|
|
1056
|
+
### Custom Rooms
|
|
1057
|
+
|
|
1058
|
+
Custom rooms enable real-time communication between users for chat, games, or collaborative features. The **first user to join** a room becomes its creator. If the creator leaves temporarily, ownership transfers to the next member — but the **original creator automatically reclaims ownership** when they rejoin. If the room empties and is recreated, the next joiner becomes the new owner.
|
|
1059
|
+
|
|
1060
|
+
```typescript
|
|
1061
|
+
// Join a room
|
|
1062
|
+
await baasix.realtime.joinRoom('game:lobby');
|
|
1063
|
+
|
|
1064
|
+
// Get current members (you must be in the room)
|
|
1065
|
+
const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
1066
|
+
// [{ socketId: string, userId: string|number, isCreator: boolean }, ...]
|
|
1067
|
+
|
|
1068
|
+
// Send a message to all room members
|
|
1069
|
+
await baasix.realtime.sendToRoom('game:lobby', 'chat', { text: 'Hello!' });
|
|
1070
|
+
|
|
1071
|
+
// Listen for room messages
|
|
1072
|
+
const unsubscribe = baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
|
|
1073
|
+
console.log(`${data.sender.userId}: ${data.payload.text}`);
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
// Listen for users joining / leaving
|
|
1077
|
+
baasix.realtime.onRoomUserJoined('game:lobby', (data) => {
|
|
1078
|
+
console.log(`${data.userId} joined`);
|
|
1079
|
+
});
|
|
1080
|
+
baasix.realtime.onRoomUserLeft('game:lobby', (data) => {
|
|
1081
|
+
console.log(`${data.userId} left`);
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
// Kick a user — only the room creator can do this
|
|
1085
|
+
await baasix.realtime.kickFromRoom('game:lobby', 'target-user-id');
|
|
1086
|
+
|
|
1087
|
+
// Listen for being kicked out (fires only on the kicked user's socket)
|
|
1088
|
+
baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
1089
|
+
console.log(`You were kicked by user ${kickedBy}`);
|
|
1090
|
+
// Room listeners are automatically cleaned up after a kick
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
// Listen for ownership changes (fires for all members when creator changes)
|
|
1094
|
+
baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
1095
|
+
console.log(`New room owner: ${newCreatorUserId}`);
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
// Leave the room
|
|
1099
|
+
await baasix.realtime.leaveRoom('game:lobby');
|
|
1100
|
+
```
|
|
1101
|
+
|
|
882
1102
|
### Connection Management
|
|
883
1103
|
|
|
884
1104
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -2584,6 +2584,37 @@ var PermissionsModule = class {
|
|
|
2584
2584
|
async reloadCache() {
|
|
2585
2585
|
await this.client.post("/permissions/reload");
|
|
2586
2586
|
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Export all permissions (admin only)
|
|
2589
|
+
*
|
|
2590
|
+
* @example
|
|
2591
|
+
* ```typescript
|
|
2592
|
+
* const exported = await baasix.permissions.export();
|
|
2593
|
+
* // Save to file or transfer
|
|
2594
|
+
* ```
|
|
2595
|
+
*/
|
|
2596
|
+
async export() {
|
|
2597
|
+
const response = await this.client.post("/permissions-export", {});
|
|
2598
|
+
return response.data;
|
|
2599
|
+
}
|
|
2600
|
+
/**
|
|
2601
|
+
* Import permissions from exported data (admin only)
|
|
2602
|
+
*
|
|
2603
|
+
* @example
|
|
2604
|
+
* ```typescript
|
|
2605
|
+
* const result = await baasix.permissions.import(exportedData, {
|
|
2606
|
+
* overwrite: true
|
|
2607
|
+
* });
|
|
2608
|
+
* console.log('Imported:', result.imported, 'permissions');
|
|
2609
|
+
* ```
|
|
2610
|
+
*/
|
|
2611
|
+
async import(data, options) {
|
|
2612
|
+
const response = await this.client.post("/permissions-import", {
|
|
2613
|
+
...data,
|
|
2614
|
+
...options
|
|
2615
|
+
});
|
|
2616
|
+
return response.data;
|
|
2617
|
+
}
|
|
2587
2618
|
};
|
|
2588
2619
|
|
|
2589
2620
|
// src/modules/settings.ts
|
|
@@ -2650,6 +2681,73 @@ var SettingsModule = class {
|
|
|
2650
2681
|
async set(key, value) {
|
|
2651
2682
|
return this.update({ [key]: value });
|
|
2652
2683
|
}
|
|
2684
|
+
/**
|
|
2685
|
+
* Get settings by application URL (useful for multi-tenant apps)
|
|
2686
|
+
*
|
|
2687
|
+
* @example
|
|
2688
|
+
* ```typescript
|
|
2689
|
+
* const settings = await baasix.settings.getByAppUrl('https://myapp.example.com');
|
|
2690
|
+
* ```
|
|
2691
|
+
*/
|
|
2692
|
+
async getByAppUrl(appUrl) {
|
|
2693
|
+
const response = await this.client.get(
|
|
2694
|
+
"/settings/by-app-url",
|
|
2695
|
+
{ params: { appUrl } }
|
|
2696
|
+
);
|
|
2697
|
+
return response.data;
|
|
2698
|
+
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Get email branding settings for the current tenant
|
|
2701
|
+
*
|
|
2702
|
+
* @example
|
|
2703
|
+
* ```typescript
|
|
2704
|
+
* const branding = await baasix.settings.getBranding();
|
|
2705
|
+
* console.log(branding.logo, branding.primaryColor);
|
|
2706
|
+
* ```
|
|
2707
|
+
*/
|
|
2708
|
+
async getBranding() {
|
|
2709
|
+
const response = await this.client.get(
|
|
2710
|
+
"/settings/branding"
|
|
2711
|
+
);
|
|
2712
|
+
return response.data;
|
|
2713
|
+
}
|
|
2714
|
+
/**
|
|
2715
|
+
* Test email configuration by sending a test email
|
|
2716
|
+
*
|
|
2717
|
+
* @example
|
|
2718
|
+
* ```typescript
|
|
2719
|
+
* await baasix.settings.testEmail('admin@example.com');
|
|
2720
|
+
* ```
|
|
2721
|
+
*/
|
|
2722
|
+
async testEmail(to) {
|
|
2723
|
+
const response = await this.client.post(
|
|
2724
|
+
"/settings/test-email",
|
|
2725
|
+
{ to }
|
|
2726
|
+
);
|
|
2727
|
+
return response;
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* Reload settings cache (admin only)
|
|
2731
|
+
*
|
|
2732
|
+
* @example
|
|
2733
|
+
* ```typescript
|
|
2734
|
+
* await baasix.settings.reload();
|
|
2735
|
+
* ```
|
|
2736
|
+
*/
|
|
2737
|
+
async reload() {
|
|
2738
|
+
await this.client.post("/settings/reload");
|
|
2739
|
+
}
|
|
2740
|
+
/**
|
|
2741
|
+
* Delete tenant settings (admin only, multi-tenant)
|
|
2742
|
+
*
|
|
2743
|
+
* @example
|
|
2744
|
+
* ```typescript
|
|
2745
|
+
* await baasix.settings.deleteTenant();
|
|
2746
|
+
* ```
|
|
2747
|
+
*/
|
|
2748
|
+
async deleteTenant() {
|
|
2749
|
+
await this.client.delete("/settings/tenant");
|
|
2750
|
+
}
|
|
2653
2751
|
};
|
|
2654
2752
|
|
|
2655
2753
|
// src/modules/reports.ts
|
|
@@ -3027,6 +3125,159 @@ var WorkflowsModule = class {
|
|
|
3027
3125
|
...overrides
|
|
3028
3126
|
});
|
|
3029
3127
|
}
|
|
3128
|
+
/**
|
|
3129
|
+
* Execute a specific node in a workflow
|
|
3130
|
+
*
|
|
3131
|
+
* @example
|
|
3132
|
+
* ```typescript
|
|
3133
|
+
* const result = await baasix.workflows.executeNode(
|
|
3134
|
+
* 'workflow-uuid',
|
|
3135
|
+
* 'node-id',
|
|
3136
|
+
* { inputData: 'value' }
|
|
3137
|
+
* );
|
|
3138
|
+
* ```
|
|
3139
|
+
*/
|
|
3140
|
+
async executeNode(workflowId, nodeId, triggerData) {
|
|
3141
|
+
const response = await this.client.post(
|
|
3142
|
+
`/workflows/${workflowId}/nodes/${nodeId}/execute`,
|
|
3143
|
+
{ triggerData }
|
|
3144
|
+
);
|
|
3145
|
+
return response.data;
|
|
3146
|
+
}
|
|
3147
|
+
/**
|
|
3148
|
+
* Get execution logs for a specific execution
|
|
3149
|
+
*
|
|
3150
|
+
* @example
|
|
3151
|
+
* ```typescript
|
|
3152
|
+
* const logs = await baasix.workflows.getExecutionLogs(
|
|
3153
|
+
* 'workflow-uuid',
|
|
3154
|
+
* 'execution-uuid'
|
|
3155
|
+
* );
|
|
3156
|
+
* ```
|
|
3157
|
+
*/
|
|
3158
|
+
async getExecutionLogs(workflowId, executionId) {
|
|
3159
|
+
const response = await this.client.get(
|
|
3160
|
+
`/workflows/${workflowId}/executions/${executionId}/logs`
|
|
3161
|
+
);
|
|
3162
|
+
return response.data;
|
|
3163
|
+
}
|
|
3164
|
+
/**
|
|
3165
|
+
* Get workflow statistics
|
|
3166
|
+
*
|
|
3167
|
+
* @example
|
|
3168
|
+
* ```typescript
|
|
3169
|
+
* const stats = await baasix.workflows.getStats('workflow-uuid');
|
|
3170
|
+
* console.log(stats.totalExecutions, stats.successRate);
|
|
3171
|
+
* ```
|
|
3172
|
+
*/
|
|
3173
|
+
async getStats(id) {
|
|
3174
|
+
const response = await this.client.get(`/workflows/${id}/stats`);
|
|
3175
|
+
return response.data;
|
|
3176
|
+
}
|
|
3177
|
+
/**
|
|
3178
|
+
* Validate a workflow definition
|
|
3179
|
+
*
|
|
3180
|
+
* @example
|
|
3181
|
+
* ```typescript
|
|
3182
|
+
* const result = await baasix.workflows.validate({
|
|
3183
|
+
* name: 'My Workflow',
|
|
3184
|
+
* nodes: [...],
|
|
3185
|
+
* edges: [...]
|
|
3186
|
+
* });
|
|
3187
|
+
* if (result.valid) {
|
|
3188
|
+
* console.log('Workflow is valid');
|
|
3189
|
+
* } else {
|
|
3190
|
+
* console.log('Errors:', result.errors);
|
|
3191
|
+
* }
|
|
3192
|
+
* ```
|
|
3193
|
+
*/
|
|
3194
|
+
async validate(workflow) {
|
|
3195
|
+
const response = await this.client.post(
|
|
3196
|
+
"/workflows/validate",
|
|
3197
|
+
workflow
|
|
3198
|
+
);
|
|
3199
|
+
return response;
|
|
3200
|
+
}
|
|
3201
|
+
/**
|
|
3202
|
+
* Export a single workflow
|
|
3203
|
+
*
|
|
3204
|
+
* @example
|
|
3205
|
+
* ```typescript
|
|
3206
|
+
* const exported = await baasix.workflows.export('workflow-uuid');
|
|
3207
|
+
* // Save to file or transfer
|
|
3208
|
+
* ```
|
|
3209
|
+
*/
|
|
3210
|
+
async export(id) {
|
|
3211
|
+
const response = await this.client.get(
|
|
3212
|
+
`/workflows/${id}/export`
|
|
3213
|
+
);
|
|
3214
|
+
return response.data;
|
|
3215
|
+
}
|
|
3216
|
+
/**
|
|
3217
|
+
* Export multiple workflows
|
|
3218
|
+
*
|
|
3219
|
+
* @example
|
|
3220
|
+
* ```typescript
|
|
3221
|
+
* // Export all workflows
|
|
3222
|
+
* const exported = await baasix.workflows.exportAll();
|
|
3223
|
+
*
|
|
3224
|
+
* // Export specific workflows
|
|
3225
|
+
* const exported = await baasix.workflows.exportAll({
|
|
3226
|
+
* ids: ['workflow-1', 'workflow-2']
|
|
3227
|
+
* });
|
|
3228
|
+
* ```
|
|
3229
|
+
*/
|
|
3230
|
+
async exportAll(options) {
|
|
3231
|
+
const response = await this.client.post(
|
|
3232
|
+
"/workflows/export",
|
|
3233
|
+
options || {}
|
|
3234
|
+
);
|
|
3235
|
+
return response.data;
|
|
3236
|
+
}
|
|
3237
|
+
/**
|
|
3238
|
+
* Preview workflow import without applying changes
|
|
3239
|
+
*
|
|
3240
|
+
* @example
|
|
3241
|
+
* ```typescript
|
|
3242
|
+
* const preview = await baasix.workflows.importPreview(file);
|
|
3243
|
+
* console.log('Will import:', preview.workflows.length, 'workflows');
|
|
3244
|
+
* console.log('Conflicts:', preview.conflicts);
|
|
3245
|
+
* ```
|
|
3246
|
+
*/
|
|
3247
|
+
async importPreview(file) {
|
|
3248
|
+
const formData = new FormData();
|
|
3249
|
+
if (file instanceof File) {
|
|
3250
|
+
formData.append("file", file);
|
|
3251
|
+
} else {
|
|
3252
|
+
formData.append("file", file);
|
|
3253
|
+
}
|
|
3254
|
+
const response = await this.client.post("/workflows/import/preview", formData);
|
|
3255
|
+
return response.data;
|
|
3256
|
+
}
|
|
3257
|
+
/**
|
|
3258
|
+
* Import workflows from a file
|
|
3259
|
+
*
|
|
3260
|
+
* @example
|
|
3261
|
+
* ```typescript
|
|
3262
|
+
* const result = await baasix.workflows.import(file, {
|
|
3263
|
+
* overwrite: true
|
|
3264
|
+
* });
|
|
3265
|
+
* console.log('Imported:', result.imported, 'workflows');
|
|
3266
|
+
* ```
|
|
3267
|
+
*/
|
|
3268
|
+
async import(file, options) {
|
|
3269
|
+
const formData = new FormData();
|
|
3270
|
+
if (file instanceof File) {
|
|
3271
|
+
formData.append("file", file);
|
|
3272
|
+
} else {
|
|
3273
|
+
formData.append("file", file);
|
|
3274
|
+
}
|
|
3275
|
+
if (options?.overwrite !== void 0) {
|
|
3276
|
+
formData.append("overwrite", String(options.overwrite));
|
|
3277
|
+
}
|
|
3278
|
+
const response = await this.client.post("/workflows/import", formData);
|
|
3279
|
+
return response.data;
|
|
3280
|
+
}
|
|
3030
3281
|
};
|
|
3031
3282
|
|
|
3032
3283
|
// src/modules/realtime.ts
|
|
@@ -3042,6 +3293,8 @@ var RealtimeModule = class {
|
|
|
3042
3293
|
roomCallbacks = /* @__PURE__ */ new Map();
|
|
3043
3294
|
// room -> event -> callbacks
|
|
3044
3295
|
roomUserCallbacks = /* @__PURE__ */ new Map();
|
|
3296
|
+
kickCallbacks = /* @__PURE__ */ new Map();
|
|
3297
|
+
creatorChangedCallbacks = /* @__PURE__ */ new Map();
|
|
3045
3298
|
connectionCallbacks = /* @__PURE__ */ new Set();
|
|
3046
3299
|
reconnecting = false;
|
|
3047
3300
|
connectionPromise = null;
|
|
@@ -3171,6 +3424,27 @@ var RealtimeModule = class {
|
|
|
3171
3424
|
}
|
|
3172
3425
|
});
|
|
3173
3426
|
});
|
|
3427
|
+
this.socket.on("room:kicked", (data) => {
|
|
3428
|
+
const callbacks = this.kickCallbacks.get(data.room);
|
|
3429
|
+
callbacks?.forEach((cb) => {
|
|
3430
|
+
try {
|
|
3431
|
+
cb(data);
|
|
3432
|
+
} catch (e) {
|
|
3433
|
+
console.error("[Baasix Realtime] Error in room kicked callback:", e);
|
|
3434
|
+
}
|
|
3435
|
+
});
|
|
3436
|
+
this.cleanupRoomListeners(data.room);
|
|
3437
|
+
});
|
|
3438
|
+
this.socket.on("room:creator:changed", (data) => {
|
|
3439
|
+
const callbacks = this.creatorChangedCallbacks.get(data.room);
|
|
3440
|
+
callbacks?.forEach((cb) => {
|
|
3441
|
+
try {
|
|
3442
|
+
cb(data);
|
|
3443
|
+
} catch (e) {
|
|
3444
|
+
console.error("[Baasix Realtime] Error in room creator changed callback:", e);
|
|
3445
|
+
}
|
|
3446
|
+
});
|
|
3447
|
+
});
|
|
3174
3448
|
this.socket.connect();
|
|
3175
3449
|
} catch (error) {
|
|
3176
3450
|
this.connectionPromise = null;
|
|
@@ -3200,6 +3474,8 @@ var RealtimeModule = class {
|
|
|
3200
3474
|
this.workflowCallbacks.clear();
|
|
3201
3475
|
this.roomCallbacks.clear();
|
|
3202
3476
|
this.roomUserCallbacks.clear();
|
|
3477
|
+
this.kickCallbacks.clear();
|
|
3478
|
+
this.creatorChangedCallbacks.clear();
|
|
3203
3479
|
}
|
|
3204
3480
|
/**
|
|
3205
3481
|
* Check if connected to the realtime server
|
|
@@ -3470,6 +3746,110 @@ var RealtimeModule = class {
|
|
|
3470
3746
|
});
|
|
3471
3747
|
});
|
|
3472
3748
|
}
|
|
3749
|
+
/**
|
|
3750
|
+
* Get the list of users currently in a room.
|
|
3751
|
+
* You must already be a member of the room to call this.
|
|
3752
|
+
*
|
|
3753
|
+
* @example
|
|
3754
|
+
* ```typescript
|
|
3755
|
+
* const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
3756
|
+
* members.forEach(m => {
|
|
3757
|
+
* console.log(m.userId, m.isCreator ? '(owner)' : '');
|
|
3758
|
+
* });
|
|
3759
|
+
* ```
|
|
3760
|
+
*/
|
|
3761
|
+
async getRoomMembers(roomName) {
|
|
3762
|
+
if (!this.socket?.connected) {
|
|
3763
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3764
|
+
}
|
|
3765
|
+
return new Promise((resolve, reject) => {
|
|
3766
|
+
this.socket.emit("room:members", { room: roomName }, (response) => {
|
|
3767
|
+
if (response.status === "success") {
|
|
3768
|
+
resolve(response.members);
|
|
3769
|
+
} else {
|
|
3770
|
+
reject(new Error(response.message || "Failed to get room members"));
|
|
3771
|
+
}
|
|
3772
|
+
});
|
|
3773
|
+
});
|
|
3774
|
+
}
|
|
3775
|
+
/**
|
|
3776
|
+
* Kick a user from a custom room. Only the room creator may call this.
|
|
3777
|
+
*
|
|
3778
|
+
* @example
|
|
3779
|
+
* ```typescript
|
|
3780
|
+
* await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
|
|
3781
|
+
* ```
|
|
3782
|
+
*/
|
|
3783
|
+
async kickFromRoom(roomName, targetUserId) {
|
|
3784
|
+
if (!this.socket?.connected) {
|
|
3785
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3786
|
+
}
|
|
3787
|
+
return new Promise((resolve, reject) => {
|
|
3788
|
+
this.socket.emit(
|
|
3789
|
+
"room:kick",
|
|
3790
|
+
{ room: roomName, userId: targetUserId },
|
|
3791
|
+
(response) => {
|
|
3792
|
+
if (response.status === "success") {
|
|
3793
|
+
resolve();
|
|
3794
|
+
} else {
|
|
3795
|
+
reject(new Error(response.message || "Failed to kick user"));
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
);
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3801
|
+
/**
|
|
3802
|
+
* Listen for being kicked from a room.
|
|
3803
|
+
* The callback fires when the current user is removed by the room creator.
|
|
3804
|
+
* Room listeners are automatically cleaned up after the kick.
|
|
3805
|
+
*
|
|
3806
|
+
* @example
|
|
3807
|
+
* ```typescript
|
|
3808
|
+
* baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
3809
|
+
* console.log(`You were kicked by user ${kickedBy}`);
|
|
3810
|
+
* });
|
|
3811
|
+
* ```
|
|
3812
|
+
*/
|
|
3813
|
+
onKicked(roomName, callback) {
|
|
3814
|
+
if (!this.kickCallbacks.has(roomName)) {
|
|
3815
|
+
this.kickCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3816
|
+
}
|
|
3817
|
+
this.kickCallbacks.get(roomName).add(callback);
|
|
3818
|
+
return () => {
|
|
3819
|
+
const callbacks = this.kickCallbacks.get(roomName);
|
|
3820
|
+
if (callbacks) {
|
|
3821
|
+
callbacks.delete(callback);
|
|
3822
|
+
if (callbacks.size === 0) {
|
|
3823
|
+
this.kickCallbacks.delete(roomName);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
/**
|
|
3829
|
+
* Listen for room ownership changes (e.g. when the creator leaves).
|
|
3830
|
+
*
|
|
3831
|
+
* @example
|
|
3832
|
+
* ```typescript
|
|
3833
|
+
* baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
3834
|
+
* console.log(`New room owner: ${newCreatorUserId}`);
|
|
3835
|
+
* });
|
|
3836
|
+
* ```
|
|
3837
|
+
*/
|
|
3838
|
+
onRoomCreatorChanged(roomName, callback) {
|
|
3839
|
+
if (!this.creatorChangedCallbacks.has(roomName)) {
|
|
3840
|
+
this.creatorChangedCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3841
|
+
}
|
|
3842
|
+
this.creatorChangedCallbacks.get(roomName).add(callback);
|
|
3843
|
+
return () => {
|
|
3844
|
+
const callbacks = this.creatorChangedCallbacks.get(roomName);
|
|
3845
|
+
if (callbacks) {
|
|
3846
|
+
callbacks.delete(callback);
|
|
3847
|
+
if (callbacks.size === 0) {
|
|
3848
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
};
|
|
3852
|
+
}
|
|
3473
3853
|
/**
|
|
3474
3854
|
* Send a message to a room
|
|
3475
3855
|
*
|
|
@@ -3622,6 +4002,8 @@ var RealtimeModule = class {
|
|
|
3622
4002
|
cleanupRoomListeners(roomName) {
|
|
3623
4003
|
this.roomCallbacks.delete(roomName);
|
|
3624
4004
|
this.roomUserCallbacks.delete(roomName);
|
|
4005
|
+
this.kickCallbacks.delete(roomName);
|
|
4006
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3625
4007
|
}
|
|
3626
4008
|
// ===================
|
|
3627
4009
|
// Channel (Room) API - Supabase-style
|