@scalekit-sdk/node 2.2.0 → 2.2.2

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.
Files changed (62) hide show
  1. package/{reference.md → REFERENCE.md} +530 -77
  2. package/lib/core.js +1 -1
  3. package/package.json +9 -3
  4. package/.github/dependabot.yml +0 -10
  5. package/.nvmrc +0 -1
  6. package/buf.gen.yaml +0 -20
  7. package/jest.config.js +0 -15
  8. package/src/auth.ts +0 -99
  9. package/src/connect.ts +0 -32
  10. package/src/connection.ts +0 -267
  11. package/src/constants/user.ts +0 -22
  12. package/src/core.ts +0 -139
  13. package/src/directory.ts +0 -431
  14. package/src/domain.ts +0 -273
  15. package/src/errors/base-exception.ts +0 -263
  16. package/src/errors/index.ts +0 -3
  17. package/src/errors/specific-exceptions.ts +0 -88
  18. package/src/index.ts +0 -10
  19. package/src/organization.ts +0 -571
  20. package/src/passwordless.ts +0 -139
  21. package/src/permission.ts +0 -310
  22. package/src/pkg/grpc/buf/validate/validate_pb.ts +0 -28
  23. package/src/pkg/grpc/google/api/annotations_pb.ts +0 -28
  24. package/src/pkg/grpc/google/api/field_behavior_pb.ts +0 -28
  25. package/src/pkg/grpc/google/api/visibility_pb.ts +0 -28
  26. package/src/pkg/grpc/protoc-gen-openapiv2/options/annotations_pb.ts +0 -28
  27. package/src/pkg/grpc/scalekit/v1/auditlogs/auditlogs_pb.ts +0 -257
  28. package/src/pkg/grpc/scalekit/v1/auth/auth_pb.ts +0 -836
  29. package/src/pkg/grpc/scalekit/v1/auth/passwordless_pb.ts +0 -264
  30. package/src/pkg/grpc/scalekit/v1/auth/webauthn_pb.ts +0 -794
  31. package/src/pkg/grpc/scalekit/v1/commons/commons_pb.ts +0 -452
  32. package/src/pkg/grpc/scalekit/v1/connections/connections_pb.ts +0 -2645
  33. package/src/pkg/grpc/scalekit/v1/directories/directories_pb.ts +0 -1393
  34. package/src/pkg/grpc/scalekit/v1/domains/domains_pb.ts +0 -599
  35. package/src/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.ts +0 -311
  36. package/src/pkg/grpc/scalekit/v1/options/options_pb.ts +0 -200
  37. package/src/pkg/grpc/scalekit/v1/organizations/organizations_pb.ts +0 -1141
  38. package/src/pkg/grpc/scalekit/v1/roles/roles_pb.ts +0 -1491
  39. package/src/pkg/grpc/scalekit/v1/sessions/sessions_pb.ts +0 -497
  40. package/src/pkg/grpc/scalekit/v1/users/users_pb.ts +0 -1404
  41. package/src/role.ts +0 -463
  42. package/src/scalekit.ts +0 -800
  43. package/src/session.ts +0 -323
  44. package/src/types/auth.ts +0 -73
  45. package/src/types/organization.ts +0 -12
  46. package/src/types/scalekit.ts +0 -50
  47. package/src/types/user.ts +0 -21
  48. package/src/user.ts +0 -829
  49. package/src/webauthn.ts +0 -99
  50. package/tests/README.md +0 -25
  51. package/tests/connection.test.ts +0 -42
  52. package/tests/directory.test.ts +0 -46
  53. package/tests/domain.test.ts +0 -293
  54. package/tests/organization.test.ts +0 -81
  55. package/tests/passwordless.test.ts +0 -108
  56. package/tests/permission.test.ts +0 -399
  57. package/tests/role.test.ts +0 -323
  58. package/tests/scalekit.test.ts +0 -104
  59. package/tests/setup.ts +0 -34
  60. package/tests/users.test.ts +0 -168
  61. package/tests/utils/test-data.ts +0 -490
  62. package/tsconfig.json +0 -19
package/src/user.ts DELETED
@@ -1,829 +0,0 @@
1
- /**
2
- * Client for managing users and their organization memberships.
3
- *
4
- * This client provides comprehensive user management capabilities including creating users,
5
- * managing their memberships across organizations, updating user profiles, and handling
6
- * invitation emails. Users can belong to multiple organizations with different roles.
7
- *
8
- * @example
9
- * const scalekitClient = new ScalekitClient(envUrl, clientId, clientSecret);
10
- * const userClient = scalekitClient.user;
11
- *
12
- * @see {@link https://docs.scalekit.com/apis/#tag/users | User API Documentation}
13
- */
14
- import type { MessageShape } from "@bufbuild/protobuf";
15
- import { create } from "@bufbuild/protobuf";
16
- import { EmptySchema } from "@bufbuild/protobuf/wkt";
17
- import type { Client } from "@connectrpc/connect";
18
- import GrpcConnect from "./connect";
19
- import CoreClient from "./core";
20
- import { UserService } from "./pkg/grpc/scalekit/v1/users/users_pb";
21
- import {
22
- CreateUserAndMembershipRequest,
23
- CreateUserAndMembershipResponse,
24
- DeleteUserRequest,
25
- GetUserRequest,
26
- GetUserResponse,
27
- ListUsersRequest,
28
- ListUsersResponse,
29
- UpdateUserRequest,
30
- UpdateUserResponse,
31
- User,
32
- UpdateUser,
33
- CreateUser,
34
- CreateUserProfile,
35
- CreateUserSchema,
36
- CreateUserProfileSchema,
37
- UpdateUserSchema,
38
- CreateUserAndMembershipRequestSchema,
39
- CreateMembershipRequest,
40
- CreateMembershipResponse,
41
- CreateMembershipRequestSchema,
42
- DeleteMembershipRequest,
43
- UpdateMembershipRequest,
44
- UpdateMembershipResponse,
45
- ListOrganizationUsersRequest,
46
- ListOrganizationUsersResponse,
47
- CreateMembership,
48
- UpdateMembership,
49
- CreateMembershipSchema,
50
- UpdateMembershipSchema,
51
- ResendInviteRequest,
52
- ResendInviteResponse,
53
- ResendInviteRequestSchema,
54
- } from "./pkg/grpc/scalekit/v1/users/users_pb";
55
- import {
56
- CreateUserRequest,
57
- UpdateUserRequest as UpdateUserRequestType,
58
- } from "./types/user";
59
-
60
- export default class UserClient {
61
- private client: Client<typeof UserService>;
62
-
63
- constructor(
64
- private readonly grpcConnect: GrpcConnect,
65
- private readonly coreClient: CoreClient
66
- ) {
67
- this.client = this.grpcConnect.createClient(UserService);
68
- }
69
-
70
- /**
71
- * Creates a new user and adds them as a member of an organization in a single operation.
72
- *
73
- * This is the primary method for user provisioning. It creates the user account and establishes
74
- * their membership in the specified organization. Optionally sends an invitation email to the user
75
- * with instructions to activate their account.
76
- *
77
- * @param {string} organizationId - The organization ID to add the user to
78
- * @param {CreateUserRequest} options - User creation configuration
79
- * @param {string} options.email - User's email address (required, must be unique)
80
- * @param {object} [options.userProfile] - Optional user profile information
81
- * @param {string} [options.userProfile.firstName] - User's first name
82
- * @param {string} [options.userProfile.lastName] - User's last name
83
- * @param {Record<string, string>} [options.metadata] - Custom metadata key-value pairs
84
- * @param {boolean} [options.sendInvitationEmail=true] - Whether to send invitation email to the user
85
- *
86
- * @returns {Promise<CreateUserAndMembershipResponse>} Response containing:
87
- * - user: The created user object with profile and membership details
88
- *
89
- * @throws {Error} When organizationId is missing or invalid
90
- * @throws {Error} When email is missing or already exists
91
- * @throws {Error} When user creation fails
92
- *
93
- * @example
94
- * // Create user with profile and send invitation
95
- * const response = await scalekitClient.user.createUserAndMembership(
96
- * 'org_123456',
97
- * {
98
- * email: 'john.doe@company.com',
99
- * userProfile: {
100
- * firstName: 'John',
101
- * lastName: 'Doe'
102
- * },
103
- * sendInvitationEmail: true,
104
- * metadata: {
105
- * department: 'Engineering',
106
- * role: 'Developer'
107
- * }
108
- * }
109
- * );
110
- *
111
- * console.log('User created:', response.user.id);
112
- *
113
- * @example
114
- * // Create user without sending invitation
115
- * const response = await scalekitClient.user.createUserAndMembership(
116
- * 'org_123456',
117
- * {
118
- * email: 'jane.smith@company.com',
119
- * sendInvitationEmail: false
120
- * }
121
- * );
122
- *
123
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Create User API}
124
- * @see {@link createMembership} - Add existing user to another organization
125
- * @see {@link resendInvite} - Resend invitation email to a user
126
- */
127
- async createUserAndMembership(
128
- organizationId: string,
129
- options: CreateUserRequest
130
- ): Promise<CreateUserAndMembershipResponse> {
131
- if (!organizationId) {
132
- throw new Error("organizationId is required");
133
- }
134
- if (!options.email) {
135
- throw new Error("email is required");
136
- }
137
-
138
- const user = create(CreateUserSchema, {
139
- email: options.email,
140
- userProfile: options.userProfile
141
- ? create(CreateUserProfileSchema, {
142
- firstName: options.userProfile.firstName,
143
- lastName: options.userProfile.lastName,
144
- })
145
- : undefined,
146
- metadata: options.metadata,
147
- });
148
-
149
- const request = create(CreateUserAndMembershipRequestSchema, {
150
- organizationId,
151
- user,
152
- sendInvitationEmail: options.sendInvitationEmail,
153
- });
154
-
155
- const response = await this.coreClient.connectExec(
156
- this.client.createUserAndMembership,
157
- request
158
- );
159
-
160
- if (!response.user) {
161
- throw new Error("Failed to create user");
162
- }
163
-
164
- return response;
165
- }
166
-
167
- /**
168
- * Retrieves comprehensive details about a specific user including their profile and memberships.
169
- *
170
- * Use this method to fetch complete user information including their organization memberships,
171
- * roles, profile details, and custom metadata. This is useful for displaying user profiles,
172
- * verifying user access, or checking membership status across organizations.
173
- *
174
- * @param {string} userId - The Scalekit-generated user identifier (format: "usr_...")
175
- *
176
- * @returns {Promise<GetUserResponse>} Response containing:
177
- * - user: Complete user object with:
178
- * - id: Scalekit's unique user identifier
179
- * - email: User's email address
180
- * - userProfile: Profile information (firstName, lastName)
181
- * - memberships: Array of organization memberships with roles
182
- * - metadata: Custom metadata key-value pairs
183
- * - createTime: When the user was created
184
- * - updateTime: When the user was last updated
185
- *
186
- * @throws {Error} If the user is not found or access is denied
187
- *
188
- * @example
189
- * // Get user details
190
- * const response = await scalekitClient.user.getUser('usr_123456');
191
- * const user = response.user;
192
- *
193
- * console.log('User:', user.email);
194
- * console.log('Name:', user.userProfile?.firstName, user.userProfile?.lastName);
195
- * console.log('Organizations:', user.memberships?.length);
196
- *
197
- * @example
198
- * // Check user's organization memberships
199
- * const response = await scalekitClient.user.getUser(userId);
200
- * const userOrgs = response.user.memberships?.map(m => m.organizationId) || [];
201
- *
202
- * if (userOrgs.includes('org_12345')) {
203
- * console.log('User is a member of this organization');
204
- * }
205
- *
206
- * @example
207
- * // Display user profile in application
208
- * app.get('/api/profile', async (req, res) => {
209
- * const userId = req.user.id;
210
- *
211
- * try {
212
- * const response = await scalekitClient.user.getUser(userId);
213
- * res.json({
214
- * email: response.user.email,
215
- * profile: response.user.userProfile,
216
- * organizations: response.user.memberships
217
- * });
218
- * } catch (error) {
219
- * res.status(404).json({ error: 'User not found' });
220
- * }
221
- * });
222
- *
223
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Get User API}
224
- * @see {@link listUsers} - List all users across the environment
225
- * @see {@link listOrganizationUsers} - List users in a specific organization
226
- */
227
- async getUser(userId: string): Promise<GetUserResponse> {
228
- return this.coreClient.connectExec(this.client.getUser, {
229
- identities: {
230
- case: "id",
231
- value: userId,
232
- },
233
- });
234
- }
235
-
236
- /**
237
- * Retrieves a paginated list of all users across your Scalekit environment.
238
- *
239
- * This method returns all users in your environment regardless of organization membership.
240
- * It's useful for administrative oversight, auditing, user management interfaces, and
241
- * searching across all users. Use pagination to efficiently handle large user bases.
242
- *
243
- * @param {object} [options] - Optional pagination parameters
244
- * @param {number} [options.pageSize] - Number of users to return per page (valid range: 10-100, default: 10)
245
- * @param {string} [options.pageToken] - Token for retrieving the next page of results.
246
- * Obtained from the previous response's nextPageToken.
247
- *
248
- * @returns {Promise<ListUsersResponse>} Response containing:
249
- * - users: Array of user objects with profiles and membership details
250
- * - nextPageToken: Token for fetching the next page (empty if no more pages)
251
- * - totalSize: Total number of users in the environment
252
- *
253
- * @example
254
- * // List first page of users
255
- * const response = await scalekitClient.user.listUsers({
256
- * pageSize: 20
257
- * });
258
- *
259
- * console.log('Users:', response.users.length);
260
- * console.log('Total users:', response.totalSize);
261
- *
262
- * @example
263
- * // Paginate through all users
264
- * let pageToken = undefined;
265
- * let allUsers = [];
266
- *
267
- * do {
268
- * const response = await scalekitClient.user.listUsers({
269
- * pageSize: 50,
270
- * pageToken
271
- * });
272
- *
273
- * allUsers.push(...response.users);
274
- * pageToken = response.nextPageToken;
275
- * } while (pageToken);
276
- *
277
- * console.log('Fetched all users:', allUsers.length);
278
- *
279
- * @example
280
- * // Build user management dashboard
281
- * app.get('/api/admin/users', async (req, res) => {
282
- * const { pageSize = 25, pageToken } = req.query;
283
- *
284
- * try {
285
- * const response = await scalekitClient.user.listUsers({
286
- * pageSize: parseInt(pageSize),
287
- * pageToken
288
- * });
289
- *
290
- * res.json({
291
- * users: response.users,
292
- * nextPageToken: response.nextPageToken,
293
- * total: response.totalSize
294
- * });
295
- * } catch (error) {
296
- * res.status(500).json({ error: 'Failed to fetch users' });
297
- * }
298
- * });
299
- *
300
- * @see {@link https://docs.scalekit.com/apis/#tag/users | List Users API}
301
- * @see {@link listOrganizationUsers} - List users in a specific organization
302
- * @see {@link getUser} - Get details of a specific user
303
- */
304
- async listUsers(options?: {
305
- pageSize?: number;
306
- pageToken?: string;
307
- }): Promise<ListUsersResponse> {
308
- return this.coreClient.connectExec(this.client.listUsers, {
309
- pageSize: options?.pageSize,
310
- pageToken: options?.pageToken,
311
- });
312
- }
313
-
314
- /**
315
- * Updates a user's profile information and custom metadata.
316
- *
317
- * Use this method to modify user profile details such as name or to update custom metadata
318
- * associated with the user. Note that the user's email address and user ID cannot be changed.
319
- * Only the fields you specify in the update object will be modified; all other fields remain unchanged.
320
- *
321
- * @param {string} userId - The Scalekit user identifier (format: "usr_...")
322
- * @param {UpdateUserRequestType} options - Object containing fields to update:
323
- * - userProfile?: Profile information to update
324
- * - firstName?: User's first name
325
- * - lastName?: User's last name
326
- * - metadata?: Custom key-value pairs for storing additional data
327
- *
328
- * @returns {Promise<UpdateUserResponse>} Response containing:
329
- * - user: The updated user object with all current values
330
- *
331
- * @throws {Error} If the user is not found or update fails
332
- *
333
- * @example
334
- * // Update user's name
335
- * const response = await scalekitClient.user.updateUser('usr_123456', {
336
- * userProfile: {
337
- * firstName: 'John',
338
- * lastName: 'Smith'
339
- * }
340
- * });
341
- *
342
- * console.log('Updated user:', response.user.userProfile);
343
- *
344
- * @example
345
- * // Update user metadata only
346
- * await scalekitClient.user.updateUser('usr_123456', {
347
- * metadata: {
348
- * department: 'Engineering',
349
- * title: 'Senior Developer',
350
- * employeeId: 'EMP-12345'
351
- * }
352
- * });
353
- *
354
- * @example
355
- * // Update both profile and metadata
356
- * const response = await scalekitClient.user.updateUser('usr_123456', {
357
- * userProfile: {
358
- * firstName: 'Jane',
359
- * lastName: 'Doe'
360
- * },
361
- * metadata: {
362
- * phoneNumber: '+1-555-0123',
363
- * timezone: 'America/New_York'
364
- * }
365
- * });
366
- *
367
- * @example
368
- * // Update user profile via API endpoint
369
- * app.patch('/api/users/:userId', async (req, res) => {
370
- * const { userId } = req.params;
371
- * const { firstName, lastName, metadata } = req.body;
372
- *
373
- * try {
374
- * const response = await scalekitClient.user.updateUser(userId, {
375
- * userProfile: { firstName, lastName },
376
- * metadata
377
- * });
378
- * res.json({ user: response.user });
379
- * } catch (error) {
380
- * res.status(500).json({ error: 'Failed to update user' });
381
- * }
382
- * });
383
- *
384
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Update User API}
385
- * @see {@link getUser} - Retrieve current user details
386
- * @see {@link createUserAndMembership} - Create a new user
387
- */
388
- async updateUser(
389
- userId: string,
390
- options: UpdateUserRequestType
391
- ): Promise<UpdateUserResponse> {
392
- const updateUser = create(UpdateUserSchema, {
393
- userProfile: options.userProfile
394
- ? {
395
- firstName: options.userProfile.firstName,
396
- lastName: options.userProfile.lastName,
397
- }
398
- : undefined,
399
- metadata: options.metadata,
400
- });
401
-
402
- return this.coreClient.connectExec(this.client.updateUser, {
403
- identities: {
404
- case: "id",
405
- value: userId,
406
- },
407
- user: updateUser,
408
- });
409
- }
410
-
411
- /**
412
- * Permanently deletes a user from your Scalekit environment.
413
- *
414
- * This operation removes the user's profile, all organization memberships, and related data
415
- * across all organizations. This action is irreversible and cannot be undone. Use with extreme
416
- * caution, especially in production environments. Consider deactivating users or removing specific
417
- * memberships instead of full deletion for compliance and audit purposes.
418
- *
419
- * @param {string} userId - The Scalekit user identifier to delete (format: "usr_...")
420
- *
421
- * @returns {Promise<MessageShape<typeof EmptySchema>>} Empty response on successful deletion
422
- *
423
- * @throws {Error} If the user is not found or deletion fails
424
- *
425
- * @example
426
- * // Delete a user
427
- * await scalekitClient.user.deleteUser('usr_123456');
428
- * console.log('User deleted successfully');
429
- *
430
- * @example
431
- * // Delete user with confirmation flow
432
- * const confirmDelete = await askUserConfirmation(
433
- * 'Are you sure you want to permanently delete this user? This action cannot be undone.'
434
- * );
435
- *
436
- * if (confirmDelete) {
437
- * try {
438
- * await scalekitClient.user.deleteUser(userId);
439
- * console.log('User permanently deleted');
440
- * } catch (error) {
441
- * console.error('Failed to delete user:', error);
442
- * }
443
- * }
444
- *
445
- *
446
- *
447
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Delete User API}
448
- * @see {@link deleteMembership} - Remove user from a specific organization only
449
- * @see {@link getUser} - Check if user exists before deletion
450
- */
451
- async deleteUser(userId: string): Promise<MessageShape<typeof EmptySchema>> {
452
- return this.coreClient.connectExec(this.client.deleteUser, {
453
- identities: {
454
- case: "id",
455
- value: userId,
456
- },
457
- });
458
- }
459
-
460
- /**
461
- * Adds an existing user as a member of a new organization with specified roles.
462
- *
463
- * Use this method to grant organization access to users who already have accounts in your
464
- * Scalekit environment. This is useful for adding users to additional organizations, managing
465
- * multi-tenant access, or onboarding existing users to new teams. Optionally sends an invitation
466
- * email to notify the user of their new organization access.
467
- *
468
- * @param {string} organizationId - The organization ID to add the user to (format: "org_...")
469
- * @param {string} userId - The user ID to add as a member (format: "usr_...")
470
- * @param {object} [options={}] - Optional membership configuration
471
- * @param {string[]} [options.roles] - Array of role names to assign to the user
472
- * (e.g., ['admin', 'editor', 'viewer'])
473
- * @param {Record<string, string>} [options.metadata] - Custom metadata key-value pairs
474
- * for this specific membership
475
- * @param {boolean} [options.sendInvitationEmail=true] - Whether to send invitation email
476
- * notifying the user of new access
477
- *
478
- * @returns {Promise<CreateMembershipResponse>} Response containing:
479
- * - user: The updated user object including the new membership details
480
- *
481
- * @throws {Error} When the user or organization is not found
482
- * @throws {Error} When the user is already a member of the organization
483
- *
484
- * @example
485
- * // Add user to organization with admin role
486
- * const response = await scalekitClient.user.createMembership(
487
- * 'org_123456',
488
- * 'usr_789012',
489
- * {
490
- * roles: ['admin'],
491
- * sendInvitationEmail: true
492
- * }
493
- * );
494
- *
495
- * console.log('Membership created:', response.user.memberships);
496
- *
497
- * @example
498
- * // Add user with multiple roles and metadata
499
- * await scalekitClient.user.createMembership(
500
- * 'org_123456',
501
- * 'usr_789012',
502
- * {
503
- * roles: ['member', 'billing_admin'],
504
- * metadata: {
505
- * department: 'Finance',
506
- * accessLevel: 'full'
507
- * },
508
- * sendInvitationEmail: true
509
- * }
510
- * );
511
- *
512
- * @example
513
- * // Add user to organization without sending email
514
- * await scalekitClient.user.createMembership(
515
- * 'org_123456',
516
- * 'usr_789012',
517
- * { sendInvitationEmail: false }
518
- * );
519
-
520
- *
521
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Create Membership API}
522
- * @see {@link createUserAndMembership} - Create new user with initial membership
523
- * @see {@link updateMembership} - Modify existing membership roles
524
- * @see {@link deleteMembership} - Remove user from organization
525
- */
526
- async createMembership(
527
- organizationId: string,
528
- userId: string,
529
- options: {
530
- roles?: string[];
531
- metadata?: Record<string, string>;
532
- sendInvitationEmail?: boolean;
533
- } = {}
534
- ): Promise<CreateMembershipResponse> {
535
- const membership = create(CreateMembershipSchema, {
536
- roles: options.roles?.map((role) => ({ name: role })) || [],
537
- metadata: options.metadata || {},
538
- });
539
-
540
- const request = create(CreateMembershipRequestSchema, {
541
- organizationId,
542
- identities: {
543
- case: "id",
544
- value: userId,
545
- },
546
- membership,
547
- sendInvitationEmail: options.sendInvitationEmail,
548
- });
549
-
550
- return this.coreClient.connectExec(this.client.createMembership, request);
551
- }
552
-
553
- /**
554
- * Removes a user's membership from a specific organization.
555
- *
556
- * This operation revokes the user's access to the specified organization while keeping their
557
- * user account intact. The user remains in the system and can still access other organizations
558
- * they're a member of. This is the recommended approach when you want to remove access to a
559
- * specific organization without deleting the entire user account. This action is irreversible.
560
- *
561
- * @param {string} organizationId - The organization ID to remove the user from (format: "org_...")
562
- * @param {string} userId - The user ID to remove (format: "usr_...")
563
- *
564
- * @returns {Promise<MessageShape<typeof EmptySchema>>} Empty response on successful removal
565
- *
566
- * @throws {Error} If the user or organization is not found
567
- * @throws {Error} If the membership doesn't exist
568
- *
569
- * @example
570
- * // Remove user from organization
571
- * await scalekitClient.user.deleteMembership('org_123456', 'usr_789012');
572
- * console.log('User removed from organization');
573
- *
574
- * @example
575
- * // Remove user with confirmation
576
- * const confirmRemoval = await askUserConfirmation(
577
- * 'Remove this user from the organization?'
578
- * );
579
- *
580
- * if (confirmRemoval) {
581
- * try {
582
- * await scalekitClient.user.deleteMembership(organizationId, userId);
583
- * console.log('User access revoked');
584
- * } catch (error) {
585
- * console.error('Failed to remove user:', error);
586
- * }
587
- * }
588
- *
589
- *
590
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Delete Membership API}
591
- * @see {@link deleteUser} - Permanently delete user from all organizations
592
- * @see {@link createMembership} - Add user to an organization
593
- * @see {@link updateMembership} - Modify user's roles in organization
594
- */
595
- async deleteMembership(
596
- organizationId: string,
597
- userId: string
598
- ): Promise<MessageShape<typeof EmptySchema>> {
599
- return this.coreClient.connectExec(this.client.deleteMembership, {
600
- organizationId,
601
- identities: {
602
- case: "id",
603
- value: userId,
604
- },
605
- });
606
- }
607
-
608
- /**
609
- * Updates a user's roles and metadata within a specific organization.
610
- *
611
- * Use this method to modify a user's permissions by changing their assigned roles or to
612
- * update membership-specific metadata. This allows you to adjust user access levels,
613
- * promote/demote users, or track organization-specific information without affecting
614
- * the user's memberships in other organizations.
615
- *
616
- * @param {string} organizationId - The organization ID where the membership exists (format: "org_...")
617
- * @param {string} userId - The user ID whose membership to update (format: "usr_...")
618
- * @param {object} [options={}] - Fields to update
619
- * @param {string[]} [options.roles] - Array of role names to assign (replaces existing roles)
620
- * (e.g., ['admin'], ['member', 'billing'])
621
- * @param {Record<string, string>} [options.metadata] - Custom metadata key-value pairs
622
- * specific to this membership
623
- *
624
- * @returns {Promise<UpdateMembershipResponse>} Response containing:
625
- * - user: The updated user object with modified membership details
626
- *
627
- * @throws {Error} If the user, organization, or membership is not found
628
- *
629
- * @example
630
- * // Promote user to admin
631
- * const response = await scalekitClient.user.updateMembership(
632
- * 'org_123456',
633
- * 'usr_789012',
634
- * { roles: ['admin'] }
635
- * );
636
- *
637
- * console.log('User promoted:', response.user.memberships);
638
- *
639
- * @example
640
- * // Assign multiple roles
641
- * await scalekitClient.user.updateMembership(
642
- * 'org_123456',
643
- * 'usr_789012',
644
- * { roles: ['member', 'billing_admin', 'support'] }
645
- * );
646
- *
647
- * @example
648
- * // Update membership metadata
649
- * await scalekitClient.user.updateMembership(
650
- * 'org_123456',
651
- * 'usr_789012',
652
- * {
653
- * metadata: {
654
- * department: 'Engineering',
655
- * team: 'Backend',
656
- * startDate: '2025-01-01'
657
- * }
658
- * }
659
- * );
660
- *
661
- * @example
662
- * // Update both roles and metadata
663
- * await scalekitClient.user.updateMembership(
664
- * 'org_123456',
665
- * 'usr_789012',
666
- * {
667
- * roles: ['team_lead', 'developer'],
668
- * metadata: {
669
- * level: 'senior',
670
- * permissions: 'full'
671
- * }
672
- * }
673
- * );
674
- *
675
- *
676
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Update Membership API}
677
- * @see {@link createMembership} - Add user to organization
678
- * @see {@link deleteMembership} - Remove user from organization
679
- * @see {@link getUser} - View current user roles and memberships
680
- */
681
- async updateMembership(
682
- organizationId: string,
683
- userId: string,
684
- options: {
685
- roles?: string[];
686
- metadata?: Record<string, string>;
687
- } = {}
688
- ): Promise<UpdateMembershipResponse> {
689
- const membership = create(UpdateMembershipSchema, {
690
- roles: options.roles?.map((role) => ({ name: role })) || [],
691
- metadata: options.metadata || {},
692
- });
693
-
694
- return this.coreClient.connectExec(this.client.updateMembership, {
695
- organizationId,
696
- identities: {
697
- case: "id",
698
- value: userId,
699
- },
700
- membership,
701
- });
702
- }
703
-
704
- /**
705
- * Retrieves a paginated list of all users who are members of a specific organization.
706
- *
707
- * This method returns all users with access to the specified organization, including their
708
- * roles, membership details, and profiles. This is useful for displaying team member lists,
709
- * managing organization access, or building user management interfaces. Use pagination to
710
- * efficiently handle organizations with large member counts.
711
- *
712
- * @param {string} organizationId - The organization ID to list users from (format: "org_...")
713
- * @param {object} [options] - Optional pagination parameters
714
- * @param {number} [options.pageSize] - Number of users to return per page (valid range: 1-100)
715
- * @param {string} [options.pageToken] - Token for retrieving the next page of results.
716
- * Obtained from the previous response's nextPageToken.
717
- *
718
- * @returns {Promise<ListOrganizationUsersResponse>} Response containing:
719
- * - users: Array of user objects with profiles, roles, and membership details
720
- * - nextPageToken: Token for fetching the next page (empty if no more pages)
721
- * - totalSize: Total number of users in the organization
722
- *
723
- * @throws {Error} If the organization is not found
724
- *
725
- * @example
726
- * // List first page of organization users
727
- * const response = await scalekitClient.user.listOrganizationUsers('org_123456', {
728
- * pageSize: 25
729
- * });
730
- *
731
- * console.log('Organization users:', response.users.length);
732
- * console.log('Total members:', response.totalSize);
733
- *
734
- * @example
735
- * // Paginate through all organization members
736
- * let pageToken = undefined;
737
- * let allMembers = [];
738
- *
739
- * do {
740
- * const response = await scalekitClient.user.listOrganizationUsers(
741
- * 'org_123456',
742
- * { pageSize: 50, pageToken }
743
- * );
744
- *
745
- * allMembers.push(...response.users);
746
- * pageToken = response.nextPageToken;
747
- * } while (pageToken);
748
- *
749
- * console.log('All organization members:', allMembers.length);
750
- *
751
- *
752
- * console.log('Organization admins:', admins.length);
753
- *
754
- * @see {@link https://docs.scalekit.com/apis/#tag/users | List Organization Users API}
755
- * @see {@link listUsers} - List all users across the environment
756
- * @see {@link getUser} - Get details of a specific user
757
- * @see {@link createMembership} - Add user to organization
758
- */
759
- async listOrganizationUsers(
760
- organizationId: string,
761
- options?: {
762
- pageSize?: number;
763
- pageToken?: string;
764
- }
765
- ): Promise<ListOrganizationUsersResponse> {
766
- return this.coreClient.connectExec(this.client.listOrganizationUsers, {
767
- organizationId,
768
- pageSize: options?.pageSize,
769
- pageToken: options?.pageToken,
770
- });
771
- }
772
-
773
- /**
774
- * Resends an invitation email to a user for a specific organization.
775
- *
776
- * Use this method when a user hasn't received or has lost their invitation email. If the
777
- * original invitation is still valid, a reminder email will be sent. If the invitation has
778
- * expired, a new invitation with a secure magic link will be created and sent. This is useful
779
- * for helping users who need to complete their account setup or activate their organization access.
780
- *
781
- * @param {string} organizationId - The organization ID for which to resend the invite (format: "org_...")
782
- * @param {string} userId - The user ID who should receive the invite (format: "usr_...")
783
- *
784
- * @returns {Promise<ResendInviteResponse>} Response containing:
785
- * - invite: The invitation details including status and expiration
786
- *
787
- * @throws {Error} When organizationId is missing or invalid
788
- * @throws {Error} When userId is missing or invalid
789
- * @throws {Error} When the user or organization is not found
790
- * @throws {Error} When the membership doesn't exist
791
- *
792
- * @example
793
- * // Resend invitation to a user
794
- * const response = await scalekitClient.user.resendInvite('org_123456', 'usr_789012');
795
- * console.log('Invitation resent:', response.invite);
796
- *
797
- * @example
798
- * // Resend invitation with error handling
799
- * try {
800
- * await scalekitClient.user.resendInvite(organizationId, userId);
801
- * console.log('Invitation email sent successfully');
802
- * } catch (error) {
803
- * console.error('Failed to resend invitation:', error);
804
- * }
805
- *
806
- * @see {@link https://docs.scalekit.com/apis/#tag/users | Resend Invite API}
807
- * @see {@link createUserAndMembership} - Create user with initial invitation
808
- * @see {@link createMembership} - Add user to organization with invitation option
809
- * @see {@link getUser} - Check user's invitation status
810
- */
811
- async resendInvite(
812
- organizationId: string,
813
- userId: string
814
- ): Promise<ResendInviteResponse> {
815
- if (!organizationId) {
816
- throw new Error("organizationId is required");
817
- }
818
- if (!userId) {
819
- throw new Error("userId is required");
820
- }
821
-
822
- const request = create(ResendInviteRequestSchema, {
823
- organizationId,
824
- id: userId,
825
- });
826
-
827
- return this.coreClient.connectExec(this.client.resendInvite, request);
828
- }
829
- }