@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/dist/index.js CHANGED
@@ -2582,6 +2582,37 @@ var PermissionsModule = class {
2582
2582
  async reloadCache() {
2583
2583
  await this.client.post("/permissions/reload");
2584
2584
  }
2585
+ /**
2586
+ * Export all permissions (admin only)
2587
+ *
2588
+ * @example
2589
+ * ```typescript
2590
+ * const exported = await baasix.permissions.export();
2591
+ * // Save to file or transfer
2592
+ * ```
2593
+ */
2594
+ async export() {
2595
+ const response = await this.client.post("/permissions-export", {});
2596
+ return response.data;
2597
+ }
2598
+ /**
2599
+ * Import permissions from exported data (admin only)
2600
+ *
2601
+ * @example
2602
+ * ```typescript
2603
+ * const result = await baasix.permissions.import(exportedData, {
2604
+ * overwrite: true
2605
+ * });
2606
+ * console.log('Imported:', result.imported, 'permissions');
2607
+ * ```
2608
+ */
2609
+ async import(data, options) {
2610
+ const response = await this.client.post("/permissions-import", {
2611
+ ...data,
2612
+ ...options
2613
+ });
2614
+ return response.data;
2615
+ }
2585
2616
  };
2586
2617
 
2587
2618
  // src/modules/settings.ts
@@ -2648,6 +2679,73 @@ var SettingsModule = class {
2648
2679
  async set(key, value) {
2649
2680
  return this.update({ [key]: value });
2650
2681
  }
2682
+ /**
2683
+ * Get settings by application URL (useful for multi-tenant apps)
2684
+ *
2685
+ * @example
2686
+ * ```typescript
2687
+ * const settings = await baasix.settings.getByAppUrl('https://myapp.example.com');
2688
+ * ```
2689
+ */
2690
+ async getByAppUrl(appUrl) {
2691
+ const response = await this.client.get(
2692
+ "/settings/by-app-url",
2693
+ { params: { appUrl } }
2694
+ );
2695
+ return response.data;
2696
+ }
2697
+ /**
2698
+ * Get email branding settings for the current tenant
2699
+ *
2700
+ * @example
2701
+ * ```typescript
2702
+ * const branding = await baasix.settings.getBranding();
2703
+ * console.log(branding.logo, branding.primaryColor);
2704
+ * ```
2705
+ */
2706
+ async getBranding() {
2707
+ const response = await this.client.get(
2708
+ "/settings/branding"
2709
+ );
2710
+ return response.data;
2711
+ }
2712
+ /**
2713
+ * Test email configuration by sending a test email
2714
+ *
2715
+ * @example
2716
+ * ```typescript
2717
+ * await baasix.settings.testEmail('admin@example.com');
2718
+ * ```
2719
+ */
2720
+ async testEmail(to) {
2721
+ const response = await this.client.post(
2722
+ "/settings/test-email",
2723
+ { to }
2724
+ );
2725
+ return response;
2726
+ }
2727
+ /**
2728
+ * Reload settings cache (admin only)
2729
+ *
2730
+ * @example
2731
+ * ```typescript
2732
+ * await baasix.settings.reload();
2733
+ * ```
2734
+ */
2735
+ async reload() {
2736
+ await this.client.post("/settings/reload");
2737
+ }
2738
+ /**
2739
+ * Delete tenant settings (admin only, multi-tenant)
2740
+ *
2741
+ * @example
2742
+ * ```typescript
2743
+ * await baasix.settings.deleteTenant();
2744
+ * ```
2745
+ */
2746
+ async deleteTenant() {
2747
+ await this.client.delete("/settings/tenant");
2748
+ }
2651
2749
  };
2652
2750
 
2653
2751
  // src/modules/reports.ts
@@ -3025,6 +3123,159 @@ var WorkflowsModule = class {
3025
3123
  ...overrides
3026
3124
  });
3027
3125
  }
3126
+ /**
3127
+ * Execute a specific node in a workflow
3128
+ *
3129
+ * @example
3130
+ * ```typescript
3131
+ * const result = await baasix.workflows.executeNode(
3132
+ * 'workflow-uuid',
3133
+ * 'node-id',
3134
+ * { inputData: 'value' }
3135
+ * );
3136
+ * ```
3137
+ */
3138
+ async executeNode(workflowId, nodeId, triggerData) {
3139
+ const response = await this.client.post(
3140
+ `/workflows/${workflowId}/nodes/${nodeId}/execute`,
3141
+ { triggerData }
3142
+ );
3143
+ return response.data;
3144
+ }
3145
+ /**
3146
+ * Get execution logs for a specific execution
3147
+ *
3148
+ * @example
3149
+ * ```typescript
3150
+ * const logs = await baasix.workflows.getExecutionLogs(
3151
+ * 'workflow-uuid',
3152
+ * 'execution-uuid'
3153
+ * );
3154
+ * ```
3155
+ */
3156
+ async getExecutionLogs(workflowId, executionId) {
3157
+ const response = await this.client.get(
3158
+ `/workflows/${workflowId}/executions/${executionId}/logs`
3159
+ );
3160
+ return response.data;
3161
+ }
3162
+ /**
3163
+ * Get workflow statistics
3164
+ *
3165
+ * @example
3166
+ * ```typescript
3167
+ * const stats = await baasix.workflows.getStats('workflow-uuid');
3168
+ * console.log(stats.totalExecutions, stats.successRate);
3169
+ * ```
3170
+ */
3171
+ async getStats(id) {
3172
+ const response = await this.client.get(`/workflows/${id}/stats`);
3173
+ return response.data;
3174
+ }
3175
+ /**
3176
+ * Validate a workflow definition
3177
+ *
3178
+ * @example
3179
+ * ```typescript
3180
+ * const result = await baasix.workflows.validate({
3181
+ * name: 'My Workflow',
3182
+ * nodes: [...],
3183
+ * edges: [...]
3184
+ * });
3185
+ * if (result.valid) {
3186
+ * console.log('Workflow is valid');
3187
+ * } else {
3188
+ * console.log('Errors:', result.errors);
3189
+ * }
3190
+ * ```
3191
+ */
3192
+ async validate(workflow) {
3193
+ const response = await this.client.post(
3194
+ "/workflows/validate",
3195
+ workflow
3196
+ );
3197
+ return response;
3198
+ }
3199
+ /**
3200
+ * Export a single workflow
3201
+ *
3202
+ * @example
3203
+ * ```typescript
3204
+ * const exported = await baasix.workflows.export('workflow-uuid');
3205
+ * // Save to file or transfer
3206
+ * ```
3207
+ */
3208
+ async export(id) {
3209
+ const response = await this.client.get(
3210
+ `/workflows/${id}/export`
3211
+ );
3212
+ return response.data;
3213
+ }
3214
+ /**
3215
+ * Export multiple workflows
3216
+ *
3217
+ * @example
3218
+ * ```typescript
3219
+ * // Export all workflows
3220
+ * const exported = await baasix.workflows.exportAll();
3221
+ *
3222
+ * // Export specific workflows
3223
+ * const exported = await baasix.workflows.exportAll({
3224
+ * ids: ['workflow-1', 'workflow-2']
3225
+ * });
3226
+ * ```
3227
+ */
3228
+ async exportAll(options) {
3229
+ const response = await this.client.post(
3230
+ "/workflows/export",
3231
+ options || {}
3232
+ );
3233
+ return response.data;
3234
+ }
3235
+ /**
3236
+ * Preview workflow import without applying changes
3237
+ *
3238
+ * @example
3239
+ * ```typescript
3240
+ * const preview = await baasix.workflows.importPreview(file);
3241
+ * console.log('Will import:', preview.workflows.length, 'workflows');
3242
+ * console.log('Conflicts:', preview.conflicts);
3243
+ * ```
3244
+ */
3245
+ async importPreview(file) {
3246
+ const formData = new FormData();
3247
+ if (file instanceof File) {
3248
+ formData.append("file", file);
3249
+ } else {
3250
+ formData.append("file", file);
3251
+ }
3252
+ const response = await this.client.post("/workflows/import/preview", formData);
3253
+ return response.data;
3254
+ }
3255
+ /**
3256
+ * Import workflows from a file
3257
+ *
3258
+ * @example
3259
+ * ```typescript
3260
+ * const result = await baasix.workflows.import(file, {
3261
+ * overwrite: true
3262
+ * });
3263
+ * console.log('Imported:', result.imported, 'workflows');
3264
+ * ```
3265
+ */
3266
+ async import(file, options) {
3267
+ const formData = new FormData();
3268
+ if (file instanceof File) {
3269
+ formData.append("file", file);
3270
+ } else {
3271
+ formData.append("file", file);
3272
+ }
3273
+ if (options?.overwrite !== void 0) {
3274
+ formData.append("overwrite", String(options.overwrite));
3275
+ }
3276
+ const response = await this.client.post("/workflows/import", formData);
3277
+ return response.data;
3278
+ }
3028
3279
  };
3029
3280
 
3030
3281
  // src/modules/realtime.ts
@@ -3040,6 +3291,8 @@ var RealtimeModule = class {
3040
3291
  roomCallbacks = /* @__PURE__ */ new Map();
3041
3292
  // room -> event -> callbacks
3042
3293
  roomUserCallbacks = /* @__PURE__ */ new Map();
3294
+ kickCallbacks = /* @__PURE__ */ new Map();
3295
+ creatorChangedCallbacks = /* @__PURE__ */ new Map();
3043
3296
  connectionCallbacks = /* @__PURE__ */ new Set();
3044
3297
  reconnecting = false;
3045
3298
  connectionPromise = null;
@@ -3169,6 +3422,27 @@ var RealtimeModule = class {
3169
3422
  }
3170
3423
  });
3171
3424
  });
3425
+ this.socket.on("room:kicked", (data) => {
3426
+ const callbacks = this.kickCallbacks.get(data.room);
3427
+ callbacks?.forEach((cb) => {
3428
+ try {
3429
+ cb(data);
3430
+ } catch (e) {
3431
+ console.error("[Baasix Realtime] Error in room kicked callback:", e);
3432
+ }
3433
+ });
3434
+ this.cleanupRoomListeners(data.room);
3435
+ });
3436
+ this.socket.on("room:creator:changed", (data) => {
3437
+ const callbacks = this.creatorChangedCallbacks.get(data.room);
3438
+ callbacks?.forEach((cb) => {
3439
+ try {
3440
+ cb(data);
3441
+ } catch (e) {
3442
+ console.error("[Baasix Realtime] Error in room creator changed callback:", e);
3443
+ }
3444
+ });
3445
+ });
3172
3446
  this.socket.connect();
3173
3447
  } catch (error) {
3174
3448
  this.connectionPromise = null;
@@ -3198,6 +3472,8 @@ var RealtimeModule = class {
3198
3472
  this.workflowCallbacks.clear();
3199
3473
  this.roomCallbacks.clear();
3200
3474
  this.roomUserCallbacks.clear();
3475
+ this.kickCallbacks.clear();
3476
+ this.creatorChangedCallbacks.clear();
3201
3477
  }
3202
3478
  /**
3203
3479
  * Check if connected to the realtime server
@@ -3468,6 +3744,110 @@ var RealtimeModule = class {
3468
3744
  });
3469
3745
  });
3470
3746
  }
3747
+ /**
3748
+ * Get the list of users currently in a room.
3749
+ * You must already be a member of the room to call this.
3750
+ *
3751
+ * @example
3752
+ * ```typescript
3753
+ * const members = await baasix.realtime.getRoomMembers('game:lobby');
3754
+ * members.forEach(m => {
3755
+ * console.log(m.userId, m.isCreator ? '(owner)' : '');
3756
+ * });
3757
+ * ```
3758
+ */
3759
+ async getRoomMembers(roomName) {
3760
+ if (!this.socket?.connected) {
3761
+ throw new Error("Not connected. Call connect() first.");
3762
+ }
3763
+ return new Promise((resolve, reject) => {
3764
+ this.socket.emit("room:members", { room: roomName }, (response) => {
3765
+ if (response.status === "success") {
3766
+ resolve(response.members);
3767
+ } else {
3768
+ reject(new Error(response.message || "Failed to get room members"));
3769
+ }
3770
+ });
3771
+ });
3772
+ }
3773
+ /**
3774
+ * Kick a user from a custom room. Only the room creator may call this.
3775
+ *
3776
+ * @example
3777
+ * ```typescript
3778
+ * await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
3779
+ * ```
3780
+ */
3781
+ async kickFromRoom(roomName, targetUserId) {
3782
+ if (!this.socket?.connected) {
3783
+ throw new Error("Not connected. Call connect() first.");
3784
+ }
3785
+ return new Promise((resolve, reject) => {
3786
+ this.socket.emit(
3787
+ "room:kick",
3788
+ { room: roomName, userId: targetUserId },
3789
+ (response) => {
3790
+ if (response.status === "success") {
3791
+ resolve();
3792
+ } else {
3793
+ reject(new Error(response.message || "Failed to kick user"));
3794
+ }
3795
+ }
3796
+ );
3797
+ });
3798
+ }
3799
+ /**
3800
+ * Listen for being kicked from a room.
3801
+ * The callback fires when the current user is removed by the room creator.
3802
+ * Room listeners are automatically cleaned up after the kick.
3803
+ *
3804
+ * @example
3805
+ * ```typescript
3806
+ * baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
3807
+ * console.log(`You were kicked by user ${kickedBy}`);
3808
+ * });
3809
+ * ```
3810
+ */
3811
+ onKicked(roomName, callback) {
3812
+ if (!this.kickCallbacks.has(roomName)) {
3813
+ this.kickCallbacks.set(roomName, /* @__PURE__ */ new Set());
3814
+ }
3815
+ this.kickCallbacks.get(roomName).add(callback);
3816
+ return () => {
3817
+ const callbacks = this.kickCallbacks.get(roomName);
3818
+ if (callbacks) {
3819
+ callbacks.delete(callback);
3820
+ if (callbacks.size === 0) {
3821
+ this.kickCallbacks.delete(roomName);
3822
+ }
3823
+ }
3824
+ };
3825
+ }
3826
+ /**
3827
+ * Listen for room ownership changes (e.g. when the creator leaves).
3828
+ *
3829
+ * @example
3830
+ * ```typescript
3831
+ * baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
3832
+ * console.log(`New room owner: ${newCreatorUserId}`);
3833
+ * });
3834
+ * ```
3835
+ */
3836
+ onRoomCreatorChanged(roomName, callback) {
3837
+ if (!this.creatorChangedCallbacks.has(roomName)) {
3838
+ this.creatorChangedCallbacks.set(roomName, /* @__PURE__ */ new Set());
3839
+ }
3840
+ this.creatorChangedCallbacks.get(roomName).add(callback);
3841
+ return () => {
3842
+ const callbacks = this.creatorChangedCallbacks.get(roomName);
3843
+ if (callbacks) {
3844
+ callbacks.delete(callback);
3845
+ if (callbacks.size === 0) {
3846
+ this.creatorChangedCallbacks.delete(roomName);
3847
+ }
3848
+ }
3849
+ };
3850
+ }
3471
3851
  /**
3472
3852
  * Send a message to a room
3473
3853
  *
@@ -3620,6 +4000,8 @@ var RealtimeModule = class {
3620
4000
  cleanupRoomListeners(roomName) {
3621
4001
  this.roomCallbacks.delete(roomName);
3622
4002
  this.roomUserCallbacks.delete(roomName);
4003
+ this.kickCallbacks.delete(roomName);
4004
+ this.creatorChangedCallbacks.delete(roomName);
3623
4005
  }
3624
4006
  // ===================
3625
4007
  // Channel (Room) API - Supabase-style