@omnibase/core-js 0.4.2 → 0.5.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.
@@ -20,189 +20,567 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/tenants/index.ts
21
21
  var tenants_exports = {};
22
22
  __export(tenants_exports, {
23
- acceptTenantInvite: () => acceptTenantInvite,
24
- createTenant: () => createTenant,
25
- createTenantUserInvite: () => createTenantUserInvite,
26
- deleteTenant: () => deleteTenant,
27
- switchActiveTenant: () => switchActiveTenant
23
+ TenantHandler: () => TenantHandler
28
24
  });
29
25
  module.exports = __toCommonJS(tenants_exports);
30
26
 
31
- // src/tenants/switch-tenant.ts
32
- async function switchActiveTenant(tenantId) {
33
- const baseUrl = process.env.OMNIBASE_AUTH_URL;
34
- if (!baseUrl) {
35
- throw new Error("OMNIBASE_AUTH_URL is not configured");
27
+ // src/tenants/invites.ts
28
+ var TenantInviteManager = class {
29
+ /**
30
+ * Creates a new TenantInviteManager instance
31
+ *
32
+ * Initializes the manager with the provided Omnibase client for making
33
+ * authenticated API requests to tenant invitation endpoints.
34
+ *
35
+ * @param omnibaseClient - Configured Omnibase client instance
36
+ *
37
+ * @group Tenant Invitations
38
+ */
39
+ constructor(omnibaseClient) {
40
+ this.omnibaseClient = omnibaseClient;
36
41
  }
37
- if (!tenantId) {
38
- throw new Error("Tenant ID is required");
42
+ /**
43
+ * Accepts a tenant invitation using a secure token
44
+ *
45
+ * Processes a tenant invitation by validating the provided token and
46
+ * adding the authenticated user to the specified tenant. The invitation
47
+ * token is consumed during this process and cannot be used again.
48
+ *
49
+ * The function performs several validations:
50
+ * - Verifies the token exists and is valid
51
+ * - Checks that the invitation hasn't expired
52
+ * - Ensures the invitation hasn't already been used
53
+ * - Confirms the user is authenticated via session cookies
54
+ *
55
+ * Upon successful acceptance, the user is granted access to the tenant
56
+ * with the role specified in the original invitation. The invitation
57
+ * record is marked as used and cannot be accepted again.
58
+ *
59
+ * @param token - The secure invitation token from the email invitation
60
+ *
61
+ * @returns Promise resolving to the tenant ID and success confirmation
62
+ *
63
+ * @throws {Error} When the token parameter is missing or empty
64
+ * @throws {Error} When the invitation token is invalid or expired
65
+ * @throws {Error} When the invitation has already been accepted
66
+ * @throws {Error} When the user is not authenticated
67
+ * @throws {Error} When the API request fails due to network issues
68
+ * @throws {Error} When the server returns an error response (4xx, 5xx status codes)
69
+ *
70
+ * @example
71
+ * Basic invitation acceptance:
72
+ * ```typescript
73
+ * const result = await acceptTenantInvite('inv_secure_token_abc123');
74
+ *
75
+ * console.log(`Successfully joined tenant: ${result.data.tenant_id}`);
76
+ * // User can now access tenant resources
77
+ * await switchActiveTenant(result.data.tenant_id);
78
+ * ```
79
+ *
80
+ * @example
81
+ * Handling the invitation flow:
82
+ * ```typescript
83
+ * // Typically called from an invitation link like:
84
+ * // https://app.com/accept-invite?token=inv_secure_token_abc123
85
+ *
86
+ * const urlParams = new URLSearchParams(window.location.search);
87
+ * const inviteToken = urlParams.get('token');
88
+ *
89
+ * if (inviteToken) {
90
+ * try {
91
+ * const result = await acceptTenantInvite(inviteToken);
92
+ *
93
+ * // Success - redirect to tenant dashboard
94
+ * window.location.href = `/dashboard?tenant=${result.data.tenant_id}`;
95
+ * } catch (error) {
96
+ * console.error('Failed to accept invitation:', error.message);
97
+ * // Show error to user
98
+ * }
99
+ * }
100
+ * ```
101
+ *
102
+ *
103
+ * @since 1.0.0
104
+ * @public
105
+ * @group User Management
106
+ */
107
+ async accept(token) {
108
+ if (!token) {
109
+ throw new Error("Invite token is required");
110
+ }
111
+ const requestBody = {
112
+ token
113
+ };
114
+ try {
115
+ const response = await this.omnibaseClient.fetch(
116
+ `/api/v1/tenants/invites/accept`,
117
+ {
118
+ method: "PUT",
119
+ headers: {
120
+ "Content-Type": "application/json"
121
+ },
122
+ body: JSON.stringify(requestBody),
123
+ credentials: "include"
124
+ }
125
+ );
126
+ if (!response.ok) {
127
+ const errorData = await response.text();
128
+ throw new Error(
129
+ `Failed to accept invite: ${response.status} - ${errorData}`
130
+ );
131
+ }
132
+ const data = await response.json();
133
+ return data;
134
+ } catch (error) {
135
+ console.error("Error accepting tenant invite:", error);
136
+ throw error;
137
+ }
39
138
  }
40
- const requestBody = {
41
- tenant_id: tenantId
42
- };
43
- try {
44
- const response = await fetch(`${baseUrl}/api/v1/tenants/switch-active`, {
45
- method: "PUT",
46
- headers: {
47
- "Content-Type": "application/json"
48
- },
49
- body: JSON.stringify(requestBody),
50
- credentials: "include"
51
- });
52
- if (!response.ok) {
53
- const errorData = await response.text();
54
- throw new Error(
55
- `Failed to switch tenant: ${response.status} - ${errorData}`
139
+ /**
140
+ * Creates a new user invitation for a specific tenant
141
+ *
142
+ * Generates a secure invitation that allows a user to join the specified
143
+ * tenant with the defined role. The invitation is sent to the provided
144
+ * email address and includes a time-limited token for security.
145
+ *
146
+ * The function creates the invitation record in the database and can
147
+ * trigger email notifications (depending on server configuration).
148
+ * The invitation expires after a predefined time period and can only
149
+ * be used once.
150
+ *
151
+ * Only existing tenant members with appropriate permissions can create
152
+ * invitations. The inviter's authentication is validated via HTTP-only
153
+ * cookies sent with the request.
154
+ *
155
+ * @param tenantId - Unique identifier of the tenant to invite the user to
156
+ * @param inviteData - Configuration object for the invitation
157
+ * @param inviteData.email - Email address of the user to invite
158
+ * @param inviteData.role - Role the user will have after joining (e.g., 'member', 'admin')
159
+ *
160
+ * @returns Promise resolving to the created invitation with secure token
161
+ *
162
+ * @throws {Error} When tenantId parameter is missing or empty
163
+ * @throws {Error} When required fields (email, role) are missing or empty
164
+ * @throws {Error} When the API request fails due to network issues
165
+ * @throws {Error} When the server returns an error response (4xx, 5xx status codes)
166
+ *
167
+ * @example
168
+ * Basic invitation creation:
169
+ * ```typescript
170
+ * const invite = await createTenantUserInvite('tenant_123', {
171
+ * email: 'colleague@company.com',
172
+ * role: 'member'
173
+ * });
174
+ *
175
+ * console.log(`Invite sent to: ${invite.data.invite.email}`);
176
+ * // The invite token can be used to generate invitation links
177
+ * const inviteLink = `https://app.com/accept-invite?token=${invite.data.invite.token}`;
178
+ * ```
179
+ *
180
+ * @example
181
+ * Creating admin invitation:
182
+ * ```typescript
183
+ * const adminInvite = await createTenantUserInvite('tenant_456', {
184
+ * email: 'admin@company.com',
185
+ * role: 'admin'
186
+ * });
187
+ *
188
+ * // Admin users get elevated permissions
189
+ * console.log(`Admin invite created with ID: ${adminInvite.data.invite.id}`);
190
+ * ```
191
+ *
192
+ *
193
+ * @since 1.0.0
194
+ * @public
195
+ * @group User Management
196
+ */
197
+ async create(tenantId, inviteData) {
198
+ if (!tenantId) {
199
+ throw new Error("Tenant ID is required");
200
+ }
201
+ if (!inviteData.email || !inviteData.role) {
202
+ throw new Error("Email and role are required");
203
+ }
204
+ try {
205
+ const response = await this.omnibaseClient.fetch(
206
+ `/api/v1/tenants/${tenantId}/invites`,
207
+ {
208
+ method: "POST",
209
+ headers: {
210
+ "Content-Type": "application/json"
211
+ },
212
+ body: JSON.stringify(inviteData),
213
+ credentials: "include"
214
+ }
56
215
  );
216
+ if (!response.ok) {
217
+ const errorData = await response.text();
218
+ throw new Error(
219
+ `Failed to create invite: ${response.status} - ${errorData}`
220
+ );
221
+ }
222
+ const data = await response.json();
223
+ return data;
224
+ } catch (error) {
225
+ console.error("Error creating tenant user invite:", error);
226
+ throw error;
57
227
  }
58
- const data = await response.json();
59
- return data;
60
- } catch (error) {
61
- console.error("Error switching active tenant:", error);
62
- throw error;
63
228
  }
64
- }
229
+ };
65
230
 
66
- // src/tenants/create-invite.ts
67
- async function createTenantUserInvite(tenantId, inviteData) {
68
- const baseUrl = process.env.OMNIBASE_AUTH_URL;
69
- if (!baseUrl) {
70
- throw new Error("OMNIBASE_AUTH_URL is not configured");
71
- }
72
- if (!tenantId) {
73
- throw new Error("Tenant ID is required");
231
+ // src/tenants/tenants.ts
232
+ var TenantManger = class {
233
+ /**
234
+ * Creates a new TenantManger instance
235
+ *
236
+ * Initializes the manager with the provided Omnibase client for making
237
+ * authenticated API requests to tenant management endpoints.
238
+ *
239
+ * @param omnibaseClient - Configured Omnibase client instance
240
+ *
241
+ * @group Tenant Management
242
+ */
243
+ constructor(omnibaseClient) {
244
+ this.omnibaseClient = omnibaseClient;
74
245
  }
75
- if (!inviteData.email || !inviteData.role) {
76
- throw new Error("Email and role are required");
77
- }
78
- try {
79
- const response = await fetch(
80
- `${baseUrl}/api/v1/tenants/${tenantId}/invites`,
81
- {
246
+ /**
247
+ * Creates a new tenant in the multi-tenant system
248
+ *
249
+ * Establishes a new tenant with integrated Stripe billing setup and assigns
250
+ * the specified user as the tenant owner. The operation creates the necessary
251
+ * database records and returns a JWT token that enables Row-Level Security
252
+ * access to the tenant's isolated data.
253
+ *
254
+ * The function automatically handles Stripe customer creation for billing
255
+ * integration and sets up the initial tenant configuration. The returned
256
+ * token should be stored securely for subsequent API calls.
257
+ *
258
+ * @param tenantData - Configuration object for the new tenant
259
+ * @param tenantData.name - Display name for the tenant organization
260
+ * @param tenantData.billing_email - Email address for Stripe billing notifications
261
+ * @param tenantData.user_id - Unique identifier of the user who will own this tenant
262
+ *
263
+ * @returns Promise resolving to the created tenant with authentication token
264
+ *
265
+ * @throws {Error} When required fields (name, user_id) are missing or empty
266
+ * @throws {Error} When the API request fails due to network issues
267
+ * @throws {Error} When the server returns an error response (4xx, 5xx status codes)
268
+ *
269
+ * @example
270
+ * Basic tenant creation:
271
+ * ```typescript
272
+ * const newTenant = await createTenant({
273
+ * name: 'Acme Corporation',
274
+ * billing_email: 'billing@acme.com',
275
+ * user_id: 'user_123'
276
+ * });
277
+ *
278
+ * console.log(`Created tenant: ${newTenant.data.tenant.name}`);
279
+ * // Store the token for authenticated requests
280
+ * localStorage.setItem('tenant_token', newTenant.data.token);
281
+ * ```
282
+ *
283
+ *
284
+ * @since 1.0.0
285
+ * @public
286
+ * @group Tenant Management
287
+ */
288
+ async createTenant(tenantData) {
289
+ if (!tenantData.name || !tenantData.user_id) {
290
+ throw new Error("Name and user_id are required");
291
+ }
292
+ try {
293
+ const response = await this.omnibaseClient.fetch(`/api/v1/tenants`, {
82
294
  method: "POST",
83
295
  headers: {
84
296
  "Content-Type": "application/json"
85
297
  },
86
- body: JSON.stringify(inviteData),
298
+ body: JSON.stringify(tenantData),
87
299
  credentials: "include"
300
+ });
301
+ if (!response.ok) {
302
+ const errorData = await response.text();
303
+ throw new Error(
304
+ `Failed to create tenant: ${response.status} - ${errorData}`
305
+ );
88
306
  }
89
- );
90
- if (!response.ok) {
91
- const errorData = await response.text();
92
- throw new Error(
93
- `Failed to create invite: ${response.status} - ${errorData}`
94
- );
307
+ const data = await response.json();
308
+ return data;
309
+ } catch (error) {
310
+ console.error("Error creating tenant:", error);
311
+ throw error;
95
312
  }
96
- const data = await response.json();
97
- return data;
98
- } catch (error) {
99
- console.error("Error creating tenant user invite:", error);
100
- throw error;
101
- }
102
- }
103
-
104
- // src/tenants/create-tenant.ts
105
- async function createTenant(tenantData) {
106
- const baseUrl = process.env.OMNIBASE_AUTH_URL;
107
- if (!baseUrl) {
108
- throw new Error("OMNIBASE_AUTH_URL is not configured");
109
313
  }
110
- if (!tenantData.name || !tenantData.user_id) {
111
- throw new Error("Name and user_id are required");
112
- }
113
- try {
114
- const response = await fetch(`${baseUrl}/api/v1/tenants`, {
115
- method: "POST",
116
- headers: {
117
- "Content-Type": "application/json"
118
- },
119
- body: JSON.stringify(tenantData),
120
- credentials: "include"
121
- });
122
- if (!response.ok) {
123
- const errorData = await response.text();
124
- throw new Error(
125
- `Failed to create tenant: ${response.status} - ${errorData}`
314
+ /**
315
+ * Permanently deletes a tenant and all associated data
316
+ *
317
+ * ⚠️ **WARNING: This operation is irreversible and will permanently delete:**
318
+ * - The tenant record and all metadata
319
+ * - All user memberships and invitations for this tenant
320
+ * - All tenant-specific data protected by row-level security
321
+ * - Any tenant-related billing information
322
+ * - All tenant configuration and settings
323
+ *
324
+ * **Access Control:**
325
+ * Only tenant owners can delete a tenant. This operation requires:
326
+ * - User must be authenticated
327
+ * - User must have 'owner' role for the specified tenant
328
+ * - Tenant must exist and be accessible to the user
329
+ *
330
+ * **Security Considerations:**
331
+ * - All tenant data is immediately and permanently removed
332
+ * - Other tenant members lose access immediately
333
+ * - Any active sessions for this tenant are invalidated
334
+ * - Billing subscriptions are cancelled (if applicable)
335
+ * - Audit logs for deletion are maintained for compliance
336
+ *
337
+ * @param tenantId - The unique identifier of the tenant to delete
338
+ *
339
+ * @returns Promise resolving to a confirmation message
340
+ *
341
+ * @throws {Error} When the tenantId parameter is missing or empty
342
+ * @throws {Error} When the user is not authenticated
343
+ * @throws {Error} When the user is not an owner of the specified tenant
344
+ * @throws {Error} When the tenant doesn't exist or is not accessible
345
+ * @throws {Error} When the API request fails due to network issues
346
+ * @throws {Error} When the server returns an error response (4xx, 5xx status codes)
347
+ *
348
+ * @example
349
+ * Basic tenant deletion with confirmation:
350
+ * ```typescript
351
+ * const tenantToDelete = 'tenant_abc123';
352
+ *
353
+ * // Always confirm before deleting
354
+ * const userConfirmed = confirm(
355
+ * 'Are you sure you want to delete this tenant? This action cannot be undone.'
356
+ * );
357
+ *
358
+ * if (userConfirmed) {
359
+ * try {
360
+ * const result = await deleteTenant(tenantToDelete);
361
+ * console.log(result.data.message); // "Tenant deleted successfully"
362
+ *
363
+ * // Redirect user away from deleted tenant
364
+ * window.location.href = '/dashboard';
365
+ * } catch (error) {
366
+ * console.error('Failed to delete tenant:', error);
367
+ * }
368
+ * }
369
+ * ```
370
+ *
371
+ * @since 1.0.0
372
+ * @public
373
+ * @group Tenant Management
374
+ */
375
+ async deleteTenant(tenantId) {
376
+ if (!tenantId) {
377
+ throw new Error("Tenant ID is required");
378
+ }
379
+ try {
380
+ const response = await this.omnibaseClient.fetch(
381
+ `/api/v1/tenants/${tenantId}`,
382
+ {
383
+ method: "DELETE",
384
+ headers: {
385
+ "Content-Type": "application/json"
386
+ },
387
+ credentials: "include"
388
+ }
126
389
  );
390
+ if (!response.ok) {
391
+ const errorData = await response.text();
392
+ throw new Error(
393
+ `Failed to delete tenant: ${response.status} - ${errorData}`
394
+ );
395
+ }
396
+ const data = await response.json();
397
+ return data;
398
+ } catch (error) {
399
+ console.error("Error deleting tenant:", error);
400
+ throw error;
127
401
  }
128
- const data = await response.json();
129
- return data;
130
- } catch (error) {
131
- console.error("Error creating tenant:", error);
132
- throw error;
133
402
  }
134
- }
135
-
136
- // src/tenants/accept-invite.ts
137
- async function acceptTenantInvite(token) {
138
- const baseUrl = process.env.OMNIBASE_AUTH_URL;
139
- if (!baseUrl) {
140
- throw new Error("OMNIBASE_AUTH_URL is not configured");
141
- }
142
- if (!token) {
143
- throw new Error("Invite token is required");
144
- }
145
- const requestBody = {
146
- token
147
- };
148
- try {
149
- const response = await fetch(`${baseUrl}/api/v1/tenants/invites/accept`, {
150
- method: "PUT",
151
- headers: {
152
- "Content-Type": "application/json"
153
- },
154
- body: JSON.stringify(requestBody),
155
- credentials: "include"
156
- });
157
- if (!response.ok) {
158
- const errorData = await response.text();
159
- throw new Error(
160
- `Failed to accept invite: ${response.status} - ${errorData}`
403
+ /**
404
+ * Switches the user's active tenant context
405
+ *
406
+ * Changes the user's active tenant to the specified tenant ID, updating
407
+ * their authentication context and permissions. This function is essential
408
+ * for multi-tenant applications where users belong to multiple tenants
409
+ * and need to switch between them.
410
+ *
411
+ * The function performs several operations:
412
+ * - Validates that the user has access to the specified tenant
413
+ * - Updates the user's active tenant in their session
414
+ * - Generates a new JWT token with updated tenant claims
415
+ * - Updates any cached tenant-specific data
416
+ *
417
+ * After switching tenants, all subsequent API calls will be made within
418
+ * the context of the new active tenant, with row-level security policies
419
+ * applied accordingly. The new JWT token should be used for all future
420
+ * authenticated requests.
421
+ *
422
+ * @param tenantId - The ID of the tenant to switch to (must be a tenant the user belongs to)
423
+ *
424
+ * @returns Promise resolving to a new JWT token and success confirmation
425
+ *
426
+ * @throws {Error} When the tenantId parameter is missing or empty
427
+ * @throws {Error} When the user doesn't have access to the specified tenant
428
+ * @throws {Error} When the user is not authenticated
429
+ * @throws {Error} When the specified tenant doesn't exist
430
+ * @throws {Error} When the API request fails due to network issues
431
+ * @throws {Error} When the server returns an error response (4xx, 5xx status codes)
432
+ *
433
+ * @example
434
+ * Basic tenant switching:
435
+ * ```typescript
436
+ * const result = await switchActiveTenant('tenant_xyz789');
437
+ *
438
+ * // Now all API calls will be in the context of tenant_xyz789
439
+ * const tenantData = await getCurrentTenantData();
440
+ * ```
441
+ *
442
+ * @example
443
+ * Using with tenant-aware data fetching:
444
+ * ```typescript
445
+ * // Switch tenant and immediately fetch tenant-specific data
446
+ * const switchAndLoadTenant = async (tenantId: string) => {
447
+ * try {
448
+ * // Switch to new tenant context
449
+ * const switchResult = await switchActiveTenant(tenantId);
450
+ *
451
+ * // Update authentication token
452
+ * setAuthToken(switchResult.data.token);
453
+ *
454
+ * // Fetch data in new tenant context
455
+ * const [tenantInfo, userPermissions, tenantSettings] = await Promise.all([
456
+ * getTenantInfo(),
457
+ * getUserPermissions(),
458
+ * getTenantSettings()
459
+ * ]);
460
+ *
461
+ * return {
462
+ * tenant: tenantInfo,
463
+ * permissions: userPermissions,
464
+ * settings: tenantSettings
465
+ * };
466
+ * } catch (error) {
467
+ * console.error('Failed to switch tenant and load data:', error);
468
+ * throw error;
469
+ * }
470
+ * };
471
+ * ```
472
+ *
473
+ * @since 1.0.0
474
+ * @public
475
+ * @group Tenant Management
476
+ */
477
+ async switchActiveTenant(tenantId) {
478
+ if (!tenantId) {
479
+ throw new Error("Tenant ID is required");
480
+ }
481
+ const requestBody = {
482
+ tenant_id: tenantId
483
+ };
484
+ try {
485
+ const response = await this.omnibaseClient.fetch(
486
+ `/api/v1/tenants/switch-active`,
487
+ {
488
+ method: "PUT",
489
+ headers: {
490
+ "Content-Type": "application/json"
491
+ },
492
+ body: JSON.stringify(requestBody),
493
+ credentials: "include"
494
+ }
161
495
  );
496
+ if (!response.ok) {
497
+ const errorData = await response.text();
498
+ throw new Error(
499
+ `Failed to switch tenant: ${response.status} - ${errorData}`
500
+ );
501
+ }
502
+ const data = await response.json();
503
+ return data;
504
+ } catch (error) {
505
+ console.error("Error switching active tenant:", error);
506
+ throw error;
162
507
  }
163
- const data = await response.json();
164
- return data;
165
- } catch (error) {
166
- console.error("Error accepting tenant invite:", error);
167
- throw error;
168
508
  }
169
- }
509
+ };
170
510
 
171
- // src/tenants/delete-tenant.ts
172
- async function deleteTenant(tenantId) {
173
- const baseUrl = process.env.OMNIBASE_AUTH_URL;
174
- if (!baseUrl) {
175
- throw new Error("OMNIBASE_AUTH_URL is not configured");
511
+ // src/tenants/handler.ts
512
+ var TenantHandler = class {
513
+ /**
514
+ * Creates a new TenantHandler instance
515
+ *
516
+ * Initializes the handler with the provided Omnibase client and sets up
517
+ * the specialized manager instances for tenant and invitation operations.
518
+ * The client is used for all underlying HTTP requests and authentication.
519
+ *
520
+ * @param omnibaseClient - Configured Omnibase client instance
521
+ *
522
+ * @example
523
+ * ```typescript
524
+ * const client = new OmnibaseClient({
525
+ * apiKey: 'your-api-key',
526
+ * baseURL: 'https://api.yourapp.com'
527
+ * });
528
+ * const tenantHandler = new TenantHandler(client);
529
+ * ```
530
+ *
531
+ * @group Tenant Management
532
+ */
533
+ constructor(omnibaseClient) {
534
+ this.omnibaseClient = omnibaseClient;
535
+ this.invites = new TenantInviteManager(this.omnibaseClient);
536
+ this.tenants = new TenantManger(this.omnibaseClient);
176
537
  }
177
- if (!tenantId) {
178
- throw new Error("Tenant ID is required");
179
- }
180
- try {
181
- const response = await fetch(`${baseUrl}/api/v1/tenants/${tenantId}`, {
182
- method: "DELETE",
183
- headers: {
184
- "Content-Type": "application/json"
185
- },
186
- credentials: "include"
187
- });
188
- if (!response.ok) {
189
- const errorData = await response.text();
190
- throw new Error(
191
- `Failed to delete tenant: ${response.status} - ${errorData}`
192
- );
193
- }
194
- const data = await response.json();
195
- return data;
196
- } catch (error) {
197
- console.error("Error deleting tenant:", error);
198
- throw error;
199
- }
200
- }
538
+ /**
539
+ * Core tenant management operations
540
+ *
541
+ * Provides access to tenant lifecycle operations including creation,
542
+ * deletion, and active tenant switching. All operations respect user
543
+ * permissions and tenant ownership rules.
544
+ *
545
+ * @example
546
+ * ```typescript
547
+ * // Create a new tenant
548
+ * const tenant = await tenantHandler.tenants.createTenant({
549
+ * name: 'New Company',
550
+ * billing_email: 'billing@newcompany.com',
551
+ * user_id: 'user_456'
552
+ * });
553
+ *
554
+ * // Switch to the tenant
555
+ * await tenantHandler.tenants.switchActiveTenant(tenant.data.tenant.id);
556
+ *
557
+ * // Delete the tenant (owner only)
558
+ * await tenantHandler.tenants.deleteTenant(tenant.data.tenant.id);
559
+ * ```
560
+ */
561
+ tenants;
562
+ /**
563
+ * Tenant invitation management operations
564
+ *
565
+ * Provides access to user invitation functionality including creating
566
+ * invitations for new users and accepting existing invitations.
567
+ * Supports role-based access control and secure token-based workflows.
568
+ *
569
+ * @example
570
+ * ```typescript
571
+ * // Create an invitation
572
+ * const invite = await tenantHandler.invites.create('tenant_123', {
573
+ * email: 'newuser@company.com',
574
+ * role: 'admin'
575
+ * });
576
+ *
577
+ * // Accept an invitation (from the invited user's session)
578
+ * const result = await tenantHandler.invites.accept('invite_token_xyz');
579
+ * ```
580
+ */
581
+ invites;
582
+ };
201
583
  // Annotate the CommonJS export names for ESM import in node:
202
584
  0 && (module.exports = {
203
- acceptTenantInvite,
204
- createTenant,
205
- createTenantUserInvite,
206
- deleteTenant,
207
- switchActiveTenant
585
+ TenantHandler
208
586
  });